HDLRuby 2.4.15 → 2.4.21

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.
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/ruby
2
+ # Script for generating the vcd files.
3
+
4
+ # The configuration scenarii
5
+ $scenarii = [
6
+ [:_clk2_clk2, :register], # 0
7
+ [:_clk2_nclk2, :register], # 1
8
+ [:_clk2_clk3, :register], # 2
9
+ [:_clk3_clk2, :register], # 3
10
+ [:_clk2_clk2, :handshake], # 4
11
+ [:_clk2_nclk2, :handshake], # 5
12
+ [:_clk2_clk3, :handshake], # 6
13
+ [:_clk3_clk2, :handshake], # 7
14
+ [:clk2_clk2_clk2, :queue], # 8
15
+ [:clk2_clk2_nclk2, :queue], # 9
16
+ [:clk1_clk2_clk3, :queue], # 10
17
+ [:clk3_clk2_clk1, :queue], # 11
18
+ [:clk2_clk3_clk1, :queue], # 12
19
+ [:clk2_clk1_clk3, :queue], # 13
20
+ ]
21
+ $scenarii.each_with_index do |scenarii,i|
22
+ puts "scenario: [#{i}] #{scenarii}"
23
+ `bundle exec ../hdrcc.rb --verilog with_multi_channels.rb WithMultiChannelPaper.V#{i} #{i}`
24
+ end
@@ -125,9 +125,12 @@ end
125
125
  # Module for testing the connector.
126
126
  system :with_connectors do
127
127
  inner :clk, :rst
128
- [4].inner :counter #, :res_0,:res_1,:res_2,:res_3
128
+
129
+ # First tester.
130
+ [4].inner :counter
129
131
  [4*4].inner :res
130
132
  inner :ack_in, :ack_out
133
+ inner :dup_req, :dup_ack
131
134
 
132
135
  # The input queue.
133
136
  queue(bit[4],4,clk,rst).(:in_qu)
@@ -141,11 +144,27 @@ system :with_connectors do
141
144
  queue(bit[4*4],4,clk,rst).(:out_qu)
142
145
 
143
146
  # Connect the input queue to the middle queues.
144
- duplicator(bit[4],clk.negedge,in_qu,mid_qus)
147
+ duplicator(bit[4],clk.negedge,in_qu,mid_qus,dup_req,dup_ack)
145
148
 
146
149
  # Connect the middle queues to the output queue.
147
150
  merger([bit[4]]*4,clk.negedge,mid_qus,out_qu)
148
151
 
152
+
153
+ # Second tester.
154
+ [4].inner :counterb
155
+ [4].inner :resb
156
+ inner :ack_inb0, :ack_inb1, :ack_outb
157
+
158
+ # The input queues.
159
+ queue(bit[4],4,clk,rst).(:in_qub0)
160
+ queue(bit[4],4,clk,rst).(:in_qub1)
161
+
162
+ # The output queue.
163
+ queue(bit[4],4,clk,rst).(:out_qub)
164
+
165
+ # Connect then with a serializer.
166
+ serializer(bit[4],clk.negedge,[in_qub0,in_qub1],out_qub)
167
+
149
168
  # # Slow version, always work
150
169
  # par(clk.posedge) do
151
170
  # ack_in <= 0
@@ -171,25 +190,39 @@ system :with_connectors do
171
190
  # Fast version but assumes connected channels are blocking
172
191
  par(clk.posedge) do
173
192
  ack_in <= 0
174
- hif(rst) { counter <= 0 }
193
+ ack_inb0 <= 0
194
+ ack_inb1 <= 0
195
+ hif(rst) { counter <= 0; counterb <= 0 }
175
196
  helse do
176
197
  in_qu.write(counter) do
177
198
  ack_in <= 1
178
199
  counter <= counter + 1
179
200
  end
180
201
  hif(ack_in) do
181
- # mid_qu0.read(res_0)
182
- # mid_qu1.read(res_1)
183
- # mid_qu2.read(res_2)
184
- # mid_qu3.read(res_3)
185
202
  out_qu.read(res)
186
203
  end
204
+ hif(~ack_inb0) do
205
+ in_qub0.write(counterb) do
206
+ ack_inb0 <= 1
207
+ counterb <= counterb + 1
208
+ end
209
+ end
210
+ helse do
211
+ in_qub1.write(counterb) do
212
+ ack_inb1 <= 1
213
+ counterb <= counterb + 1
214
+ end
215
+ end
216
+ hif(ack_inb0 | ack_inb1) do
217
+ out_qub.read(resb)
218
+ end
187
219
  end
