HDLRuby 2.4.9 → 2.4.15

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: cd62e24fab42fee5c7a9e3cefda920cab67ec3a739e7ec0e66e6e637e890b959
4
- data.tar.gz: d294cb0479e6388dea6e318c458f26ddabf71fd9281fa25f6ee69d6039bd1526
3
+ metadata.gz: 80660af24803dfe38c615c2172d6cf243c6eda9968477d085d804eaa1f57f88e
4
+ data.tar.gz: ce672bdc08f5413d87e0a3ce4c83316f68560e3bdc270cf306474a63ef9d1dbc
5
5
  SHA512:
6
- metadata.gz: d2039cd7158a2e2296005639474f9076f4f72f667777c97a94d7581975e92242e2be31fe3b7fb1cadf722b4f9fa6d8f8287252ec9944077512ffcd7d036ad28f
7
- data.tar.gz: 8107f68c9c15f2f5e33a6f1a94c3454d46b9d4493ed00868c660d084b0e94e64747da3b984f7812254c31f3595988833de1df6e71253648ed1f85042cd45b534
6
+ metadata.gz: d9526ced19d1faa8155c42a4279f2813b3682fc19a17b0e0956950ee554c2173959d0d8c08e4e98fa2fa3b1b6270645f30aef4baa3ebc48e8b5bd10028013f3f
7
+ data.tar.gz: 70320cd784ea0928f2ced5a747229af97121387bfbd92db64b9e663b6e8ed743f6e96b519fd24dc02828cca7a8a384ffde90d64985b40384469e96558abec13f
@@ -0,0 +1,25 @@
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 -S --vcd with_multi_channels.rb WithMultiChannelPaper #{i}`
24
+ `mv WithMultiChannelPaper/hruby_simulator.vcd WithMultiChannelPaper/#{i.to_s.to_s.rjust(2,"0")}_#{scenarii[0]}_#{scenarii[1]}.vcd`
25
+ end
@@ -5,7 +5,7 @@ include HDLRuby::High::Std
5
5
  # A simple implementation of the MEI8 processor.
6
6
  #
7
7
  # In this implementation, the program is hard-coded in an internal ROM
8
- system :mei8 do |prog_file = "./prog_encrypt.obj"|
8
+ system :mei8 do |prog_file = "./prog.obj"|
9
9
  # Clock and reset.
10
10
  input :clk, :rst
11
11
  # Bus.
