HDLRuby 2.7.5 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4995e808d0aa2901a483011a4848bb9416d68850c95c74b9c2f2bf1fb3f648dc
4
- data.tar.gz: 729643cd60228ab9ba4f3ab719e434b48963805ed6f4ac01dbcff2fdd6eb54b9
3
+ metadata.gz: 96e1ddbe94d4b2b40301b61373ed4cea3b2b5bcb461338844af6ebd23380ad4f
4
+ data.tar.gz: e8e3c5bdc2c7a91c25f41964a15a80a39701c54a49b09540c637b14130bc08e6
5
5
  SHA512:
6
- metadata.gz: 82316dd87a532dbfa67d86fcdb13ade3f8329912bb6aa56ae0b5a4efe0a6110922912f52ae3558c4683147bb224ae2ed0b67e1d60e265d5d30624b3a2bee77be
7
- data.tar.gz: 4df2cfb5c257838246fa2f953b3eeaa751902900ae4ea5319a69ca81f9e7eae49b75163fc621a81b2af1b399360c030ccf8717916c2abb7a5d2ffaad27d2b5df
6
+ metadata.gz: 2c63c50fb2aa3683cb43246b0036ccbe89155ad08d122f738a6ba68bd0886a089608ddc6592d0a728dc7476d00e480ed1f8e0ba4ac97dd97dcbb994099598f90
7
+ data.tar.gz: 04ee073e082ab0cc9993a7f7888d85959570e969bf83b3247874df6888559be8c4a8d561d5276a9c9d8042f86302b95d4454bb7803aec0e41210c1c747cc4fba
data/README.md CHANGED
@@ -439,7 +439,7 @@ The description above is straight forward, but it would be necessary to rewrite
439
439
 
