HDLRuby 2.4.29 → 2.6.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/HDLRuby/drivers/xcd.rb +79 -0
- data/lib/HDLRuby/drivers/xcd/dummy.xcd +4 -0
- data/lib/HDLRuby/hdr_samples/adder.rb +1 -1
- data/lib/HDLRuby/hdr_samples/adder_bench.rb +1 -1
- data/lib/HDLRuby/hdr_samples/adder_gen.rb +1 -1
- data/lib/HDLRuby/hdr_samples/constant_in_function.rb +27 -0
- data/lib/HDLRuby/hdr_samples/dff_properties.rb +19 -0
- data/lib/HDLRuby/hdr_samples/dff_unit.rb +54 -0
- data/lib/HDLRuby/hdr_samples/huge_rom.rb +25 -0
- data/lib/HDLRuby/hdr_samples/logic_bench.rb +21 -0
- data/lib/HDLRuby/hdr_samples/mei8_bench.rb +1 -1
- data/lib/HDLRuby/hdr_samples/multi_timed_bench.rb +54 -0
- data/lib/HDLRuby/hdr_samples/music.rb +79 -0
- data/lib/HDLRuby/hdr_samples/named_sub.rb +42 -0
- data/lib/HDLRuby/hdr_samples/rom.rb +16 -0
- data/lib/HDLRuby/hdr_samples/with_function_generator.rb +25 -0
- data/lib/HDLRuby/hdrcc.rb +162 -26
- data/lib/HDLRuby/hruby_decorator.rb +250 -0
- data/lib/HDLRuby/hruby_high.rb +468 -91
- data/lib/HDLRuby/hruby_low.rb +913 -45
- data/lib/HDLRuby/hruby_low2c.rb +122 -168
- data/lib/HDLRuby/hruby_low2hdr.rb +738 -0
- data/lib/HDLRuby/hruby_low2high.rb +331 -549
- data/lib/HDLRuby/hruby_low2vhd.rb +39 -2
- data/lib/HDLRuby/hruby_low_bool2select.rb +29 -0
- data/lib/HDLRuby/hruby_low_casts_without_expression.rb +27 -0
- data/lib/HDLRuby/hruby_low_fix_types.rb +25 -0
- data/lib/HDLRuby/hruby_low_mutable.rb +70 -0
- data/lib/HDLRuby/hruby_low_resolve.rb +28 -0
- data/lib/HDLRuby/hruby_low_without_connection.rb +6 -3
- data/lib/HDLRuby/hruby_low_without_namespace.rb +7 -4
- data/lib/HDLRuby/hruby_low_without_select.rb +13 -0
- data/lib/HDLRuby/hruby_tools.rb +11 -1
- data/lib/HDLRuby/hruby_verilog.rb +1577 -1709
- data/lib/HDLRuby/sim/hruby_sim.h +29 -3
- data/lib/HDLRuby/sim/hruby_sim_calc.c +63 -6
- data/lib/HDLRuby/sim/hruby_sim_core.c +24 -9
- data/lib/HDLRuby/sim/hruby_sim_vcd.c +5 -1
- data/lib/HDLRuby/sim/hruby_sim_vizualize.c +22 -6
- data/lib/HDLRuby/std/fixpoint.rb +9 -0
- data/lib/HDLRuby/std/function_generator.rb +139 -0
- data/lib/HDLRuby/std/hruby_unit.rb +75 -0
- data/lib/HDLRuby/template_expander.rb +61 -0
- data/lib/HDLRuby/version.rb +1 -1
- metadata +21 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: af0232d02d732388bb78569f40cf262167aeb9a5dc51b3b7ea98cf58a39da918
|
4
|
+
data.tar.gz: 5f46a159e7c3e0bf4414de3cda6bc78e5ac57060d958f0760a52012e18bc551e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 69176b251e8c1a226e08ad1c45d3d57176c58424e849094ee07cbb3591a5743daf146a332076691ebbab9e100adb7d6a7a23104a1657bb684b79598f6df3ee03
|
7
|
+
data.tar.gz: 7f99f1f0551682713ecb20b9a0e93c85b6f7244c6ad6b0c3aa7e587b915be400ce914cedbb2f17a890a1e813db79c5d50b7117746c0d405386788d78d09c22db
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require "HDLRuby/template_expander"
|
2
|
+
|
3
|
+
##
|
4
|
+
# XCD file generator from 'xcd' properties
|
5
|
+
##########################################
|
6
|
+
|
7
|
+
|
8
|
+
# Generates a xcd file from the HDLRuby objects from +top+ using
|
9
|
+
# their 'xcd' properties.
|
10
|
+
# The file is saved in +path+ directory.
|
11
|
+
def xcd_generator(top, path)
|
12
|
+
# Ensure top is a system.
|
13
|
+
if top.is_a?(HDLRuby::Low::SystemI) then
|
14
|
+
top = top.systemT
|
15
|
+
elsif !top.is_a?(HDLRuby::Low::SystemT) then
|
16
|
+
raise "The 'xcd_generator' driver can only be applied on SystemT objects."
|
17
|
+
end
|
18
|
+
|
19
|
+
# Get the name of the resulting file if any.
|
20
|
+
if (top.properties.key?(:xcd_file)) then
|
21
|
+
xcd_file = top.properties[:xcd_file].join
|
22
|
+
else
|
23
|
+
# Default file name.
|
24
|
+
xcd_file = "default.xcd"
|
25
|
+
end
|
26
|
+
|
27
|
+
# Get the target template.
|
28
|
+
xcd_target = top.properties[:xcd_target].join
|
29
|
+
xcd_target_name = xcd_target
|
30
|
+
xcd_target_name += ".xcd" unless xcd_target_name.end_with?(".xcd")
|
31
|
+
xcd_target_tries = [ xcd_target_name,
|
32
|
+
File.join(path,xcd_target_name),
|
33
|
+
File.join(File.dirname(__FILE__),"xcd",xcd_target_name) ]
|
34
|
+
xcd_target_file = xcd_target_tries.find { |fname| File.exist?(fname) }
|
35
|
+
unless xcd_target_file then
|
36
|
+
raise "XCD target template not found for #{xcd_target}."
|
37
|
+
end
|
38
|
+
# Load the template.
|
39
|
+
template = File.read(xcd_target_file)
|
40
|
+
|
41
|
+
# Gather the signals by xcd key.
|
42
|
+
xcd2sig = top.each_signal.reduce([]) do |ar,sig|
|
43
|
+
ar += sig.properties.each_with_key(:xcd).map do |val|
|
44
|
+
[val,sig.name.to_s]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Create the template expander that will generate the xcd file.
|
49
|
+
expander = TemplateExpander.new([
|
50
|
+
[ /^\?.*(\n|\z)/, proc do |str| # Signal link to port
|
51
|
+
if xcd2sig.any? do |match,rep|
|
52
|
+
if str.include?(match) then
|
53
|
+
str = str.gsub("<>",rep)[1..-1]
|
54
|
+
else
|
55
|
+
false
|
56
|
+
end
|
57
|
+
end then
|
58
|
+
str
|
59
|
+
else
|
60
|
+
""
|
61
|
+
end
|
62
|
+
end ]
|
63
|
+
])
|
64
|
+
|
65
|
+
# # Generate the xcd file.
|
66
|
+
# File.open(File.join(path,xcd_file),"w") do |file|
|
67
|
+
# # Generate the signals mapping.
|
68
|
+
# top.each_signal do |signal|
|
69
|
+
# signal.properties.each_with_key(:xcd) do |value|
|
70
|
+
# file << "#{value}\n"
|
71
|
+
# end
|
72
|
+
# end
|
73
|
+
# end
|
74
|
+
|
75
|
+
# Generate the xcd file.
|
76
|
+
File.open(File.join(path,xcd_file),"w") do |file|
|
77
|
+
expander.expand(template,file)
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Sample for testing constant declaration in function.
|
2
|
+
|
3
|
+
|
4
|
+
function :func do |addr|
|
5
|
+
bit[4][-4].constant tbl: [ _0000, _0001, _0010, _0011 ]
|
6
|
+
|
7
|
+
tbl[addr]
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
system :with_func do
|
12
|
+
[4].inner :addr, :val
|
13
|
+
|
14
|
+
val <= func(addr)
|
15
|
+
# val <= 1
|
16
|
+
|
17
|
+
timed do
|
18
|
+
addr <= 0
|
19
|
+
!10.ns
|
20
|
+
addr <= 1
|
21
|
+
!10.ns
|
22
|
+
addr <= 2
|
23
|
+
!10.ns
|
24
|
+
addr <= 3
|
25
|
+
!10.ns
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# A simple D-FF
|
2
|
+
system :dff do
|
3
|
+
input :clk, :rst, :d
|
4
|
+
output :q, :qb
|
5
|
+
|
6
|
+
qb <= ~q
|
7
|
+
|
8
|
+
par(clk.posedge) { q <= d & ~rst }
|
9
|
+
|
10
|
+
clk.properties[:xcd] = "CLK"
|
11
|
+
rst.properties[:xcd] = "RST"
|
12
|
+
d.properties[:xcd] = "PORT0"
|
13
|
+
q.properties[:xcd] = "PORT1"
|
14
|
+
qb.properties[:xcd] = "PORT2"
|
15
|
+
cur_system.properties[:xcd_target] = "dummy"
|
16
|
+
cur_system.properties[:xcd_file] = "dff.xcd"
|
17
|
+
cur_system.properties[:post_driver] = "drivers/xcd.rb", :xcd_generator
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Testing HDLRuby unit test.
|
2
|
+
# require 'std/hruby_unit.rb'
|
3
|
+
|
4
|
+
# Declare multiple simple dff-systems and their corresponding test.
|
5
|
+
|
6
|
+
3.times do |i|
|
7
|
+
|
8
|
+
# A simple D-FF
|
9
|
+
system:"dff#{i}" do
|
10
|
+
input :clk, :rst, :d
|
11
|
+
output :q, :qb
|
12
|
+
|
13
|
+
qb <= ~q
|
14
|
+
|
15
|
+
par(clk.posedge) { q <= d & ~rst }
|
16
|
+
end
|
17
|
+
|
18
|
+
# Code for testing it.
|
19
|
+
Unit.system :"test_dff#{i}" do
|
20
|
+
inner :clk, :rst, :d, :q, :qb
|
21
|
+
|
22
|
+
send(:"dff#{i}",:dffI).(clk,rst,d,q,qb)
|
23
|
+
|
24
|
+
test do
|
25
|
+
clk <= 0
|
26
|
+
rst <= 0
|
27
|
+
d <= 0
|
28
|
+
!10.ns
|
29
|
+
clk <= 1
|
30
|
+
!10.ns
|
31
|
+
clk <= 0
|
32
|
+
rst <= 1
|
33
|
+
!10.ns
|
34
|
+
clk <= 1
|
35
|
+
!10.ns
|
36
|
+
clk <= 0
|
37
|
+
rst <= 0
|
38
|
+
!10.ns
|
39
|
+
clk <= 1
|
40
|
+
!10.ns
|
41
|
+
clk <= 0
|
42
|
+
d <= 1
|
43
|
+
!10.ns
|
44
|
+
clk <= 1
|
45
|
+
!10.ns
|
46
|
+
clk <= 0
|
47
|
+
d <= 0
|
48
|
+
!10.ns
|
49
|
+
clk <= 1
|
50
|
+
!10.ns
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Describes an 8-bit data 16-bit address ROM.
|
2
|
+
system :huge_rom do
|
3
|
+
[15..0].input :addr
|
4
|
+
[7..0].output :data
|
5
|
+
|
6
|
+
bit[7..0][-65536].constant content: 65536.times.to_a
|
7
|
+
|
8
|
+
data <= content[addr]
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
system :test_rom do
|
14
|
+
[15..0].inner :addr
|
15
|
+
[7..0].inner :data
|
16
|
+
|
17
|
+
huge_rom(:my_rom).(addr,data)
|
18
|
+
|
19
|
+
timed do
|
20
|
+
8.times do |i|
|
21
|
+
addr <= i
|
22
|
+
!10.ns
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
# A benchmark for the logic operations.
|
3
|
+
system :logic_bench do
|
4
|
+
[3].inner :x,:y
|
5
|
+
[3].inner :s_not, :s_and, :s_or, :s_xor, :s_nxor
|
6
|
+
|
7
|
+
timed do
|
8
|
+
8.times do |i|
|
9
|
+
8.times do |j|
|
10
|
+
x <= i
|
11
|
+
y <= j
|
12
|
+
s_not <= ~x
|
13
|
+
s_and <= x & y
|
14
|
+
s_or <= x | y
|
15
|
+
s_xor <= x ^ y
|
16
|
+
s_nxor <= (x == y)
|
17
|
+
!10.ns
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -28,7 +28,7 @@ system :mei8 do |prog_file = "./prog.obj"|
|
|
28
28
|
bit[7..0][-256].constant mem: # The content of the memory
|
29
29
|
( File.readlines(prog_file).map {|l| l.split[0] }.select do |l|
|
30
30
|
["0","1"].include?(l[2])
|
31
|
-
end.map {|l| l[2..9] } )
|
31
|
+
end.map {|l| l[2..9].to_i(2) } )
|
32
32
|
instr <= mem[addr] # The access procedure
|
33
33
|
end
|
34
34
|
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Test the execution of multiple timed behaviors
|
2
|
+
system :multi_timed do
|
3
|
+
inner :clk1, :clk2, :rst, :button
|
4
|
+
[8].inner :counter1, :counter2
|
5
|
+
|
6
|
+
# The process controlling counter1.
|
7
|
+
par(clk1.posedge) do
|
8
|
+
hif(rst) { counter1 <= 0 }
|
9
|
+
helsif(button) { counter1 <= counter1 + 1 }
|
10
|
+
end
|
11
|
+
|
12
|
+
# The process controlling counter2.
|
13
|
+
par(clk2.posedge) do
|
14
|
+
hif(rst) { counter2 <= 0 }
|
15
|
+
helsif(button) { counter2 <= counter2 + 1 }
|
16
|
+
end
|
17
|
+
|
18
|
+
# The process for clk1
|
19
|
+
timed do
|
20
|
+
50.times do
|
21
|
+
clk1 <= 0
|
22
|
+
!10.ns
|
23
|
+
clk1 <= 1
|
24
|
+
!10.ns
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# The process for clk2
|
29
|
+
timed do
|
30
|
+
80.times do
|
31
|
+
clk2 <= 0
|
32
|
+
!3.ns
|
33
|
+
clk2 <= 1
|
34
|
+
!3.ns
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# The control process
|
39
|
+
timed do
|
40
|
+
rst <= 0
|
41
|
+
button <= 0
|
42
|
+
!10.ns
|
43
|
+
rst <= 1
|
44
|
+
!20.ns
|
45
|
+
rst <= 0
|
46
|
+
!10.ns
|
47
|
+
10.times do
|
48
|
+
button <= 1
|
49
|
+
!20.ns
|
50
|
+
button <= 0
|
51
|
+
!20.ns
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# require "std/fixpoint.rb"
|
2
|
+
# require_relative "activation_function.rb"
|
3
|
+
require 'std/function_generator.rb'
|
4
|
+
|
5
|
+
include HDLRuby::High::Std
|
6
|
+
|
7
|
+
system :music do
|
8
|
+
|
9
|
+
input :clk, :rst
|
10
|
+
[24].output :sound
|
11
|
+
|
12
|
+
# func_sin = proc { |i| Math.sin(i) }
|
13
|
+
# More efficient:
|
14
|
+
func_sin = Math.method(:sin)
|
15
|
+
|
16
|
+
# bit[8,8].inner :time
|
17
|
+
# signed[2,22].inner :sin_val0
|
18
|
+
# signed[2,22].inner :sin_val1
|
19
|
+
bit[8].inner :time
|
20
|
+
signed[24].inner :sin_val0
|
21
|
+
signed[24].inner :sin_val1
|
22
|
+
|
23
|
+
# activation_function(func_sin,signed[2,22],8,8,16).(:func_sin0_generator).(time,sin_val0)
|
24
|
+
# activation_function(func_sin,signed[2,22],8,8,16).(:func_sin1_generator).(time/2,sin_val1)
|
25
|
+
function_generator(func_sin,bit[8],signed[24],4,-Math::PI..Math::PI,-2..2).(:func_sin0_generator).(time,sin_val0)
|
26
|
+
function_generator(func_sin,bit[8],signed[24],4,-Math::PI*2..Math::PI*2,-2..2).(:func_sin1_generator).(time/2,sin_val1)
|
27
|
+
|
28
|
+
# signed[2,22].inner :sound0
|
29
|
+
signed[48].inner :sound0
|
30
|
+
|
31
|
+
sound0 <= sin_val0.as(signed[24]) * sin_val1
|
32
|
+
|
33
|
+
sound <= sound0[47..24]
|
34
|
+
|
35
|
+
par(clk.posedge) do
|
36
|
+
hif(rst) { time <= 0 }
|
37
|
+
helse do
|
38
|
+
# time <= time + _0000000000000001
|
39
|
+
time <= time + _00000001
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
system :music_test do
|
49
|
+
|
50
|
+
inner :clk,:rst
|
51
|
+
[24].inner :sound
|
52
|
+
|
53
|
+
music(:my_music).(clk,rst,sound)
|
54
|
+
|
55
|
+
timed do
|
56
|
+
clk <= 0
|
57
|
+
rst <= 0
|
58
|
+
!10.ns
|
59
|
+
clk <= 1
|
60
|
+
!10.ns
|
61
|
+
clk <= 0
|
62
|
+
rst <= 1
|
63
|
+
!10.ns
|
64
|
+
clk <= 1
|
65
|
+
!10.ns
|
66
|
+
clk <= 0
|
67
|
+
!10.ns
|
68
|
+
clk <= 1
|
69
|
+
!10.ns
|
70
|
+
clk <= 0
|
71
|
+
rst <= 0
|
72
|
+
256.times do
|
73
|
+
!10.ns
|
74
|
+
clk <= 1
|
75
|
+
!10.ns
|
76
|
+
clk <= 0
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
##
|
2
|
+
# Sample testing named sub
|
3
|
+
#######################################
|
4
|
+
|
5
|
+
|
6
|
+
# A simple circuit with named sub
|
7
|
+
system :named_sub do
|
8
|
+
input :x, :y
|
9
|
+
output :s
|
10
|
+
|
11
|
+
sub :somesub do
|
12
|
+
inner :sig
|
13
|
+
end
|
14
|
+
|
15
|
+
seq do
|
16
|
+
somesub.sig <= x | y
|
17
|
+
s <= ~somesub.sig
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
# A benchmark for the circuit.
|
23
|
+
system :named_sub_bench do
|
24
|
+
inner :x, :y, :s
|
25
|
+
|
26
|
+
named_sub(:my_named_sub).(x,y,s)
|
27
|
+
|
28
|
+
timed do
|
29
|
+
x <= 0
|
30
|
+
y <= 0
|
31
|
+
!10.ns
|
32
|
+
x <= 1
|
33
|
+
y <= 0
|
34
|
+
!10.ns
|
35
|
+
x <= 0
|
36
|
+
y <= 1
|
37
|
+
!10.ns
|
38
|
+
x <= 1
|
39
|
+
y <= 1
|
40
|
+
!10.ns
|
41
|
+
end
|
42
|
+
end
|