@@ -0,0 +1,214 @@
1
+ require 'std/channel.rb'
2
+ require 'std/connector.rb'
3
+
4
+ include HDLRuby::High::Std
5
+
6
+ # Sample for testing the connectors of channels.
7
+
8
+ # Channel describing a buffered queue storing data of +typ+ type of +depth+,
9
+ # synchronized through clk and reset on +rst+.
10
+ channel(:queue) do |typ,depth,clk,rst|
11
+ # The inner buffer of the queue.
12
+ typ[-depth].inner :buffer
13
+ # The read and write pointers.
14
+ [depth.width].inner :rptr, :wptr
15
+ # The read and write command signals.
16
+ inner :rreq, :wreq
17
+ # The read and write ack signals.
18
+ inner :rack, :wack
19
+ # The read/write data registers.
20
+ typ.inner :rdata, :wdata
21
+
22
+ # The flags telling of the channel is synchronized
23
+ inner :rsync, :wsync
24
+
25
+ # The process handling the decoupled access to the buffer.
26
+ par(clk.posedge) do
27
+ hif(rst) { rptr <= 0; wptr <= 0 }
28
+ helse do
29
+ hif(~rsync) do
30
+ hif (~rreq) { rack <= 0 }
31
+ hif(rreq & (~rack) & (rptr != wptr)) do
32
+ rdata <= buffer[rptr]
33
+ rptr <= (rptr + 1) % depth
34
+ rack <= 1
35
+ end
36
+ end
37
+
38
+ hif(~wsync) do
39
+ hif (~wreq) { wack <= 0 }
40
+ hif(wreq & (~wack) & (((wptr+1) % depth) != rptr)) do
41
+ buffer[wptr] <= wdata
42
+ wptr <= (wptr + 1) % depth
43
+ wack <= 1
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ reader_output :rreq, :rptr, :rsync
50
+ reader_input :rdata, :rack, :wptr, :buffer
51
+
52
+ # The read primitive.
53
+ reader do |blk,target|
54
+ if (cur_behavior.on_event?(clk.posedge,clk.negedge)) then
55
+ # Same clk event, synchrone case: perform a direct access.
56
+ # Now perform the access.
57
+ top_block.unshift do
58
+ rsync <= 1
59
+ rreq <= 0
60
+ end
61
+ seq do
62
+ hif(rptr != wptr) do
63
+ # target <= rdata
64
+ target <= buffer[rptr]
65
+ rptr <= (rptr + 1) % depth
66
+ blk.call if blk
67
+ end
68
+ end
69
+ else
70
+ # Different clk event, perform a decoupled access.
71
+ top_block.unshift do
72
+ rsync <= 0
73
+ rreq <= 0
74
+ end
75
+ par do
76
+ hif (~rack) { rreq <= 1 }
77
+ helsif(rreq) do
78
+ rreq <= 0
79
+ target <= rdata
80
+ blk.call if blk
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ writer_output :wreq, :wdata, :wptr, :wsync, :buffer
87
+ writer_input :wack, :rptr
88
+
89
+ # The write primitive.
90
+ writer do |blk,target|
91
+ if (cur_behavior.on_event?(clk.negedge,clk.posedge)) then
92
+ # Same clk event, synchrone case: perform a direct access.
93
+ top_block.unshift do
94
+ wsync <= 1
95
+ wreq <= 0
96
+ end
97
+ hif(((wptr+1) % depth) != rptr) do
98
+ buffer[wptr] <= target
99
+ wptr <= (wptr + 1) % depth
100
+ blk.call if blk
101
+ end
102
+ else
103
+ # Different clk event, asynchrone case: perform a decoupled access.
104
+ top_block.unshift do
105
+ wsync <= 0
106
+ wreq <= 0
107
+ end
108
+ seq do
109
+ hif (~wack) do
110
+ wreq <= 1
111
+ wdata <= target
112
+ end
113
+ helsif(wreq) do
114
+ wreq <= 0
115
+ blk.call if blk
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+
122
+
123
+
124
+
125
+ # Module for testing the connector.
126
+ system :with_connectors do
127
+ inner :clk, :rst
128
+ [4].inner :counter #, :res_0,:res_1,:res_2,:res_3
129
+ [4*4].inner :res
130
+ inner :ack_in, :ack_out
131
+
132
+ # The input queue.
133
+ queue(bit[4],4,clk,rst).(:in_qu)
134
+
135
+ # The middle queues.
136
+ mid_qus = 4.times.map do |i|
137
+ queue(bit[4],4,clk,rst).(:"mid_qu#{i}")
138
+ end
139
+
140
+ # The output queue.
141
+ queue(bit[4*4],4,clk,rst).(:out_qu)
142
+
143
+ # Connect the input queue to the middle queues.
144
+ duplicator(bit[4],clk.negedge,in_qu,mid_qus)
145
+
146
+ # Connect the middle queues to the output queue.
147
+ merger([bit[4]]*4,clk.negedge,mid_qus,out_qu)
148
+
149
+ # # Slow version, always work
150
+ # par(clk.posedge) do
151
+ # ack_in <= 0
152
+ # ack_out <= 1
153
+ # hif(rst) { counter <= 0 }
154
+ # helse do
155
+ # hif(ack_out) do
156
+ # ack_out <= 0
157
+ # in_qu.write(counter) do
158
+ # ack_in <= 1
159
+ # counter <= counter + 1
160
+ # end
161
+ # end
162
+ # hif(ack_in) do
163
+ # mid_qu0.read(res_0)
164
+ # mid_qu1.read(res_1)
165
+ # mid_qu2.read(res_2)
166
+ # mid_qu3.read(res_3) { ack_out <= 1 }
167
+ # end
168
+ # end
169
+ # end
170
+
171
+ # Fast version but assumes connected channels are blocking
172
+ par(clk.posedge) do
173
+ ack_in <= 0
174
+ hif(rst) { counter <= 0 }
175
+ helse do
176
+ in_qu.write(counter) do
177
+ ack_in <= 1
178
+ counter <= counter + 1
179
+ end
180
+ 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
+ out_qu.read(res)
186
+ end
187
+ end
188
+ end
189
+
190
+ timed do
191
+ clk <= 0
192
+ rst <= 0
193
+ !10.ns
194
+ clk <= 1
195
+ !10.ns
196
+ clk <= 0
197
+ rst <= 1
198
+ !10.ns
199
+ clk <= 1
200
+ !10.ns
201
+ clk <= 0
202
+ !10.ns
203
+ clk <= 1
204
+ !10.ns
205
+ clk <= 0
206
+ rst <= 0
207
+ 16.times do
208
+ !10.ns
209
+ clk <= 1
210
+ !10.ns
211
+ clk <= 0
212
+ end
213
+ end
214
+ end
@@ -32,6 +32,18 @@ system :fix_test do
32
32
  !10.ns
33
33
  d <= d + c
34
34
  !10.ns
35
+ d <= d / c
36
+ !10.ns
37
+ d <= d / 3.to_fix(4)
38
+ !10.ns
39
+ d <= 1.to_fix(4) - d
40
+ !10.ns
41
+ d <= -d
42
+ !10.ns
43
+ d <= d * 3.to_fix(4)
44
+ !10.ns
45
+ d <= -d
46
+ !10.ns
35
47
  a <= -0.375.to_fix(4)
36
48
  b <= 1.625.to_fix(4)
37
49
  !10.ns
@@ -0,0 +1,53 @@
1
+ require 'std/memory.rb'
2
+
3
+ include HDLRuby::High::Std
4
+
5
+
6
+
7
+
8
+
9
+ # A system testing the rom channel.
10
+ system :rorm_test do
11
+ inner :clk,:rst
12
+ [8].inner :value
13
+ inner :addr
14
+
15
+ # Declares a 8-bit-data and 1 element rom address synchronous memory
16
+ # on negative edge of clk.
17
+ # mem_rom([8],2,clk,rst,[_00000110,_00000111], rinc: :rst).(:romI)
18
+ mem_rom([8],1,clk,rst,[_00000110], rinc: :rst).(:romI)
19
+ rd = romI.branch(:rinc)
20
+
21
+ par(clk.posedge) do
22
+ hif(rst) { addr <= 0 }
23
+ helse do
24
+ rd.read(value)
25
+ end
26
+ end
27
+
28
+ timed do
29
+ clk <= 0
30
+ rst <= 0
31
+ !10.ns
32
+ clk <= 1
33
+ !10.ns
34
+ clk <= 0
35
+ rst <= 1
36
+ !10.ns
37
+ clk <= 1
38
+ !10.ns
39
+ clk <= 0
40
+ !10.ns
41
+ clk <= 1
42
+ !10.ns
43
+ clk <= 0
44
+ rst <= 0
45
+ !10.ns
46
+ 10.times do
47
+ clk <= 1
48
+ !10.ns
49
+ clk <= 0
50
+ !10.ns
51
+ end
52
+ end
53
+ end
@@ -10,36 +10,51 @@ channel(:queue) do |typ,depth,clk,rst|
10
10
  # The read and write pointers.