440
440
  ```ruby
441
441
  system :sumprod do |typ,coefs|
442
- typ[coefs.size].input ins
442
+ typ[coefs.size].input :ins
443
443
  typ.output :o
444
444
 
445
445
  o <= coefs.each_with_index.reduce(_0) do |sum,(coef,i)|
@@ -5,3 +5,25 @@ system :adder do |w|
5
5
 
6
6
  s <= x.as(bit[w+1]) + y
7
7
  end
8
+
9
+
10
+ # Testing the generic adder.
11
+ system :adder_bench do
12
+ width = 4
13
+ [width].inner :x,:y
14
+ [width+1].inner :z
15
+
16
+ adder(width).(:my_adder).(x,y,z)
17
+
18
+ timed do
19
+ x <= 0
20
+ y <= 0
21
+ !10.ns
22
+ x <= 1
23
+ !10.ns
24
+ y <= 1
25
+ !10.ns
26
+ x <= 15
27
+ !10.ns
28
+ end
29
+ end
@@ -0,0 +1,40 @@
1
+ # A simple generic adder
2
+ system :adder do |w|
3
+ [(w-1)..0].input :i,:j
4
+ [w..0].output :k
5
+
6
+ k <= i.as(bit[w+1]) + j
7
+ end
8
+
9
+ # A module embedding two generic adders.
10
+ system :two_adders do |w|
11
+ [w*2].input :x, :y
12
+ [(w+1)*2].output :z
13
+
14
+ adder(w).(:adderI0).(x[(w-1)..0],y[(w-1)..0],z[w..0])
15
+ adder(w).(:adderI1).(x[(w*2-1)..w],y[(w*2-1)..w],z[(w*2+1)..(w+1)])
16
+ end
17
+
18
+
19
+ # Testing the generic adder.
20
+ system :adder_bench do
21
+ width = 4
22
+ [width*2].inner :a,:b
23
+ [(width+1)*2].inner :c
24
+
25
+ two_adders(width).(:my_adders).(a,b,c)
26
+
27
+ timed do
28
+ a <= 0
29
+ b <= 0
30
+ !10.ns
31
+ a <= 1
32
+ !10.ns
33
+ b <= 1
34
+ !10.ns
35
+ a <= 255
36
+ !10.ns
37
+ b <= 128
38
+ !10.ns
39
+ end
40
+ end
@@ -6,7 +6,7 @@
6
6
  3.times do |i|
7
7
 
8
8
  # A simple D-FF
9
- system:"dff#{i}" do
9
+ system :"dff#{i}" do
10
10
  input :clk, :rst, :d
11
11
  output :q, :qb
12
12
 
@@ -0,0 +1,61 @@
1
+ # Check of various par and seq.
2
+
3
+ # A benchmark for the dff.
4
+ system :parseq_bench do
5
+ [4].inner :x0, :x1, :x2, :x3
6
+ [4].inner :y0, :y1, :y2, :y3
7
+ [4].inner :z00, :z01
8
+ [4].inner :z10, :z11
9
+ [4].inner :z20, :z21
10
+ [4].inner :z30, :z31
11
+ [4].inner :u0, :u1, :u2, :u3
12
+ bit[4][-16].constant mem: 16.times.to_a
13
+
14
+ par(x0) do
15
+ z00 <= x0 + y0
16
+ z01 <= z00 + 1
17
+ u0 <= mem[z00]
18
+ end
19
+
20
+ seq(y1) do
21
+ z10 <= x1 + y1
22
+ z11 <= z10 + 1
23
+ u1 <= mem[z10]
24
+ end
25
+
26
+ seq(x2,y2) do
27
+ z20 <= x2 + y2
28
+ z21 <= z20 + 1
29
+ u2 <= mem[z20]
30
+ end
31
+
32
+ par do
33
+ bit[4].constant inc: 1
34
+ z30 <= x3 + y3
35
+ z31 <= z30 + inc
36
+ u3 <= mem[z30]
37
+ end
38
+
39
+
40
+ timed do
41
+ x0 <= 1
42
+ x1 <= 1
43
+ x2 <= 1
44
+ x3 <= 1
45
+ !10.ns
46
+ y0 <= 2
47
+ y1 <= 2
48
+ y2 <= 2
49
+ y3 <= 2
50
+ !10.ns
51
+ x0 <= 3
52
+ x1 <= 3
53
+ x2 <= 3
54
+ x3 <= 3
55
+ y0 <= 4
56
+ y1 <= 4
57
+ y2 <= 4
58
+ y3 <= 4
59
+ !10.ns
60
+ end
61
+ end
@@ -3,13 +3,16 @@
3
3
  # A benchmark for the index access..
4
4
  system :if_bench do
5
5
  [8].inner :x
6
- [2].inner :r0,:r1,:r2,:r3
6
+ [2].inner :r0,:r1,:r2,:r3, :r4
7
+ inner :r5
7
8
 
8
9
  par do
9
10
  r0 <= x[1..0]
10
11
  r1 <= x[3..2]
11
12
  r2 <= x[5..4]
12
13
  r3 <= x[7..6]
14
+ r4 <= x[-1..-2]
15
+ r5 <= x[-1]
13
16
  end
14
17
 
15
18
  timed do
@@ -0,0 +1,27 @@
1
+ # Rom access generator, def case.
2
+ def rom_gen(addr,&func)
3
+ bit[8][-8].constant tbl? => 8.times.map {|i| func.(i).to_i }
4
+ tbl![addr]
5
+ end
6
+
7
+
8
+
9
+ system :test_rom do
10
+ [2..0].inner :addr
11
+ [7..0].inner :data0, :data1, :data2, :data3
12
+
13
+ data0 <= rom_gen(addr) { |i| i*i }
14
+ data1 <= rom_gen(addr) { |i| i*i }
15
+
16
+ par do
17
+ data2 <= rom_gen(addr) { |i| i*i }
18
+ data3 <= rom_gen(addr) { |i| i*i }
19
+ end
20
+
21
+ timed do
22
+ 8.times do |i|
23
+ addr <= i
24
+ !10.ns
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,128 @@
1
+ require 'std/channel.rb'
2
+ require 'std/hruby_unit.rb'
3
+
4
+ include HDLRuby::High::Std
5
+
6
+ # A clocked handshake channel for testing purpuse.
7
+ channel(:handshake) do |typ,clk|
8
+ inner has_data: 0
9
+ inner :set_data
10
+ inner :get_data
11
+ typ.inner :data, :data_val
12
+
13
+ writer_input :has_data
14
+ writer_output :set_data, :data_val
15
+ reader_input :has_data, :data
16
+ reader_output :get_data
17
+
18
+ par(clk.negedge) do
19
+ hif(set_data) do
20
+ data <= data_val
21
+ has_data <= 1
22
+ end
23
+ helsif(get_data) do
24
+ has_data <= 0
25
+ end
26
+ end
27
+
28
+ # The writer.
29
+ writer do |blk,target|
30
+ hif(~has_data) do
31
+ set_data <= 1
32
+ data_val <= target
33
+ blk.call if blk
34
+ end
35
+ helse { set_data <= 0 }
36
+ end
37
+
38
+ # The reader
39
+ reader do |blk,target|
40
+ hif(has_data) do
41
+ target <= data
42
+ get_data <= 1
43
+ blk.call if blk
44
+ end
45
+ helse { get_data <= 0 }
46
+ end
47
+ end
48
+
49
+
50
+
51
+ # A system writing indefinitely to a channel.
52
+ # Checking usage of channel without declaring a port.
53
+ system :producer8 do |channel|
54
+ # Inputs of the producer: clock and reset.
55
+ input :clk, :rst
56
+ # Inner 8-bit counter for generating values.
57
+ [8].inner :counter
58
+
59
+ # The value production process
60
+ par(clk.posedge) do
61
+ hif(rst) { counter <= 0 }
62
+ helse do
63
+ channel.write(counter) { counter <= counter + 1 }
64
+ end
65
+ end
66
+ end
67
+
68
+ # A system reading indefinitely from a channel.
69
+ system :consummer8 do |channel|
70
+ # Input of the consummer: a clock is enough.
71
+ input :clk
72
+ # # Instantiate the channel ports
73
+ # channel.input :ch
74
+ # Inner buffer for storing the cunsummed value.
75
+ [8].inner :buf
76
+
77
+ # The value consumption process
78
+ par(clk.posedge) do
79
+ channel.read(buf)
80
+ end
81
+ end
82
+
83
+
84
+ # A system testing the handshaker.
85
+ Unit.system :hs_test do
86
+ inner :clk,:rst
87
+
88
+ # Declares two handshakers
89
+ handshake(bit[8],clk).(:hs)
90
+
91
+ # For the first handshake
92
+
93
+ # Instantiate the producer.
94
+ producer8(hs).(:producerI).(clk,rst)
95
+
96
+ # Instantiate the consummer.
97
+ consummer8(hs).(:consummerI).(clk)
98
+
99
+ test do
100
+ clk <= 0
101
+ rst <= 0
102
+ !10.ns
103
+ clk <= 1
104
+ !10.ns
105
+ clk <= 0
106
+ rst <= 1
107
+ !10.ns
108
+ clk <= 1
109
+ !10.ns
110
+ clk <= 0
111
+ !10.ns
112
+ !10.ns
113
+ clk <= 1
114
+ !10.ns
115
+ clk <= 0
116
+ rst <= 0
117
+ !10.ns
118
+ clk <= 1
119
+ !10.ns
120
+ 10.times do
121
+ clk <= 0
122
+ !10.ns
123
+ clk <= 1
124
+ !10.ns
125
+ end
126
+ end
127
+
128
+ end
@@ -0,0 +1,29 @@
1
+ # A test of def.
2
+ def lut84(content,addr)
3
+ bit[8][-4].inner tbl? => content.to_a
4
+ tbl![addr]
5
+ end
6
+
7
+
8
+ # A benchmark for testing the initialization of signals.
9
+ system :def_bench do
10
+
11
+ [2].inner :addr
12
+ [8].inner :val0, :val1
13
+
14
+ par do
15
+ val0 <= lut84([0,1,4,9],addr)
16
+ val1 <= lut84([0,1,4,9],3-addr)
17
+ end
18
+
19
+ timed do
20
+ addr <= 0
21
+ !10.ns
22
+ addr <= 1
23
+ !10.ns
24
+ addr <= 2
25
+ !10.ns
26
+ addr <= 3
27
+ !10.ns
28
+ end
29
+ end
@@ -0,0 +1,51 @@
1
+ # Some abstract system.
2
+ system :sysA do
3
+ input :clk,:rst
4
+ input :d
5
+ output :q
6
+ end
7
+
8
+ # Some inheriting system.
9
+ system :sysH, sysA do
10
+ par(clk.posedge, rst.posedge) do
11
+ hprint("sys1\n")
12
+ q <= d & ~rst
13
+ end
14
+ end
15
+
16
+ # Another system that have nothing to see with the others.
17
+ # Some abstract system.
18
+ system :sysO do
19
+ input :clk,:rst
20
+ input :d
21
+ output :q
22
+
23
+ par(clk.posedge, rst.posedge) do
24
+ hprint("sys1\n")
25
+ q <= d & ~rst
26
+ end
27
+ end
28
+
29
+
30
+ # A system for testing inheritance and of?
31
+ system :with_reconf do
32
+ input :clk,:rst
33
+ input :d
34
+ output :q
35
+
36
+ # Instantiate the abstract system.
37
+ sysA(:my_dffA).(clk,rst,d,q)
38
+
39
+ # Test the of?
40
+ puts "my_dffA.systemT.of?(sysA)=#{my_dffA.systemT.of?(sysA)}"
41
+ puts "my_dffA.systemT.of?(sysH)=#{my_dffA.systemT.of?(sysH)}"
42
+ puts "my_dffA.systemT.of?(sysO)=#{my_dffA.systemT.of?(sysO)}"
43
+
44
+ # Instantiate the inheriting system.
45
+ sysH(:my_dffH).(clk,rst,d,q)
46
+
47
+ # Test the of?
48
+ puts "my_dffH.systemT.of?(sysH)=#{my_dffH.systemT.of?(sysH)}"
49
+ puts "my_dffH.systemT.of?(sysA)=#{my_dffH.systemT.of?(sysA)}"
50
+ puts "my_dffH.systemT.of?(sysO)=#{my_dffH.systemT.of?(sysO)}"
51
+ end
@@ -1,63 +1,14 @@
1
- require 'std/reconf.rb'
2
1
 
3
- include HDLRuby::High::Std
4
-
5
-
6
-
7
-
8
- # Implementation of a vivado partial reconfiguration system.
9
- reconf(:vivado_reconf) do |clk,rst|
10
-
11
- # Get access to the interface of the reconfigurable component.
12
- inputs = each_input
13
- outputs = each_output
14
- inouts = each_inout
15
-
16
- # Create the main system with the interface and a channel for
17
- # handling the reconfiguration.
18
- main = system do
19
- # Declares the inputs.
20
- inputs.each do |i|
21
- i.type.input(i.name)
22
- end
23
- # Declares the outputs.
24
- outputs.each do |o|
25
- o.type.output(o.name)
26
- end
27
- # Declares the inouts.
28
- inouts.each do |io|
29
- io.type.inout(io.name)
30
- end
31
- # An that's all: in vivado the main system is to be a black-box.
32
- end
33
-
34
- # And set it as the main system.
35
- set_main(main)
36
-
37
- # The switching circuit.
38
- # reconfer = vivado_reconfigurer :do_reconf # Will be that later
39
- # reconfer.clk <= clk
40
- # reconfer.rst <= rst
41
- reconfer = proc do |idx|
42
- puts "Instantiating reconfiguration circuits with #{idx}"
43
- end
44
-
45
- # Defines the reconfiguring procedure: switch to system idx.
46
- switcher do |idx,ruby_block|
47
- reconfer.call(idx)
48
- ruby_block.call
49
- end
50
-
51
- end
52
-
53
-
54
- # Some system that can be used for recponfiguration.
2
+ # Some system that can be used for reconfiguration.
55
3
  system :sys0 do
56
4
  input :clk,:rst
57
5
  input :d
58
6
  output :q
59
7
 
60
- q <= d
8
+ par(clk.posedge) do
9
+ hprint("sys0\n")
10
+ q <= d & ~rst
11
+ end
61
12
  end
62
13
 
63
14
  system :sys1 do
@@ -65,7 +16,10 @@ system :sys1 do
65
16
  input :d
66
17
  output :q
67
18
 
68
- (q <= d).at(clk.posedge)
19
+ par(clk.posedge, rst.posedge) do
20
+ hprint("sys1\n")
21
+ q <= d & ~rst
22
+ end
69
23
  end
70
24
 
71
25
  system :sys2 do
@@ -73,7 +27,10 @@ system :sys2 do
73
27
  input :d
74
28
  output :q
75
29
 
76
- (q <= d & ~rst).at(clk.posedge)
30
+ par(clk.posedge, rst.negedge) do
31
+ hprint("sys2\n")
32
+ q <= d & ~rst
33
+ end
77
34
  end
78
35
 
79
36
  # A system with a reconfifurable part.
@@ -81,23 +38,69 @@ system :with_reconf do
81
38
  input :clk,:rst
82
39
  input :d
83
40
  output :q
84
- [2].input :conf # The configuration number
85
-
86
- inner :wait_reconf
87
41
 
88
- # Create a reconfigurable component.
89
- vivado_reconf(clk,rst).(:my_reconf)
90
- # It is to be reconfigured to sys0, sys1 or sys2
91
- my_reconf.(sys0, sys1, sys2)
92
-
93
- # Connect the reconfigurable instance.
94
- my_reconf.instance.(clk,rst,d,q)
95
-
96
- par(clk.posedge) do
97
- hif(rst) { wait_reconf <= 0 }
98
- helsif(conf != 0 && my_reconf.index != conf && wait_reconf == 0) do
99
- wait_reconf <= 1
100
- my_reconf.switch(conf) { wait_reconf <= 0 }
42
+ # Instantiate the default configuration.
43
+ sys0(:my_dff).(clk,rst,d,q)
44
+
45
+ # Adds the additional configuration.
46
+ my_dff.choice(conf1: sys1, conf2: sys2)
47
+
48
+ timed do
49
+ clk <= 0
50
+ rst <= 0
51
+ d <= 0
52
+ !10.ns
53
+ clk <= 1
54
+ !10.ns
55
+ clk <= 0
56
+ rst <= 1
57
+ !10.ns
58
+ clk <= 1
59
+ !10.ns
60
+ clk <= 0
61
+ rst <= 0
62
+ !10.ns
63
+ 3.times do |i|
64
+ clk <= 1
65
+ !10.ns
66
+ clk <= 0
67
+ d <= 1
68
+ !10.ns
69
+ clk <= 1
70
+ !10.ns
71
+ clk <= 0
72
+ d <= 0
73
+ !10.ns
74
+ clk <= 1
75
+ my_dff.configure((i+1)%3)
76
+ !10.ns
77
+ clk <= 0
78
+ !10.ns
101
79
  end
80
+ clk <= 1
81
+ !10.ns
82
+ clk <= 0
83
+ d <= 1
84
+ !10.ns
85
+ clk <= 1
86
+ my_dff.configure(:conf1)
87
+ !10.ns
88
+ clk <= 0
89
+ d <= 0
90
+ !10.ns
91
+ clk <= 1
92
+ my_dff.configure(:conf2)
93
+ !10.ns
94
+ clk <= 0
95
+ d <= 1
96
+ !10.ns
97
+ clk <= 1
98
+ my_dff.configure(:my_dff)
99
+ !10.ns
100
+ clk <= 0
101
+ d <= 0
102
+ !10.ns
103
+ clk <= 1
104
+ !10.ns
102
105
  end
103
106
  end
@@ -0,0 +1,32 @@
1
+
2
+ # A benchmark for testing the terminate statement.
3
+ system :with_terminate do
4
+ [8].constant cst0: 127
5
+ constant cst1: _1
6
+ [8].inner sig0: _10000000
7
+ inner sig1: _1
8
+ [8].inner :sig2
9
+ [8].inner count: 0
10
+
11
+ timed do
12
+ !20.ns
13
+ 100.times do
14
+ count <= count + 1
15
+ !20.ns
16
+ end
17
+ end
18
+
19
+ timed do
20
+ !10.ns
21
+ sig2 <= cst0 + cst1
22
+ sig0 <= sig0 + sig1
23
+ !10.ns
24
+ sig2 <= sig2 + sig1
25
+ !10.ns
26
+ terminate
27
+ sig0 <= sig0 + sig0
28
+ !10.ns
29
+ sig0 <= sig0 + sig0
30
+ !10.ns
31
+ end
32
+ end
data/lib/HDLRuby/hdrcc.rb CHANGED
@@ -647,12 +647,19 @@ elsif $options[:clang] then
647
647
  init_visualizer = $options[:vcd] ? "init_vcd_visualizer" :
648
648
  "init_default_visualizer"
649
649
 
650
+ # Gather the system to generate and sort them in the right order
651
+ # to ensure references are generated before being used.
652
+ # Base: reverse order of the tree.
653
+ # Then, multiple configuration of a system instance must be
654
+ # reverversed so that the base configuration is generated first.
655
+ c_systems = $top_system.each_systemT_deep_ref
650
656
  # Generate the code of the main function.
651
657
  # HDLRuby start code
652
658
  $main << HDLRuby::Low::Low2C.main("hruby_simulator",
653
659
  init_visualizer,
654
660
  $top_system,
655
- $top_system.each_systemT_deep.to_a.reverse,$hnames)
661
+ c_systems,
662
+ $hnames)
656
663
  $main.close
657
664
 
658
665
  $top_system.each_systemT_deep do |systemT|