HDLRuby 3.7.2 → 3.7.4

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.
@@ -15,6 +15,8 @@ module RubyHDL::High
15
15
  ########################################################################
16
16
 
17
17
 
18
+
19
+
18
20
  @@absoluteCounter = -1 # The absolute name counter.
19
21
 
20
22
  @@uniq_names = Set.new(Symbol.all_symbols.map {|sym| sym.to_s})
@@ -52,6 +54,42 @@ module RubyHDL::High
52
54
  nil
53
55
  end
54
56
 
57
+ # Generate input signals with type +type+ and names from +names+ list.
58
+ def make_inputs(type,*names)
59
+ # puts "make_inputs with names=#{names.join(",")}"
60
+ type = type.to_type
61
+ last_sig = nil
62
+ names.each do |name|
63
+ name = name.to_sym
64
+ # Create and add the signal.
65
+ sig = SignalI.new(name,type,:input)
66
+ @signals << sig
67
+ # Register it.
68
+ # self.register(name) { puts("sig=",sig.inspect); sig }
69
+ self.register(name) { sig }
70
+ last_sig = sig
71
+ end
72
+ return last_sig
73
+ end
74
+
75
+ # Generate output signals with type +type+ and names from +names+ list.
76
+ def make_outputs(type,*names)
77
+ # puts "make_outputs with names=#{names.join(",")}"
78
+ type = type.to_type
79
+ last_sig = nil
80
+ names.each do |name|
81
+ name = name.to_sym
82
+ # Create and add the signal.
83
+ sig = SignalI.new(name,type,:output)
84
+ @signals << sig
85
+ # Register it.
86
+ # self.register(name) { puts("sig=",sig.inspect); sig }
87
+ self.register(name) { sig }
88
+ last_sig = sig
89
+ end
90
+ return last_sig
91
+ end
92
+
55
93
  # Generate inner signals with type +type+ and names from +names+ list.
56
94
  def make_inners(type,*names)
57
95
  # puts "make_inners with names=#{names.join(",")}"
@@ -60,7 +98,7 @@ module RubyHDL::High
60
98
  names.each do |name|
61
99
  name = name.to_sym
62
100
  # Create and add the signal.
63
- sig = SignalI.new(type,name)
101
+ sig = SignalI.new(name,type,:inner)
64
102
  @signals << sig
65
103
  # Register it.
66
104
  # self.register(name) { puts("sig=",sig.inspect); sig }
@@ -73,12 +111,12 @@ module RubyHDL::High
73
111
  # Register a new object named +name+ generated by +ruby_block+.
74
112
  def register(name,&ruby_block)
75
113
  # Add a way to call it from the stack of SW blocks.
76
- ::Object.define_method(name) do
77
- RubyHDL::High.call_sblock(name)
114
+ ::Object.define_method(name) do |*args|
115
+ RubyHDL::High.call_sblock(name,*args)
78
116
  end
79
117
  # Add a method for accessing the object.
80
118
  # self.define_singleton_method(name,&ruby_block)
81
- res = ruby_block.call
119
+ # res = ruby_block.call
82
120
  @callables[name] = ruby_block
83
121
  end
84
122
 
@@ -183,12 +221,12 @@ module RubyHDL::High
183
221
  :"&" => "(%{l})&(%{r})", :"|" => "(%{l})|(%{r})",
184
222
  :"^" => "(%{l})^(%{r})",
185
223
  :"<<" => "(%{l})<<(%{r})", :">>" => "(%{l})>>(%{r})",
186
- :"==" => "(%{l}) & %{m}==(%{r}) & %{m}",
187
- :"!=" => "(%{l}) & %{m}!=(%{r}) %{m}",
188
- :"<" => "(%{l}) & %{m}%{s} < (%{r}) & %{m}%{s}",
189
- :">" => "(%{l}) & %{m}%{s} > (%{r}) & %{m}%{s}",
190
- :"<=" => "(%{l}) & %{m}%{s} <=(%{r}) & %{m}%{s}",
191
- :">=" => "(%{l}) & %{m}%{s} >=(%{r}) & %{m}%{s}"
224
+ :"==" => "((%{l}) & %{m}==(%{r}) & %{m}) ? 1:0",
225
+ :"!=" => "((%{l}) & %{m}!=(%{r}) %{m}) ? 1:0",
226
+ :"<" => "((%{l}) & %{m}%{s} < (%{r}) & %{m}%{s}) ? 1:0",
227
+ :">" => "((%{l}) & %{m}%{s} > (%{r}) & %{m}%{s}) ? 1:0",
228
+ :"<=" => "((%{l}) & %{m}%{s} <=(%{r}) & %{m}%{s}) ? 1:0",
229
+ :">=" => "((%{l}) & %{m}%{s} >=(%{r}) & %{m}%{s}) ? 1:0"
192
230
  }
193
231
 
194
232
  # The translation of operators into C code.
@@ -618,7 +656,23 @@ module RubyHDL::High
618
656
  return TypeVector.new(:"",base,self[0])
619
657
  end
620
658
 
621
- # Generate signals from +names+.
659
+ # Generate input signals from +names+.
660
+ def input(*names)
661
+ # Generate the type.
662
+ type = self.to_type
663
+ # Generate the resulting signals.
664
+ return type.input(*names)
665
+ end
666
+
667
+ # Generate output signals from +names+.
668
+ def output(*names)
669
+ # Generate the type.
670
+ type = self.to_type
671
+ # Generate the resulting signals.
672
+ return type.output(*names)
673
+ end
674
+
675
+ # Generate inner signals from +names+.
622
676
  def inner(*names)