11
11
  [depth.width].inner :rptr, :wptr
12
12
  # The read and write command signals.
13
- inner :rcmd, :wcmd
13
+ inner :rreq, :wreq
14
14
  # The read and write ack signals.
15
15
  inner :rack, :wack
16
- # The ack check deactivator (for synchron accesses).
17
- inner :hrack, :hwack
18
16
  # The read/write data registers.
19
17
  typ.inner :rdata, :wdata
20
18
 
19
+ # The flags telling of the channel is synchronized
20
+ inner :rsync, :wsync
21
+
21
22
  # The process handling the decoupled access to the buffer.
22
23
  par(clk.posedge) do
23
- # rack <= 0
24
- # wack <= 0
25
- hif (~rcmd) { rack <= 0 }
26
- hif (~wcmd) { wack <= 0 }
27
24
  hif(rst) { rptr <= 0; wptr <= 0 }
28
- hif(rcmd & (hrack|~rack) & (rptr != wptr)) do
29
- rptr <= (rptr + 1) % depth
30
- rack <= 1
31
- end
32
- hif(wcmd & (hwack|~wack) & (((wptr+1) % depth) != rptr)) do
33
- buffer[wptr] <= wdata
34
- # buffer[1] <= wdata
35
- wptr <= (wptr + 1) % depth
36
- wack <= 1
25
+ helse do
26
+ # hif(rsync) do
27
+ # hif(rptr != wptr) do
28
+ # rdata <= buffer[rptr]
29
+ # end
30
+ # end
31
+ # helse do
32
+ hif(~rsync) do
33
+ hif (~rreq) { rack <= 0 }
34
+ hif(rreq & (~rack) & (rptr != wptr)) do
35
+ rdata <= buffer[rptr]
36
+ rptr <= (rptr + 1) % depth
37
+ rack <= 1
38
+ end
39
+ end
40
+
41
+ # hif(wsync) do
42
+ # buffer[wptr] <= wdata
43
+ # end
44
+ # helse do
45
+ hif(~wsync) do
46
+ hif (~wreq) { wack <= 0 }
47
+ hif(wreq & (~wack) & (((wptr+1) % depth) != rptr)) do
48
+ buffer[wptr] <= wdata
49
+ wptr <= (wptr + 1) % depth
50
+ wack <= 1
51
+ end
52
+ end
37
53
  end
38
54
  end
39
- par { rdata <= buffer[rptr] }
40
55
 
41
- reader_output :rcmd, :rptr, :hrack
42
- reader_input :rdata, :rack
56
+ reader_output :rreq, :rptr, :rsync
57
+ reader_input :rdata, :rack, :wptr, :buffer
43
58
 
44
59
  # The read primitive.
45
60
  reader do |blk,target|
@@ -47,58 +62,66 @@ channel(:queue) do |typ,depth,clk,rst|
47
62
  # Same clk event, synchrone case: perform a direct access.
48
63
  # Now perform the access.
49
64
  top_block.unshift do
50
- rcmd <= 0
51
- hrack <= 1
65
+ rsync <= 1
66
+ rreq <= 0
52
67
  end
53
68
  seq do
54
- rptr <= (rptr + 1) % depth
55
- target <= rdata
56
- blk.call if blk
69
+ hif(rptr != wptr) do
70
+ # target <= rdata
71
+ target <= buffer[rptr]
72
+ rptr <= (rptr + 1) % depth
73
+ blk.call if blk
74
+ end
57
75
  end
58
76
  else
59
77
  # Different clk event, perform a decoupled access.
60
78
  top_block.unshift do
61
- rcmd <= 0
62
- hrack <= 0
79
+ rsync <= 0
80
+ rreq <= 0
63
81
  end
64
- seq do
65
- hif(rack) do
66
- blk.call if blk
67
- end
68
- helse do
69
- rcmd <= 1
82
+ par do
83
+ hif (~rack) { rreq <= 1 }
84
+ helsif(rreq) do
85
+ rreq <= 0
70
86
  target <= rdata
87
+ blk.call if blk
71
88
  end
72
89
  end
73
90
  end
74
91
  end
75
92
 
76
- writer_output :wcmd, :wdata, :hwack
77
- writer_input :wack
93
+ writer_output :wreq, :wdata, :wptr, :wsync, :buffer
94
+ writer_input :wack, :rptr
78
95
 
79
96
  # The write primitive.
80
97
  writer do |blk,target|
81
98
  if (cur_behavior.on_event?(clk.negedge,clk.posedge)) then
82
99
  # Same clk event, synchrone case: perform a direct access.
83
100
  top_block.unshift do
