HDLRuby 3.0.0 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/HDLRuby.gemspec +1 -0
  3. data/README.md +149 -79
  4. data/ext/hruby_sim/hruby_rcsim_build.c +2 -0
  5. data/ext/hruby_sim/hruby_sim_calc.c +33 -6
  6. data/ext/hruby_sim/hruby_sim_tree_calc.c +111 -22
  7. data/lib/HDLRuby/hdr_samples/comparison_bench.rb +2 -2
  8. data/lib/HDLRuby/hdr_samples/constant_in_function.rb +2 -1
  9. data/lib/HDLRuby/hdr_samples/counter_bench.rb +1 -1
  10. data/lib/HDLRuby/hdr_samples/counter_dff_bench.rb +8 -7
  11. data/lib/HDLRuby/hdr_samples/dff_properties.rb +2 -0
  12. data/lib/HDLRuby/hdr_samples/enum_as_param.rb +52 -0
  13. data/lib/HDLRuby/hdr_samples/linear_test.rb +2 -0
  14. data/lib/HDLRuby/hdr_samples/logic_bench.rb +6 -0
  15. data/lib/HDLRuby/hdr_samples/mei8.rb +6 -6
  16. data/lib/HDLRuby/hdr_samples/mei8_bench.rb +6 -6
  17. data/lib/HDLRuby/hdr_samples/memory_test.rb +2 -0
  18. data/lib/HDLRuby/hdr_samples/named_sub.rb +9 -5
  19. data/lib/HDLRuby/hdr_samples/ram.rb +7 -6
  20. data/lib/HDLRuby/hdr_samples/ruby_fir_hw.rb +2 -0
  21. data/lib/HDLRuby/hdr_samples/struct.rb +15 -3
  22. data/lib/HDLRuby/hdr_samples/with_bram.rb +1 -1
  23. data/lib/HDLRuby/hdr_samples/with_bram_frame_stack.rb +1 -1
  24. data/lib/HDLRuby/hdr_samples/with_bram_stack.rb +1 -1
  25. data/lib/HDLRuby/hdr_samples/with_channel.rb +2 -0
  26. data/lib/HDLRuby/hdr_samples/with_channel_other.rb +2 -0
  27. data/lib/HDLRuby/hdr_samples/with_class.rb +3 -1
  28. data/lib/HDLRuby/hdr_samples/with_connector.rb +2 -0
  29. data/lib/HDLRuby/hdr_samples/with_connector_memory.rb +2 -0
  30. data/lib/HDLRuby/hdr_samples/with_fixpoint.rb +6 -0
  31. data/lib/HDLRuby/hdr_samples/with_fixpoint_adv.rb +73 -0
  32. data/lib/HDLRuby/hdr_samples/with_leftright.rb +1 -1
  33. data/lib/HDLRuby/hdr_samples/with_ref_expr.rb +30 -0
  34. data/lib/HDLRuby/hdr_samples/with_sequencer.rb +49 -37
  35. data/lib/HDLRuby/hdr_samples/with_sequencer_channel.rb +58 -0
  36. data/lib/HDLRuby/hdr_samples/with_sequencer_enumerable.rb +113 -69
  37. data/lib/HDLRuby/hdr_samples/with_sequencer_enumerator.rb +28 -14
  38. data/lib/HDLRuby/hdr_samples/with_sequencer_func.rb +63 -0
  39. data/lib/HDLRuby/hdr_samples/with_sequencer_sync.rb +2 -1
  40. data/lib/HDLRuby/hdrcc.rb +13 -1
  41. data/lib/HDLRuby/hruby_high.rb +105 -31
  42. data/lib/HDLRuby/hruby_low.rb +127 -3
  43. data/lib/HDLRuby/hruby_low2programs.rb +47 -0
  44. data/lib/HDLRuby/hruby_low_resolve.rb +3 -2
  45. data/lib/HDLRuby/hruby_low_without_namespace.rb +133 -5
  46. data/lib/HDLRuby/hruby_low_without_subsignals.rb +51 -12
  47. data/lib/HDLRuby/hruby_rcsim.rb +24 -1
  48. data/lib/HDLRuby/hruby_serializer.rb +2 -1
  49. data/lib/HDLRuby/hruby_types.rb +5 -5
  50. data/lib/HDLRuby/hruby_values.rb +7 -7
  51. data/lib/HDLRuby/hruby_verilog.rb +193 -35
  52. data/lib/HDLRuby/hruby_verilog_name.rb +35 -42
  53. data/lib/HDLRuby/std/fixpoint.rb +2 -2
  54. data/lib/HDLRuby/std/fsm.rb +10 -1
  55. data/lib/HDLRuby/std/function_generator.rb +1 -1
  56. data/lib/HDLRuby/std/linear.rb +7 -7
  57. data/lib/HDLRuby/std/sequencer.rb +538 -60
  58. data/lib/HDLRuby/std/sequencer_channel.rb +90 -0
  59. data/lib/HDLRuby/std/sequencer_func.rb +546 -0
  60. data/lib/HDLRuby/std/std.rb +2 -0
  61. data/lib/HDLRuby/version.rb +1 -1
  62. data/tuto/tutorial_sw.md +267 -61
  63. metadata +25 -4
  64. 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
- # Get the closest loop status in the status stack.
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 the flag and the result array size index
1225
- # used for implementing the algorithm (shift-based sorting).
1376
+ # Declare the result signal.
1226
1377
  res = nil
1227
1378
  flg = nil
1228
- idx = nil
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
- # Performs the sort using a shift-based algorithm (also used in
1235
- # smin).
1236
- enum.srewind
1237
- # Do the iteration.
1238
- idx <= 0
1239
- SequencerT.current.swhile(enum.snext?) do
1240
- # Multiple min case.
1241
- SequencerT.current.sif(enum.snext?) do
1242
- elem = enum.snext
1243
- flg <= 1
1244
- n.times do |i|
1245
- # Compute the comparison between the result element at i
1246
- # and the enum element.
1247
- if ruby_block then
1248
- cond = ruby_block.call(res[i],elem) > 0
1249
- else
1250
- cond = res[i] > elem
1251
- end
1252
- # If flg is 0, elem is already set as min, skip.
1253
- # If the result array size index is equal to i, then
1254
- # put the element whatever the comparison is since the
1255
- # place is still empty.
1256
- hif(flg & (cond | (idx == i))) do
1257
- # A new min is found, shift res from i.
1258
- ((i+1)..(n-1)).reverse_each { |j| res[j] <= res[j-1] }
1259
- # An set the new min in current position.
1260
- res[i] <= elem
1261
- # For now skip.
1262
- flg <= 0
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 su,
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
- # Reitialize the iteration.
1746
+ # Reinitialize the iteration.
1520
1747
  this.srewind
1521
- # Performs the iteration.
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 @enumerator.size
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 : 32
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
- this[idx]
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
- typ = bit[[self.first.width,self.last.width].max]
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
- hw_enum = SEnumeratorBase.new(signed[32],size) do |idx|
1795
- idx.as(typ) + this.first
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...self).seach(&ruby_block)
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