HDLRuby 3.0.0 → 3.2.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/HDLRuby.gemspec +1 -0
- data/README.md +149 -79
- data/ext/hruby_sim/hruby_rcsim_build.c +2 -0
- data/ext/hruby_sim/hruby_sim_calc.c +33 -6
- data/ext/hruby_sim/hruby_sim_tree_calc.c +111 -22
- data/lib/HDLRuby/hdr_samples/comparison_bench.rb +2 -2
- data/lib/HDLRuby/hdr_samples/constant_in_function.rb +2 -1
- data/lib/HDLRuby/hdr_samples/counter_bench.rb +1 -1
- data/lib/HDLRuby/hdr_samples/counter_dff_bench.rb +8 -7
- data/lib/HDLRuby/hdr_samples/dff_properties.rb +2 -0
- data/lib/HDLRuby/hdr_samples/enum_as_param.rb +52 -0
- data/lib/HDLRuby/hdr_samples/linear_test.rb +2 -0
- data/lib/HDLRuby/hdr_samples/logic_bench.rb +6 -0
- data/lib/HDLRuby/hdr_samples/mei8.rb +6 -6
- data/lib/HDLRuby/hdr_samples/mei8_bench.rb +6 -6
- data/lib/HDLRuby/hdr_samples/memory_test.rb +2 -0
- data/lib/HDLRuby/hdr_samples/named_sub.rb +9 -5
- data/lib/HDLRuby/hdr_samples/ram.rb +7 -6
- data/lib/HDLRuby/hdr_samples/ruby_fir_hw.rb +2 -0
- data/lib/HDLRuby/hdr_samples/struct.rb +15 -3
- data/lib/HDLRuby/hdr_samples/with_bram.rb +1 -1
- data/lib/HDLRuby/hdr_samples/with_bram_frame_stack.rb +1 -1
- data/lib/HDLRuby/hdr_samples/with_bram_stack.rb +1 -1
- data/lib/HDLRuby/hdr_samples/with_channel.rb +2 -0
- data/lib/HDLRuby/hdr_samples/with_channel_other.rb +2 -0
- data/lib/HDLRuby/hdr_samples/with_class.rb +3 -1
- data/lib/HDLRuby/hdr_samples/with_connector.rb +2 -0
- data/lib/HDLRuby/hdr_samples/with_connector_memory.rb +2 -0
- data/lib/HDLRuby/hdr_samples/with_fixpoint.rb +6 -0
- data/lib/HDLRuby/hdr_samples/with_fixpoint_adv.rb +73 -0
- data/lib/HDLRuby/hdr_samples/with_leftright.rb +1 -1
- data/lib/HDLRuby/hdr_samples/with_ref_expr.rb +30 -0
- data/lib/HDLRuby/hdr_samples/with_sequencer.rb +49 -37
- data/lib/HDLRuby/hdr_samples/with_sequencer_channel.rb +58 -0
- data/lib/HDLRuby/hdr_samples/with_sequencer_enumerable.rb +113 -69
- data/lib/HDLRuby/hdr_samples/with_sequencer_enumerator.rb +28 -14
- data/lib/HDLRuby/hdr_samples/with_sequencer_func.rb +63 -0
- data/lib/HDLRuby/hdr_samples/with_sequencer_sync.rb +2 -1
- data/lib/HDLRuby/hdrcc.rb +13 -1
- data/lib/HDLRuby/hruby_high.rb +105 -31
- data/lib/HDLRuby/hruby_low.rb +127 -3
- data/lib/HDLRuby/hruby_low2programs.rb +47 -0
- data/lib/HDLRuby/hruby_low_resolve.rb +3 -2
- data/lib/HDLRuby/hruby_low_without_namespace.rb +133 -5
- data/lib/HDLRuby/hruby_low_without_subsignals.rb +51 -12
- data/lib/HDLRuby/hruby_rcsim.rb +24 -1
- data/lib/HDLRuby/hruby_serializer.rb +2 -1
- data/lib/HDLRuby/hruby_types.rb +5 -5
- data/lib/HDLRuby/hruby_values.rb +7 -7
- data/lib/HDLRuby/hruby_verilog.rb +193 -35
- data/lib/HDLRuby/hruby_verilog_name.rb +35 -42
- data/lib/HDLRuby/std/fixpoint.rb +2 -2
- data/lib/HDLRuby/std/fsm.rb +10 -1
- data/lib/HDLRuby/std/function_generator.rb +1 -1
- data/lib/HDLRuby/std/linear.rb +7 -7
- data/lib/HDLRuby/std/sequencer.rb +538 -60
- data/lib/HDLRuby/std/sequencer_channel.rb +90 -0
- data/lib/HDLRuby/std/sequencer_func.rb +546 -0
- data/lib/HDLRuby/std/std.rb +2 -0
- data/lib/HDLRuby/version.rb +1 -1
- data/tuto/tutorial_sw.md +267 -61
- metadata +25 -4
- data/lib/HDLRuby/hdr_samples/with_register_stack.rb +0 -150
|
@@ -77,20 +77,17 @@ module HDLRuby::High::Std
|
|
|
77
77
|
this.fill_top_user(blk)
|
|
78
78
|
end
|
|
79
79
|
end
|
|
80
|
-
# # Ends the fsm with an infinite loop state.
|
|
81
|
-
# st = @fsm.state {}
|
|
82
|
-
# st.gotos << proc do
|
|
83
|
-
# HDLRuby::High.top_user.instance_exec do
|
|
84
|
-
# # next_state_sig <= st.value
|
|
85
|
-
# next_state_sig <= EndStateValue
|
|
86
|
-
# end
|
|
87
|
-
# end
|
|
88
80
|
|
|
89
81
|
# Build the fsm.
|
|
90
82
|
@fsm.build
|
|
91
83
|
end
|
|
92
84
|
|
|
93
|
-
#
|
|
85
|
+
# Gets the number of states of the underlining fsm.
|
|
86
|
+
def size
|
|
87
|
+
return @fsm.size
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Gets the closest loop status in the status stack.
|
|
94
91
|
# NOTE: raises an exception if there are not swhile state.
|
|
95
92
|
def loop_status
|
|
96
93
|
i = @status.size-1
|
|
@@ -122,6 +119,25 @@ module HDLRuby::High::Std
|
|
|
122
119
|
return st
|
|
123
120
|
end
|
|
124
121
|
|
|
122
|
+
# Mark several steps.
|
|
123
|
+
def steps(num)
|
|
124
|
+
# Create a counter.
|
|
125
|
+
count = nil
|
|
126
|
+
zero = nil
|
|
127
|
+
one = nil
|
|
128
|
+
HDLRuby::High.cur_system.open do
|
|
129
|
+
if num.respond_to?(:width) then
|
|
130
|
+
count = [num.width].inner(HDLRuby.uniq_name(:"steps_count"))
|
|
131
|
+
else
|
|
132
|
+
count = num.to_expr.type.inner(HDLRuby.uniq_name(:"steps_count"))
|
|
133
|
+
end
|
|
134
|
+
zero = _b0
|
|
135
|
+
one = _b1
|
|
136
|
+
end
|
|
137
|
+
count <= num
|
|
138
|
+
swhile(count > zero) { count <= count - one }
|
|
139
|
+
end
|
|
140
|
+
|
|
125
141
|
# Breaks current iteration.
|
|
126
142
|
def sbreak
|
|
127
143
|
# Mark a step.
|
|
@@ -311,9 +327,49 @@ module HDLRuby::High::Std
|
|
|
311
327
|
end
|
|
312
328
|
|
|
313
329
|
|
|
330
|
+
## Remplement make_inners of block to support declaration within sequencers.
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
class HDLRuby::High::Block
|
|
334
|
+
# Save module method (unbounded) for further call since going to
|
|
335
|
+
# override make_inners.
|
|
336
|
+
# alias_method does not seem to work in such a context, so use
|
|
337
|
+
# this approach.
|
|
338
|
+
@@old_make_inners_proc = self.instance_method(:make_inners)
|
|
339
|
+
|
|
340
|
+
def make_inners(typ,*names)
|
|
341
|
+
res = nil
|
|
342
|
+
if SequencerT.current then
|
|
343
|
+
unames = names.map {|name| HDLRuby.uniq_name(name) }
|
|
344
|
+
res = HDLRuby::High.cur_scope.make_inners(typ, *unames)
|
|
345
|
+
names.zip(unames).each do |name,uname|
|
|
346
|
+
HDLRuby::High.space_reg(name) { send(uname) }
|
|
347
|
+
end
|
|
348
|
+
else
|
|
349
|
+
# self.old_make_inners(typ,*names)
|
|
350
|
+
# Call the old make_inners.
|
|
351
|
+
res = @@old_make_inners_proc.bind(self).call(typ,*names)
|
|
352
|
+
end
|
|
353
|
+
return res
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
|
|
314
360
|
# Module adding functionalities to object including the +seach+ method.
|
|
315
361
|
module SEnumerable
|
|
316
|
-
|
|
362
|
+
|
|
363
|
+
# Iterator on each of the elements in range +rng+.
|
|
364
|
+
# *NOTE*:
|
|
365
|
+
# - Stop iteration when the end of the range is reached or when there
|
|
366
|
+
# are no elements left
|
|
367
|
+
# - This is not a method from Ruby but one specific for hardware where
|
|
368
|
+
# creating a array is very expensive.
|
|
369
|
+
def seach_range(rng,&ruby_block)
|
|
370
|
+
return self.seach.seach_range(rng,&ruby_block)
|
|
371
|
+
end
|
|
372
|
+
|
|
317
373
|
# Tell if all the elements respect a given criterion given either
|
|
318
374
|
# as +arg+ or as block.
|
|
319
375
|
def sall?(arg = nil,&ruby_block)
|
|
@@ -713,8 +769,10 @@ module HDLRuby::High::Std
|
|
|
713
769
|
# Declares the resulting vector.
|
|
714
770
|
enum = self.seach
|
|
715
771
|
res = nil
|
|
772
|
+
# size = enum.size.to_value
|
|
716
773
|
HDLRuby::High.cur_system.open do
|
|
717
|
-
res = enum.type[-enum.size].inner(HDLRuby.uniq_name(:"to_a_res"))
|
|
774
|
+
# res = enum.type[-enum.size].inner(HDLRuby.uniq_name(:"to_a_res"))
|
|
775
|
+
res = enum.type[-enum.size.to_i].inner(HDLRuby.uniq_name(:"to_a_res"))
|
|
718
776
|
end
|
|
719
777
|
# Fills it.
|
|
720
778
|
self.seach_with_index do |elem,i|
|
|
@@ -1217,54 +1275,174 @@ module HDLRuby::High::Std
|
|
|
1217
1275
|
raise "sslice_before is not supported yet."
|
|
1218
1276
|
end
|
|
1219
1277
|
|
|
1278
|
+
# # HW implementation of the Ruby sort.
|
|
1279
|
+
# def ssort(&ruby_block)
|
|
1280
|
+
# enum = self.seach
|
|
1281
|
+
# n = enum.size
|
|
1282
|
+
# # Declare the result signal the flag and the result array size index
|
|
1283
|
+
# # used for implementing the algorithm (shift-based sorting).
|
|
1284
|
+
# res = nil
|
|
1285
|
+
# flg = nil
|
|
1286
|
+
# idx = nil
|
|
1287
|
+
# HDLRuby::High.cur_system.open do
|
|
1288
|
+
# res = enum.type[-n].inner(HDLRuby.uniq_name(:"sort_res"))
|
|
1289
|
+
# flg = bit.inner(HDLRuby.uniq_name(:"sort_flg"))
|
|
1290
|
+
# idx = bit[n.width].inner(HDLRuby.uniq_name(:"sort_idx"))
|
|
1291
|
+
# end
|
|
1292
|
+
# # Performs the sort using a shift-based algorithm (also used in
|
|
1293
|
+
# # smin).
|
|
1294
|
+
# enum.srewind
|
|
1295
|
+
# # Do the iteration.
|
|
1296
|
+
# idx <= 0
|
|
1297
|
+
# SequencerT.current.swhile(enum.snext?) do
|
|
1298
|
+
# # Multiple min case.
|
|
1299
|
+
# SequencerT.current.sif(enum.snext?) do
|
|
1300
|
+
# elem = enum.snext
|
|
1301
|
+
# flg <= 1
|
|
1302
|
+
# n.times do |i|
|
|
1303
|
+
# # Compute the comparison between the result element at i
|
|
1304
|
+
# # and the enum element.
|
|
1305
|
+
# if ruby_block then
|
|
1306
|
+
# cond = ruby_block.call(res[i],elem) > 0
|
|
1307
|
+
# else
|
|
1308
|
+
# cond = res[i] > elem
|
|
1309
|
+
# end
|
|
1310
|
+
# # If flg is 0, elem is already set as min, skip.
|
|
1311
|
+
# # If the result array size index is equal to i, then
|
|
1312
|
+
# # put the element whatever the comparison is since the
|
|
1313
|
+
# # place is still empty.
|
|
1314
|
+
# hif(flg & (cond | (idx == i))) do
|
|
1315
|
+
# # A new min is found, shift res from i.
|
|
1316
|
+
# ((i+1)..(n-1)).reverse_each { |j| res[j] <= res[j-1] }
|
|
1317
|
+
# # An set the new min in current position.
|
|
1318
|
+
# res[i] <= elem
|
|
1319
|
+
# # For now skip.
|
|
1320
|
+
# flg <= 0
|
|
1321
|
+
# end
|
|
1322
|
+
# end
|
|
1323
|
+
# idx <= idx + 1
|
|
1324
|
+
# end
|
|
1325
|
+
# end
|
|
1326
|
+
# return res
|
|
1327
|
+
# end
|
|
1328
|
+
|
|
1329
|
+
# Merge two arrays in order, for ssort only.
|
|
1330
|
+
def ssort_merge(arI, arO, first, middle, last, &ruby_block)
|
|
1331
|
+
# puts "first=#{first} middle=#{middle} last=#{last}"
|
|
1332
|
+
# Declare and initialize the indexes and
|
|
1333
|
+
# the ending flag.
|
|
1334
|
+
idF = nil; idM = nil; idO = nil
|
|
1335
|
+
flg = nil
|
|
1336
|
+
HDLRuby::High.cur_system.open do
|
|
1337
|
+
typ = [(last+1).width]
|
|
1338
|
+
idF = typ.inner(HDLRuby.uniq_name(:"sort_idF"))
|
|
1339
|
+
idM = typ.inner(HDLRuby.uniq_name(:"sort_idM"))
|
|
1340
|
+
idO = typ.inner(HDLRuby.uniq_name(:"sort_idO"))
|
|
1341
|
+
flg = inner(HDLRuby.uniq_name(:"sort_flg"))
|
|
1342
|
+
end
|
|
1343
|
+
idF <= first; idM <= middle; idO <= first
|
|
1344
|
+
flg <= 0
|
|
1345
|
+
SequencerT.current.swhile((flg == 0) & (idO < middle*2)) do
|
|
1346
|
+
if ruby_block then
|
|
1347
|
+
cond = ruby_block.call(arI[idF],arI[idM]) < 0
|
|
1348
|
+
else
|
|
1349
|
+
cond = arI[idF] < arI[idM]
|
|
1350
|
+
end
|
|
1351
|
+
hif((idF >= middle) & (idM > last)) { flg <= 1 }
|
|
1352
|
+
helsif (idF >= middle) do
|
|
1353
|
+
arO[idO] <= arI[idM]
|
|
1354
|
+
idM <= idM + 1
|
|
1355
|
+
end
|
|
1356
|
+
helsif(idM > last) do
|
|
1357
|
+
arO[idO] <= arI[idF]
|
|
1358
|
+
idF <= idF + 1
|
|
1359
|
+
end
|
|
1360
|
+
helsif(cond) do
|
|
1361
|
+
arO[idO] <= arI[idF]
|
|
1362
|
+
idF <= idF + 1
|
|
1363
|
+
end
|
|
1364
|
+
helse do
|
|
1365
|
+
arO[idO] <= arI[idM]
|
|
1366
|
+
idM <= idM + 1
|
|
1367
|
+
end
|
|
1368
|
+
idO <= idO + 1
|
|
1369
|
+
end
|
|
1370
|
+
end
|
|
1371
|
+
|
|
1220
1372
|
# HW implementation of the Ruby sort.
|
|
1221
1373
|
def ssort(&ruby_block)
|
|
1222
1374
|
enum = self.seach
|
|
1223
1375
|
n = enum.size
|
|
1224
|
-
# Declare the result signal
|
|
1225
|
-
# used for implementing the algorithm (shift-based sorting).
|
|
1376
|
+
# Declare the result signal.
|
|
1226
1377
|
res = nil
|
|
1227
1378
|
flg = nil
|
|
1228
|
-
|
|
1379
|
+
siz = nil
|
|
1229
1380
|
HDLRuby::High.cur_system.open do
|
|
1230
1381
|
res = enum.type[-n].inner(HDLRuby.uniq_name(:"sort_res"))
|
|
1231
|
-
flg = bit.inner(HDLRuby.uniq_name(:"sort_flg"))
|
|
1232
|
-
idx = bit[n.width].inner(HDLRuby.uniq_name(:"sort_idx"))
|
|
1233
1382
|
end
|
|
1234
|
-
#
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
end
|
|
1264
|
-
end
|
|
1265
|
-
idx <= idx + 1
|
|
1383
|
+
# Only one element?
|
|
1384
|
+
if n == 1 then
|
|
1385
|
+
# Just copy to the result and end here.
|
|
1386
|
+
res[0] <= enum.snext
|
|
1387
|
+
return res
|
|
1388
|
+
end
|
|
1389
|
+
tmp = []
|
|
1390
|
+
idxF = nil; idxM = nil; idxO = nil
|
|
1391
|
+
HDLRuby::High.cur_system.open do
|
|
1392
|
+
# More elements, need to declare intermediate arrays.
|
|
1393
|
+
((n-1).width).times do
|
|
1394
|
+
tmp << enum.type[-n].inner(HDLRuby.uniq_name(:"sort_tmp"))
|
|
1395
|
+
end
|
|
1396
|
+
# The result will be the last of the intermediate arrays.
|
|
1397
|
+
tmp << res
|
|
1398
|
+
end
|
|
1399
|
+
# Fills the first temporary array.
|
|
1400
|
+
enum.seach_with_index { |e,i| tmp[0][i] <= e }
|
|
1401
|
+
# Is there only 2 elements?
|
|
1402
|
+
if n == 2 then
|
|
1403
|
+
if ruby_block then
|
|
1404
|
+
cond = ruby_block.call(tmp[0][0],tmp[0][1]) < 0
|
|
1405
|
+
else
|
|
1406
|
+
cond = tmp[0][0] < tmp[0][1]
|
|
1407
|
+
end
|
|
1408
|
+
# Just look for the min and the max.
|
|
1409
|
+
hif(cond) do
|
|
1410
|
+
res[0] <= tmp[0][0]
|
|
1411
|
+
res[1] <= tmp[0][1]
|
|
1266
1412
|
end
|
|
1413
|
+
helse do
|
|
1414
|
+
res[1] <= tmp[0][0]
|
|
1415
|
+
res[0] <= tmp[0][1]
|
|
1416
|
+
end
|
|
1417
|
+
return res
|
|
1267
1418
|
end
|
|
1419
|
+
# Performs the sort using a merge-based algorithm.
|
|
1420
|
+
breadth = 1; i = 0
|
|
1421
|
+
# while(breadth*2 < n)
|
|
1422
|
+
while(breadth < n)
|
|
1423
|
+
pos = 0; last = 0
|
|
1424
|
+
while(pos+breadth < n)
|
|
1425
|
+
last = [n-1,pos+breadth*2-1].min
|
|
1426
|
+
ssort_merge(tmp[i], tmp[i+1], pos, pos+breadth,last,&ruby_block)
|
|
1427
|
+
pos = pos + breadth * 2
|
|
1428
|
+
end
|
|
1429
|
+
# Copy the remaining elements if any
|
|
1430
|
+
# puts "n=#{n} breadth=#{breadth} last=#{last} n-last-1=#{n-last-1}"
|
|
1431
|
+
if last < n-1 then
|
|
1432
|
+
(n-last-1).stimes do |j|
|
|
1433
|
+
tmp[i+1][last+1+j] <= tmp[i][last+1+j]
|
|
1434
|
+
end
|
|
1435
|
+
end
|
|
1436
|
+
# Next step
|
|
1437
|
+
# SequencerT.current.step
|
|
1438
|
+
breadth = breadth * 2
|
|
1439
|
+
i += 1
|
|
1440
|
+
end
|
|
1441
|
+
# # Last merge if the array size was not a power of 2.
|
|
1442
|
+
# if (breadth*2 != n) then
|
|
1443
|
+
# ssort_merge(tmp[-2],tmp[-1],0,breadth,n-1,&ruby_block)
|
|
1444
|
+
# # SequencerT.current.step
|
|
1445
|
+
# end
|
|
1268
1446
|
return res
|
|
1269
1447
|
end
|
|
1270
1448
|
|
|
@@ -1302,7 +1480,7 @@ module HDLRuby::High::Std
|
|
|
1302
1480
|
# There is a ruby block, use it to process the element first.
|
|
1303
1481
|
res <= res + ruby_block.call(enum.snext)
|
|
1304
1482
|
else
|
|
1305
|
-
# No ruby block, just do the
|
|
1483
|
+
# No ruby block, just do the sum
|
|
1306
1484
|
res <= res + enum.snext
|
|
1307
1485
|
end
|
|
1308
1486
|
end
|
|
@@ -1493,6 +1671,55 @@ module HDLRuby::High::Std
|
|
|
1493
1671
|
end
|
|
1494
1672
|
end
|
|
1495
1673
|
|
|
1674
|
+
# Iterator on the +num+ next elements.
|
|
1675
|
+
# *NOTE*:
|
|
1676
|
+
# - Stop iteration when the end of the range is reached or when there
|
|
1677
|
+
# are no elements left
|
|
1678
|
+
# - This is not a method from Ruby but one specific for hardware where
|
|
1679
|
+
# creating a array is very expensive.
|
|
1680
|
+
def seach_nexts(num,&ruby_block)
|
|
1681
|
+
# # No block given, returns a new enumerator.
|
|
1682
|
+
# unless ruby_block then
|
|
1683
|
+
# res = SEnumeratorWrapper.new(self,:seach_nexts,num)
|
|
1684
|
+
# res.size = num
|
|
1685
|
+
# return res
|
|
1686
|
+
# end
|
|
1687
|
+
# # A block is given, iterate.
|
|
1688
|
+
# enum = self.seach
|
|
1689
|
+
# # Create a counter.
|
|
1690
|
+
# count = nil
|
|
1691
|
+
# zero = nil
|
|
1692
|
+
# one = nil
|
|
1693
|
+
# HDLRuby::High.cur_system.open do
|
|
1694
|
+
# if num.respond_to?(:width) then
|
|
1695
|
+
# count = [num.width].inner(HDLRuby.uniq_name(:"snexts_count"))
|
|
1696
|
+
# else
|
|
1697
|
+
# count = num.to_expr.type.inner(HDLRuby.uniq_name(:"snexts_count"))
|
|
1698
|
+
# end
|
|
1699
|
+
# zero = _b0
|
|
1700
|
+
# one = _b1
|
|
1701
|
+
# end
|
|
1702
|
+
# count <= num
|
|
1703
|
+
# SequencerT.current.swhile(count > zero) do
|
|
1704
|
+
# ruby_block.call(enum.snext)
|
|
1705
|
+
# count <= count - one
|
|
1706
|
+
# end
|
|
1707
|
+
zero = nil
|
|
1708
|
+
one = nil
|
|
1709
|
+
HDLRuby::High.cur_system.open do
|
|
1710
|
+
zero = _b0.as(num.to_expr.type)
|
|
1711
|
+
one = _b1.as(num.to_expr.type)
|
|
1712
|
+
end
|
|
1713
|
+
subE = SEnumeratorSub.new(self,zero..num-one)
|
|
1714
|
+
if ruby_block then
|
|
1715
|
+
# A block is given, iterate immediatly.
|
|
1716
|
+
subE.seach(&ruby_block)
|
|
1717
|
+
else
|
|
1718
|
+
# No block given, return the new sub iterator.
|
|
1719
|
+
return subE
|
|
1720
|
+
end
|
|
1721
|
+
end
|
|
1722
|
+
|
|
1496
1723
|
end
|
|
1497
1724
|
|
|
1498
1725
|
|
|
@@ -1516,10 +1743,30 @@ module HDLRuby::High::Std
|
|
|
1516
1743
|
return self unless ruby_block
|
|
1517
1744
|
# A block is given, iterate.
|
|
1518
1745
|
this = self
|
|
1519
|
-
#
|
|
1746
|
+
# Reinitialize the iteration.
|
|
1520
1747
|
this.srewind
|
|
1521
|
-
#
|
|
1748
|
+
# Perform the iteration.
|
|
1522
1749
|
SequencerT.current.swhile(self.index < self.size) do
|
|
1750
|
+
# ruby_block.call(this.snext)
|
|
1751
|
+
HDLRuby::High.top_user.instance_exec(this.snext,&ruby_block)
|
|
1752
|
+
end
|
|
1753
|
+
end
|
|
1754
|
+
|
|
1755
|
+
# Iterator on each of the elements in range +rng+.
|
|
1756
|
+
# *NOTE*:
|
|
1757
|
+
# - Stop iteration when the end of the range is reached or when there
|
|
1758
|
+
# are no elements left
|
|
1759
|
+
# - This is not a method from Ruby but one specific for hardware where
|
|
1760
|
+
# creating a array is very expensive.
|
|
1761
|
+
def seach_range(rng,&ruby_block)
|
|
1762
|
+
# No block given, returns a new enumerator.
|
|
1763
|
+
return SEnumeratorWrapper.new(self,:seach_range) unless ruby_block
|
|
1764
|
+
# A block is given, iterate.
|
|
1765
|
+
this = self
|
|
1766
|
+
# Perform the iteration.
|
|
1767
|
+
self.index <= rng.first
|
|
1768
|
+
SequencerT.current.swhile((self.index < self.size) &
|
|
1769
|
+
(self.index <= rng.last) ) do
|
|
1523
1770
|
ruby_block.call(this.snext)
|
|
1524
1771
|
end
|
|
1525
1772
|
end
|
|
@@ -1604,7 +1851,7 @@ module HDLRuby::High::Std
|
|
|
1604
1851
|
|
|
1605
1852
|
# The directly delegate methods.
|
|
1606
1853
|
def size
|
|
1607
|
-
return @
|
|
1854
|
+
return @enumertor.size
|
|
1608
1855
|
end
|
|
1609
1856
|
|
|
1610
1857
|
def type
|
|
@@ -1632,13 +1879,32 @@ module HDLRuby::High::Std
|
|
|
1632
1879
|
end
|
|
1633
1880
|
|
|
1634
1881
|
def snext?
|
|
1882
|
+
# if @size then
|
|
1883
|
+
# return @enumerator.index < @size
|
|
1884
|
+
# else
|
|
1885
|
+
# return @enumerator.snext?
|
|
1886
|
+
# end
|
|
1635
1887
|
return @enumerator.snext?
|
|
1636
1888
|
end
|
|
1637
1889
|
|
|
1890
|
+
def snext!(val)
|
|
1891
|
+
return @enumerator.snext!(val)
|
|
1892
|
+
end
|
|
1893
|
+
|
|
1638
1894
|
def srewind
|
|
1639
1895
|
return @enumerator.srewind
|
|
1640
1896
|
end
|
|
1641
1897
|
|
|
1898
|
+
# Iterator on each of the elements in range +rng+.
|
|
1899
|
+
# *NOTE*:
|
|
1900
|
+
# - Stop iteration when the end of the range is reached or when there
|
|
1901
|
+
# are no elements left
|
|
1902
|
+
# - This is not a method from Ruby but one specific for hardware where
|
|
1903
|
+
# creating a array is very expensive.
|
|
1904
|
+
def seach_range(rng,&ruby_block)
|
|
1905
|
+
return @enumerator.seach_range(rng,&ruby_block)
|
|
1906
|
+
end
|
|
1907
|
+
|
|
1642
1908
|
# Clones the enumerator.
|
|
1643
1909
|
def clone
|
|
1644
1910
|
return SEnumeratorWrapper.new(@enumerator,@iterator,*@arguments)
|
|
@@ -1654,6 +1920,92 @@ module HDLRuby::High::Std
|
|
|
1654
1920
|
end
|
|
1655
1921
|
|
|
1656
1922
|
|
|
1923
|
+
# Describes a sequencer enumerator class that allows to generate HW iterations
|
|
1924
|
+
# over HW or SW objects within sequencers.
|
|
1925
|
+
# This is the sub Enumerator over an other one for interating inside the
|
|
1926
|
+
# enumerator.
|
|
1927
|
+
# This is specific the HDLRuby for avoiding creation of array which are
|
|
1928
|
+
# expensive in HW. Used by seach_next for example.
|
|
1929
|
+
# Will change the index position of the initial iterator without reseting
|
|
1930
|
+
# it.
|
|
1931
|
+
class SEnumeratorSub < SEnumerator
|
|
1932
|
+
|
|
1933
|
+
# Create a new SEnumerator wrapper over +enum+ among +rng+ indexes.
|
|
1934
|
+
def initialize(enum,rng,*args)
|
|
1935
|
+
@enumerator = enum.seach
|
|
1936
|
+
@range = rng.first..rng.last
|
|
1937
|
+
# Declare the sub index.
|
|
1938
|
+
idx = nil
|
|
1939
|
+
siz = @range.last-@range.first+1
|
|
1940
|
+
HDLRuby::High.cur_system.open do
|
|
1941
|
+
idx = [siz.width].inner({
|
|
1942
|
+
HDLRuby.uniq_name("sub_idx") => 0 })
|
|
1943
|
+
end
|
|
1944
|
+
@index = idx
|
|
1945
|
+
@size = siz
|
|
1946
|
+
end
|
|
1947
|
+
|
|
1948
|
+
# The directly delegate methods.
|
|
1949
|
+
def size
|
|
1950
|
+
return @size
|
|
1951
|
+
end
|
|
1952
|
+
|
|
1953
|
+
def type
|
|
1954
|
+
return @enumerator.type
|
|
1955
|
+
end
|
|
1956
|
+
|
|
1957
|
+
def result
|
|
1958
|
+
return @enumerator.result
|
|
1959
|
+
end
|
|
1960
|
+
|
|
1961
|
+
def index
|
|
1962
|
+
return @index
|
|
1963
|
+
end
|
|
1964
|
+
|
|
1965
|
+
def access(idx)
|
|
1966
|
+
return @enumerator.access(@index+@range.first)
|
|
1967
|
+
end
|
|
1968
|
+
|
|
1969
|
+
def speek
|
|
1970
|
+
return @enumerator.speek
|
|
1971
|
+
end
|
|
1972
|
+
|
|
1973
|
+
def snext
|
|
1974
|
+
@index <= @index + 1
|
|
1975
|
+
return @enumerator.snext
|
|
1976
|
+
end
|
|
1977
|
+
|
|
1978
|
+
def snext?
|
|
1979
|
+
return @index < self.size
|
|
1980
|
+
end
|
|
1981
|
+
|
|
1982
|
+
def snext!(val)
|
|
1983
|
+
return @enumerator.snext!(val)
|
|
1984
|
+
end
|
|
1985
|
+
|
|
1986
|
+
def srewind
|
|
1987
|
+
@index <= 0
|
|
1988
|
+
end
|
|
1989
|
+
|
|
1990
|
+
# Clones the enumerator.
|
|
1991
|
+
def clone
|
|
1992
|
+
return SEnumeratorSub.new(@enumerator,@range)
|
|
1993
|
+
end
|
|
1994
|
+
|
|
1995
|
+
# Iterate over each element.
|
|
1996
|
+
def seach(&ruby_block)
|
|
1997
|
+
# No block given, returns self.
|
|
1998
|
+
return self unless ruby_block
|
|
1999
|
+
# A block is given, iterate.
|
|
2000
|
+
this = self
|
|
2001
|
+
SequencerT.current.swhile(this.snext?) do
|
|
2002
|
+
ruby_block.call(this.snext)
|
|
2003
|
+
end
|
|
2004
|
+
end
|
|
2005
|
+
end
|
|
2006
|
+
|
|
2007
|
+
|
|
2008
|
+
|
|
1657
2009
|
# Describes a sequencer enumerator class that allows to generate HW
|
|
1658
2010
|
# iterations over HW or SW objects within sequencers.
|
|
1659
2011
|
# This is the base Enumerator that directly iterates.
|
|
@@ -1674,7 +2026,9 @@ module HDLRuby::High::Std
|
|
|
1674
2026
|
# Sets the accesser.
|
|
1675
2027
|
@access = access
|
|
1676
2028
|
# Compute the index width (default: safe 32 bits).
|
|
1677
|
-
width = @size.respond_to?(:width) ? @size.width :
|
|
2029
|
+
width = @size.respond_to?(:width) ? @size.width :
|
|
2030
|
+
@size.respond_to?(:type) ? size.type.width : 32
|
|
2031
|
+
# puts "width=#{width}"
|
|
1678
2032
|
# Create the index and the iteration result.
|
|
1679
2033
|
idx = nil
|
|
1680
2034
|
result = nil
|
|
@@ -1712,9 +2066,17 @@ module HDLRuby::High::Std
|
|
|
1712
2066
|
|
|
1713
2067
|
# Tell if there is a next element.
|
|
1714
2068
|
def snext?
|
|
2069
|
+
# puts "@index=#{index}, @size=#{@size}"
|
|
1715
2070
|
return @index < @size
|
|
1716
2071
|
end
|
|
1717
2072
|
|
|
2073
|
+
# Set the next element.
|
|
2074
|
+
def snext!(val)
|
|
2075
|
+
@access.call(@index,val)
|
|
2076
|
+
@index <= @index + 1
|
|
2077
|
+
return val
|
|
2078
|
+
end
|
|
2079
|
+
|
|
1718
2080
|
# Restart the iteration.
|
|
1719
2081
|
def srewind
|
|
1720
2082
|
@index <= 0
|
|
@@ -1722,6 +2084,8 @@ module HDLRuby::High::Std
|
|
|
1722
2084
|
end
|
|
1723
2085
|
|
|
1724
2086
|
|
|
2087
|
+
|
|
2088
|
+
|
|
1725
2089
|
module HDLRuby::High::HExpression
|
|
1726
2090
|
# Enhance the HExpression module with sequencer iteration.
|
|
1727
2091
|
|
|
@@ -1729,8 +2093,14 @@ module HDLRuby::High::Std
|
|
|
1729
2093
|
def seach(&ruby_block)
|
|
1730
2094
|
# Create the hardware iterator.
|
|
1731
2095
|
this = self
|
|
1732
|
-
hw_enum = SEnumeratorBase.new(this.type.base,this.type.size) do |idx|
|
|
1733
|
-
|
|
2096
|
+
hw_enum = SEnumeratorBase.new(this.type.base,this.type.size) do |idx,val = nil|
|
|
2097
|
+
if val then
|
|
2098
|
+
# Write access
|
|
2099
|
+
this[idx] <= val
|
|
2100
|
+
else
|
|
2101
|
+
# Read access
|
|
2102
|
+
this[idx]
|
|
2103
|
+
end
|
|
1734
2104
|
end
|
|
1735
2105
|
# Is there a ruby block?
|
|
1736
2106
|
if(ruby_block) then
|
|
@@ -1749,6 +2119,42 @@ module HDLRuby::High::Std
|
|
|
1749
2119
|
end
|
|
1750
2120
|
|
|
1751
2121
|
|
|
2122
|
+
# class HDLRuby::High::Value
|
|
2123
|
+
module HDLRuby::High::HExpression
|
|
2124
|
+
# Enhance the Value class with sequencer iterations.
|
|
2125
|
+
|
|
2126
|
+
# HW times iteration.
|
|
2127
|
+
def stimes(&ruby_block)
|
|
2128
|
+
# return (0..self-1).seach(&ruby_block)
|
|
2129
|
+
return AnyRange.new(0,self-1).seach(&ruby_block)
|
|
2130
|
+
end
|
|
2131
|
+
|
|
2132
|
+
# HW upto iteration.
|
|
2133
|
+
def supto(val,&ruby_block)
|
|
2134
|
+
# return (self..val).seach(&ruby_block)
|
|
2135
|
+
return AnyRange.new(self,val).seach(&ruby_block)
|
|
2136
|
+
end
|
|
2137
|
+
|
|
2138
|
+
# HW downto iteration.
|
|
2139
|
+
def sdownto(val,&ruby_block)
|
|
2140
|
+
# Create the hardware iterator.
|
|
2141
|
+
# range = val..(self.to_i)
|
|
2142
|
+
range = AnyRange.new(val,self)
|
|
2143
|
+
hw_enum = SEnumeratorBase.new(signed[32],range.size) do |idx|
|
|
2144
|
+
range.last - idx
|
|
2145
|
+
end
|
|
2146
|
+
# Is there a ruby block?
|
|
2147
|
+
if(ruby_block) then
|
|
2148
|
+
# Yes, apply it.
|
|
2149
|
+
return hw_enum.seach(&ruby_block)
|
|
2150
|
+
else
|
|
2151
|
+
# No, return the resulting enumerator.
|
|
2152
|
+
return hw_enum
|
|
2153
|
+
end
|
|
2154
|
+
end
|
|
2155
|
+
end
|
|
2156
|
+
|
|
2157
|
+
|
|
1752
2158
|
module ::Enumerable
|
|
1753
2159
|
# Enhance the Enumerable module with sequencer iteration.
|
|
1754
2160
|
|
|
@@ -1787,12 +2193,85 @@ module HDLRuby::High::Std
|
|
|
1787
2193
|
# HW iteration on each element.
|
|
1788
2194
|
def seach(&ruby_block)
|
|
1789
2195
|
# Create the iteration type.
|
|
1790
|
-
|
|
2196
|
+
# if self.first < 0 || self.last < 0 then
|
|
2197
|
+
# fw = self.first.is_a?(Numeric) ? self.first.abs.width :
|
|
2198
|
+
# self.first.width
|
|
2199
|
+
# lw = self.last.is_a?(Numeric) ? self.last.abs.width :
|
|
2200
|
+
# self.last.width
|
|
2201
|
+
# typ = signed[[fw,lw].max]
|
|
2202
|
+
# else
|
|
2203
|
+
# typ = bit[[self.first.width,self.last.width].max]
|
|
2204
|
+
# end
|
|
2205
|
+
# Create the iteration type: selection of the larger HDLRuby type
|
|
2206
|
+
# between first and last. If one of first and last is a Numeric,
|
|
2207
|
+
# priority to the non Numeric one.
|
|
2208
|
+
if (self.last.is_a?(Numeric)) then
|
|
2209
|
+
typ = self.first.to_expr.type
|
|
2210
|
+
elsif (self.first.is_a?(Numeric)) then
|
|
2211
|
+
typ = self.last.to_expr.type
|
|
2212
|
+
else
|
|
2213
|
+
typ = self.first.type.width > self.last.type.width ?
|
|
2214
|
+
self.first.type : self.last.type
|
|
2215
|
+
end
|
|
1791
2216
|
# Create the hardware iterator.
|
|
1792
2217
|
this = self
|
|
1793
2218
|
size = this.size ? this.size : this.last - this.first + 1
|
|
1794
|
-
|
|
1795
|
-
|
|
2219
|
+
# size = size.to_expr
|
|
2220
|
+
# if size.respond_to?(:cast) then
|
|
2221
|
+
# size = size.cast(typ)
|
|
2222
|
+
# else
|
|
2223
|
+
# size = size.as(typ)
|
|
2224
|
+
# end
|
|
2225
|
+
size = size.to_expr.as(typ)
|
|
2226
|
+
# hw_enum = SEnumeratorBase.new(signed[32],size) do |idx|
|
|
2227
|
+
hw_enum = SEnumeratorBase.new(typ,size) do |idx|
|
|
2228
|
+
# idx.as(typ) + this.first
|
|
2229
|
+
idx.as(typ) + this.first.to_expr.as(typ)
|
|
2230
|
+
end
|
|
2231
|
+
# Is there a ruby block?
|
|
2232
|
+
if(ruby_block) then
|
|
2233
|
+
# Yes, apply it.
|
|
2234
|
+
return hw_enum.seach(&ruby_block)
|
|
2235
|
+
else
|
|
2236
|
+
# No, return the resulting enumerator.
|
|
2237
|
+
return hw_enum
|
|
2238
|
+
end
|
|
2239
|
+
end
|
|
2240
|
+
end
|
|
2241
|
+
|
|
2242
|
+
|
|
2243
|
+
# Range substitute class for sequencers that supports any kind of bounds.
|
|
2244
|
+
class AnyRange
|
|
2245
|
+
# Enhance the AnyRange class with sequencer iteration.
|
|
2246
|
+
include SEnumerable
|
|
2247
|
+
|
|
2248
|
+
attr_reader :first, :last
|
|
2249
|
+
|
|
2250
|
+
def initialize(first,last)
|
|
2251
|
+
@first = first
|
|
2252
|
+
@last = last
|
|
2253
|
+
end
|
|
2254
|
+
|
|
2255
|
+
# HW iteration on each element.
|
|
2256
|
+
def seach(&ruby_block)
|
|
2257
|
+
# Create the iteration type: selection of the larger HDLRuby type
|
|
2258
|
+
# between first and last. If one of first and last is a Numeric,
|
|
2259
|
+
# priority to the non Numeric one.
|
|
2260
|
+
if (self.last.is_a?(Numeric)) then
|
|
2261
|
+
typ = self.first.to_expr.type
|
|
2262
|
+
elsif (self.first.is_a?(Numeric)) then
|
|
2263
|
+
typ = self.last.to_expr.type
|
|
2264
|
+
else
|
|
2265
|
+
typ = self.first.type.width > self.last.type.width ?
|
|
2266
|
+
self.first.type : self.last.type
|
|
2267
|
+
end
|
|
2268
|
+
# Create the hardware iterator.
|
|
2269
|
+
this = self
|
|
2270
|
+
# size = this.size ? this.size : this.last - this.first + 1
|
|
2271
|
+
size = this.last - this.first + 1
|
|
2272
|
+
size = size.to_expr.as(typ)
|
|
2273
|
+
hw_enum = SEnumeratorBase.new(typ,size) do |idx|
|
|
2274
|
+
idx.as(typ) + this.first.to_expr.as(typ)
|
|
1796
2275
|
end
|
|
1797
2276
|
# Is there a ruby block?
|
|
1798
2277
|
if(ruby_block) then
|
|
@@ -1811,7 +2290,7 @@ module HDLRuby::High::Std
|
|
|
1811
2290
|
|
|
1812
2291
|
# HW times iteration.
|
|
1813
2292
|
def stimes(&ruby_block)
|
|
1814
|
-
return (0
|
|
2293
|
+
return (0..self-1).seach(&ruby_block)
|
|
1815
2294
|
end
|
|
1816
2295
|
|
|
1817
2296
|
# HW upto iteration.
|
|
@@ -1853,5 +2332,4 @@ module HDLRuby::High::Std
|
|
|
1853
2332
|
end
|
|
1854
2333
|
|
|
1855
2334
|
|
|
1856
|
-
|
|
1857
2335
|
end
|