HDLRuby 2.4.11 → 2.4.18

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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,245 @@
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
+
129
+ # First tester.
130
+ [4].inner :counter
131
+ [4*4].inner :res
132
+ inner :ack_in, :ack_out
133
+
134
+ # The input queue.
135
+ queue(bit[4],4,clk,rst).(:in_qu)
136
+
137
+ # The middle queues.
138
+ mid_qus = 4.times.map do |i|
139
+ queue(bit[4],4,clk,rst).(:"mid_qu#{i}")
140
+ end
141
+
142
+ # The output queue.
143
+ queue(bit[4*4],4,clk,rst).(:out_qu)
144
+
145
+ # Connect the input queue to the middle queues.
146
+ duplicator(bit[4],clk.negedge,in_qu,mid_qus)
147
+
148
+ # Connect the middle queues to the output queue.
149
+ merger([bit[4]]*4,clk.negedge,mid_qus,out_qu)
150
+
151
+
152
+ # Second tester.
153
+ [4].inner :counterb
154
+ [4].inner :resb
155
+ inner :ack_inb0, :ack_inb1, :ack_outb
156
+
157
+ # The input queues.
158
+ queue(bit[4],4,clk,rst).(:in_qub0)
159
+ queue(bit[4],4,clk,rst).(:in_qub1)
160
+
161
+ # The output queue.
162
+ queue(bit[4],4,clk,rst).(:out_qub)
163
+
164
+ # Connect then with a serializer.
165
+ serializer(bit[4],clk.negedge,[in_qub0,in_qub1],out_qub)
166
+
167
+ # # Slow version, always work
168
+ # par(clk.posedge) do
169
+ # ack_in <= 0
170
+ # ack_out <= 1
171
+ # hif(rst) { counter <= 0 }
172
+ # helse do
173
+ # hif(ack_out) do
174
+ # ack_out <= 0
175
+ # in_qu.write(counter) do
176
+ # ack_in <= 1
177
+ # counter <= counter + 1
178
+ # end
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) { ack_out <= 1 }
185
+ # end
186
+ # end
187
+ # end
188
+
189
+ # Fast version but assumes connected channels are blocking
190
+ par(clk.posedge) do
191
+ ack_in <= 0
192
+ ack_inb0 <= 0
193
+ ack_inb1 <= 0
194
+ hif(rst) { counter <= 0; counterb <= 0 }
195
+ helse do
196
+ in_qu.write(counter) do
197
+ ack_in <= 1
198
+ counter <= counter + 1
199
+ end
200
+ hif(ack_in) do
201
+ out_qu.read(res)
202
+ end
203
+ hif(~ack_inb0) do
204
+ in_qub0.write(counterb) do
205
+ ack_inb0 <= 1
206
+ counterb <= counterb + 1
207
+ end
208
+ end
209
+ helse do
210
+ in_qub1.write(counterb) do
211
+ ack_inb1 <= 1
212
+ counterb <= counterb + 1
213
+ end
214
+ end
215
+ hif(ack_inb0 | ack_inb1) do
216
+ out_qub.read(resb)
217
+ end
218
+ end
219
+ end
220
+
221
+ timed do
222
+ clk <= 0
223
+ rst <= 0
224
+ !10.ns
225
+ clk <= 1
226
+ !10.ns
227
+ clk <= 0
228
+ rst <= 1
229
+ !10.ns
230
+ clk <= 1
231
+ !10.ns
232
+ clk <= 0
233
+ !10.ns
234
+ clk <= 1
235
+ !10.ns
236
+ clk <= 0
237
+ rst <= 0
238
+ 16.times do
239
+ !10.ns
240
+ clk <= 1
241
+ !10.ns
242
+ clk <= 0
243
+ end
244
+ end
245
+ 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
@@ -10,36 +10,41 @@ 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 (~rreq) { rack <= 0 }
28
+ hif(rreq & (~rack) & (rptr != wptr)) do
29
+ rdata <= buffer[rptr]
30
+ rptr <= (rptr + 1) % depth
31
+ rack <= 1
32
+ end
33
+ end
34
+
35
+ hif(~wsync) do
36
+ hif (~wreq) { wack <= 0 }
37
+ hif(wreq & (~wack) & (((wptr+1) % depth) != rptr)) do
38
+ buffer[wptr] <= wdata
39
+ wptr <= (wptr + 1) % depth
40
+ wack <= 1
41
+ end
42
+ end
37
43
  end