623
677
  # Generate the type.
624
678
  type = self.to_type
@@ -639,6 +693,8 @@ module RubyHDL::High
639
693
  using RubyHDL::High
640
694
  include HDLRuby::Tprocess
641
695
 
696
+ attr_reader :name
697
+
642
698
  # Type creation.
643
699
 
644
700
  # Creates a new type named +name+.
@@ -707,13 +763,13 @@ module RubyHDL::High
707
763
  # Gets the type max value if any.
708
764
  # Default: not defined.
709
765
  def max
710
- raise AnyError, "No max value for type #{self}"
766
+ raise "No max value for type #{self} (#{self.name})"
711
767
  end
712
768
 
713
769
  # Gets the type min value if any.
714
770
  # Default: not defined.
715
771
  def min
716
- raise AnyError, "No min value for type #{self}"
772
+ raise "No min value for type #{self} (#{self.name})"
717
773
  end
718
774
 
719
775
  # Get the direction of the type, little or big endian.
@@ -729,7 +785,7 @@ module RubyHDL::High
729
785
 
730
786
  # Gets the range of the type, by default range is not defined.
731
787
  def range
732
- raise AnyError, "No range for type #{self}"
788
+ raise "No range for type #{self} (#{self.name})"
733
789
  end
734
790
 
735
791
  # Tells if the type has a base.
@@ -739,7 +795,7 @@ module RubyHDL::High
739
795
 
740
796
  # Gets the base type, by default base type is not defined.
741
797
  def base
742
- raise AnyError, "No base type for type #{self}"
798
+ raise "No base type for type #{self} (#{self.name})"
743
799
  end
744
800
 
745
801
  # Tells if the type has sub types.
@@ -802,12 +858,12 @@ module RubyHDL::High
802
858
  # NOTE: can only be done if the name is not already set.
803
859
  def name=(name)
804
860
  unless @name.empty? then
805
- raise AnyError, "Name of type already set to: #{@name}."
861
+ raise "Name of type already set to: #{@name}."
806
862
  end
807
863
  # Checks and sets the name.
808
864
  name = name.to_sym
809
865
  if name.empty? then
810
- raise AnyError, "Cannot set an empty name."
866
+ raise "Cannot set an empty name."
811
867
  end
812
868
  @name = name
813
869
  # Registers the name.
@@ -857,17 +913,17 @@ module RubyHDL::High
857
913
 
858
914
  # SignalI creation through the type.
859
915
 
860
- # # Declares high-level input signals named +names+ of the current type.
861
- # def input(*names)
862
- # High.top_sblock.make_inputs(self,*names)
863
- # end
916
+ # Declares high-level input signals named +names+ of the current type.
917
+ def input(*names)
918
+ RubyHDL::High.top_sblock.make_inputs(self,*names)
919
+ end
864
920
 
865
- # # Declares high-level untyped output signals named +names+ of the
866
- # # current type.
867
- # def output(*names)
868
- # # High.top_user.make_outputs(self.instantiate,*names)
869
- # High.top_sblock.make_outputs(self,*names)
870
- # end
921
+ # Declares high-level untyped output signals named +names+ of the
922
+ # current type.
923
+ def output(*names)
924
+ # High.top_user.make_outputs(self.instantiate,*names)
925
+ RubyHDL::High.top_sblock.make_outputs(self,*names)
926
+ end
871
927
 
872
928
  # # Declares high-level untyped inout signals named +names+ of the
873
929
  # # current type.
@@ -1076,7 +1132,7 @@ module RubyHDL::High
1076
1132
  # Ensures a type has been produced.
1077
1133
  gtype = gtype.to_type if gtype.respond_to?(:to_type)
1078
1134
  unless gtype.is_a?(Type) then
1079
- raise AnyError, "Generic type #{self.name} did not produce a valid type: #{gtype.class}"
1135
+ raise "Generic type #{self.name} did not produce a valid type: #{gtype.class}"
1080
1136
  end
1081
1137
  # Create a new type definition from it.