188
220
  end
189
221
 
190
222
  timed do
191
223
  clk <= 0
192
224
  rst <= 0
225
+ dup_req <= 0
193
226
  !10.ns
194
227
  clk <= 1
195
228
  !10.ns
@@ -204,6 +237,13 @@ system :with_connectors do
204
237
  !10.ns
205
238
  clk <= 0
206
239
  rst <= 0
240
+ 4.times do
241
+ !10.ns
242
+ clk <= 1
243
+ !10.ns
244
+ clk <= 0
245
+ end
246
+ dup_req <= 1
207
247
  16.times do
208
248
  !10.ns
209
249
  clk <= 1
@@ -0,0 +1,102 @@
1
+ require 'std/memory.rb'
2
+ require "std/fixpoint.rb"
3
+ require 'std/channel.rb'
4
+ require 'std/connector.rb'
5
+
6
+ include HDLRuby::High::Std
7
+
8
+ system :channel_connector do
9
+ # データ型の宣言
10
+ integer_width = 4 # 整数部のビット幅
11
+ decimal_width = 4 # 実数部のビット幅
12
+ address_width = 4 # lutのアドレスのビット幅
13
+ typ = signed[integer_width + decimal_width] # データ型
14
+
15
+ inputs_x = _00010011
16
+ inputs_h = _10100001
17
+ columns = [2, 2, 1]
18
+
19
+ inner :clk, # clock
20
+ :rst, # reset
21
+ :req, # request
22
+ :fill # 入力値のメモリへの書き込み
23
+
24
+ # inputs_x = quantize(inputs_x, typ, decimal_width)
25
+ # inputs_h = quantize(inputs_h, typ, decimal_width)
26
+
27
+ mem_rom(typ, columns[0], clk, rst, inputs_x, rinc: :rst, winc: :rst).(:rom_inputs_x) # 入力値を格納するrom(x)
28
+
29
+ mem_rom(typ, columns[0], clk, rst, inputs_h, rinc: :rst, winc: :rst).(:rom_inputs_h) # 入力値を格納するrom(h)
30
+
31
+ mem_dual(typ, columns[0], clk, rst, rinc: :rst, winc: :rst).(:ram_inputs_serializer) #
32
+
33
+ mem_dual(typ, columns[0]*2, clk, rst, rinc: :rst, winc: :rst).(:ram_inputs_merger) #
34
+
35
+ reader_inputs_x = rom_inputs_x.branch(:rinc) #入力値xの読みだし用branch
36
+ reader_inputs_h = rom_inputs_h.branch(:rinc) #入力値hの読みだし用branch
37
+ writer_inputs_serializer = ram_inputs_serializer.branch(:winc) #入力値を合成した値の書き込み用branch
38
+ writer_inputs_meger = ram_inputs_merger.branch(:winc) #入力値を合成した値の書き込み用branch
39
+
40
+
41
+ serializer(typ,clk.negedge,[reader_inputs_x,reader_inputs_h],writer_inputs_serializer)
42
+
43
+ mem_rom(typ, columns[0], clk, rst, inputs_x, rinc: :rst, winc: :rst).(:rom_inputs_r) # 入力値を格納するrom(x)
44
+ mem_dual(typ, columns[0], clk, rst, rinc: :rst, winc: :rst).(:ram_duplicator0) #
45
+ mem_dual(typ, columns[0], clk, rst, rinc: :rst, winc: :rst).(:ram_duplicator1) #
46
+ reader_inputs_r = rom_inputs_r.branch(:rinc)
47
+ writer_duplicator0 = ram_duplicator0.branch(:winc)
48
+ writer_duplicator1 = ram_duplicator1.branch(:winc)
49
+
50
+ duplicator(typ,clk.posedge,reader_inputs_r,[writer_duplicator0, writer_duplicator1])
51
+
52
+ timed do
53
+ # リセット
54
+ clk <= 0
55
+ rst <= 0
56
+ req <= 0
57
+ fill <= 0
58
+ !10.ps
59
+
60
+ # メモリ読み出し位置の初期化
61
+ rst <= 1
62
+ !10.ps
63
+ clk <= 1
64
+ !10.ps
65
+ clk <= 0
66
+ !10.ps
67
+ clk <= 1
68
+ !10.ps
69
+
70
+ # パラメータのメモリへの書き込み
71
+ clk <= 0
72
+ rst <= 0
73
+ fill <= 1
74
+
75
+ !10.ps
76
+ 10.times do |i|
77
+ clk <= 1
78
+ !10.ps
79
+ clk <= 0
80
+ !10.ps
81
+ end
82
+
83
+ fill <= 0
84
+ clk <= 1
85
+ !10.ps
86
+
87
+ # 計算の実行
88
+ clk <= 0
89
+ req <= 1
90
+ !10.ps
91
+ clk <= 1
92
+ !10.ps
93
+ clk <= 0
94
+ !10.ps
95
+ 30.times do
96
+ clk <= 1
97
+ !10.ps
98
+ clk <= 0
99
+ !10.ps
100
+ end
101
+ end
102
+ end
@@ -23,12 +23,6 @@ channel(:queue) do |typ,depth,clk,rst|
23
23
  par(clk.posedge) do