84
- wcmd <= 0
85
- hwack <= 1
101
+ wsync <= 1
102
+ wreq <= 0
103
+ end
104
+ hif(((wptr+1) % depth) != rptr) do
105
+ # wdata <= target
106
+ buffer[wptr] <= target
107
+ wptr <= (wptr + 1) % depth
108
+ blk.call if blk
86
109
  end
87
- wcmd <= 1
88
- wdata <= target
89
- blk.call if blk
90
110
  else
91
111
  # Different clk event, asynchrone case: perform a decoupled access.
92
112
  top_block.unshift do
93
- wcmd <= 0
94
- hwack <= 0
113
+ wsync <= 0
114
+ wreq <= 0
95
115
  end
96
116
  seq do
97
- hif(wack) do
117
+ hif (~wack) do
118
+ wreq <= 1
119
+ wdata <= target
120
+ end
121
+ helsif(wreq) do
122
+ wreq <= 0
98
123
  blk.call if blk
99
124
  end
100
- helse { wcmd <= 1 }
101
- wdata <= target
102
125
  end
103
126
  end
104
127
  end
@@ -135,7 +158,7 @@ channel(:handshake) do |typ|
135
158
  # The data signal.
136
159
  typ.inner :data
137
160
  # The request and acknowledge.
138
- typ.inner :req, :ack
161
+ inner :req, :ack
139
162
 
140
163
  reader_input :ack, :data
141
164
  reader_output :req
@@ -174,110 +197,102 @@ channel(:handshake) do |typ|
174
197
  end
175
198
 
176
199
 
177
- # $mode = :sync
178
- # $mode = :nsync
179
- # $mode = :async
180
- # $mode = :proco # Producter / Consummer
200
+ # $mode: channel clock, producer clock, consumer clock (n: not clock)
181
201
  # $channel = :register
182
202
  # $channel = :handshake
183
203
  # $channel = :queue
184
204
 
185
205
  # The configuration scenarii
186
- $scenarii = [ [:sync, :register], [:sync, :handshake], [:sync, :queue],
187
- [:nsync, :register], [:nsync, :handshake], [:nsync, :queue],
188
- [:async, :register], [:async, :handshake], [:async, :queue],
189
- [:proco, :register], [:proco, :handshake], [:proco, :queue] ]
206
+ $scenarii = [
207
+ [:_clk2_clk2, :register], # 0
208
+ [:_clk2_nclk2, :register], # 1
209
+ [:_clk2_clk3, :register], # 2
210
+ [:_clk3_clk2, :register], # 3
211
+ [:_clk2_clk2, :handshake], # 4
212
+ [:_clk2_nclk2, :handshake], # 5
213
+ [:_clk2_clk3, :handshake], # 6
214
+ [:_clk3_clk2, :handshake], # 7
215
+ [:clk2_clk2_clk2, :queue], # 8
216
+ [:clk2_clk2_nclk2, :queue], # 9
217
+ [:clk1_clk2_clk3, :queue], # 10
218
+ [:clk3_clk2_clk1, :queue], # 11
219
+ [:clk2_clk3_clk1, :queue], # 12
220
+ [:clk2_clk1_clk3, :queue], # 13
221
+ ]
190
222
 
191
223
  # The configuration
192
- $mode, $channel = $scenarii[11]
224
+ # $mode, $channel = $scenarii[11]
225
+ $mode, $channel = $scenarii[ARGV[-1].to_i]
226
+ puts "scenario: #{$scenarii[ARGV[-1].to_i]}"
193
227
 
194
228
  # Testing the queue channel.
195
229
  system :test_queue do
196
- inner :clk, :rst, :clk2, :clk3
197
- [8].inner :idata, :odata
230
+ inner :rst, :clk1, :clk2, :clk3
231
+ [8].inner :idata, :odata, :odata2
198
232
  [4].inner :counter
199
233
 
234
+
235
+ # Assign the clocks
236
+ mode = $mode.to_s.split("_")
237
+ if ($channel == :queue) then
238
+ clk_que = send(mode[0])
239
+ end
240
+ ev_pro = mode[1][0] == "n" ?
241
+ send(mode[1][1..-1]).negedge : send(mode[1]).posedge
242
+ ev_con = mode[2][0] == "n" ?
243
+ send(mode[2][1..-1]).negedge : send(mode[2]).posedge
244
+
245
+ # Set up the channel
200
246
  if $channel == :register then
201
247
  register(bit[8]).(:my_ch)
202
248
  elsif $channel == :handshake then
203
249
  handshake(bit[8],rst).(:my_ch)
204
250
  elsif $channel == :queue then
205
- queue(bit[8],5,clk,rst).(:my_ch)
251
+ queue(bit[8],3,clk_que,rst).(:my_ch)
206
252
  end
207
253
 
208
- ev = $mode == :sync ? clk.posedge :
209
- $mode == :nsync ? clk.negedge : clk2.posedge
210
-
211
- if $mode != :proco then
212
- # Sync/Neg sync and async tests mode
213
- par(ev) do
214
- hif(rst) do
215
- counter <= 0
216
- idata <= 0
217
- odata <= 0
218
- end
219
- helse do
220
- hif (counter < 4) do
221
- my_ch.write(idata) do
222
- idata <= idata + 1
223
- counter <= counter + 1
224
- end
225
- end
226
- helsif ((counter > 10) & (counter < 15)) do
227
- my_ch.read(odata) do
228
- idata <= idata - odata
229
- counter <= counter + 1
230
- end
231
- end
232
- helse do
233
- counter <= counter + 1
234
- end
235
- end
254
+ # Producter/consumer mode
255
+ # Producer
256
+ par(ev_pro) do
257
+ hif(rst) do
258
+ idata <= 0
236
259
  end