1082
1138
  gtype = TypeDef.new(self.name.to_s + "_#{args.join(':')}",
@@ -1121,8 +1177,7 @@ module RubyHDL::High
1121
1177
 
1122
1178
  # Check and set the base
1123
1179
  unless base.is_a?(Type)
1124
- raise AnyError,
1125
- "Invalid class for VectorType base: #{base.class}."
1180
+ raise "Invalid class for VectorType base: #{base.class}."
1126
1181
  end
1127
1182
  @base = base
1128
1183
 
@@ -1335,13 +1390,13 @@ module RubyHDL::High
1335
1390
  # Set the direction.
1336
1391
  @direction = direction.to_sym
1337
1392
  unless [:little, :big].include?(@direction)
1338
- raise AnyError, "Invalid direction for a type: #{direction}"
1393
+ raise "Invalid direction for a type: #{direction}"
1339
1394
  end
1340
1395
 
1341
1396
  # Check and set the content.
1342
1397
  content.each do |sub|
1343
1398
  unless sub.is_a?(Type) then
1344
- raise AnyError, "Invalid class for a type: #{sub.class}"
1399
+ raise "Invalid class for a type: #{sub.class}"
1345
1400
  end
1346
1401
  end
1347
1402
  @types = content
@@ -1385,8 +1440,7 @@ module RubyHDL::High
1385
1440
  # Adds a sub +type+.
1386
1441
  def add_type(type)
1387
1442
  unless type.is_a?(Type) then
1388
- raise AnyError,
1389
- "Invalid class for a type: #{type.class} (#{type})"
1443
+ raise "Invalid class for a type: #{type.class} (#{type})"
1390
1444
  end
1391
1445
  @types << type
1392
1446
  end
@@ -1454,7 +1508,7 @@ module RubyHDL::High
1454
1508
  # Regular tuple, return its range as if it was an array.
1455
1509
  return 0..@types.size-1
1456
1510
  else
1457
- raise AnyError, "No range for type #{self}"
1511
+ raise "No range for type #{self}"
1458
1512
  end
1459
1513
  end
1460
1514
 
@@ -1475,7 +1529,7 @@ module RubyHDL::High
1475
1529
  # Regular tuple, return the type of its first element.
1476
1530
  return @types[0]
1477
1531
  else
1478
- raise AnyError, "No base type for type #{self}"
1532
+ raise "No base type for type #{self}"
1479
1533
  end
1480
1534
  end
1481
1535
 
@@ -1503,14 +1557,14 @@ module RubyHDL::High
1503
1557
  # Set the direction.
1504
1558
  @direction = dir.to_sym
1505
1559
  unless [:little, :big].include?(@direction)
1506
- raise AnyError, "Invalid direction for a type: #{dir}"
1560
+ raise "Invalid direction for a type: #{dir}"
1507
1561
  end
1508
1562
 
1509
1563
  # Check and set the content.
1510
1564
  content = Hash[content]
1511
1565
  @types = content.map do |k,v|
1512
1566
  unless v.is_a?(Type) then
1513
- raise AnyError, "Invalid class for a type: #{v.class}"
1567
+ raise "Invalid class for a type: #{v.class}"
1514
1568
  end
1515
1569
  [ k.to_sym, v ]
1516
1570
  end.to_h
@@ -1889,6 +1943,7 @@ module RubyHDL::High
1889
1943
  @right = right.to_expr
1890
1944
  # Compute the mask for fixing the bit width.
1891
1945
  @mask = (2 ** @type.width)-1
1946
+ # puts "@type=#{@type} name=#{@type.name} @type.width=#{@type.width} @mask=#{@mask}"
1892
1947
  # Compute xor mask for handling the sign.
1893
1948
  # Make it as a string so that no addition computation is required
1894
1949
  # if no sign is required.
@@ -1923,7 +1978,7 @@ module RubyHDL::High
1923
1978
 
1924
1979
  # Convert to Ruby code.
1925
1980
  def to_ruby
1926
- return "case(#{@sel.to_}) ; " +
1981
+ return "case(#{@sel.to_ruby}) ; " +
1927
1982
  @choices.map.with_index do |choice,i|
1928
1983
  "when #{i} ; #{choice.to_ruby} ; "
1929
1984
  end.join + "end"
@@ -2115,10 +2170,27 @@ module RubyHDL::High
2115
2170
  end
2116
2171
  end
2117
2172
 
2118
-
2173
+
2174
+ # Describes a SW implementation of a statement.
2175
+ class Statement
2176
+
2177
+ # Iterate on the statements.
2178
+ def each_statement(&ruby_block)
2179
+ return to_enum(:each_statement) unless ruby_block
2180
+ # By default nothing to do.
2181
+ end
2182
+
2183
+ # Iterate deeply on the statements.
2184
+ def each_statement_deep(&ruby_block)
2185
+ return to_enum(:each_statement_deep) unless ruby_block
2186
+ # Just apply ruby_block on self.
2187
+ ruby_block.call(self)
2188
+ end
2189
+ end
2190
+
2119
2191
 
2120
2192
  # Describes a SW implementation of a transmit statement.
2121
- class Transmit
2193
+ class Transmit < Statement
2122
2194
  using RubyHDL::High
2123
2195
 
2124
2196
  attr_reader :left, :right
@@ -2185,12 +2257,11 @@ module RubyHDL::High
2185
2257
  else
2186
2258
  return "#{@left.to_c} = #{@right.to_c};"
2187
2259
  end
2188
- end
2189
-
2260
+ end
2190
2261
  end
2191
2262
 
2192
2263
  # Describes a SW implementation of a if statement.
2193
- class Sif
2264
+ class Sif < Statement
2194
2265
  # Create a new if statement in sequencer +sequencer+
2195
2266
  # with +cond+ condition and +ruby_block+
2196
2267
  # for generating the block that is taken if the condition is met.
@@ -2212,9 +2283,33 @@ module RubyHDL::High
2212
2283
  @else_blk = Sblock.new(@sequencer,&ruby_block)
2213
2284
  end
2214
2285
 
2286
+ # Iterate on the statements.
2287
+ def each_statement(&ruby_block)
2288
+ return to_enum(:each_statement) unless ruby_block
2289
+ # Apply ruby_block on the yes block.
2290
+ ruby_block.call(@yes_blk)
2291
+ # On the elsifs.
2292
+ @elsifs.each { |cond,statement| ruby_block.call(statement) }
2293
+ # On the else if any.
2294
+ ruby_block.call(@else_blk) if @else_blk
2295
+ end
2296
+
2297
+ # Iterate deeply on the statements.
2298
+ def each_statement_deep(&ruby_block)
2299
+ return to_enum(:each_statement_deep) unless ruby_block
2300
+ # Recurse on the yes block.
2301
+ @yes_blk.each_statement_deep
2302
+ # On the elsifs.
2303
+ @elsifs.each { |cond,statement| statement.each_statement_deep }
2304
+ # On the else if any.
2305
+ @else_blk.each_statement_deep if @else_blk
2306
+ # And apply ruby_block on self.
2307
+ ruby_block.call(self)
2308
+ end
2309
+
2215
2310
  # Convert to Ruby code.
2216
2311
  def to_ruby
2217
- res = @sequencer.clk_up + "\nif(#{@condition.to_ruby})\n#{@yes_blk.to_ruby}\n"
2312
+ res = @sequencer.clk_up + "\nif(#{@condition.to_ruby} != 0)\n#{@yes_blk.to_ruby}\n"
2218
2313
  @elsifs.each do |(cond,blk)|
2219
2314
  res << "elsif(#{cond.to_ruby})\n#{blk.to_ruby}\n"
2220
2315
  end
@@ -2238,7 +2333,7 @@ module RubyHDL::High
2238
2333
  end
2239
2334
 
2240
2335
  # Describes a SW implementation of a loop statement.
2241
- class Sloop
2336
+ class Sloop < Statement
2242
2337
  # Create a new infinite loop statement in sequencer +sequencer+
2243
2338
  # with +ruby_block+ for generating the block that is taken.
2244
2339
  def initialize(sequencer, &ruby_block)
@@ -2246,6 +2341,22 @@ module RubyHDL::High
2246
2341
  @blk = Sblock.new(sequencer,&ruby_block)
2247
2342
  end
2248
2343
 
2344
+ # Iterate on the statements.
2345
+ def each_statement(&ruby_block)
2346
+ return to_enum(:each_statement) unless ruby_block
2347
+ # Apply ruby_block on the block.
2348
+ ruby_block.call(@blk)
2349
+ end
2350
+
2351
+ # Iterate deeply on the statements.
2352
+ def each_statement_deep(&ruby_block)
2353
+ return to_enum(:each_statement_deep) unless ruby_block
2354
+ # Recurse on the block.
2355
+ @blk.each_statement_deep
2356
+ # And apply ruby_block on self.
2357
+ ruby_block.call(self)
2358
+ end
2359
+
2249
2360
  # Convert to Ruby code.
2250
2361
  def to_ruby
2251
2362
  return "loop do\n#{@blk.to_ruby}\n#{@sequencer.clk_up}\nend"
@@ -2258,7 +2369,7 @@ module RubyHDL::High
2258
2369
  end
2259
2370
 
2260
2371
  # Describes a SW implementation of a while statement.
2261
- class Swhile
2372
+ class Swhile < Statement
2262
2373
  # Create a new while statement in sequencer +sequencer+
2263
2374
  # with +cond+ condition and +ruby_block+
2264
2375
  # for generating the block that is taken while the condition is met.
@@ -2268,6 +2379,22 @@ module RubyHDL::High
2268
2379
  @yes_blk = Sblock.new(sequencer,&ruby_block)
2269
2380
  end
2270
2381
 
2382
+ # Iterate on the statements.
2383
+ def each_statement(&ruby_block)
2384
+ return to_enum(:each_statement) unless ruby_block
2385
+ # Apply ruby_block on the block.
2386
+ ruby_block.call(@yes_blk)
2387
+ end
2388
+
2389
+ # Iterate deeply on the statements.
2390
+ def each_statement_deep(&ruby_block)
2391
+ return to_enum(:each_statement_deep) unless ruby_block
2392
+ # Recurse on the yes block.
2393
+ @yes_blk.each_statement_deep
2394
+ # And apply ruby_block on self.
2395
+ ruby_block.call(self)
2396
+ end
2397
+
2271
2398
  # Convert to Ruby code.
2272
2399
  def to_ruby
2273
2400
  return @sequencer.clk_up +
@@ -2281,7 +2408,7 @@ module RubyHDL::High
2281
2408
  end
2282
2409
 
2283
2410
  # Describes a SW implementation of a step statement.
2284
- class Step
2411
+ class Step < Statement
2285
2412
  # Create a new step statement in sequencer +sequencer+.
2286
2413
  def initialize(sequencer)
2287
2414
  @sequencer = sequencer
@@ -2299,7 +2426,7 @@ module RubyHDL::High
2299
2426
  end
2300
2427
 
2301
2428
  # Describes a SW implementation of a break statement.
2302
- class Sbreak
2429
+ class Sbreak < Statement
2303
2430
  # Create a new break statement in sequencer +sequencer+.
2304
2431
  def initialize(sequencer)
2305
2432
  @sequencer = sequencer
@@ -2317,7 +2444,7 @@ module RubyHDL::High
2317
2444
  end
2318
2445
 
2319
2446
  # Describes a SW implementation of a continue statement.
2320
- class Scontinue
2447
+ class Scontinue < Statement
2321
2448
  # Create a new break statement in sequencer +sequencer+.
2322
2449
  def initialize
2323
2450
  @sequencer = sequencer
@@ -2334,10 +2461,32 @@ module RubyHDL::High
2334
2461
  end
2335
2462
  end
2336
2463
 
2464
+ # Describes a SW implementation of a return statement.
2465
+ class Sreturn < Statement
2466
+ attr_reader :value
2467
+
2468
+ # Create a new break statement in sequencer +sequencer+
2469
+ # returning value +val+.
2470
+ def initialize(sequencer,val)
2471
+ @sequencer = sequencer
2472
+ @value = val
2473
+ end
2474
+
2475
+ # Convert to Ruby code.
2476
+ def to_ruby
2477
+ return @sequencer.clk_up + "\nreturn #{@value.to_ruby}"
2478
+ end
2479
+
2480
+ # Convert to Ruby code.
2481
+ def to_c
2482
+ return @sequencer.clk_up_c + "\nreturn #{val.to_c};"
2483
+ end
2484
+ end
2485
+
2337
2486
  # Describes a SW implementation of a terminate statement.
2338
- class Sterminate
2487
+ class Sterminate < Statement
2339
2488
  # Create a new break statement in sequencer +sequencer+.
2340
- def initialize
2489
+ def initialize(sequencer)
2341
2490
  @sequencer = sequencer
2342
2491
  end
2343
2492
 
@@ -2355,13 +2504,25 @@ module RubyHDL::High
2355
2504
  end
2356
2505
 
2357
2506
  # Describes a SW synchronization of a signal.
2358
- class Sync
2359
- def initialize
2507
+ class Sync < Statement
2508
+ def initialize(sequencer)
2509
+ @sequencer = sequencer
2360
2510
  end
2361
2511
 
2362
2512
  # Convert to Ruby code.
2363
2513
  def to_ruby
2364
- return "Fiber.yield"
2514
+ # Update the inputs and outputs.
2515
+ res = ""
2516
+ RubyHDL::High.global_sblock.each_signal do |signal|
2517
+ case signal.dir
2518
+ when :input
2519
+ res << signal.to_ruby + " = RubyHDL.#{signal.name}\n"
2520
+ when :output
2521
+ res << "RubyHDL.#{signal.name} = " + signal.to_ruby + "\n"
2522
+ end
2523
+ end
2524
+ res << "Fiber.yield"
2525
+ return res
2365
2526
  end
2366
2527
 
2367
2528
  # Convert to C code.
@@ -2397,6 +2558,19 @@ module RubyHDL::High
2397
2558
  return self
2398
2559
  end
2399
2560
 
2561
+ # Iterate on the statements.
2562
+ def each_statement(&ruby_block)
2563
+ return to_enum(:each_statement) unless ruby_block
2564
+ # By default nothing to do.
2565
+ end
2566
+
2567
+ # Iterate deeply on the statements.
2568
+ def each_statement_deep(&ruby_block)
2569
+ return to_enum(:each_statement_deep) unless ruby_block
2570
+ # Just apply ruby_block on self.
2571
+ ruby_block.call(self)
2572
+ end
2573
+
2400
2574
  # Execute a ruby code block for +ruby_block+.
2401
2575
  def self.call(id)
2402
2576
  # puts "id=#{id}"
@@ -2421,27 +2595,39 @@ module RubyHDL::High
2421
2595
 
2422
2596
 
2423
2597
  # Describes a SW implementation of an call statement.
2424
- class Scall
2598
+ class Scall < Expression
2425
2599
  using RubyHDL::High
2426
2600
 
2427
- # Create a new call statement in sequencer +sequencer+ for function
2428
- # named +name+ with arguments +args+.
2429
- def initialize(sequencer, name, *args)
2601
+ # Create a new call to function named +func+ statement in
2602
+ # sequencer +sequencer+ with arguments +args+.
2603
+ def initialize(func, sequencer, *args)
2604
+ super(func.type)
2430
2605
  @sequencer = sequencer
2431
- @name = name.to_sym
2606
+ @name = func.name
2432
2607
  @args = args
2433
2608
  end
2434
2609
 
2610
+ # Iterate on the statements.
2611
+ def each_statement(&ruby_block)
2612
+ return to_enum(:each_statement) unless ruby_block
2613
+ # By default nothing to do.
2614
+ end
2615
+
2616
+ # Iterate deeply on the statements.
2617
+ def each_statement_deep(&ruby_block)
2618
+ return to_enum(:each_statement_deep) unless ruby_block
2619
+ # Just apply ruby_block on self.
2620
+ ruby_block.call(self)
2621
+ end
2622
+
2435
2623
  # Convert to Ruby code.
2436
2624
  def to_ruby
2437
- return @sequencer.clk_up + "\n#{name}(" +
2438
- @args.map {|arg| arg.to_ruby}.join(",") + ")"
2625
+ return "__#{@name}(" + @args.map {|arg| arg.to_ruby}.join(",") + ")"
2439
2626
  end
2440
2627
 
2441
2628
  # Convert to C code.
2442
2629
  def to_c
2443
- return @sequencer.clk_up + "\n#{name}(" +
2444
- @args.map {|arg| arg.to_ruby}.join(",") + ");"
2630
+ return "\n__#{name}(" + @args.map {|arg| arg.to_ruby}.join(",") + ");"
2445
2631
  end
2446
2632
 
2447
2633
  # Create an iterator for a given method +meth+.
@@ -2778,7 +2964,7 @@ module RubyHDL::High
2778
2964
 
2779
2965
 
2780
2966
  # Describes a SW implementation of an iterator statement.
2781
- class Siter
2967
+ class Siter < Statement
2782
2968
  using RubyHDL::High
2783
2969
 
2784
2970
  # Create a new iteration statement in sequencer +sequencer+
@@ -2801,12 +2987,31 @@ module RubyHDL::High
2801
2987
  end
2802
2988
  alias_method :each, :each_command
2803
2989
 
2990
+ # Iterate on the statements.
2991
+ def each_statement(&ruby_block)
2992
+ return to_enum(:each_statement) unless ruby_block
2993
+ # Apply ruby_block on the block.
2994
+ @blk.each_statement(&ruby_block)
2995
+ end
2996
+
2997
+ # Iterate deeply on the statements.
2998
+ def each_statement_deep(&ruby_block)
2999
+ return to_enum(:each_statement_deep) unless ruby_block
3000
+ # Recurse on the yes block.
3001
+ @blk.each_statement_deep
3002
+ # And apply ruby_block on self.
3003
+ ruby_block.call(self)
3004
+ end
3005
+
2804
3006
  # Convert to Ruby code.
2805
3007
  def to_ruby
2806
3008
  # puts "to_ruby with blk=#{@blk} commands=#{@commands}"
2807
3009
  res = @sequencer.clk_up + "\n" +
2808
3010
  @commands.map { |command| command.to_ruby }.join(".")
2809
- return res + " do\n#{@blk.to_ruby}\n#{@sequencer.clk_up}\nend"
3011
+ return res + " do" +
3012
+ (@blk.each_arg.any? ?
3013
+ "|#{@blk.each_arg.map(&:to_ruby).join(",")}|" : "") +
3014
+ "\n#{@blk.to_ruby}\n#{@sequencer.clk_up}\nend"
2810
3015
  end
2811
3016
 
2812
3017
  # Convert to C code.
@@ -3158,14 +3363,26 @@ module RubyHDL::High
3158
3363
  # Describes a SW implementation of a signal.
3159
3364
  class SignalI < Expression
3160
3365
  using RubyHDL::High
3161
- attr_reader :type, :name #, :content
3366
+ attr_reader :name, :type, :dir
3162
3367
  # Create a new signal with type +type+ and name +name+.
3163
- def initialize(type,name)
3164
- @type = type.to_type
3368
+ def initialize(name,type,dir)
3165
3369
  @name = name.to_sym
3370
+ @type = type.to_type
3371
+ @dir = dir.to_sym
3166
3372
  # Compute the mask for adjusting the value to the type.
3167
3373
  @mask = (2 ** @type.width)-1
3168
3374
  @sign = 2 ** (@type.width-1)
3375
+ @global = "" # The global indicator: empty or '$'
3376
+ end
3377
+
3378
+ # Tell if the signal is global or not.
3379
+ def global?
3380
+ return @global == "$"
3381
+ end
3382
+
3383
+ # Set the signal to be a global.
3384
+ def global!
3385
+ @global = "$"
3169
3386
  end
3170
3387
 
3171
3388
  # Tell if the signal is an array.
@@ -3175,7 +3392,7 @@ module RubyHDL::High
3175
3392
 
3176
3393
  # Convert to Ruby code.
3177
3394
  def to_ruby
3178
- return "__" + self.name.to_s
3395
+ return @global + "__" + self.name.to_s
3179
3396
  end
3180
3397
 
3181
3398
  # Convert to C code.
@@ -3183,7 +3400,11 @@ module RubyHDL::High
3183
3400
 
3184
3401
  # Check if a value is defined for the signal.
3185
3402
  def value?
3186
- return TOPLEVEL_BINDING.local_variable_defined?(self.to_ruby)
3403
+ if global? then
3404
+ return global_variables.include?(self.to_ruby)
3405
+ else
3406
+ return TOPLEVEL_BINDING.local_variable_defined?(self.to_ruby)
3407
+ end
3187
3408
  end
3188
3409
 
3189
3410
  # Gets the value of the signal.
@@ -3236,7 +3457,6 @@ module RubyHDL::High
3236
3457
  end
3237
3458
  end
3238
3459
 
3239
-
3240
3460
  # Describes a SW implementation of a block.
3241
3461
  class Sblock < SblockTop
3242
3462
  using RubyHDL::High
@@ -3254,9 +3474,11 @@ module RubyHDL::High
3254
3474
  # Push the new sblock on top of the stack.
3255
3475
  RubyHDL::High.push_sblock(self)
3256
3476
  # Make signals from the arguments of the ruby block.
3477
+ # unsigned 32-bit integers by default.
3257
3478
  @args = []
3258
3479
  ruby_block.parameters.each do |typ,arg|
3259
- @args << SignalI.new(Void,arg)
3480
+ # @args << SignalI.new(arg,Void,:inner)
3481
+ @args << SignalI.new(arg,bit[32],:inner)
3260
3482
  end
3261
3483
  # Fill it.
3262
3484
  self.instance_exec(*@args,&ruby_block)
@@ -3277,6 +3499,21 @@ module RubyHDL::High
3277
3499
  end
3278
3500
  alias_method :<<, :add
3279
3501
 
3502
+ # Iterate on the statements.
3503
+ def each_statement(&ruby_block)
3504
+ return to_enum(:each_statement) unless ruby_block
3505
+ @statements.each { |statement| ruby_block(statement) }
3506
+ end
3507
+
3508
+ # Iterate deeply on the statements.
3509
+ def each_statement_deep(&ruby_block)
3510
+ return to_enum(:each_statement_deep) unless ruby_block
3511
+ @statements.each do |statement|
3512
+ statement.each_statement_deep(&ruby_block)
3513
+ ruby_block(statement)
3514
+ end
3515
+ end
3516
+
3280
3517
  # Delete a statement.
3281
3518
  def delete(statement)
3282
3519
  @statements.delete(statement)
@@ -3292,14 +3529,20 @@ module RubyHDL::High
3292
3529
  return @statements[-1]
3293
3530
  end
3294
3531
 
3532
+ # Iterate on the arguments if any.
3533
+ def each_arg(&ruby_block)
3534
+ return to_enum(:each_arg) unless ruby_block
3535
+ @args.each(&ruby_block)
3536
+ end
3295
3537
 
3296
3538
  # Convert to Ruby code.
3297
3539
  def to_ruby
3298
3540
  res = ""
3299
- # Generate the arguments if any.
3300
- if @args.any? then
3301
- res = "|#{@args.map(&:to_ruby).join(",")}|\n"
3302
- end
3541
+ # The arguments are ignored, as they are handled in SfunctionT.
3542
+ # # Generate the arguments if any.
3543
+ # if @args.any? then
3544
+ # res = "|#{@args.map(&:to_ruby).join(",")}|\n"
3545
+ # end
3303
3546
  # Generate the statements.
3304
3547
  res += @statements.map do |stmnt|
3305
3548
  stmnt.to_ruby + "\n"
@@ -3343,6 +3586,11 @@ module RubyHDL::High
3343
3586
  self << RubyHDL::High::Scontinue.new(@sequencer)
3344
3587
  end
3345
3588
 
3589
+ # Create a return statement.
3590
+ def sreturn(val)
3591
+ self << RubyHDL::High::Sreturn.new(@sequencer,val)
3592
+ end
3593
+
3346
3594
  # Terminates the sequencer.
3347
3595
  def sterminate
3348
3596
  self << RubyHDL::High::Sterminate.new(@sequencer)
@@ -3390,13 +3638,26 @@ module RubyHDL::High
3390
3638
  self << expr.seach.with_index(&ruby_block)
3391
3639
  end
3392
3640
 
3641
+ # Implements a multiplexer.
3642
+ def mux(cond, *choices)
3643
+ return Select.new(choices[0].type,:mux,cond,*choices)
3644
+ end
3645
+
3646
+ # Displays a string for debugging purpose.
3647
+ def hprint(*args)
3648
+ args.each do |arg|
3649
+ arg = arg.to_value if arg.is_a?(RubyHDL::High::Expression)
3650
+ print arg
3651
+ end
3652
+ end
3653
+
3393
3654
  # The SW-specific statements and expressions.
3394
3655
 
3395
3656
  # Mark a synchronisation.
3396
3657
  # For software only: stop the current sequencer for allowing
3397
3658
  # sharing of variables with other ones.
3398
3659
  def sync
3399
- self << RubyHDL::High::Sync.new
3660
+ self << RubyHDL::High::Sync.new(@sequencer)
3400
3661
  end
3401
3662
 
3402
3663
  # Some arbirary Ruby code as a string +str+ or as a proc
@@ -3415,23 +3676,36 @@ module RubyHDL::High
3415
3676
  # Describes a SW implementation of a sequencer function.
3416
3677
  class SfunctionT
3417
3678
  using RubyHDL::High
3418
- attr_reader :name
3679
+ attr_reader :name, :type
3419
3680
  # Create a new named +name+ with arguments +args+ and
3420
3681
  # executing the content of block +sblock+
3421
- def initialize(type,name,sblock,*args)
3682
+ def initialize(name,sblock,*args)
3422
3683
  @name = name.to_sym
3423
3684
  @args = args
3424
3685
  @blk = sblock
3686
+ @type = self.make_return_type(@blk)
3687
+ end
3688
+
3689
+ # Compute the return type from current sblock +sblock+
3690
+ def make_return_type(sblock)
3691
+ # Locate a return statement.
3692
+ sblock.each_statement_deep do |statement|
3693
+ if statement.is_a?(RubyHDL::High::Sreturn) then
3694
+ return statement.value.type
3695
+ end
3696
+ end
3697
+ # No return, so void type.
3698
+ return RubyHDL::High::Void
3425
3699
  end
3426
3700
 
3427
3701
  # Convert to Ruby code.
3428
3702
  def to_ruby
3429
- return "def #{name}(#{@args.map {|arg| arg.to_ruby}.join(",")}\n#{@blk.to_ruby}\nend\n"
3703
+ return "def __#{name}(#{@args.map {|arg| "__" + arg.to_ruby}.join(",")})\n#{@blk.sequencer.clk_up}\n#{@blk.to_ruby}\nend\n"
3430
3704
  end
3431
3705
 
3432
3706
  # Convert to C code.
3433
3707
  def to_c
3434
- return "unsigned long long #{name}(#{@args.map {|arg| "unsigned long long " + arg.to_c}.join(",")} {\n#{@blk.to_c}\n}\n"
3708
+ return "unsigned long long __#{name}(#{@args.map {|arg| "unsigned long long " + arg.to_c}.join(",")} {\n#{@blk.sequencer.clk_up_c}\n#{@blk.to_c}\n}\n"
3435
3709
  end
3436
3710
  end
3437
3711
 
@@ -3464,7 +3738,7 @@ module RubyHDL::High
3464
3738
  # Create a set of sfunction used in the sequencer.
3465
3739
  @sfunctions = {}
3466
3740
  # Create the main block.
3467
- @sblock = RubyHDL::High::Sblock.new(self,&ruby_block)
3741
+ @blk = RubyHDL::High::Sblock.new(self,&ruby_block)
3468
3742
  # Build the Ruby code.
3469
3743
  @source = ""
3470
3744
  @code = nil
@@ -3491,11 +3765,20 @@ module RubyHDL::High
3491
3765
  this = self
3492
3766
  @source = <<-BUILD
3493
3767
  #{RubyHDL::High.global_sblock.each_signal.map do |signal|
3494
- signal.to_ruby + " ||= " +
3495
- (signal.array? ? "[]" : signal.value? ? signal.value.inspect : "nil")
3768
+ # puts "for signal=#{signal.name} with type=#{signal.type}"
3769
+ case signal.dir
3770
+ when :input
3771
+ signal.to_ruby + " = RubyHDL.#{signal.name}"
3772
+ else
3773
+ signal.to_ruby + " ||= " +
3774
+ (signal.array? ? "[]" : signal.value? ? signal.value.inspect : "0")
3775
+ end
3496
3776
  end.join("\n")}