24
24
  hif(rst) { rptr <= 0; wptr <= 0 }
25
25
  helse do
26
- # hif(rsync) do
27
- # hif(rptr != wptr) do
28
- # rdata <= buffer[rptr]
29
- # end
30
- # end
31
- # helse do
32
26
  hif(~rsync) do
33
27
  hif (~rreq) { rack <= 0 }
34
28
  hif(rreq & (~rack) & (rptr != wptr)) do
@@ -38,10 +32,6 @@ channel(:queue) do |typ,depth,clk,rst|
38
32
  end
39
33
  end
40
34
 
41
- # hif(wsync) do
42
- # buffer[wptr] <= wdata
43
- # end
44
- # helse do
45
35
  hif(~wsync) do
46
36
  hif (~wreq) { wack <= 0 }
47
37
  hif(wreq & (~wack) & (((wptr+1) % depth) != rptr)) do
@@ -67,7 +57,6 @@ channel(:queue) do |typ,depth,clk,rst|
67
57
  end
68
58
  seq do
69
59
  hif(rptr != wptr) do
70
- # target <= rdata
71
60
  target <= buffer[rptr]
72
61
  rptr <= (rptr + 1) % depth
73
62
  blk.call if blk
@@ -102,7 +91,6 @@ channel(:queue) do |typ,depth,clk,rst|
102
91
  wreq <= 0
103
92
  end
104
93
  hif(((wptr+1) % depth) != rptr) do
105
- # wdata <= target
106
94
  buffer[wptr] <= target
107
95
  wptr <= (wptr + 1) % depth
108
96
  blk.call if blk
@@ -29,8 +29,14 @@ module HDLRuby
29
29
  class ::Integer
30
30
 
31
31
  # Gets the bit width
32
+ # NOTE: returns infinity if the number is negative.
32
33
  def width
33
- return Math.log2(self+1).ceil
34
+ return self >= 0 ? Math.log2(self+1).ceil : 1.0/0.0
35
+ end
36
+
37
+ # Tells if the value is a power of 2.
38
+ def pow2?
39
+ return self > 0 && (self & (self - 1) == 0)
34
40
  end
35
41
  end
36
42
 
@@ -9,13 +9,28 @@ module HDLRuby::High::Std
9
9
  # channel +in_ch+ and connect it to channels +out_chs+ with data of
10
10
  # +typ+.
11
11
  # The duplication is done according to event +ev+.
12
- function :duplicator do |typ, ev, in_ch, out_chs|
13
- ev = ev.poswedge unless ev.is_a?(Event)
14
- inner :in_ack, :in_req
12
+ # The optional req and ack arguments are the signals for controlling the
13
+ # duplicator using a handshake protocol. If set to nil, the duplicator
14
+ # runs automatically.
15
+ function :duplicator do |typ, ev, in_ch, out_chs, req = nil, ack = nil|
16
+ ev = ev.posedge unless ev.is_a?(Event)
17
+ inner :in_ack
18
+ inner :in_req
15
19
  out_acks = out_chs.size.times.map { |i| inner(:"out_ack#{i}") }
16
20
  typ.inner :data
17
21
  par(ev) do
18
- in_req <= 1
22
+ if (ack) then
23
+ # Output ack mode.
24
+ ack <= 0
25
+ end
26
+ if (req) then
27
+ # Input request mode.
28
+ in_req <= 0
29
+ hif(req) { in_req <= 1 }
30
+ else
31
+ # Automatic mode.
32
+ in_req <= 1
33
+ end
19
34
  out_acks.each { |ack| ack <= 0 }
20
35
  out_acks.each do |ack|
21
36
  hif(ack == 1) { in_req <= 0 }