237
- else
238
- # Producter/consumer mode
239
- # Producer
240
- par(clk2.posedge) do
241
- hif(rst) do
242
- idata <= 0
243
- end
244
- helse do
245
- my_ch.write(idata) do
246
- idata <= idata + 1
247
- end
260
+ helse do
261
+ my_ch.write(idata) do
262
+ idata <= idata + 1
248
263
  end
249
264
  end
250
- # Consumer
251
- par(clk3.posedge) do
252
- hif(rst) do
253
- counter <= 0
254
- end
255
- helse do
256
- my_ch.read(odata) do
257
- counter <= counter + 1
258
- end
265
+ end
266
+ # Consumer
267
+ par(ev_con) do
268
+ hif(rst) do
269
+ counter <= 0
270
+ end
271
+ helse do
272
+ my_ch.read(odata) do
273
+ counter <= counter + 1
259
274
  end
260
275
  end
261
276
  end
262
277
 
263
278
  timed do
264
- clk <= 0
279
+ clk1 <= 0
265
280
  clk2 <= 0
266
281
  clk3 <= 0
267
282
  rst <= 0
268
283
  !10.ns
269
- clk <= 1
284
+ clk1 <= 1
270
285
  !10.ns
271
- clk <= 0
286
+ clk1 <= 0
272
287
  rst <= 1
273
288
  !3.ns
274
289
  clk2 <= 1
275
290
  !3.ns
276
291
  clk3 <= 0
277
292
  !4.ns
278
- clk <= 1
293
+ clk1 <= 1
279
294
  !10.ns
280
- clk <= 0
295
+ clk1 <= 0
281
296
  !3.ns
282
297
  clk2 <= 0
283
298
  !3.ns
@@ -286,9 +301,9 @@ system :test_queue do
286
301
  rst <= 0
287
302
  !2.ns
288
303
  64.times do
289
- clk <= 1
304
+ clk1 <= 1
290
305
  !10.ns
291
- clk <= 0
306
+ clk1 <= 0
292
307
  !3.ns
293
308
  clk2 <= ~clk2
294
309
  !3.ns
@@ -1223,6 +1223,8 @@ static Value concat_value_bitstring_array(int num, int dir,
1223
1223
  }
1224
1224
  /* Resize the destination accordignly. */
1225
1225
  resize_value(dst,width);
1226
+ /* Ensure it is not numeric. */
1227
+ dst->numeric = 0;
1226
1228
 
1227
1229
  /* Access the data of the destination. */
1228
1230
  char* dst_data = dst->data_str;
@@ -1233,7 +1235,7 @@ static Value concat_value_bitstring_array(int num, int dir,
1233
1235
  unsigned int idx = dir ? (num-i-1) : i;
1234
1236
  Value value = args[idx];
1235
1237
  unsigned long long cw = type_width(value->type);
1236
- // printf("value=%s cw=%llu\n",value->data_str,cw);
1238
+ // printf("value=%s cw=%llu pos=%llu\n",value->data_str,cw,pos);
1237
1239
  memcpy(dst_data+pos,value->data_str,cw);
1238
1240
  pos += cw;
1239
1241
  }
@@ -0,0 +1,67 @@
1
+ module HDLRuby::High::Std
2
+
3
+ ##
4
+ # Standard HDLRuby::High library: connectors between channels
5
+ #
6
+ ########################################################################
7
+
8
+ # Function for generating a connector that duplicates the output of
9
+ # channel +in_ch+ and connect it to channels +out_chs+ with data of
10
+ # +typ+.
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
15
+ out_acks = out_chs.size.times.map { |i| inner(:"out_ack#{i}") }
16
+ typ.inner :data
17
+ par(ev) do
18
+ in_req <= 1
19
+ out_acks.each { |ack| ack <= 0 }
20
+ out_acks.each do |ack|
21
+ hif(ack == 1) { in_req <= 0 }
22
+ end
23
+ hif(in_req) do
24
+ in_ack <= 0
25
+ in_ch.read(data) { in_ack <= 1 }
26
+ end
27
+ hif(in_ack) do
28
+ out_chs.zip(out_acks).each do |ch,ack|
29
+ hif(ack == 0) { ch.write(data) { ack <= 1 } }
30
+ end
31
+ hif (out_acks.reduce(_1) { |sum,ack| ack & sum }) do
32
+ out_acks.each { |ack| ack <= 0 }
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ # Function for generating a connector that merges the output of
39
+ # channels +in_chs+ and connects the result to channel +out_ch+ with
40
+ # data of +typ+.
41
+ # The merge is done according to event +ev+.
42
+ function :merger do |typs, ev, in_chs, out_ch|
43
+ ev = ev.posedge unless ev.is_a?(Event)
44
+ inner :out_ack
45
+ in_reqs = in_chs.size.times.map { |i| inner(:"in_req#{i}") }
46
+ in_acks = in_chs.size.times.map { |i| inner(:"in_ack#{i}") }
47
+ datas = typs.map.with_index { |typ,i| typ.inner(:"data#{i}") }
48
+ par(ev) do
49
+ in_reqs.each { |req| req <= 1 }
50
+ out_ack <= 0
51
+ hif(out_ack == 1) { in_reqs.each { |req| req <= 0 } }
52
+ hif(in_reqs.reduce(_1) { |sum,req| req & sum }) do
53
+ in_chs.each_with_index do |ch,i|
54
+ in_acks[i] <= 0
55
+ ch.read(datas[i]) { in_acks[i] <= 1 }
56
+ end
57
+ end
58
+ hif(in_acks.reduce(_1) { |sum,req| req & sum }) do
59
+ hif(out_ack == 0) { out_ch.write(datas) { out_ack <= 1 } }
60
+ hif (out_ack == 1) { out_ack <= 0 }
61
+ end
62
+ end
63
+ end
64
+
65
+
66
+
67
+ end
@@ -34,6 +34,7 @@ HDLRuby::High::Std.channel(:mem_sync) do |n,typ,size,clk_e,rst,br_rsts = []|
34
34
  size = size.to_i