3777
+
3778
+ #{@sfunctions.map {|n,f| f.to_ruby }.join("\n\n")}
3779
+
3497
3780
  Fiber.new do
3498
- #{@sblock.to_ruby}
3781
+ #{@blk.to_ruby}
3499
3782
  end
3500
3783
  BUILD
3501
3784
  # puts "building code_txt=" + @source
@@ -3569,10 +3852,22 @@ BUILDC
3569
3852
  # Create a new sequencer block, with clock counter +clk+ and
3570
3853
  # run control +start+
3571
3854
  def sequencer(clk = nil, start = nil, &ruby_block)
3855
+ # Ensure the clock is global.
3856
+ clk.global! if clk
3572
3857
  return SequencerT.new(clk,start,&ruby_block)
3573
3858
  end
3574
3859
 
3575
- # Create a 1-bit signal.
3860
+ # Create a 1-bit input signal.
3861
+ def input(*names)
3862
+ return [1].input(*names)
3863
+ end
3864
+
3865
+ # Create a 1-bit output signal.
3866
+ def output(*names)
3867
+ return [1].output(*names)
3868
+ end
3869
+
3870
+ # Create a 1-bit inner signal.
3576
3871
  def inner(*names)
3577
3872
  return [1].inner(*names)
3578
3873
  end