38
44
  end
39
- par { rdata <= buffer[rptr] }
40
45
 
41
- reader_output :rcmd, :rptr, :hrack
42
- reader_input :rdata, :rack
46
+ reader_output :rreq, :rptr, :rsync
47
+ reader_input :rdata, :rack, :wptr, :buffer
43
48
 
44
49
  # The read primitive.
45
50
  reader do |blk,target|
@@ -47,58 +52,64 @@ channel(:queue) do |typ,depth,clk,rst|
47
52
  # Same clk event, synchrone case: perform a direct access.
48
53
  # Now perform the access.
49
54
  top_block.unshift do
50
- rcmd <= 0
51
- hrack <= 1
55
+ rsync <= 1
56
+ rreq <= 0
52
57
  end
53
58
  seq do
54
- rptr <= (rptr + 1) % depth
55
- target <= rdata
56
- blk.call if blk
59
+ hif(rptr != wptr) do
60
+ target <= buffer[rptr]
61
+ rptr <= (rptr + 1) % depth
62
+ blk.call if blk
63
+ end
57
64
  end
58
65
  else
59
66
  # Different clk event, perform a decoupled access.
60
67
  top_block.unshift do
61
- rcmd <= 0
62
- hrack <= 0
68
+ rsync <= 0
69
+ rreq <= 0
63
70
  end
64
- seq do
65
- hif(rack) do
66
- blk.call if blk
67
- end
68
- helse do
69
- rcmd <= 1
71
+ par do
72
+ hif (~rack) { rreq <= 1 }
73
+ helsif(rreq) do
74
+ rreq <= 0
70
75
  target <= rdata
76
+ blk.call if blk
71
77
  end
72
78
  end
73
79
  end
74
80
  end
75
81
 
76
- writer_output :wcmd, :wdata, :hwack
77
- writer_input :wack
82
+ writer_output :wreq, :wdata, :wptr, :wsync, :buffer
83
+ writer_input :wack, :rptr
78
84
 
79
85
  # The write primitive.
80
86
  writer do |blk,target|
81
87
  if (cur_behavior.on_event?(clk.negedge,clk.posedge)) then
82
88
  # Same clk event, synchrone case: perform a direct access.
83
89
  top_block.unshift do
84
- wcmd <= 0
85
- hwack <= 1
90
+ wsync <= 1
91
+ wreq <= 0
92
+ end
93
+ hif(((wptr+1) % depth) != rptr) do
94
+ buffer[wptr] <= target
95
+ wptr <= (wptr + 1) % depth
96
+ blk.call if blk
86
97
  end
87
- wcmd <= 1
88
- wdata <= target
89
- blk.call if blk
90
98
  else
91
99
  # Different clk event, asynchrone case: perform a decoupled access.
92
100
  top_block.unshift do
93
- wcmd <= 0
94
- hwack <= 0
101
+ wsync <= 0
102
+ wreq <= 0
95
103
  end
96
104
  seq do
97
- hif(wack) do
105
+ hif (~wack) do
106
+ wreq <= 1
107
+ wdata <= target
108
+ end
109
+ helsif(wreq) do
110
+ wreq <= 0
98
111
  blk.call if blk
99
112
  end
100
- helse { wcmd <= 1 }
101
- wdata <= target
102
113
  end
103
114
  end
104
115
  end
@@ -174,110 +185,102 @@ channel(:handshake) do |typ|
174
185
  end
175
186
 
176
187
 
177
- # $mode = :sync
178
- # $mode = :nsync
179
- # $mode = :async
180
- # $mode = :proco # Producter / Consummer
188
+ # $mode: channel clock, producer clock, consumer clock (n: not clock)
181
189
  # $channel = :register
182
190
  # $channel = :handshake
183
191
  # $channel = :queue
184
192
 
185
193
  # 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] ]
