HDLRuby 3.7.9 → 3.8.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.
@@ -232,6 +232,11 @@ module HDLRuby::High
232
232
  # integer-constant choice. If only constant integer choices,
233
233
  # use the largest type of them.
234
234
  def mux(select,*choices)
235
+ select = select ? 1 : 0 if [true,false,nil].include?(select)
236
+ if select.respond_to?(:to_i) then
237
+ # The mux can be evaluate straight away. Do metaprograming.
238
+ return choices[select.to_i]
239
+ end
235
240
  # Process the choices.
236
241
  choices = choices.flatten(1) if choices.size == 1
237
242
  choices.map! { |choice| choice.to_expr }
@@ -310,7 +315,8 @@ module HDLRuby::High
310
315
  unless instance_methods.include?(:inner) then
311
316
  # Declares high-level bit inner signals named +names+.
312
317
  def inner(*names)
313
- self.make_inners(bit,*names)
318
+ # self.make_inners(bit,*names)
319
+ bit.inner(*names)
314
320
  end
315
321
  end
316
322
 
@@ -318,7 +324,8 @@ module HDLRuby::High
318
324
  # Declares high-level untyped constant signals by name and
319
325
  # value given by +hsh+ of the current type.
320
326
  def constant(hsh)
321
- self.make_constants(bit,hsh)
327
+ # self.make_constants(bit,hsh)
328
+ bit.constant(hsh)
322
329
  end
323
330
  end
324
331
  end
@@ -901,6 +908,101 @@ module HDLRuby::High
901
908
  end
902
909
 
903
910
 
911
+ # Module adding metaprogramming capabilities to control statements.
912
+ module HmetaControl
913
+ # Adds meta programming capability to a if statement.
914
+ def metaif(condition, &ruby_block)
915
+ @metacond = nil
916
+ condition = condition ? 1 : 0 if [true,false,nil].include?(condition)
917
+ if condition.respond_to?(:to_i) then
918
+ # The hif can be evaluate straight away. Do metaprograming.
919
+ if condition.to_i != 0 then
920
+ HDLRuby::High.top_user.sub do
921
+ ruby_block.call
922
+ end
923
+ @metacond = :hif
924
+ else
925
+ @metacond = :helse
926
+ end
927
+ return true
928
+ end
929
+ return false
930
+ end
931
+
932
+ # Adds meta programming capability to a elsif statement.
933
+ def metaelsif(condition, &ruby_block)
934
+ @metacond ||= nil
935
+ if @metacond == :helse then
936
+ condition = condition ? 1 : 0 if [true,false,nil].include?(condition)
937
+ # Need to convert the elsif to a if since it is not
938
+ # compatible with metaprogramming.
939
+ return :toif unless condition.respond_to?(:to_i)
940
+ # The hif can be evaluate straight away. Do metaprograming.
941
+ if condition.to_i != 0 then
942
+ HDLRuby::High.top_user.sub do
943
+ ruby_block.call
944
+ end
945
+ @metacond = :hif
946
+ else
947
+ @metacond = :helse
948
+ end
949
+ return true
950
+ elsif @metacond == :hif
951
+ return true
952
+ end
953
+ return false
954
+ end
955
+
956
+ # Adds meta programming capability to a case statement.
957
+ def metacase(value, &ruby_block)
958
+ @metacond = nil
959
+ @metavalue = nil
960
+ value = value ? 1 : 0 if [true,false,nil].include?(value)
961
+ if value.respond_to?(:to_i) then
962
+ @metavalue = value.to_i
963
+ return true
964
+ end
965
+ return false
966
+ end
967
+
968
+ # Adds meta programming capability to a when statement.
969
+ def metawhen(match, &ruby_block)
970
+ @metacond ||= nil
971
+ @metavalue ||= nil
972
+ match = match ? 1 : 0 if [true,false,nil].include?(match)
973
+ if match.respond_to?(:to_i) then
974
+ # The hwen can be evaluate straight away. Do metaprograming.
975
+ if @metavalue == match.to_i then
976
+ HDLRuby::High.top_user.sub do
977
+ ruby_block.call
978
+ end
979
+ @metacond = :hwhen
980
+ else
981
+ @metacond = :helse
982
+ end
983
+ return true
984
+ end
985
+ return false
986
+ end
987
+
988
+ # Adds meta programming capability to a else statement.
989
+ def metaelse(&ruby_block)
990
+ @metacond ||= nil
991
+ if @metacond then
992
+ if @metacond == :helse then
993
+ if ruby_block then
994
+ HDLRuby::High.top_user.sub do
995
+ ruby_block.call
996
+ end
997
+ end
998
+ @metacond = nil
999
+ end
1000
+ return true
1001
+ end
1002
+ return false
1003
+ end
1004
+ end
1005
+
904
1006
 
