HDLRuby 2.2.17 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/HDLRuby/hdr_samples/ruby_fir_hw.rb +96 -0
- data/lib/HDLRuby/hdr_samples/with_linear.rb +4 -1
- data/lib/HDLRuby/hdr_samples/with_loop.rb +69 -0
- data/lib/HDLRuby/hdr_samples/with_memory.rb +13 -3
- data/lib/HDLRuby/hruby_high.rb +6 -0
- data/lib/HDLRuby/hruby_low.rb +24 -9
- data/lib/HDLRuby/hruby_low2c.rb +9 -5
- data/lib/HDLRuby/hruby_low_fix_types.rb +4 -2
- data/lib/HDLRuby/hruby_low_resolve.rb +5 -3
- data/lib/HDLRuby/hruby_low_without_concat.rb +8 -4
- data/lib/HDLRuby/hruby_types.rb +82 -72
- data/lib/HDLRuby/sim/hruby_sim.h +7 -0
- data/lib/HDLRuby/sim/hruby_sim_calc.c +79 -6
- data/lib/HDLRuby/std/channel.rb +39 -16
- data/lib/HDLRuby/std/fixpoint.rb +7 -6
- data/lib/HDLRuby/std/linear.rb +68 -0
- data/lib/HDLRuby/std/loop.rb +101 -0
- data/lib/HDLRuby/std/memory.rb +1000 -30
- data/lib/HDLRuby/std/task.rb +850 -0
- data/lib/HDLRuby/version.rb +1 -1
- metadata +6 -2
data/lib/HDLRuby/std/memory.rb
CHANGED
@@ -170,6 +170,187 @@ HDLRuby::High::Std.channel(:mem_sync) do |n,typ,size,clk_e,rst,br_rsts = []|
|
|
170
170
|
end
|
171
171
|
|
172
172
|
|
173
|
+
# Flexible ROM memory of +size+ elements of +typ+ typ, syncrhonized on +clk+
|
174
|
+
# (positive and negative edges) and reset on +rst+.
|
175
|
+
# At each rising edge of +clk+ a read and a write is guaranteed to be
|
176
|
+
# completed provided they are triggered.
|
177
|
+
# +br_rsts+ are reset names on the branches, if not given, a reset input
|
178
|
+
# is added and connected to rst.
|
179
|
+
# The content of the ROM is passed through +content+ argument.
|
180
|
+
#
|
181
|
+
# NOTE:
|
182
|
+
#
|
183
|
+
# * such memories uses the following ports:
|
184
|
+
# - trig_r: read access trigger (output)
|
185
|
+
# - trig_w: write access trigger (output)
|
186
|
+
# - dbus_r: read data bus (input)
|
187
|
+
# - dbus_w: write data bus (output)
|
188
|
+
#
|
189
|
+
# * The following branches are possible (only one read and one write can
|
190
|
+
# be used per channel)
|
191
|
+
# - raddr: read by address, this channel adds the following port:
|
192
|
+
# abus_r: read address bus (output)
|
193
|
+
# - waddr: read by address, this channel adds the following port:
|
194
|
+
# abus_w: write address bus (output)
|
195
|
+
# - rinc: read by automatically incremented address.
|
196
|
+
# - winc: write by automatically incremented address.
|
197
|
+
# - rdec: read by automatically decremented address.
|
198
|
+
# - wdec: write by automatically decremented address.
|
199
|
+
# - rque: read in queue mode: automatically incremented address ensuring
|
200
|
+
# the read address is always different from the write address.
|
201
|
+
# - wque: write in queue mode: automatically incremented address ensuring
|
202
|
+
# the write address is always differnet from the read address.
|
203
|
+
#
|
204
|
+
HDLRuby::High::Std.channel(:mem_rom) do |typ,size,clk,rst,content,
|
205
|
+
br_rsts = {}|
|
206
|
+
# Ensure typ is a type.
|
207
|
+
typ = typ.to_type
|
208
|
+
# Ensure size in an integer.
|
209
|
+
size = size.to_i
|
210
|
+
# Compute the address bus width from the size.
|
211
|
+
awidth = (size-1).width
|
212
|
+
# Process the table of reset mapping for the branches.
|
213
|
+
# Ensures br_srts is a hash.
|
214
|
+
br_rsts = br_rsts.to_hash
|
215
|
+
|
216
|
+
# Declare the control signals.
|
217
|
+
# Access trigger.
|
218
|
+
inner :trig_r
|
219
|
+
# Data bus
|
220
|
+
typ.inner :dbus_r
|
221
|
+
# Address bus (or simply register)
|
222
|
+
[awidth].inner :abus_r
|
223
|
+
|
224
|
+
# Declare the ROM with its inner content.
|
225
|
+
# typ[-size].constant mem: content.map { |val| val.to_expr }
|
226
|
+
typ[-size].constant mem: content
|
227
|
+
|
228
|
+
# Processes handling the memory access.
|
229
|
+
par(clk.negedge) do
|
230
|
+
dbus_r <= mem[abus_r]
|
231
|
+
end
|
232
|
+
|
233
|
+
# The address branches.
|
234
|
+
# Read with address
|
235
|
+
brancher(:raddr) do
|
236
|
+
reader_output :trig_r, :abus_r
|
237
|
+
reader_input :dbus_r
|
238
|
+
if br_rsts[:raddr] then
|
239
|
+
rst_name = br_rsts[:raddr].to_sym
|
240
|
+
else
|
241
|
+
rst_name = rst.name
|
242
|
+
reader_input rst_name
|
243
|
+
end
|
244
|
+
|
245
|
+
# Defines the read procedure at address +addr+
|
246
|
+
# using +target+ as target of access result.
|
247
|
+
reader do |blk,addr,target|
|
248
|
+
# By default the read trigger is 0.
|
249
|
+
top_block.unshift { trig_r <= 0 }
|
250
|
+
# The read procedure.
|
251
|
+
rst = send(rst_name)
|
252
|
+
par do
|
253
|
+
hif(rst == 0) do
|
254
|
+
# No reset, so can perform the read.
|
255
|
+
hif(trig_r == 1) do
|
256
|
+
# The trigger was previously set, read ok.
|
257
|
+
target <= dbus_r
|
258
|
+
trig_r <= 0
|
259
|
+
blk.call if blk
|
260
|
+
end
|
261
|
+
helse do
|
262
|
+
# Prepare the read.
|
263
|
+
abus_r <= addr
|
264
|
+
trig_r <= 1
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
# The increment branches.
|
272
|
+
# Read with increment
|
273
|
+
brancher(:rinc) do
|
274
|
+
reader_output :trig_r, :abus_r
|
275
|
+
reader_input :dbus_r
|
276
|
+
if br_rsts[:rinc] then
|
277
|
+
rst_name = br_rsts[:rinc].to_sym
|
278
|
+
else
|
279
|
+
rst_name = rst.name
|
280
|
+
reader_input rst_name
|
281
|
+
end
|
282
|
+
|
283
|
+
# Defines the read procedure at address +addr+
|
284
|
+
# using +target+ as target of access result.
|
285
|
+
reader do |blk,target|
|
286
|
+
# On reset the read trigger is 0.
|
287
|
+
rst = send(rst_name)
|
288
|
+
top_block.unshift do
|
289
|
+
# Initialize the address so that the next access is at address 0.
|
290
|
+
hif(rst==1) { abus_r <= -1 }
|
291
|
+
# Reset so switch of the access trigger.
|
292
|
+
trig_r <= 0
|
293
|
+
end
|
294
|
+
# The read procedure.
|
295
|
+
par do
|
296
|
+
hif(rst == 0) do
|
297
|
+
# No reset, so can perform the read.
|
298
|
+
hif(trig_r == 1) do
|
299
|
+
# The trigger was previously set, read ok.
|
300
|
+
target <= dbus_r
|
301
|
+
blk.call if blk
|
302
|
+
end
|
303
|
+
# Prepare the read.
|
304
|
+
abus_r <= abus_r + 1
|
305
|
+
trig_r <= 1
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
# The decrement branches.
|
312
|
+
# Read with increment
|
313
|
+
brancher(:rdec) do
|
314
|
+
reader_output :trig_r, :abus_r
|
315
|
+
reader_input :dbus_r
|
316
|
+
if br_rsts[:rdec] then
|
317
|
+
rst_name = br_rsts[:rdec].to_sym
|
318
|
+
else
|
319
|
+
rst_name = rst.name
|
320
|
+
reader_input rst_name
|
321
|
+
end
|
322
|
+
|
323
|
+
# Defines the read procedure at address +addr+
|
324
|
+
# using +target+ as target of access result.
|
325
|
+
reader do |blk,target|
|
326
|
+
# On reset the read trigger is 0.
|
327
|
+
rst = send(rst_name)
|
328
|
+
top_block.unshift do
|
329
|
+
# Initialize the address so that the next access is at address 0.
|
330
|
+
hif(rst==1) { abus_r <= 0 }
|
331
|
+
# Reset so switch of the access trigger.
|
332
|
+
trig_r <= 0
|
333
|
+
end
|
334
|
+
# The read procedure.
|
335
|
+
par do
|
336
|
+
hif(rst == 0) do
|
337
|
+
# No reset, so can perform the read.
|
338
|
+
hif(trig_r == 1) do
|
339
|
+
# The trigger was previously set, read ok.
|
340
|
+
target <= dbus_r
|
341
|
+
blk.call if blk
|
342
|
+
end
|
343
|
+
# Prepare the read.
|
344
|
+
abus_r <= abus_r - 1
|
345
|
+
trig_r <= 1
|
346
|
+
end
|
347
|
+
end
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
end
|
352
|
+
|
353
|
+
|
173
354
|
|
174
355
|
|
175
356
|
|
@@ -213,28 +394,32 @@ HDLRuby::High::Std.channel(:mem_dual) do |typ,size,clk,rst,br_rsts = {}|
|
|
213
394
|
awidth = (size-1).width
|
214
395
|
# Process the table of reset mapping for the branches.
|
215
396
|
# puts "first br_rsts=#{br_rsts}"
|
216
|
-
if br_rsts.is_a?(Array) then
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
397
|
+
# if br_rsts.is_a?(Array) then
|
398
|
+
# # It is a list, convert it to a hash with the following order:
|
399
|
+
# # raddr, waddr, rinc, winc, rdec, wdec, rque, wque
|
400
|
+
# # When not specified the reset is +rst+ by default.
|
401
|
+
# # If there is only two entries they will be duplicated and mapped
|
402
|
+
# # as follows:
|
403
|
+
# # [raddr,waddr], [rinc,winc], [rdec,wdec], [rque,wque]
|
404
|
+
# # If there is only one entry it will be duplicated and mapped as
|
405
|
+
# # follows:
|
406
|
+
# # raddr, rinc, rdec, rque
|
407
|
+
# if br_rsts.size == 2 then
|
408
|
+
# br_rsts = br_rsts * 4
|
409
|
+
# elsif br_rsts.size == 1 then
|
410
|
+
# br_rsts = br_rsts * 8
|
411
|
+
# end
|
412
|
+
# br_rsts = { raddr: br_rsts[0], waddr: br_rsts[1],
|
413
|
+
# rinc: br_rsts[2], winc: br_rsts[3],
|
414
|
+
# rdec: br_rsts[4], wdec: br_rsts[5],
|
415
|
+
# rque: br_rsts[6], wque: br_rsts[6] }
|
416
|
+
# end
|
417
|
+
# unless br_rsts.respond_to?(:[])
|
418
|
+
# raise "Invalid reset mapping description: #{br_rsts}"
|
419
|
+
# end
|
420
|
+
#
|
421
|
+
# Ensures br_srts is a hash.
|
422
|
+
br_rsts = br_rsts.to_hash
|
238
423
|
|
239
424
|
# Declare the control signals.
|
240
425
|
# Access triggers.
|
@@ -342,7 +527,7 @@ HDLRuby::High::Std.channel(:mem_dual) do |typ,size,clk,rst,br_rsts = {}|
|
|
342
527
|
# Defines the read procedure at address +addr+
|
343
528
|
# using +target+ as target of access result.
|
344
529
|
reader do |blk,target|
|
345
|
-
#
|
530
|
+
# On reset the read trigger is 0.
|
346
531
|
rst = send(rst_name)
|
347
532
|
top_block.unshift do
|
348
533
|
# Initialize the address so that the next access is at address 0.
|
@@ -382,7 +567,7 @@ HDLRuby::High::Std.channel(:mem_dual) do |typ,size,clk,rst,br_rsts = {}|
|
|
382
567
|
# Defines the read procedure at address +addr+
|
383
568
|
# using +target+ as target of access result.
|
384
569
|
writer do |blk,target|
|
385
|
-
#
|
570
|
+
# On reset the read trigger is 0.
|
386
571
|
rst = send(rst_name)
|
387
572
|
top_block.unshift do
|
388
573
|
# Initialize the address so that the next access is at address 0.
|
@@ -420,7 +605,7 @@ HDLRuby::High::Std.channel(:mem_dual) do |typ,size,clk,rst,br_rsts = {}|
|
|
420
605
|
# Defines the read procedure at address +addr+
|
421
606
|
# using +target+ as target of access result.
|
422
607
|
reader do |blk,target|
|
423
|
-
#
|
608
|
+
# On reset the read trigger is 0.
|
424
609
|
rst = send(rst_name)
|
425
610
|
top_block.unshift do
|
426
611
|
# Initialize the address so that the next access is at address 0.
|
@@ -460,7 +645,7 @@ HDLRuby::High::Std.channel(:mem_dual) do |typ,size,clk,rst,br_rsts = {}|
|
|
460
645
|
# Defines the read procedure at address +addr+
|
461
646
|
# using +target+ as target of access result.
|
462
647
|
writer do |blk,target|
|
463
|
-
#
|
648
|
+
# On reset the read trigger is 0.
|
464
649
|
rst = send(rst_name)
|
465
650
|
top_block.unshift do
|
466
651
|
# Initialize the address so that the next access is at address 0.
|
@@ -675,7 +860,7 @@ HDLRuby::High::Std.channel(:mem_file) do |typ,size,clk,rst,br_rsts = {}|
|
|
675
860
|
# using +target+ as target of access result.
|
676
861
|
reader do |blk,target|
|
677
862
|
regs = size.times.map {|i| send(:"reg_#{i}") }
|
678
|
-
#
|
863
|
+
# On reset the read trigger is 0.
|
679
864
|
rst = send(rst_name)
|
680
865
|
top_block.unshift do
|
681
866
|
# Initialize the address so that the next access is at address 0.
|
@@ -714,7 +899,7 @@ HDLRuby::High::Std.channel(:mem_file) do |typ,size,clk,rst,br_rsts = {}|
|
|
714
899
|
# using +target+ as target of access result.
|
715
900
|
writer do |blk,target|
|
716
901
|
regs = size.times.map {|i| send(:"reg_#{i}") }
|
717
|
-
#
|
902
|
+
# On reset the read trigger is 0.
|
718
903
|
rst = send(rst_name)
|
719
904
|
top_block.unshift do
|
720
905
|
# Initialize the address so that the next access is at address 0.
|
@@ -755,7 +940,7 @@ HDLRuby::High::Std.channel(:mem_file) do |typ,size,clk,rst,br_rsts = {}|
|
|
755
940
|
# using +target+ as target of access result.
|
756
941
|
reader do |blk,target|
|
757
942
|
regs = size.times.map {|i| send(:"reg_#{i}") }
|
758
|
-
#
|
943
|
+
# On reset the read trigger is 0.
|
759
944
|
rst = send(rst_name)
|
760
945
|
top_block.unshift do
|
761
946
|
# Initialize the address so that the next access is at address 0.
|
@@ -794,7 +979,7 @@ HDLRuby::High::Std.channel(:mem_file) do |typ,size,clk,rst,br_rsts = {}|
|
|
794
979
|
# using +target+ as target of access result.
|
795
980
|
writer do |blk,target|
|
796
981
|
regs = size.times.map {|i| send(:"reg_#{i}") }
|
797
|
-
#
|
982
|
+
# On reset the read trigger is 0.
|
798
983
|
rst = send(rst_name)
|
799
984
|
top_block.unshift do
|
800
985
|
# Initialize the address so that the next access is at address 0.
|
@@ -817,3 +1002,788 @@ HDLRuby::High::Std.channel(:mem_file) do |typ,size,clk,rst,br_rsts = {}|
|
|
817
1002
|
end
|
818
1003
|
|
819
1004
|
end
|
1005
|
+
|
1006
|
+
|
1007
|
+
|
1008
|
+
|
1009
|
+
# Multi-bank memory combining several dual-edge memories of +nbanks+ banks
|
1010
|
+
# of +size+ elements of +typ+ typ, syncrhonized on +clk+ (positive and
|
1011
|
+
# negative edges) and reset on +rst+.
|
1012
|
+
# at each rising edge of +clk+ a read and a write is guaranteed to be
|
1013
|
+
# completed provided they are triggered.
|
1014
|
+
# +br_rsts+ are reset names on the branches, if not given, a reset input
|
1015
|
+
# is added and connected to rst.
|
1016
|
+
#
|
1017
|
+
# NOTE:
|
1018
|
+
#
|
1019
|
+
# * such memories uses the following ports:
|
1020
|
+
# - trig_r: read access trigger (output)
|
1021
|
+
# - trig_w: write access trigger (output)
|
1022
|
+
# - dbus_r: read data bus (input)
|
1023
|
+
# - dbus_w: write data bus (output)
|
1024
|
+
#
|
1025
|
+
# * The following branches are possible (only one read and one write can
|
1026
|
+
# be used per channel)
|
1027
|
+
# - raddr: read by address, this channel adds the following port:
|
1028
|
+
# abus_r: read address bus (output)
|
1029
|
+
# - waddr: read by address, this channel adds the following port:
|
1030
|
+
# abus_w: write address bus (output)
|
1031
|
+
# - rinc: read by automatically incremented address.
|
1032
|
+
# - winc: write by automatically incremented address.
|
1033
|
+
# - rdec: read by automatically decremented address.
|
1034
|
+
# - wdec: write by automatically decremented address.
|
1035
|
+
# - rque: read in queue mode: automatically incremented address ensuring
|
1036
|
+
# the read address is always different from the write address.
|
1037
|
+
# - wque: write in queue mode: automatically incremented address ensuring
|
1038
|
+
# the write address is always differnet from the read address.
|
1039
|
+
HDLRuby::High::Std.channel(:mem_bank) do |typ,nbanks,size,clk,rst,br_rsts = {}|
|
1040
|
+
# Ensure typ is a type.
|
1041
|
+
typ = typ.to_type
|
1042
|
+
# Ensure size in an integer.
|
1043
|
+
size = size.to_i
|
1044
|
+
# Compute the address bus width from the size.
|
1045
|
+
awidth = (size*nbanks-1).width
|
1046
|
+
awidth_b = (size-1).width # Bank width
|
1047
|
+
# Ensures br_srts is a hash.
|
1048
|
+
br_rsts = br_rsts.to_hash
|
1049
|
+
|
1050
|
+
# The global buses and control signals.
|
1051
|
+
[awidth].inner :abus_r, :abus_w
|
1052
|
+
typ.inner :dbus_r, :dbus_w
|
1053
|
+
inner :trig_r, :trig_w
|
1054
|
+
|
1055
|
+
# For each bank.
|
1056
|
+
nbanks.times do |id|
|
1057
|
+
# Declare the control signals.
|
1058
|
+
# Access triggers.
|
1059
|
+
inner :"trig_r_#{id}", :"trig_w_#{id}"
|
1060
|
+
# Data buses
|
1061
|
+
typ.inner :"dbus_r_#{id}", :"dbus_w_#{id}"
|
1062
|
+
# Address buses (or simply registers)
|
1063
|
+
[awidth_b].inner :"abus_r_#{id}", :"abus_w_#{id}"
|
1064
|
+
|
1065
|
+
# Declare the memory content.
|
1066
|
+
typ[-size].inner :"mem_#{id}"
|
1067
|
+
|
1068
|
+
# Processes handling the memory access.
|
1069
|
+
par(clk.negedge) do
|
1070
|
+
send(:"dbus_r_#{id}") <= send(:"mem_#{id}")[send(:"abus_r_#{id}")]
|
1071
|
+
hif(trig_w & ((abus_w % nbanks) == id)) do
|
1072
|
+
send(:"mem_#{id}")[send(:"abus_w_#{id}")] <= dbus_w
|
1073
|
+
end
|
1074
|
+
helsif(send(:"trig_w_#{id}")) do
|
1075
|
+
send(:"mem_#{id}")[send(:"abus_w_#{id}")] <= send(:"dbus_w_#{id}")
|
1076
|
+
end
|
1077
|
+
end
|
1078
|
+
end
|
1079
|
+
# Interconnect the buses and triggers
|
1080
|
+
nbanks.times do |id|
|
1081
|
+
send(:"abus_r_#{id}") <= abus_r / nbanks
|
1082
|
+
send(:"abus_w_#{id}") <= abus_w / nbanks
|
1083
|
+
end
|
1084
|
+
par do
|
1085
|
+
# By default triggers are off.
|
1086
|
+
nbanks.times do |id|
|
1087
|
+
send(:"trig_w_#{id}") <= 0
|
1088
|
+
send(:"trig_r_#{id}") <= 0
|
1089
|
+
end
|
1090
|
+
# Set the read address bus and trigger if required.
|
1091
|
+
hcase(abus_r % nbanks)
|
1092
|
+
nbanks.times do |id|
|
1093
|
+
hwhen(id) do
|
1094
|
+
dbus_r <= send(:"dbus_r_#{id}")
|
1095
|
+
send(:"trig_r_#{id}") <= trig_r
|
1096
|
+
end
|
1097
|
+
end
|
1098
|
+
end
|
1099
|
+
|
1100
|
+
|
1101
|
+
# The address branches.
|
1102
|
+
# Read with address
|
1103
|
+
brancher(:raddr) do
|
1104
|
+
reader_output :trig_r, :abus_r
|
1105
|
+
reader_input :dbus_r
|
1106
|
+
if br_rsts[:raddr] then
|
1107
|
+
rst_name = br_rsts[:raddr].to_sym
|
1108
|
+
else
|
1109
|
+
rst_name = rst.name
|
1110
|
+
reader_input rst_name
|
1111
|
+
end
|
1112
|
+
|
1113
|
+
# Defines the read procedure at address +addr+
|
1114
|
+
# using +target+ as target of access result.
|
1115
|
+
reader do |blk,addr,target|
|
1116
|
+
# By default the read trigger is 0.
|
1117
|
+
top_block.unshift { trig_r <= 0 }
|
1118
|
+
# The read procedure.
|
1119
|
+
rst = send(rst_name)
|
1120
|
+
par do
|
1121
|
+
hif(rst == 0) do
|
1122
|
+
# No reset, so can perform the read.
|
1123
|
+
hif(trig_r == 1) do
|
1124
|
+
# The trigger was previously set, read ok.
|
1125
|
+
target <= dbus_r
|
1126
|
+
trig_r <= 0
|
1127
|
+
blk.call if blk
|
1128
|
+
end
|
1129
|
+
helse do
|
1130
|
+
# Prepare the read.
|
1131
|
+
abus_r <= addr
|
1132
|
+
trig_r <= 1
|
1133
|
+
end
|
1134
|
+
end
|
1135
|
+
end
|
1136
|
+
end
|
1137
|
+
end
|
1138
|
+
|
1139
|
+
# Write with address
|
1140
|
+
brancher(:waddr) do
|
1141
|
+
writer_output :trig_w, :abus_w, :dbus_w
|
1142
|
+
if br_rsts[:waddr] then
|
1143
|
+
rst_name = br_rsts[:waddr].to_sym
|
1144
|
+
else
|
1145
|
+
rst_name = rst.name
|
1146
|
+
writer_input rst_name
|
1147
|
+
end
|
1148
|
+
# puts "br_rsts=#{br_rsts}"
|
1149
|
+
# puts "rst_name=#{rst_name}"
|
1150
|
+
|
1151
|
+
# Defines the read procedure at address +addr+
|
1152
|
+
# using +target+ as target of access result.
|
1153
|
+
writer do |blk,addr,target|
|
1154
|
+
# By default the read trigger is 0.
|
1155
|
+
top_block.unshift { trig_w <= 0 }
|
1156
|
+
# The write procedure.
|
1157
|
+
rst = send(rst_name)
|
1158
|
+
par do
|
1159
|
+
hif(rst == 0) do
|
1160
|
+
# No reset, so can perform the write.
|
1161
|
+
hif(trig_w == 1) do
|
1162
|
+
# The trigger was previously set, write ok.
|
1163
|
+
blk.call if blk
|
1164
|
+
end
|
1165
|
+
# Prepare the write.
|
1166
|
+
abus_w <= addr
|
1167
|
+
trig_w <= 1
|
1168
|
+
dbus_w <= target
|
1169
|
+
end
|
1170
|
+
end
|
1171
|
+
end
|
1172
|
+
end
|
1173
|
+
|
1174
|
+
# The increment branches.
|
1175
|
+
# Read with increment
|
1176
|
+
brancher(:rinc) do
|
1177
|
+
reader_output :trig_r, :abus_r
|
1178
|
+
reader_input :dbus_r
|
1179
|
+
if br_rsts[:rinc] then
|
1180
|
+
rst_name = br_rsts[:rinc].to_sym
|
1181
|
+
else
|
1182
|
+
rst_name = rst.name
|
1183
|
+
reader_input rst_name
|
1184
|
+
end
|
1185
|
+
|
1186
|
+
# Defines the read procedure at address +addr+
|
1187
|
+
# using +target+ as target of access result.
|
1188
|
+
reader do |blk,target|
|
1189
|
+
# On reset the read trigger is 0.
|
1190
|
+
rst = send(rst_name)
|
1191
|
+
top_block.unshift do
|
1192
|
+
# Initialize the address so that the next access is at address 0.
|
1193
|
+
hif(rst==1) { abus_r <= -1 }
|
1194
|
+
# Reset so switch of the access trigger.
|
1195
|
+
trig_r <= 0
|
1196
|
+
end
|
1197
|
+
# The read procedure.
|
1198
|
+
par do
|
1199
|
+
hif(rst == 0) do
|
1200
|
+
# No reset, so can perform the read.
|
1201
|
+
hif(trig_r == 1) do
|
1202
|
+
# The trigger was previously set, read ok.
|
1203
|
+
target <= dbus_r
|
1204
|
+
blk.call if blk
|
1205
|
+
end
|
1206
|
+
# Prepare the read.
|
1207
|
+
abus_r <= abus_r + 1
|
1208
|
+
trig_r <= 1
|
1209
|
+
end
|
1210
|
+
end
|
1211
|
+
end
|
1212
|
+
end
|
1213
|
+
|
1214
|
+
# Write with address
|
1215
|
+
brancher(:winc) do
|
1216
|
+
writer_output :trig_w, :abus_w, :dbus_w
|
1217
|
+
if br_rsts[:winc] then
|
1218
|
+
rst_name = br_rsts[:winc].to_sym
|
1219
|
+
else
|
1220
|
+
rst_name = rst.name
|
1221
|
+
writer_input rst_name
|
1222
|
+
end
|
1223
|
+
# puts "br_rsts=#{br_rsts}"
|
1224
|
+
# puts "rst_name=#{rst_name}"
|
1225
|
+
|
1226
|
+
# Defines the read procedure at address +addr+
|
1227
|
+
# using +target+ as target of access result.
|
1228
|
+
writer do |blk,target|
|
1229
|
+
# On reset the read trigger is 0.
|
1230
|
+
rst = send(rst_name)
|
1231
|
+
top_block.unshift do
|
1232
|
+
# Initialize the address so that the next access is at address 0.
|
1233
|
+
hif(rst == 1) { abus_w <= -1 }
|
1234
|
+
# Reset so switch of the access trigger.
|
1235
|
+
trig_w <= 0
|
1236
|
+
end
|
1237
|
+
# The write procedure.
|
1238
|
+
par do
|
1239
|
+
hif(rst == 0) do
|
1240
|
+
# No reset, so can perform the write.
|
1241
|
+
blk.call if blk
|
1242
|
+
# Prepare the write.
|
1243
|
+
abus_w <= abus_w + 1
|
1244
|
+
trig_w <= 1
|
1245
|
+
dbus_w <= target
|
1246
|
+
end
|
1247
|
+
end
|
1248
|
+
end
|
1249
|
+
end
|
1250
|
+
|
1251
|
+
# The decrement branches.
|
1252
|
+
# Read with increment
|
1253
|
+
brancher(:rdec) do
|
1254
|
+
reader_output :trig_r, :abus_r
|
1255
|
+
reader_input :dbus_r
|
1256
|
+
if br_rsts[:rdec] then
|
1257
|
+
rst_name = br_rsts[:rdec].to_sym
|
1258
|
+
else
|
1259
|
+
rst_name = rst.name
|
1260
|
+
reader_input rst_name
|
1261
|
+
end
|
1262
|
+
|
1263
|
+
# Defines the read procedure at address +addr+
|
1264
|
+
# using +target+ as target of access result.
|
1265
|
+
reader do |blk,target|
|
1266
|
+
# On reset the read trigger is 0.
|
1267
|
+
rst = send(rst_name)
|
1268
|
+
top_block.unshift do
|
1269
|
+
# Initialize the address so that the next access is at address 0.
|
1270
|
+
hif(rst==1) { abus_r <= 0 }
|
1271
|
+
# Reset so switch of the access trigger.
|
1272
|
+
trig_r <= 0
|
1273
|
+
end
|
1274
|
+
# The read procedure.
|
1275
|
+
par do
|
1276
|
+
hif(rst == 0) do
|
1277
|
+
# No reset, so can perform the read.
|
1278
|
+
hif(trig_r == 1) do
|
1279
|
+
# The trigger was previously set, read ok.
|
1280
|
+
target <= dbus_r
|
1281
|
+
blk.call if blk
|
1282
|
+
end
|
1283
|
+
# Prepare the read.
|
1284
|
+
abus_r <= abus_r - 1
|
1285
|
+
trig_r <= 1
|
1286
|
+
end
|
1287
|
+
end
|
1288
|
+
end
|
1289
|
+
end
|
1290
|
+
|
1291
|
+
# Write with address
|
1292
|
+
brancher(:wdec) do
|
1293
|
+
writer_output :trig_w, :abus_w, :dbus_w
|
1294
|
+
if br_rsts[:wdec] then
|
1295
|
+
rst_name = br_rsts[:wdec].to_sym
|
1296
|
+
else
|
1297
|
+
rst_name = rst.name
|
1298
|
+
writer_input rst_name
|
1299
|
+
end
|
1300
|
+
# puts "br_rsts=#{br_rsts}"
|
1301
|
+
# puts "rst_name=#{rst_name}"
|
1302
|
+
|
1303
|
+
# Defines the read procedure at address +addr+
|
1304
|
+
# using +target+ as target of access result.
|
1305
|
+
writer do |blk,target|
|
1306
|
+
# On reset the read trigger is 0.
|
1307
|
+
rst = send(rst_name)
|
1308
|
+
top_block.unshift do
|
1309
|
+
# Initialize the address so that the next access is at address 0.
|
1310
|
+
hif(rst == 1) { abus_w <= 0 }
|
1311
|
+
# Reset so switch of the access trigger.
|
1312
|
+
trig_w <= 0
|
1313
|
+
end
|
1314
|
+
# The write procedure.
|
1315
|
+
par do
|
1316
|
+
hif(rst == 0) do
|
1317
|
+
# No reset, so can perform the write.
|
1318
|
+
blk.call if blk
|
1319
|
+
# Prepare the write.
|
1320
|
+
abus_w <= abus_w - 1
|
1321
|
+
trig_w <= 1
|
1322
|
+
dbus_w <= target
|
1323
|
+
end
|
1324
|
+
end
|
1325
|
+
end
|
1326
|
+
end
|
1327
|
+
|
1328
|
+
|
1329
|
+
# Declare the branchers for accessing directly the banks.
|
1330
|
+
nbanks.times do |id|
|
1331
|
+
# Read with address.
|
1332
|
+
brancher(:"raddr_#{id}") do
|
1333
|
+
reader_output :"trig_r_#{id}", :"abus_r_#{id}"
|
1334
|
+
reader_input :"dbus_r_#{id}"
|
1335
|
+
if br_rsts[:"raddr_#{id}"] then
|
1336
|
+
rst_name = br_rsts[:"raddr_#{id}"].to_sym
|
1337
|
+
else
|
1338
|
+
rst_name = rst.name
|
1339
|
+
reader_input rst_name
|
1340
|
+
end
|
1341
|
+
|
1342
|
+
# Defines the read procedure at address +addr+
|
1343
|
+
# using +target+ as target of access result.
|
1344
|
+
reader do |blk,addr,target|
|
1345
|
+
# By default the read trigger is 0.
|
1346
|
+
top_block.unshift { send(:"trig_r_#{id}") <= 0 }
|
1347
|
+
# The read procedure.
|
1348
|
+
rst = send(rst_name)
|
1349
|
+
par do
|
1350
|
+
hif(rst == 0) do
|
1351
|
+
# No reset, so can perform the read.
|
1352
|
+
hif(send(:"trig_r_#{id}") == 1) do
|
1353
|
+
# The trigger was previously set, read ok.
|
1354
|
+
target <= send(:"dbus_r_#{id}")
|
1355
|
+
send(:"trig_r_#{id}") <= 0
|
1356
|
+
blk.call if blk
|
1357
|
+
end
|
1358
|
+
helse do
|
1359
|
+
# Prepare the read.
|
1360
|
+
send(:"abus_r_#{id}") <= addr
|
1361
|
+
send(:"trig_r_#{id}") <= 1
|
1362
|
+
end
|
1363
|
+
end
|
1364
|
+
end
|
1365
|
+
end
|
1366
|
+
end
|
1367
|
+
|
1368
|
+
# Write with address
|
1369
|
+
brancher(:"waddr_#{id}") do
|
1370
|
+
writer_output :"trig_w_#{id}", :"abus_w_#{id}", :"dbus_w_#{id}"
|
1371
|
+
if br_rsts[:"waddr_#{id}"] then
|
1372
|
+
rst_name = br_rsts[:"waddr_#{id}"].to_sym
|
1373
|
+
else
|
1374
|
+
rst_name = rst.name
|
1375
|
+
writer_input rst_name
|
1376
|
+
end
|
1377
|
+
|
1378
|
+
# Defines the read procedure at address +addr+
|
1379
|
+
# using +target+ as target of access result.
|
1380
|
+
writer do |blk,addr,target|
|
1381
|
+
# By default the read trigger is 0.
|
1382
|
+
top_block.unshift { send(:"trig_w_#{id}") <= 0 }
|
1383
|
+
# The write procedure.
|
1384
|
+
rst = send(rst_name)
|
1385
|
+
par do
|
1386
|
+
hif(rst == 0) do
|
1387
|
+
# No reset, so can perform the write.
|
1388
|
+
hif(send(:"trig_w_#{id}") == 1) do
|
1389
|
+
# The trigger was previously set, write ok.
|
1390
|
+
blk.call if blk
|
1391
|
+
end
|
1392
|
+
# Prepare the write.
|
1393
|
+
send(:"abus_w_#{id}") <= addr
|
1394
|
+
send(:"trig_w_#{id}") <= 1
|
1395
|
+
send(:"dbus_w_#{id}") <= target
|
1396
|
+
end
|
1397
|
+
end
|
1398
|
+
end
|
1399
|
+
end
|
1400
|
+
|
1401
|
+
# The increment branches.
|
1402
|
+
# Read with increment
|
1403
|
+
brancher(:"rinc_#{id}") do
|
1404
|
+
reader_output :"trig_r_#{id}", :"abus_r_#{id}"
|
1405
|
+
reader_input :"dbus_r_#{id}"
|
1406
|
+
if br_rsts[:"rinc_#{id}"] then
|
1407
|
+
rst_name = br_rsts[:"rinc_#{id}"].to_sym
|
1408
|
+
else
|
1409
|
+
rst_name = rst.name
|
1410
|
+
reader_input rst_name
|
1411
|
+
end
|
1412
|
+
|
1413
|
+
# Defines the read procedure at address +addr+
|
1414
|
+
# using +target+ as target of access result.
|
1415
|
+
reader do |blk,target|
|
1416
|
+
# On reset the read trigger is 0.
|
1417
|
+
rst = send(rst_name)
|
1418
|
+
top_block.unshift do
|
1419
|
+
# Initialize the address so that the next access is at address 0.
|
1420
|
+
hif(rst==1) { send(:"abus_r_#{id}") <= -1 }
|
1421
|
+
# Reset so switch of the access trigger.
|
1422
|
+
send(:"trig_r_#{id}") <= 0
|
1423
|
+
end
|
1424
|
+
# The read procedure.
|
1425
|
+
par do
|
1426
|
+
hif(rst == 0) do
|
1427
|
+
# No reset, so can perform the read.
|
1428
|
+
hif(send(:"trig_r_#{id}") == 1) do
|
1429
|
+
# The trigger was previously set, read ok.
|
1430
|
+
target <= send(:"dbus_r_#{id}")
|
1431
|
+
blk.call if blk
|
1432
|
+
end
|
1433
|
+
# Prepare the read.
|
1434
|
+
send(:"abus_r_#{id}") <= send(:"abus_r_#{id}") + 1
|
1435
|
+
send(:"trig_r_#{id}") <= 1
|
1436
|
+
end
|
1437
|
+
end
|
1438
|
+
end
|
1439
|
+
end
|
1440
|
+
|
1441
|
+
# Write with address
|
1442
|
+
brancher(:"winc_#{id}") do
|
1443
|
+
writer_output :"trig_w_#{id}", :"abus_w_#{id}", :"dbus_w_#{id}"
|
1444
|
+
if br_rsts[:"winc_#{id}"] then
|
1445
|
+
rst_name = br_rsts[:"winc_#{id}"].to_sym
|
1446
|
+
else
|
1447
|
+
rst_name = rst.name
|
1448
|
+
writer_input rst_name
|
1449
|
+
end
|
1450
|
+
|
1451
|
+
# Defines the read procedure at address +addr+
|
1452
|
+
# using +target+ as target of access result.
|
1453
|
+
writer do |blk,target|
|
1454
|
+
# On reset the read trigger is 0.
|
1455
|
+
rst = send(rst_name)
|
1456
|
+
top_block.unshift do
|
1457
|
+
# Initialize the address so that the next access is at address 0.
|
1458
|
+
hif(rst == 1) { send(:"abus_w_#{id}") <= -1 }
|
1459
|
+
# Reset so switch of the access trigger.
|
1460
|
+
send(:"trig_w_#{id}") <= 0
|
1461
|
+
end
|
1462
|
+
# The write procedure.
|
1463
|
+
par do
|
1464
|
+
hif(rst == 0) do
|
1465
|
+
# No reset, so can perform the write.
|
1466
|
+
blk.call if blk
|
1467
|
+
# Prepare the write.
|
1468
|
+
send(:"abus_w_#{id}") <= send(:"abus_w_#{id}") + 1
|
1469
|
+
send(:"trig_w_#{id}") <= 1
|
1470
|
+
send(:"dbus_w_#{id}") <= target
|
1471
|
+
end
|
1472
|
+
end
|
1473
|
+
end
|
1474
|
+
end
|
1475
|
+
|
1476
|
+
# The decrement branches.
|
1477
|
+
# Read with increment
|
1478
|
+
brancher(:"rdec_#{id}") do
|
1479
|
+
reader_output :"trig_r_#{id}", :"abus_r_#{id}"
|
1480
|
+
reader_input :"dbus_r_#{id}"
|
1481
|
+
if br_rsts[:"rdec_#{id}"] then
|
1482
|
+
rst_name = br_rsts[:"rdec_#{id}"].to_sym
|
1483
|
+
else
|
1484
|
+
rst_name = rst.name
|
1485
|
+
reader_input rst_name
|
1486
|
+
end
|
1487
|
+
|
1488
|
+
# Defines the read procedure at address +addr+
|
1489
|
+
# using +target+ as target of access result.
|
1490
|
+
reader do |blk,target|
|
1491
|
+
# On reset the read trigger is 0.
|
1492
|
+
rst = send(rst_name)
|
1493
|
+
top_block.unshift do
|
1494
|
+
# Initialize the address so that the next access is at address 0.
|
1495
|
+
hif(rst==1) { send(:"abus_r_#{id}") <= 0 }
|
1496
|
+
# Reset so switch of the access trigger.
|
1497
|
+
send(:"trig_r_#{id}") <= 0
|
1498
|
+
end
|
1499
|
+
# The read procedure.
|
1500
|
+
par do
|
1501
|
+
hif(rst == 0) do
|
1502
|
+
# No reset, so can perform the read.
|
1503
|
+
hif(send(:"trig_r_#{id}") == 1) do
|
1504
|
+
# The trigger was previously set, read ok.
|
1505
|
+
target <= send(:"dbus_r_#{id}")
|
1506
|
+
blk.call if blk
|
1507
|
+
end
|
1508
|
+
# Prepare the read.
|
1509
|
+
send(:"abus_r_#{id}") <= send(:"abus_r_#{id}") - 1
|
1510
|
+
send(:"trig_r_#{id}") <= 1
|
1511
|
+
end
|
1512
|
+
end
|
1513
|
+
end
|
1514
|
+
end
|
1515
|
+
|
1516
|
+
# Write with address
|
1517
|
+
brancher(:"wdec_#{id}") do
|
1518
|
+
writer_output :"trig_w_#{id}", :"abus_w_#{id}", :"dbus_w_#{id}"
|
1519
|
+
if br_rsts[:"wdec_#{id}"] then
|
1520
|
+
rst_name = br_rsts[:"wdec_#{id}"].to_sym
|
1521
|
+
else
|
1522
|
+
rst_name = rst.name
|
1523
|
+
writer_input rst_name
|
1524
|
+
end
|
1525
|
+
|
1526
|
+
# Defines the read procedure at address +addr+
|
1527
|
+
# using +target+ as target of access result.
|
1528
|
+
writer do |blk,target|
|
1529
|
+
# On reset the read trigger is 0.
|
1530
|
+
rst = send(rst_name)
|
1531
|
+
top_block.unshift do
|
1532
|
+
# Initialize the address so that the next access is at address 0.
|
1533
|
+
hif(rst == 1) { send(:"abus_w_#{id}") <= 0 }
|
1534
|
+
# Reset so switch of the access trigger.
|
1535
|
+
trig_w <= 0
|
1536
|
+
end
|
1537
|
+
# The write procedure.
|
1538
|
+
par do
|
1539
|
+
hif(rst == 0) do
|
1540
|
+
# No reset, so can perform the write.
|
1541
|
+
blk.call if blk
|
1542
|
+
# Prepare the write.
|
1543
|
+
send(:"abus_w_#{id}") <= send(:"abus_w_#{id}") - 1
|
1544
|
+
send(:"trig_w_#{id}") <= 1
|
1545
|
+
send(:"dbus_w_#{id}") <= target
|
1546
|
+
end
|
1547
|
+
end
|
1548
|
+
end
|
1549
|
+
end
|
1550
|
+
end
|
1551
|
+
|
1552
|
+
end
|
1553
|
+
|
1554
|
+
# HDLRuby::High::Std.channel(:mem_bank) do |typ,nbanks,size,clk,rst,br_rsts = {}|
|
1555
|
+
# # Ensure typ is a type.
|
1556
|
+
# typ = typ.to_type
|
1557
|
+
# # Ensure nbank is an integer.
|
1558
|
+
# nbanks = nbanks.to_i
|
1559
|
+
# # Ensure size in an integer.
|
1560
|
+
# size = size.to_i
|
1561
|
+
# # Compute the address bus width from the size.
|
1562
|
+
# awidth = (size-1).width
|
1563
|
+
# # # Process the table of reset mapping for the branches.
|
1564
|
+
# # # puts "first br_rsts=#{br_rsts}"
|
1565
|
+
# # if br_rsts.is_a?(Array) then
|
1566
|
+
# # # It is a list, convert it to a hash with the following order:
|
1567
|
+
# # # raddr, waddr, rinc, winc, rdec, wdec, rque, wque
|
1568
|
+
# # # If there is only two entries they will be duplicated and mapped
|
1569
|
+
# # # as follows:
|
1570
|
+
# # # [raddr,waddr], [rinc,winc], [rdec,wdec], [rque,wque]
|
1571
|
+
# # # If there is only one entry it will be duplicated and mapped as
|
1572
|
+
# # # follows:
|
1573
|
+
# # # raddr, rinc, rdec, rque
|
1574
|
+
# # if br_rsts.size == 2 then
|
1575
|
+
# # br_rsts = br_rsts * 4
|
1576
|
+
# # elsif br_rsts.size == 1 then
|
1577
|
+
# # br_rsts = br_rsts * 8
|
1578
|
+
# # end
|
1579
|
+
# # br_rsts = { raddr: br_rsts[0], waddr: br_rsts[1],
|
1580
|
+
# # rinc: br_rsts[2], winc: br_rsts[3],
|
1581
|
+
# # rdec: br_rsts[4], wdec: br_rsts[5],
|
1582
|
+
# # rque: br_rsts[6], wque: br_rsts[6] }
|
1583
|
+
# # end
|
1584
|
+
# # unless br_rsts.respond_to?(:[])
|
1585
|
+
# # raise "Invalid reset mapping description: #{br_rsts}"
|
1586
|
+
# # end
|
1587
|
+
# # Ensures br_rsts is a hash.
|
1588
|
+
# br_rsts = br_rsts.to_hash
|
1589
|
+
#
|
1590
|
+
# # Declares the banks.
|
1591
|
+
# banks = nbanks.times.map do |id|
|
1592
|
+
# # Extract the resets corresponding to the bank.
|
1593
|
+
# cur_br_rsts = {}
|
1594
|
+
# br_rsts.each do |k,v|
|
1595
|
+
# num = k.to_s[/\d+$/]
|
1596
|
+
# if num && num.to_i == id then
|
1597
|
+
# cur_br_rsts[k.to_s.chomp[num]] = v
|
1598
|
+
# end
|
1599
|
+
# end
|
1600
|
+
# # Declare the bank.
|
1601
|
+
# mem_dual(typ,size,clk,rst, cur_br_rsts).(HDLRuby.uniq_name)
|
1602
|
+
# end
|
1603
|
+
#
|
1604
|
+
# # Declare the branchers for accessing directly the banks.
|
1605
|
+
# banks.each_with_index do |bank,id|
|
1606
|
+
# brancher(id,bank)
|
1607
|
+
# end
|
1608
|
+
#
|
1609
|
+
# # Generate the gobal access to the memory.
|
1610
|
+
#
|
1611
|
+
# # The address branches.
|
1612
|
+
# # Read with address
|
1613
|
+
# brancher(:raddr) do
|
1614
|
+
# # Create the read branch for each bank.
|
1615
|
+
# bank_brs = banks.map do |bank|
|
1616
|
+
# bank.branch(:raddr).inner HDLRuby.uniq_name
|
1617
|
+
# end
|
1618
|
+
# # Defines the read procedure at address +addr+
|
1619
|
+
# # using +target+ as target of access result.
|
1620
|
+
# reader do |blk,addr,target|
|
1621
|
+
# # Select the bank depending on the address.
|
1622
|
+
# hcase(addr / nbanks)
|
1623
|
+
# nbanks.times do |i|
|
1624
|
+
# hwhen(i) do
|
1625
|
+
# bank_brs[i].read(addr % nbanks,target,&blk)
|
1626
|
+
# end
|
1627
|
+
# end
|
1628
|
+
# end
|
1629
|
+
# end
|
1630
|
+
# # Write with address
|
1631
|
+
# brancher(:waddr) do
|
1632
|
+
# # Create the write branch for each bank.
|
1633
|
+
# bank_brs = banks.map do |bank|
|
1634
|
+
# bank.branch(:waddr).inner HDLRuby.uniq_name
|
1635
|
+
# end
|
1636
|
+
# # Defines the read procedure at address +addr+
|
1637
|
+
# # using +target+ as target of access result.
|
1638
|
+
# writer do |blk,addr,target|
|
1639
|
+
# # Select the bank depending on the address.
|
1640
|
+
# hcase(addr / nbanks)
|
1641
|
+
# nbanks.times do |i|
|
1642
|
+
# hwhen(i) do
|
1643
|
+
# bank_brs[i].write(addr % nbanks,target,&blk)
|
1644
|
+
# end
|
1645
|
+
# end
|
1646
|
+
# end
|
1647
|
+
# end
|
1648
|
+
#
|
1649
|
+
#
|
1650
|
+
# # Address buses (or simply registers) for increment/decrement accesses
|
1651
|
+
# [awidth].inner :abus_r, :abus_w
|
1652
|
+
#
|
1653
|
+
# # The increment branches.
|
1654
|
+
# # Read with increment
|
1655
|
+
# brancher(:rinc) do
|
1656
|
+
# reader_output :abus_r
|
1657
|
+
# if br_rsts[:rinc] then
|
1658
|
+
# rst_name = br_rsts[:rinc].to_sym
|
1659
|
+
# else
|
1660
|
+
# rst_name = rst.name
|
1661
|
+
# reader_input rst_name
|
1662
|
+
# end
|
1663
|
+
# # Create the write branch for each bank.
|
1664
|
+
# bank_brs = banks.map do |bank|
|
1665
|
+
# bank.branch(:raddr).inner HDLRuby.uniq_name
|
1666
|
+
# end
|
1667
|
+
#
|
1668
|
+
# # Defines the read procedure at address +addr+
|
1669
|
+
# # using +target+ as target of access result.
|
1670
|
+
# reader do |blk,target|
|
1671
|
+
# # On reset the read trigger is 0.
|
1672
|
+
# rst = send(rst_name)
|
1673
|
+
# top_block.unshift do
|
1674
|
+
# # Initialize the address so that the next access is at address 0.
|
1675
|
+
# hif(rst==1) { abus_r <= 0 }
|
1676
|
+
# end
|
1677
|
+
# # Select the bank depending on the address.
|
1678
|
+
# hcase(abus_r / nbanks)
|
1679
|
+
# nbanks.times do |i|
|
1680
|
+
# hwhen(i) do
|
1681
|
+
# bank_brs[i].read(abus_r % nbanks,target) do
|
1682
|
+
# abus_r <= abus_r + 1
|
1683
|
+
# blk.call
|
1684
|
+
# end
|
1685
|
+
# end
|
1686
|
+
# end
|
1687
|
+
# end
|
1688
|
+
# end
|
1689
|
+
# # Write with increment
|
1690
|
+
# brancher(:winc) do
|
1691
|
+
# reader_output :abus_w
|
1692
|
+
# if br_rsts[:winc] then
|
1693
|
+
# rst_name = br_rsts[:winc].to_sym
|
1694
|
+
# else
|
1695
|
+
# rst_name = rst.name
|
1696
|
+
# writer_input rst_name
|
1697
|
+
# end
|
1698
|
+
# # Create the write branch for each bank.
|
1699
|
+
# bank_brs = banks.map do |bank|
|
1700
|
+
# bank.branch(:waddr).inner HDLRuby.uniq_name
|
1701
|
+
# end
|
1702
|
+
#
|
1703
|
+
# # Defines the read procedure at address +addr+
|
1704
|
+
# # using +target+ as target of access result.
|
1705
|
+
# writer do |blk,target|
|
1706
|
+
# # On reset the read trigger is 0.
|
1707
|
+
# rst = send(rst_name)
|
1708
|
+
# top_block.unshift do
|
1709
|
+
# # Initialize the address so that the next access is at address 0.
|
1710
|
+
# hif(rst==1) { abus_w <= 0 }
|
1711
|
+
# end
|
1712
|
+
# # Select the bank depending on the address.
|
1713
|
+
# hcase(abus_w / nbanks)
|
1714
|
+
# nbanks.times do |i|
|
1715
|
+
# hwhen(i) do
|
1716
|
+
# bank_brs[i].read(abus_w % nbanks,target) do
|
1717
|
+
# abus_w <= abus_w + 1
|
1718
|
+
# blk.call
|
1719
|
+
# end
|
1720
|
+
# end
|
1721
|
+
# end
|
1722
|
+
# end
|
1723
|
+
# end
|
1724
|
+
#
|
1725
|
+
# # The decrement branches.
|
1726
|
+
# # Read with decrement
|
1727
|
+
# brancher(:rdec) do
|
1728
|
+
# reader_output :abus_r
|
1729
|
+
# if br_rsts[:rdec] then
|
1730
|
+
# rst_name = br_rsts[:rdec].to_sym
|
1731
|
+
# else
|
1732
|
+
# rst_name = rst.name
|
1733
|
+
# reader_input rst_name
|
1734
|
+
# end
|
1735
|
+
#
|
1736
|
+
# # Defines the read procedure at address +addr+
|
1737
|
+
# # using +target+ as target of access result.
|
1738
|
+
# reader do |blk,target|
|
1739
|
+
# # On reset the read trigger is 0.
|
1740
|
+
# rst = send(rst_name)
|
1741
|
+
# top_block.unshift do
|
1742
|
+
# # Initialize the address so that the next access is at address 0.
|
1743
|
+
# hif(rst==1) { abus_r <= 0 }
|
1744
|
+
# end
|
1745
|
+
# # Select the bank depending on the address.
|
1746
|
+
# hcase(abus_r / nbanks)
|
1747
|
+
# nbanks.times do |i|
|
1748
|
+
# hwhen(i) do
|
1749
|
+
# banks[i].read(abus_r % nbanks,target) do
|
1750
|
+
# abus_r <= abus_r + 1
|
1751
|
+
# blk.call
|
1752
|
+
# end
|
1753
|
+
# end
|
1754
|
+
# end
|
1755
|
+
# end
|
1756
|
+
# end
|
1757
|
+
# # Write with decrement
|
1758
|
+
# brancher(:wdec) do
|
1759
|
+
# reader_output :abus_w
|
1760
|
+
# if br_rsts[:wdec] then
|
1761
|
+
# rst_name = br_rsts[:wdec].to_sym
|
1762
|
+
# else
|
1763
|
+
# rst_name = rst.name
|
1764
|
+
# writer_input rst_name
|
1765
|
+
# end
|
1766
|
+
#
|
1767
|
+
# # Defines the read procedure at address +addr+
|
1768
|
+
# # using +target+ as target of access result.
|
1769
|
+
# writer do |blk,target|
|
1770
|
+
# # On reset the read trigger is 0.
|
1771
|
+
# rst = send(rst_name)
|
1772
|
+
# top_block.unshift do
|
1773
|
+
# # Initialize the address so that the next access is at address 0.
|
1774
|
+
# hif(rst==1) { abus_w <= 0 }
|
1775
|
+
# end
|
1776
|
+
# # Select the bank depending on the address.
|
1777
|
+
# hcase(abus_w / nbanks)
|
1778
|
+
# nbanks.times do |i|
|
1779
|
+
# hwhen(i) do
|
1780
|
+
# banks[i].read(abus_w % nbanks,target) do
|
1781
|
+
# abus_w <= abus_w + 1
|
1782
|
+
# blk.call
|
1783
|
+
# end
|
1784
|
+
# end
|
1785
|
+
# end
|
1786
|
+
# end
|
1787
|
+
# end
|
1788
|
+
#
|
1789
|
+
# end
|