HDLRuby 2.4.9 → 2.4.15

Sign up to get free protection for your applications and to get access to all the features.
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