905
1007
  ##
906
1008
  # Describes a scope for a system type
@@ -1220,7 +1322,8 @@ module HDLRuby::High
1220
1322
  end
1221
1323
 
1222
1324
  # Declares a sub scope with possible +name+ and built from +ruby_block+.
1223
- def sub(name = :"", &ruby_block)
1325
+ # def sub(name = :"", &ruby_block)
1326
+ def sub(name = HDLRuby.uniq_name, &ruby_block)
1224
1327
  # Ensure there is a block.
1225
1328
  ruby_block = proc {} unless block_given?
1226
1329
  # Creates the new scope.
@@ -1278,7 +1381,8 @@ module HDLRuby::High
1278
1381
  self.add_behavior(TimeBehavior.new(:seq,&ruby_block))
1279
1382
  end
1280
1383
 
1281
- # Statements automatically enclosed in a behavior.
1384
+ # Handling metaprogramming
1385
+ include HmetaControl
1282
1386
 
1283
1387
  # Creates a new if statement with a +condition+ that when met lead
1284
1388
  # to the execution of the block in +mode+ generated by the +ruby_block+.
@@ -1287,10 +1391,11 @@ module HDLRuby::High
1287
1391
  # * the else part is defined through the helse method.
1288
1392
  # * a behavior is created to enclose the hif.
1289
1393
  def hif(condition, mode = nil, &ruby_block)
1394
+ return if self.metaif(condition,&ruby_block)
1290
1395
  # Ensure there is a block.
1291
1396
  ruby_block = proc {} unless block_given?
1292
1397
  self.par do
1293
- hif(condition,mode,&ruby_block)
1398
+ hif(condition,mode,&ruby_block)
1294
1399
  end
1295
1400
  end
1296
1401
 
@@ -1301,6 +1406,7 @@ module HDLRuby::High
1301
1406
  #
1302
1407
  # NOTE: added to the hif of the last behavior.
1303
1408
  def helse(mode = nil, &ruby_block)
1409
+ return if self.metaelse(&ruby_block)
1304
1410
  # Ensure there is a block.
1305
1411
  ruby_block = proc {} unless block_given?
1306
1412
  # There is a ruby_block: the helse is assumed to be with
@@ -1317,6 +1423,13 @@ module HDLRuby::High
1317
1423
  # with a +condition+ that when met lead
1318
1424
  # to the execution of the block in +mode+ generated by the +ruby_block+.
1319
1425
  def helsif(condition, mode = nil, &ruby_block)
1426
+ meta = self.metaelsif(condition,&ruby_block)
1427
+ if meta == :toif then
1428
+ # Must be converted to hif.
1429
+ return self.hif(condition,mode, &ruby_block)
1430
+ elsif meta then
1431
+ return
1432
+ end
1320
1433
  # Ensure there is a block.
1321
1434
  ruby_block = proc {} unless block_given?
1322
1435
  # There is a ruby_block: the helse is assumed to be with
@@ -1336,6 +1449,7 @@ module HDLRuby::High
1336
1449
  # * the when part is defined through the hwhen method.
1337
1450
  # * a new behavior is created to enclose the hcase.
1338
1451
  def hcase(value)
1452
+ return if self.metacase(value)
1339
1453
  self.par do
1340
1454
  hcase(value)
1341
1455
  end
@@ -1346,6 +1460,7 @@ module HDLRuby::High
1346
1460
  #
1347
1461
  # Can only be used once.
1348
1462
  def hwhen(match, mode = nil, &ruby_block)
1463
+ return if self.metawhen(match,&ruby_block)
1349
1464
  # Ensure there is a block.
1350
1465
  ruby_block = proc {} unless block_given?
1351
1466
  # There is a ruby_block: the helse is assumed to be with
@@ -2270,6 +2385,10 @@ module HDLRuby::High
2270
2385
  res = HDLRuby::High.top_user.instance_exec(*args,
2271
2386
  *other_block, &ruby_block)
2272
2387
  end