@@ -30,6 +45,10 @@ module HDLRuby::High::Std
30
45
  end
31
46
  hif (out_acks.reduce(_1) { |sum,ack| ack & sum }) do
32
47
  out_acks.each { |ack| ack <= 0 }
48
+ if (ack) then
49
+ # Output ack mode.
50
+ ack <= 1
51
+ end
33
52
  end
34
53
  end
35
54
  end
@@ -37,7 +56,7 @@ module HDLRuby::High::Std
37
56
 
38
57
  # Function for generating a connector that merges the output of
39
58
  # channels +in_chs+ and connects the result to channel +out_ch+ with
40
- # data of +typ+.
59
+ # data of types from +typs+.
41
60
  # The merge is done according to event +ev+.
42
61
  function :merger do |typs, ev, in_chs, out_ch|
43
62
  ev = ev.posedge unless ev.is_a?(Event)
@@ -63,5 +82,48 @@ module HDLRuby::High::Std
63
82
  end
64
83
 
65
84
 
85
+ # Function for generating a connector that serialize to the output of
86
+ # channels +in_chs+ and connects the result to channel +out_ch+ with
87
+ # data of +typ+.
88
+ # The merge is done according to event +ev+.
89
+ function :serializer do |typ, ev, in_chs, out_ch|
90
+ ev = ev.posedge unless ev.is_a?(Event)
91
+ size = in_chs.size
92
+ inner :out_ack
93
+ # in_reqs = size.times.map { |i| inner(:"in_req#{i}") }
94
+ in_acks = size.times.map { |i| inner(:"in_ack#{i}") }
95
+ datas = size.times.map { |i| typ.inner(:"data#{i}") }
96
+ # The inpt channel selector
97
+ [size.width].inner :idx
98
+ inner :reading
99
+ par(ev) do
100
+ # in_reqs.each { |req| req <= 1 }
101
+ idx <= 0
102
+ reading <= 0
103
+ out_ack <= 0
104
+ hif(idx == size-1) { in_acks.each { |ack| ack <= 0 } }
105
+ # hif((idx == 0) & (in_reqs.reduce(_1) { |sum,req| req & sum })) do
106
+ hif(idx == 0) do
107
+ hif(~reading) do
108
+ size.times { |i| in_acks[i] <= 0 }
109
+ end
110
+ reading <= 1
111
+ in_chs.each_with_index do |ch,i|
112
+ hif(~in_acks[i]) do
113
+ ch.read(datas[i]) { in_acks[i] <= 1 }
114
+ end
115
+ end
116
+ end
117
+ hif(in_acks.reduce(_1) { |sum,req| req & sum }) do
118
+ hcase(idx)
119
+ datas.each_with_index do |data,i|
120
+ hwhen(i) do
121
+ out_ch.write(data) { idx <= idx + 1; out_ack <= 1 }
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
127
+
66
128
 
67
129
  end
@@ -289,9 +289,10 @@ HDLRuby::High::Std.channel(:mem_rom) do |typ,size,clk,rst,content,
289
289
  rst = send(rst_name)
290
290
  top_block.unshift do
291
291
  # Initialize the address so that the next access is at address 0.
292
- hif(rst==1) { abus_r <= -1 }
293
- # Reset so switch of the access trigger.
294
- trig_r <= 0
292
+ # hif(rst==1) { abus_r <= -1 }
293
+ # # Reset so switch of the access trigger.
294
+ # trig_r <= 0
295
+ hif(rst==1) { abus_r <= -1; trig_r <= 0 }
295
296
  end
296
297
  # The read procedure.
297
298
  # par do
@@ -317,6 +318,7 @@ HDLRuby::High::Std.channel(:mem_rom) do |typ,size,clk,rst,content,
317
318
  # blk.call if blk
318
319
  seq do
319
320
  # abus_r <= abus_r + 1
321
+ trig_r <= 0
320
322
  target <= dbus_r
321
323
  blk.call if blk
322
324
  end
@@ -1704,6 +1706,127 @@ HDLRuby::High::Std.channel(:mem_bank) do |typ,nbanks,size,clk,rst,br_rsts = {}|
1704
1706
 
1705
1707
  end
1706
1708
 