@@ -3581,31 +3876,36 @@ BUILDC
3581
3876
  def sdef(name,&ruby_block)
3582
3877
  name = name.to_sym
3583
3878
  # Get the arguments of the ruby_block.
3584
- args = ruby_block.parameters.map {|typ,name| name.to_s }
3585
- # Register the call to the function.
3586
- RubyHDL::High.register(name.to_sym) do |args|
3587
- cur_seq = Ruby::HDL::High.top_sblock.sequencer
3588
- unless cur_seq.sfunction?(name) then
3589
- # Need to create a new sfunction.
3590
- # Push a new empty sblock for building the function.
3591
- RubyHDL::High.push_sblock(SblockTop.new)
3592
- args.each do |arg|
3593
- RubyHDL::High.top_sblock.make_inners(Void,arg.to_sym)
3594
- end
3879
+ block_args = ruby_block.parameters.map {|typ,name| name.to_s }
3880
+ # Create function.
3881
+ cur_sblock = RubyHDL::High.top_sblock
3882
+ # Register the call.
3883
+ cur_sblock.register(name.to_sym) do |*args|
3884
+ # Create the function.
3885
+ # Get the current sequencer.
3886
+ cur_seq = RubyHDL::High.top_sblock.sequencer
3887
+ # Get the function from the sequencer if any.
3888
+ function = cur_seq.sfunction(name)
3889
+ unless function then
3890
+ # There were no function for the sequencer, create it.
3595
3891
  # Execute the ruby block in a sequencer environment for building
3596
3892
  # the sblock.
3597
3893
  sblock = Sblock.new(cur_seq,&ruby_block)
3598
- RubyHDL::High.pop_sblock
3894
+ # Create the arguments.
3895
+ block_args.each_with_index do |block_arg,i|
3896
+ # puts "args[#{i}]=(#{args[i].name},#{args[i].type})"
3897
+ sblock.make_inners(args[i].type,block_arg.to_sym)
3898
+ end
3599
3899
  # Create the function.
3600
- function = SfunctionT.new(name,args,sblock)
3601
- # Add it to the sequencer.
3602
- cur_seq.add_sfunction(name)
3900
+ function = SfunctionT.new(name,sblock,*block_args)
3901
+ # Add it to the current sequencer.
3902
+ cur_seq.add_sfunction(name,function)
3603
3903
  end
3604
- Scall.new(cur_seq,name,args)
3904
+ # And create the call
3905
+ Scall.new(function,cur_seq,*args)
3605
3906
  end
3606
3907
  end
3607
3908
 
3608
-
3609
3909
  end
3610
3910
 
3611
3911