2388
+ unless res.respond_to?(:to_expr) then
2389
+ raise AnyError,
2390
+ "The last statement of a function must be an expression: #{res}"
2391
+ end
2273
2392
  res
2274
2393
  end
2275
2394
  else
@@ -2279,6 +2398,10 @@ module HDLRuby::High
2279
2398
  res = HDLRuby::High.top_user.instance_exec(*args,
2280
2399
  *other_block, &ruby_block)
2281
2400
  end
2401
+ unless res.respond_to?(:to_expr) then
2402
+ raise AnyError,
2403
+ "The last statement of a function must be an expression: #{res}"
2404
+ end
2282
2405
  res
2283
2406
  end
2284
2407
  end
@@ -2647,6 +2770,11 @@ module HDLRuby::High
2647
2770
  ##
2648
2771
  # Module giving high-level statement properties
2649
2772
  module HStatement
2773
+
2774
+ # Handling metaprogramming
2775
+ # Also adds the methods of HEnumerable.
2776
+ define_method(:metaif,HmetaControl.instance_method(:metaif))
2777
+
2650
2778
  # Creates a new if statement with a +condition+ enclosing the statement.
2651
2779
  #
2652
2780
  # NOTE: the else part is defined through the helse method.
@@ -2656,6 +2784,8 @@ module HDLRuby::High
2656
2784
  # Remove self from the current block.
2657
2785
  obj = self
2658
2786
  ::HDLRuby::High.cur_block.delete_statement!(obj)
2787
+ # Handles the metaprogramming.
2788
+ return obj if self.metaif(condition,proc { add_statement(obj) })
2659
2789
  # Creates the if statement.
2660
2790
  stmnt = If.new(condition) { add_statement(obj) }
2661
2791
  # Add it to the current block.
@@ -3206,11 +3336,18 @@ module HDLRuby::High
3206
3336
  # If +choices+ has only two entries
3207
3337
  # (and it is not a hash), +value+ will be converted to a boolean.
3208
3338
  def mux(*choices)
3339
+ select = self
3340
+ select = select ? 1 : 0 if [true,false,nil].include?(select)
3341
+ if select.respond_to?(:to_i) then
3342
+ # The mux can be evaluate straight away.
3343
+ # Do metaprograming.
3344
+ return choices[select.to_i]
3345
+ end
3209
3346
  # Process the choices.
3210
3347
  choices = choices.flatten(1) if choices.size == 1
3211
3348
  choices.map! { |choice| choice.to_expr }
3212
3349
  # Generate the select expression.
3213
- return Select.new(choices[0].type,"?",self.to_expr,*choices)
3350
+ return Select.new(choices[0].type,"?",select.to_expr,*choices)
3214
3351
  end
3215
3352
 
3216
3353
 
@@ -3236,11 +3373,17 @@ module HDLRuby::High
3236
3373
  # If +choices+ has only two entries
3237
3374
  # (and it is not a hash), +value+ will be converted to a boolean.
3238
3375
  def mux(*choices)
3376
+ select = self
3377
+ select = select ? 1 : 0 if [true,false,nil].include?(select)
3378
+ if select.respond_to?(:to_i) then
3379
+ # The mux can be evaluate straight away. Do metaprograming.
3380
+ return choices[select.to_i]
3381
+ end
3239
3382
  # Process the choices.
3240
3383
  choices = choices.flatten(1) if choices.size == 1
3241
3384
  choices.map! { |choice| choice.to_expr }
3242
3385
  # Generate the select expression.
3243
- return Select.new(choices[0].type,"?",self.to_expr,*choices)
3386
+ return Select.new(choices[0].type,"?",select.to_expr,*choices)
3244
3387
  end
3245
3388
 
3246
3389
  end
@@ -3461,6 +3604,21 @@ module HDLRuby::High
3461
3604
  return valueL
3462
3605
  end
3463
3606
 
3607
+
3608
+ # Iterate over the elements.
3609
+ #
3610
+ # Returns an enumerator if no ruby block is given.
3611
+ def each(&ruby_block)
3612
+ # No ruby block? Return an enumerator.
3613
+ return to_enum(:each) unless ruby_block
3614
+ # A block? Apply it on each element.
3615
+ self.type.range.heach do |i|
3616
+ yield(self.content[i])
3617
+ end
3618
+ end
3619
+
3620
+ # Reference can be used like enumerator
3621
+ include Enumerable
3464
3622
  end