194
+ $scenarii = [
195
+ [:_clk2_clk2, :register], # 0
196
+ [:_clk2_nclk2, :register], # 1
197
+ [:_clk2_clk3, :register], # 2
198
+ [:_clk3_clk2, :register], # 3
199
+ [:_clk2_clk2, :handshake], # 4
200
+ [:_clk2_nclk2, :handshake], # 5
201
+ [:_clk2_clk3, :handshake], # 6
202
+ [:_clk3_clk2, :handshake], # 7
203
+ [:clk2_clk2_clk2, :queue], # 8
204
+ [:clk2_clk2_nclk2, :queue], # 9
205
+ [:clk1_clk2_clk3, :queue], # 10
206
+ [:clk3_clk2_clk1, :queue], # 11
207
+ [:clk2_clk3_clk1, :queue], # 12
208
+ [:clk2_clk1_clk3, :queue], # 13
209
+ ]
190
210
 
191
211
  # The configuration
192
- $mode, $channel = $scenarii[11]
212
+ # $mode, $channel = $scenarii[11]
213
+ $mode, $channel = $scenarii[ARGV[-1].to_i]
214
+ puts "scenario: #{$scenarii[ARGV[-1].to_i]}"
193
215
 
194
216
  # Testing the queue channel.
195
217
  system :test_queue do
196
- inner :clk, :rst, :clk2, :clk3
197
- [8].inner :idata, :odata
218
+ inner :rst, :clk1, :clk2, :clk3
219
+ [8].inner :idata, :odata, :odata2
198
220
  [4].inner :counter
199
221
 
222
+
223
+ # Assign the clocks
224
+ mode = $mode.to_s.split("_")
225
+ if ($channel == :queue) then
226
+ clk_que = send(mode[0])
227
+ end
228
+ ev_pro = mode[1][0] == "n" ?
229
+ send(mode[1][1..-1]).negedge : send(mode[1]).posedge
230
+ ev_con = mode[2][0] == "n" ?
231
+ send(mode[2][1..-1]).negedge : send(mode[2]).posedge
232
+
233
+ # Set up the channel
200
234
  if $channel == :register then
201
235
  register(bit[8]).(:my_ch)
202
236
  elsif $channel == :handshake then
203
237
  handshake(bit[8],rst).(:my_ch)
204
238
  elsif $channel == :queue then
205
- queue(bit[8],5,clk,rst).(:my_ch)
239
+ queue(bit[8],3,clk_que,rst).(:my_ch)
206
240
  end
207
241
 
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
242
+ # Producter/consumer mode
243
+ # Producer
244
+ par(ev_pro) do
245
+ hif(rst) do
246
+ idata <= 0
236
247
  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
248
+ helse do
249
+ my_ch.write(idata) do
250
+ idata <= idata + 1
248
251
  end
249
252
  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
253
+ end
254
+ # Consumer
255
+ par(ev_con) do
256
+ hif(rst) do
257
+ counter <= 0
258
+ end
259
+ helse do
260
+ my_ch.read(odata) do
261
+ counter <= counter + 1
259
262
  end
260
263
  end
261
264
  end
262
265
 
263
266
  timed do
264
- clk <= 0
267
+ clk1 <= 0
265
268
  clk2 <= 0
266
269
  clk3 <= 0
267
270
  rst <= 0
268
271
  !10.ns
269
- clk <= 1
272
+ clk1 <= 1
270
273
  !10.ns
271
- clk <= 0
274
+ clk1 <= 0
272
275
  rst <= 1
273
276
  !3.ns
274
277
  clk2 <= 1
275
278
  !3.ns
276
279
  clk3 <= 0
277
280
  !4.ns
278
- clk <= 1
281
+ clk1 <= 1
279
282
  !10.ns
280
- clk <= 0
283
+ clk1 <= 0
281
284
  !3.ns
282
285
  clk2 <= 0
283
286
  !3.ns
@@ -286,9 +289,9 @@ system :test_queue do
286
289
  rst <= 0
287
290
  !2.ns
288
291
  64.times do
289
- clk <= 1
292
+ clk1 <= 1
290
293
  !10.ns
291
- clk <= 0
294
+ clk1 <= 0
292
295
  !3.ns
293
296
  clk2 <= ~clk2
294
297
  !3.ns