35
35
  # Compute the address bus width from the size.
36
36
  awidth = (size-1).width
37
+ awidth = 1 if awidth == 0
37
38
  # Ensure clk_e is an event, if not set it to a positive edge.
38
39
  clk_e = clk_e.posedge unless clk_e.is_a?(Event)
39
40
 
@@ -209,6 +210,7 @@ HDLRuby::High::Std.channel(:mem_rom) do |typ,size,clk,rst,content,
209
210
  size = size.to_i
210
211
  # Compute the address bus width from the size.
211
212
  awidth = (size-1).width
213
+ awidth = 1 if awidth == 0
212
214
  # Process the table of reset mapping for the branches.
213
215
  # Ensures br_srts is a hash.
214
216
  br_rsts = br_rsts.to_hash
@@ -321,7 +323,12 @@ HDLRuby::High::Std.channel(:mem_rom) do |typ,size,clk,rst,content,
321
323
  end
322
324
  helse do
323
325
  # Prepare the read.
324
- abus_r <= abus_r + 1
326
+ # abus_r <= abus_r + 1
327
+ if 2**size.width != size then
328
+ abus_r <= mux((abus_r + 1) == size, abus_r + 1, 0)
329
+ else
330
+ abus_r <= abus_r + 1
331
+ end
325
332
  trig_r <= 1
326
333
  end
327
334
  end
@@ -382,7 +389,12 @@ HDLRuby::High::Std.channel(:mem_rom) do |typ,size,clk,rst,content,
382
389
  end
383
390
  helse do
384
391
  # Prepare the read.
385
- abus_r <= abus_r - 1
392
+ # abus_r <= abus_r - 1
393
+ if 2**size.width != size then
394
+ abus_r <= mux(abus_r == 0, abus_r - 1, size - 1)
395
+ else
396
+ abus_r <= abus_r - 1
397
+ end
386
398
  trig_r <= 1
387
399
  end
388
400
  end
@@ -434,6 +446,7 @@ HDLRuby::High::Std.channel(:mem_dual) do |typ,size,clk,rst,br_rsts = {}|
434
446
  size = size.to_i
435
447
  # Compute the address bus width from the size.
436
448
  awidth = (size-1).width
449
+ awidth = 1 if awidth == 0
437
450
  # Process the table of reset mapping for the branches.
438
451
  # puts "first br_rsts=#{br_rsts}"
439
452
  # if br_rsts.is_a?(Array) then
@@ -593,7 +606,12 @@ HDLRuby::High::Std.channel(:mem_dual) do |typ,size,clk,rst,br_rsts = {}|
593
606
  end
594
607
  helse do
595
608
  # Prepare the read.
596
- abus_r <= abus_r + 1
609
+ # abus_r <= abus_r + 1
610
+ if 2**size.width != size then
611
+ abus_r <= mux((abus_r + 1) == size, abus_r + 1, 0)
612
+ else
613
+ abus_r <= abus_r + 1
614
+ end
597
615
  trig_r <= 1
598
616
  end
599
617
  end
@@ -630,7 +648,12 @@ HDLRuby::High::Std.channel(:mem_dual) do |typ,size,clk,rst,br_rsts = {}|
630
648
  # No reset, so can perform the write.
631
649
  blk.call if blk
632
650
  # Prepare the write.
633
- abus_w <= abus_w + 1
651
+ # abus_w <= abus_w + 1
652
+ if 2**size.width != size then
653
+ abus_w <= mux((abus_w + 1) == size, abus_w + 1, 0)
654
+ else
655
+ abus_w <= abus_w + 1
656
+ end
634
657
  trig_w <= 1
635
658
  dbus_w <= target
636
659
  end
@@ -692,7 +715,12 @@ HDLRuby::High::Std.channel(:mem_dual) do |typ,size,clk,rst,br_rsts = {}|
692
715
  end
693
716
  helse do
694
717
  # Prepare the read.
695
- abus_r <= abus_r - 1
718
+ # abus_r <= abus_r - 1
719
+ if 2**size.width != size then
720
+ abus_r <= mux(abus_r == 0, abus_r - 1, size - 1)
721
+ else
722
+ abus_r <= abus_r - 1
723
+ end
696
724
  trig_r <= 1
697
725
  end
698
726
  end
@@ -729,7 +757,12 @@ HDLRuby::High::Std.channel(:mem_dual) do |typ,size,clk,rst,br_rsts = {}|
729
757
  # No reset, so can perform the write.
730
758
  blk.call if blk
731
759
  # Prepare the write.