3465
3623
 
3466
3624
 
@@ -3512,26 +3670,14 @@ module HDLRuby::High
3512
3670
  return Event.new(:anyedge,self.to_ref)
3513
3671
  end
3514
3672
 
3515
- # Iterate over the elements.
3516
- #
3517
- # Returns an enumerator if no ruby block is given.
3518
- def each(&ruby_block)
3519
- # No ruby block? Return an enumerator.
3520
- return to_enum(:each) unless ruby_block
3521
- # A block? Apply it on each element.
3522
- self.type.range.heach do |i|
3523
- yield(self[i])
3524
- end
3525
- end
3526
-
3527
3673
  # Get the refered objects.
3528
3674
  def objects
3529
3675
  return [ self.object] if self.is_a?(RefObject)
3530
3676
  return self.each.map { |ref| ref.objects }.flatten
3531
3677
  end
3532
3678
 
3533
- # Reference can be used like enumerator
3534
- include Enumerable
3679
+ # # Reference can be used like enumerator
3680
+ # include Enumerable
3535
3681
  end
3536
3682
 
3537
3683
 
@@ -3977,12 +4123,22 @@ module HDLRuby::High
3977
4123
  High.top_user.delete_connection!(self)
3978
4124
  end
3979
4125
 
4126
+ # Handling metaprogramming
4127
+ # Also adds the methods of HEnumerable.
4128
+ define_method(:metaif,HmetaControl.instance_method(:metaif))
4129
+
3980
4130
  # Creates a new behavior with an if statement from +condition+
3981
4131
  # enclosing the connection converted to a transmission, and replace the
3982
4132
  # former by the new behavior.
3983
4133
  #
3984
4134
  # NOTE: the else part is defined through the helse method.
3985
4135
  def hif(condition)
4136
+ # Handles the metaprogramming.
4137
+ if self.metaif(condition,proc { left <= right }) then
4138
+ High.top_user.delete_connection!(self)
4139
+ return
4140
+ end
4141
+
3986
4142
  # Creates the behavior.
3987
4143
  left, right = self.left, self.right
3988
4144
  # Detached left and right from their connection since they will
@@ -4291,6 +4447,10 @@ module HDLRuby::High
4291
4447
  # built from +ruby_block+.
4292
4448
  def par(name = :"", &ruby_block)
4293
4449
  return :par unless ruby_block
4450
+ unless name.is_a?(::Symbol) or name.is_a?(::String) then
4451
+ raise AnyError,
4452
+ "Events can only be used at top level seq blocks."
4453
+ end
4294
4454
  self.add_block(:par,name,&ruby_block)
4295
4455
  end
4296
4456
 
@@ -4298,12 +4458,17 @@ module HDLRuby::High
4298
4458
  # built from +ruby_block+.
4299
4459
  def seq(name = :"", &ruby_block)
4300
4460
  return :seq unless ruby_block
4461
+ unless name.is_a?(::Symbol) or name.is_a?(::String) then
4462
+ raise AnyError,
4463
+ "Events can only be used at top level seq blocks."
4464
+ end
4301
4465
  self.add_block(:seq,name,&ruby_block)
4302
4466
  end
4303
4467
 
4304
4468
  # Creates a new block with the current mode with possible +name+ and
4305
4469
  # built from +ruby_block+.
4306
- def sub(name = :"", &ruby_block)
4470
+ # def sub(name = :"", &ruby_block)
4471
+ def sub(name = HDLRuby.uniq_name, &ruby_block)
4307
4472
  # Ensure there is a block.
4308
4473
  ruby_block = proc {} unless block_given?
4309
4474
  self.add_block(self.mode,name,&ruby_block)
@@ -4351,6 +4516,11 @@ module HDLRuby::High
4351
4516
  # Need to be able to declare select operators
4352
4517
  include Hmux
4353
4518
 
4519
+ # Also adds the methods of HEnumerable.
4520
+ HmetaControl.instance_methods.each do |meth|
4521
+ define_method(meth,HmetaControl.instance_method(meth))
4522
+ end
4523
+
4354
4524
  # Creates a new if statement with a +condition+ that when met lead
4355
4525
  # to the execution of the block in +mode+ generated by the
4356
4526
  # +ruby_block+.
@@ -4358,6 +4528,7 @@ module HDLRuby::High
4358
4528
  # NOTE: the else part is defined through the helse method.