1709
+
1710
+ # Queue memory of +size+ elements of +typ+ typ, syncrhonized on +clk+
1711
+ # (positive and negative edges) and reset on +rst+.
1712
+ # At each rising edge of +clk+ a read and a write is guaranteed to be
1713
+ # completed provided they are triggered.
1714
+ #
1715
+ # NOTE: this channel does not have any branch.
1716
+ HDLRuby::High::Std.channel(:mem_queue) do |typ,size,clk,rst|
1717
+ # The inner buffer of the queue.
1718
+ typ[-size].inner :buffer
1719
+ # The read and write pointers.
1720
+ [size.width].inner :rptr, :wptr
1721
+ # The read and write command signals.
1722
+ inner :rreq, :wreq
1723
+ # The read and write ack signals.
1724
+ inner :rack, :wack
1725
+ # The read/write data registers.
1726
+ typ.inner :rdata, :wdata
1727
+
1728
+ # The flags telling of the channel is synchronized
1729
+ inner :rsync, :wsync
1730
+
1731
+ # The process handling the decoupled access to the buffer.
1732
+ par(clk.posedge) do
1733
+ hif(rst) { rptr <= 0; wptr <= 0 }
1734
+ helse do
1735
+ hif(~rsync) do
1736
+ hif (~rreq) { rack <= 0 }
1737
+ hif(rreq & (~rack) & (rptr != wptr)) do
1738
+ rdata <= buffer[rptr]
1739
+ rptr <= (rptr + 1) % depth
1740
+ rack <= 1
1741
+ end
1742
+ end
1743
+
1744
+ hif(~wsync) do
1745
+ hif (~wreq) { wack <= 0 }
1746
+ hif(wreq & (~wack) & (((wptr+1) % size) != rptr)) do
1747
+ buffer[wptr] <= wdata
1748
+ wptr <= (wptr + 1) % size
1749
+ wack <= 1
1750
+ end
1751
+ end
1752
+ end
1753
+ end
1754
+
1755
+ reader_output :rreq, :rptr, :rsync
1756
+ reader_input :rdata, :rack, :wptr, :buffer
1757
+
1758
+ # The read primitive.
1759
+ reader do |blk,target|
1760
+ if (cur_behavior.on_event?(clk.posedge,clk.negedge)) then
1761
+ # Same clk event, synchrone case: perform a direct access.
1762
+ # Now perform the access.
1763
+ top_block.unshift do
1764
+ rsync <= 1
1765
+ rreq <= 0
1766
+ end
1767
+ seq do
1768
+ hif(rptr != wptr) do
1769
+ # target <= rdata
1770
+ target <= buffer[rptr]
1771
+ rptr <= (rptr + 1) % size
1772
+ blk.call if blk
1773
+ end
1774
+ end
1775
+ else
1776
+ # Different clk event, perform a decoupled access.
1777
+ top_block.unshift do
1778
+ rsync <= 0
1779
+ rreq <= 0
1780
+ end
1781
+ par do
1782
+ hif (~rack) { rreq <= 1 }
1783
+ helsif(rreq) do
1784
+ rreq <= 0
1785
+ target <= rdata
1786
+ blk.call if blk
1787
+ end
1788
+ end
1789
+ end
1790
+ end
1791
+
1792
+ writer_output :wreq, :wdata, :wptr, :wsync, :buffer
1793
+ writer_input :wack, :rptr
1794
+
1795
+ # The write primitive.
1796
+ writer do |blk,target|
1797
+ if (cur_behavior.on_event?(clk.negedge,clk.posedge)) then
1798
+ # Same clk event, synchrone case: perform a direct access.
1799
+ top_block.unshift do
1800
+ wsync <= 1
1801
+ wreq <= 0
1802
+ end
1803
+ hif(((wptr+1) % size) != rptr) do
1804
+ buffer[wptr] <= target
1805
+ wptr <= (wptr + 1) % size
1806
+ blk.call if blk
1807
+ end
1808
+ else
1809
+ # Different clk event, asynchrone case: perform a decoupled access.
1810
+ top_block.unshift do
1811
+ wsync <= 0
1812
+ wreq <= 0
1813
+ end
1814
+ seq do
1815
+ hif (~wack) do
1816
+ wreq <= 1
1817
+ wdata <= target
1818
+ end
1819
+ helsif(wreq) do
1820
+ wreq <= 0
1821
+ blk.call if blk
1822
+ end
1823
+ end
1824
+ end
1825
+ end
1826
+ end
1827
+
1828
+
1829
+
1707
1830
  # HDLRuby::High::Std.channel(:mem_bank) do |typ,nbanks,size,clk,rst,br_rsts = {}|
1708
1831
  # # Ensure typ is a type.
1709
1832
  # typ = typ.to_type