732
- abus_w <= abus_w - 1
760
+ # abus_w <= abus_w - 1
761
+ if 2**size.width != size then
762
+ abus_w <= mux(abus_w == 0, abus_w - 1, size - 1)
763
+ else
764
+ abus_w <= abus_w - 1
765
+ end
733
766
  trig_w <= 1
734
767
  dbus_w <= target
735
768
  end
@@ -923,7 +956,9 @@ HDLRuby::High::Std.channel(:mem_file) do |typ,size,clk,rst,br_rsts = {}|
923
956
  reader_input rst_name
924
957
  end
925
958
  # Declares the address counter.
926
- [size.width-1].inner :abus_r
959
+ awidth = (size-1).width
960
+ awidth = 1 if awidth == 0
961
+ [awidth].inner :abus_r
927
962
  reader_inout :abus_r
928
963
 
929
964
  # Defines the read procedure at address +addr+
@@ -946,7 +981,12 @@ HDLRuby::High::Std.channel(:mem_file) do |typ,size,clk,rst,br_rsts = {}|
946
981
  end
947
982
  blk.call if blk
948
983
  # Prepare the next read.
949
- abus_r <= abus_r + 1
984
+ # abus_r <= abus_r + 1
985
+ if 2**size.width != size then
986
+ abus_r <= mux((abus_r + 1) == size, abus_r + 1, 0)
987
+ else
988
+ abus_r <= abus_r + 1
989
+ end
950
990
  end
951
991
  end
952
992
  end
@@ -962,7 +1002,9 @@ HDLRuby::High::Std.channel(:mem_file) do |typ,size,clk,rst,br_rsts = {}|
962
1002
  writer_input rst_name
963
1003
  end
964
1004
  # Declares the address counter.
965
- [size.width-1].inner :abus_w
1005
+ awidth = (size-1).width
1006
+ awidth = 1 if awidth == 0
1007
+ [awidth].inner :abus_w
966
1008
  writer_inout :abus_w
967
1009
 
968
1010
  # Defines the write procedure at address +addr+
@@ -985,7 +1027,12 @@ HDLRuby::High::Std.channel(:mem_file) do |typ,size,clk,rst,br_rsts = {}|
985
1027
  end
986
1028
  blk.call if blk
987
1029
  # Prepare the next write.
988
- abus_w <= abus_w + 1
1030
+ # abus_w <= abus_w + 1
1031
+ if 2**size.width != size then
1032
+ abus_w <= mux((abus_w + 1) == size, abus_w + 1, 0)
1033
+ else
1034
+ abus_w <= abus_w + 1
1035
+ end
989
1036
  end
990
1037
  end
991
1038
  end
@@ -1003,7 +1050,9 @@ HDLRuby::High::Std.channel(:mem_file) do |typ,size,clk,rst,br_rsts = {}|
1003
1050
  reader_input rst_name
1004
1051
  end
1005
1052
  # Declares the address counter.
1006
- [size.width-1].inner :abus_r
1053
+ awidth = (size-1).width
1054
+ awidth = 1 if awidth == 0
1055
+ [awidth].inner :abus_r
1007
1056
  reader_inout :abus_r
1008
1057
 
1009
1058
  # Defines the read procedure at address +addr+
@@ -1026,7 +1075,12 @@ HDLRuby::High::Std.channel(:mem_file) do |typ,size,clk,rst,br_rsts = {}|
1026
1075
  end
1027
1076
  blk.call if blk
1028
1077
  # Prepare the next read.
1029
- abus_r <= abus_r - 1
1078
+ # abus_r <= abus_r - 1
1079
+ if 2**size.width != size then
1080
+ abus_r <= mux(abus_r == 0, abus_r - 1, size - 1)
1081
+ else
1082
+ abus_r <= abus_r - 1
1083
+ end
1030
1084
  end
1031
1085
  end
1032
1086
  end
@@ -1042,7 +1096,9 @@ HDLRuby::High::Std.channel(:mem_file) do |typ,size,clk,rst,br_rsts = {}|
1042
1096
  reader_input rst_name
1043
1097
  end
1044
1098
  # Declares the address counter.
1045
- [size.width-1].inner :abus_w
1099
+ awidth = (size-1).width
1100
+ awidth = 1 if awidth == 0
1101
+ [awidth].inner :abus_w
1046
1102
  reader_inout :abus_w
1047
1103
 
1048
1104
  # Defines the write procedure at address +addr+
@@ -1065,7 +1121,12 @@ HDLRuby::High::Std.channel(:mem_file) do |typ,size,clk,rst,br_rsts = {}|
1065
1121
  end
1066
1122
  blk.call if blk
1067
1123
  # Prepare the next write.
1068
- abus_w <= abus_w - 1
1124
+ # abus_w <= abus_w - 1
1125
+ if 2**size.width != size then
1126
+ abus_w <= mux(abus_w == 0, abus_w - 1, size - 1)
1127
+ else
1128
+ abus_w <= abus_w - 1
1129
+ end
1069
1130
  end
1070
1131
  end
1071
1132
  end
@@ -1113,7 +1174,9 @@ HDLRuby::High::Std.channel(:mem_bank) do |typ,nbanks,size,clk,rst,br_rsts = {}|
1113
1174
  size = size.to_i
1114
1175
  # Compute the address bus width from the size.
1115
1176
  awidth = (size*nbanks-1).width
1177
+ awidth = 1 if awidth == 0
1116
1178
  awidth_b = (size-1).width # Bank width