4359
4529
  # def hif(condition, mode = nil, &ruby_block)
4360
4530
  def hif(condition, mode = self.mode, &ruby_block)
4531
+ return if self.metaif(condition,&ruby_block)
4361
4532
  # Ensure there is a block.
4362
4533
  ruby_block = proc {} unless block_given?
4363
4534
  # Creates the if statement.
@@ -4369,6 +4540,7 @@ module HDLRuby::High
4369
4540
  #
4370
4541
  # Can only be used once.
4371
4542
  def helse(mode = nil, &ruby_block)
4543
+ return if self.metaelse(&ruby_block)
4372
4544
  # Ensure there is a block.
4373
4545
  ruby_block = proc {} unless block_given?
4374
4546
  # There is a ruby_block: the helse is assumed to be with
@@ -4385,6 +4557,13 @@ module HDLRuby::High
4385
4557
  # with a +condition+ that when met lead
4386
4558
  # to the execution of the block in +mode+ generated by the +ruby_block+.
4387
4559
  def helsif(condition, mode = nil, &ruby_block)
4560
+ meta = self.metaelsif(condition,&ruby_block)
4561
+ if meta == :toif then
4562
+ # Must be converted to hif.
4563
+ return self.hif(condition,mode, &ruby_block)
4564
+ elsif meta then
4565
+ return
4566
+ end
4388
4567
  # Ensure there is a block.
4389
4568
  ruby_block = proc {} unless block_given?
4390
4569
  # There is a ruby_block: the helse is assumed to be with
@@ -4405,6 +4584,7 @@ module HDLRuby::High
4405
4584
  #
4406
4585
  # NOTE: the when part is defined through the hwhen method.
4407
4586
  def hcase(value)
4587
+ return if self.metacase(value)
4408
4588
  # Creates the case statement.
4409
4589
  self.add_statement(Case.new(value))
4410
4590
  end
@@ -4414,6 +4594,7 @@ module HDLRuby::High
4414
4594
  #
4415
4595
  # Can only be used once.
4416
4596
  def hwhen(match, mode = nil, &ruby_block)
4597
+ return if self.metawhen(match,&ruby_block)
4417
4598
  # Ensure there is a block.
4418
4599
  ruby_block = proc {} unless block_given?
4419
4600
  # There is a ruby_block: the helse is assumed to be with
@@ -5245,22 +5426,22 @@ module HDLRuby::High
5245
5426
  # self.to_expr <= expr
5246
5427
  # end
5247
5428
 
5248
- # Array construction shortcuts
5429
+ # # Array construction shortcuts
5249
5430
 
5250
- # Create an array whose number of elements is given by the content
5251
- # of the current array, filled by +obj+ objects.
5252
- # If +obj+ is nil, +ruby_block+ is used instead for filling the array.
5253
- def call(obj = nil, &ruby_block)
5254
- unless self.size == 1 then
5255
- raise AnyError, "Invalid array for call opertor."
5256
- end
5257
- number = self[0].to_i
5258
- if obj then
5259
- return Array.new(number,obj)
5260
- else
5261
- return Array.new(number,&ruby_block)
5262
- end
5263
- end
5431
+ # # Create an array whose number of elements is given by the content
5432
+ # # of the current array, filled by +obj+ objects.
5433
+ # # If +obj+ is nil, +ruby_block+ is used instead for filling the array.
5434
+ # def call(obj = nil, &ruby_block)
5435
+ # unless self.size == 1 then
5436
+ # raise AnyError, "Invalid array for call opertor."
5437
+ # end
5438
+ # number = self[0].to_i
5439
+ # if obj then
5440
+ # return Array.new(number,obj)
5441
+ # else
5442
+ # return Array.new(number,&ruby_block)
5443
+ # end
5444
+ # end
5264
5445
 
5265
5446
  # Create an array of instances of system +name+, using +args+ as
5266
5447
  # arguments.
@@ -943,7 +943,7 @@ module HDLRuby::High
943
943
 
944
944
  # Generate the C description of the cast.
945
945
  def to_rcsim
946
- # puts "Cast to width=#{self.type.width} and child=#{self.child}"
946
+ # puts "Cast to width=#{self.type.width} and child=#{self.child} and child.to_rcsim=#{child.to_rcsim}"
947
947
  # Shall we reverse when casting?
948
948
  if self.type.direction != self.child.type.direction then
949
949
  # Yes, reverse the direction of the child.