1179
+ awidth_b = 1 if awidth_b == 0
1117
1180
  # Ensures br_srts is a hash.
1118
1181
  br_rsts = br_rsts.to_hash
1119
1182
 
@@ -1274,7 +1337,12 @@ HDLRuby::High::Std.channel(:mem_bank) do |typ,nbanks,size,clk,rst,br_rsts = {}|
1274
1337
  blk.call if blk
1275
1338
  end
1276
1339
  # Prepare the read.
1277
- abus_r <= abus_r + 1
1340
+ # abus_r <= abus_r + 1
1341
+ if 2**size.width != size then
1342
+ abus_r <= mux((abus_r + 1) == size, abus_r + 1, 0)
1343
+ else
1344
+ abus_r <= abus_r + 1
1345
+ end
1278
1346
  trig_r <= 1
1279
1347
  end
1280
1348
  end
@@ -1310,7 +1378,12 @@ HDLRuby::High::Std.channel(:mem_bank) do |typ,nbanks,size,clk,rst,br_rsts = {}|
1310
1378
  # No reset, so can perform the write.
1311
1379
  blk.call if blk
1312
1380
  # Prepare the write.
1313
- abus_w <= abus_w + 1
1381
+ # abus_w <= abus_w + 1
1382
+ if 2**size.width != size then
1383
+ abus_w <= mux((abus_w + 1) == size, abus_w + 1, 0)
1384
+ else
1385
+ abus_w <= abus_w + 1
1386
+ end
1314
1387
  trig_w <= 1
1315
1388
  dbus_w <= target
1316
1389
  end
@@ -1351,7 +1424,12 @@ HDLRuby::High::Std.channel(:mem_bank) do |typ,nbanks,size,clk,rst,br_rsts = {}|
1351
1424
  blk.call if blk
1352
1425
  end
1353
1426
  # Prepare the read.
1354
- abus_r <= abus_r - 1
1427
+ # abus_r <= abus_r - 1
1428
+ if 2**size.width != size then
1429
+ abus_r <= mux(abus_r == 0, abus_r - 1, size - 1)
1430
+ else
1431
+ abus_r <= abus_r - 1
1432
+ end
1355
1433
  trig_r <= 1
1356
1434
  end
1357
1435
  end
@@ -1388,6 +1466,11 @@ HDLRuby::High::Std.channel(:mem_bank) do |typ,nbanks,size,clk,rst,br_rsts = {}|
1388
1466
  blk.call if blk
1389
1467
  # Prepare the write.
1390
1468
  abus_w <= abus_w - 1
1469
+ if 2**size.width != size then
1470
+ abus_w <= mux(abus_w == 0, abus_w - 1, size - 1)
1471
+ else
1472
+ abus_w <= abus_w - 1
1473
+ end
1391
1474
  trig_w <= 1
1392
1475
  dbus_w <= target
1393
1476
  end
@@ -1,3 +1,3 @@
1
1
  module HDLRuby
2
- VERSION = "2.4.9"
2
+ VERSION = "2.4.15"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: HDLRuby
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.9
4
+ version: 2.4.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lovic Gauthier
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-10-15 00:00:00.000000000 Z
11
+ date: 2020-11-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -84,6 +84,7 @@ files:
84
84
  - lib/HDLRuby/hdr_samples/include.rb
85
85
  - lib/HDLRuby/hdr_samples/instance_open.rb
86
86
  - lib/HDLRuby/hdr_samples/linear_test.rb
87
+ - lib/HDLRuby/hdr_samples/make_multi_channels_vcd.rb
87
88
  - lib/HDLRuby/hdr_samples/mei8.rb
88
89
  - lib/HDLRuby/hdr_samples/mei8_bench.rb
89
90
  - lib/HDLRuby/hdr_samples/memory_test.rb
@@ -119,12 +120,14 @@ files:
119
120
  - lib/HDLRuby/hdr_samples/tuple.rb
120
121
  - lib/HDLRuby/hdr_samples/with_channel.rb
121
122
  - lib/HDLRuby/hdr_samples/with_class.rb
123
+ - lib/HDLRuby/hdr_samples/with_connector.rb
122
124
  - lib/HDLRuby/hdr_samples/with_decoder.rb
123
125
  - lib/HDLRuby/hdr_samples/with_fixpoint.rb
124
126
  - lib/HDLRuby/hdr_samples/with_fsm.rb
125
127
  - lib/HDLRuby/hdr_samples/with_linear.rb
126
128
  - lib/HDLRuby/hdr_samples/with_loop.rb
127
129
  - lib/HDLRuby/hdr_samples/with_memory.rb
130
+ - lib/HDLRuby/hdr_samples/with_memory_rom.rb
128
131
  - lib/HDLRuby/hdr_samples/with_multi_channels.rb
129
132
  - lib/HDLRuby/hdr_samples/with_reconf.rb
130
133
  - lib/HDLRuby/hdrcc.rb
@@ -270,6 +273,7 @@ files:
270
273
  - lib/HDLRuby/sim/hruby_value_pool.c
271
274
  - lib/HDLRuby/std/channel.rb
272
275
  - lib/HDLRuby/std/clocks.rb
276
+ - lib/HDLRuby/std/connector.rb
273
277
  - lib/HDLRuby/std/counters.rb
274
278
  - lib/HDLRuby/std/decoder.rb
275
279
  - lib/HDLRuby/std/fixpoint.rb