HDLRuby 3.7.1 → 3.7.3

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,15 +54,51 @@ 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
- puts "make_inners with names=#{names.join(",")}"
95
+ # puts "make_inners with names=#{names.join(",")}"
58
96
  type = type.to_type
59
97
  last_sig = nil
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
 
@@ -151,22 +189,44 @@ module RubyHDL::High
151
189
  # end
152
190
 
153
191
 
192
+ # RUBY_OPERATOR = {
193
+ # # Unary operators.
194
+ # :"-@" => "-(%s)", :"+@" => "+(%s)", :"~" => "~(%s)",
195
+ # :abs => "(%s).abs",
196
+ # :boolean => "%s", :bit => "%s",
197
+ # :signed => "%s", :unsigned => "(%s) & 0xFFFFFFFFFFFFFFFF",
198
+
199
+ # # Binary operators.
200
+ # :"+" => "(%s)+(%s)", :"-" => "(%s)-(%s)", :"*" => "(%s)*(%s)",
201
+ # :"/" => "(%s)/(%s)", :"%" => "(%s)%%(%s)", :"**" => "(%s)**(%s)",
202
+ # :"&" => "(%s)&(%s)", :"|" => "(%s)|(%s)", :"^" => "(%s)^(%s)",
203
+ # :"<<" => "(%s)<<(%s)", :">>" => "(%s)>>(%s)",
204
+ # :"==" => "(%s)==(%s)", :"!=" => "(%s)!=(%s)",
205
+ # :"<" => "(%s)<(%s)", :">" => "(%s)>(%s)",
206
+ # :"<=" => "(%s)<=(%s)",:">=" => "(%s)>=(%s)"
207
+ # }
208
+
154
209
  # The translation of operators into Ruby code.
155
210
  RUBY_OPERATOR = {
156
211
  # Unary operators.
157
- :"-@" => "-(%s)", :"+@" => "+(%s)", :"~" => "~(%s)",
158
- :abs => "(%s).abs",
159
- :boolean => "%s", :bit => "%s",
160
- :signed => "%s", :unsigned => "(%s) & 0xFFFFFFFFFFFFFFFF",
212
+ :"-@" => "-(%{l})", :"+@" => "+(%{l})", :"~" => "~(%{l})",
213
+ :abs => "(%{l}).abs",
214
+ :boolean => "%{l}", :bit => "%{l}",
215
+ :signed => "%{l}", :unsigned => "(%{l}) & 0xFFFFFFFFFFFFFFFF",
161
216
 
162
217
  # Binary operators.
163
- :"+" => "(%s)+(%s)", :"-" => "(%s)-(%s)", :"*" => "(%s)*(%s)",
164
- :"/" => "(%s)/(%s)", :"%" => "(%s)%%(%s)", :"**" => "(%s)**(%s)",
165
- :"&" => "(%s)&(%s)", :"|" => "(%s)|(%s)", :"^" => "(%s)^(%s)",
166
- :"<<" => "(%s)<<(%s)", :">>" => "(%s)>>(%s)",
167
- :"==" => "(%s)==(%s)", :"!=" => "(%s)!=(%s)",
168
- :"<" => "(%s)<(%s)", :">" => "(%s)>(%s)",
169
- :"<=" => "(%s)<=(%s)",:">=" => "(%s)>=(%s)"
218
+ :"+" => "(%{l})+(%{r})", :"-" => "(%{l})-(%{r})",
219
+ :"*" => "(%{l})*(%{r})", :"/" => "(%{l})/(%{r})",
220
+ :"%" => "(%{l})%%(%{r})", :"**" => "(%{l})**(%{r})",
221
+ :"&" => "(%{l})&(%{r})", :"|" => "(%{l})|(%{r})",
222
+ :"^" => "(%{l})^(%{r})",
223
+ :"<<" => "(%{l})<<(%{r})", :">>" => "(%{l})>>(%{r})",
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"
170
230
  }
171
231
 
172
232
  # The translation of operators into C code.
@@ -596,7 +656,23 @@ module RubyHDL::High
596
656
  return TypeVector.new(:"",base,self[0])
597
657
  end
598
658
 
599
- # 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+.
600
676
  def inner(*names)
601
677
  # Generate the type.
602
678
  type = self.to_type
@@ -617,6 +693,8 @@ module RubyHDL::High
617
693
  using RubyHDL::High
618
694
  include HDLRuby::Tprocess
619
695
 
696
+ attr_reader :name
697
+
620
698
  # Type creation.
621
699
 
622
700
  # Creates a new type named +name+.
@@ -685,13 +763,13 @@ module RubyHDL::High
685
763
  # Gets the type max value if any.
686
764
  # Default: not defined.
687
765
  def max
688
- raise AnyError, "No max value for type #{self}"
766
+ raise "No max value for type #{self} (#{self.name})"
689
767
  end
690
768
 
691
769
  # Gets the type min value if any.
692
770
  # Default: not defined.
693
771
  def min
694
- raise AnyError, "No min value for type #{self}"
772
+ raise "No min value for type #{self} (#{self.name})"
695
773
  end
696
774
 
697
775
  # Get the direction of the type, little or big endian.
@@ -707,7 +785,7 @@ module RubyHDL::High
707
785
 
708
786
  # Gets the range of the type, by default range is not defined.
709
787
  def range
710
- raise AnyError, "No range for type #{self}"
788
+ raise "No range for type #{self} (#{self.name})"
711
789
  end
712
790
 
713
791
  # Tells if the type has a base.
@@ -717,7 +795,7 @@ module RubyHDL::High
717
795
 
718
796
  # Gets the base type, by default base type is not defined.
719
797
  def base
720
- raise AnyError, "No base type for type #{self}"
798
+ raise "No base type for type #{self} (#{self.name})"
721
799
  end
722
800
 
723
801
  # Tells if the type has sub types.
@@ -780,12 +858,12 @@ module RubyHDL::High
780
858
  # NOTE: can only be done if the name is not already set.
781
859
  def name=(name)
782
860
  unless @name.empty? then
783
- raise AnyError, "Name of type already set to: #{@name}."
861
+ raise "Name of type already set to: #{@name}."
784
862
  end
785
863
  # Checks and sets the name.
786
864
  name = name.to_sym
787
865
  if name.empty? then
788
- raise AnyError, "Cannot set an empty name."
866
+ raise "Cannot set an empty name."
789
867
  end
790
868
  @name = name
791
869
  # Registers the name.
@@ -835,17 +913,17 @@ module RubyHDL::High
835
913
 
836
914
  # SignalI creation through the type.
837
915
 
838
- # # Declares high-level input signals named +names+ of the current type.
839
- # def input(*names)
840
- # High.top_sblock.make_inputs(self,*names)
841
- # 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
842
920
 
843
- # # Declares high-level untyped output signals named +names+ of the
844
- # # current type.
845
- # def output(*names)
846
- # # High.top_user.make_outputs(self.instantiate,*names)
847
- # High.top_sblock.make_outputs(self,*names)
848
- # 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
849
927
 
850
928
  # # Declares high-level untyped inout signals named +names+ of the
851
929
  # # current type.
@@ -985,12 +1063,30 @@ module RubyHDL::High
985
1063
 
986
1064
  # The signed bit type.
987
1065
  Signed = define_type(:signed)
1066
+ class << Signed
1067
+ # Tells if the type signed.
1068
+ def signed?
1069
+ return true
1070
+ end
1071
+ end
988
1072
 
989
1073
  # The unsigned bit type.
990
1074
  Unsigned = define_type(:unsigned)
1075
+ class << Unsigned
1076
+ # Tells if the type unsigned.
1077
+ def unsigned?
1078
+ return true
1079
+ end
1080
+ end
991
1081
 
992
1082
  # The float bit type
993
1083
  Float = define_type(:float)
1084
+ class << Float
1085
+ # Tells if the type signed.
1086
+ def signed?
1087
+ return true
1088
+ end
1089
+ end
994
1090
 
995
1091
  # The string type
996
1092
  StringT = define_type(:string)
@@ -1036,7 +1132,7 @@ module RubyHDL::High
1036
1132
  # Ensures a type has been produced.
1037
1133
  gtype = gtype.to_type if gtype.respond_to?(:to_type)
1038
1134
  unless gtype.is_a?(Type) then
1039
- 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}"
1040
1136
  end
1041
1137
  # Create a new type definition from it.
1042
1138
  gtype = TypeDef.new(self.name.to_s + "_#{args.join(':')}",
@@ -1081,8 +1177,7 @@ module RubyHDL::High
1081
1177
 
1082
1178
  # Check and set the base
1083
1179
  unless base.is_a?(Type)
1084
- raise AnyError,
1085
- "Invalid class for VectorType base: #{base.class}."
1180
+ raise "Invalid class for VectorType base: #{base.class}."
1086
1181
  end
1087
1182
  @base = base
1088
1183
 
@@ -1295,13 +1390,13 @@ module RubyHDL::High
1295
1390
  # Set the direction.
1296
1391
  @direction = direction.to_sym
1297
1392
  unless [:little, :big].include?(@direction)
1298
- raise AnyError, "Invalid direction for a type: #{direction}"
1393
+ raise "Invalid direction for a type: #{direction}"
1299
1394
  end
1300
1395
 
1301
1396
  # Check and set the content.
1302
1397
  content.each do |sub|
1303
1398
  unless sub.is_a?(Type) then
1304
- raise AnyError, "Invalid class for a type: #{sub.class}"
1399
+ raise "Invalid class for a type: #{sub.class}"
1305
1400
  end
1306
1401
  end
1307
1402
  @types = content
@@ -1345,8 +1440,7 @@ module RubyHDL::High
1345
1440
  # Adds a sub +type+.
1346
1441
  def add_type(type)
1347
1442
  unless type.is_a?(Type) then
1348
- raise AnyError,
1349
- "Invalid class for a type: #{type.class} (#{type})"
1443
+ raise "Invalid class for a type: #{type.class} (#{type})"
1350
1444
  end
1351
1445
  @types << type
1352
1446
  end
@@ -1414,7 +1508,7 @@ module RubyHDL::High
1414
1508
  # Regular tuple, return its range as if it was an array.
1415
1509
  return 0..@types.size-1
1416
1510
  else
1417
- raise AnyError, "No range for type #{self}"
1511
+ raise "No range for type #{self}"
1418
1512
  end
1419
1513
  end
1420
1514
 
@@ -1435,7 +1529,7 @@ module RubyHDL::High
1435
1529
  # Regular tuple, return the type of its first element.
1436
1530
  return @types[0]
1437
1531
  else
1438
- raise AnyError, "No base type for type #{self}"
1532
+ raise "No base type for type #{self}"
1439
1533
  end
1440
1534
  end
1441
1535
 
@@ -1463,14 +1557,14 @@ module RubyHDL::High
1463
1557
  # Set the direction.
1464
1558
  @direction = dir.to_sym
1465
1559
  unless [:little, :big].include?(@direction)
1466
- raise AnyError, "Invalid direction for a type: #{dir}"
1560
+ raise "Invalid direction for a type: #{dir}"
1467
1561
  end
1468
1562
 
1469
1563
  # Check and set the content.
1470
1564
  content = Hash[content]
1471
1565
  @types = content.map do |k,v|
1472
1566
  unless v.is_a?(Type) then
1473
- raise AnyError, "Invalid class for a type: #{v.class}"
1567
+ raise "Invalid class for a type: #{v.class}"
1474
1568
  end
1475
1569
  [ k.to_sym, v ]
1476
1570
  end.to_h
@@ -1823,11 +1917,13 @@ module RubyHDL::High
1823
1917
  super(type)
1824
1918
  @operator = operator.to_sym
1825
1919
  @child = child.to_expr
1920
+ @mask = (2 ** @type.width)-1
1826
1921
  end
1827
1922
 
1828
1923
  # Convert to Ruby code.
1829
1924
  def to_ruby
1830
- return RUBY_OPERATOR[@operator] % @child.to_ruby
1925
+ # return RUBY_OPERATOR[@operator] % @child.to_ruby
1926
+ return RUBY_OPERATOR[@operator] % { l: @child.to_ruby }
1831
1927
  end
1832
1928
 
1833
1929
  # Convert to C code.
@@ -1845,11 +1941,23 @@ module RubyHDL::High
1845
1941
  @operator = operator.to_sym
1846
1942
  @left = left.to_expr
1847
1943
  @right = right.to_expr
1944
+ # Compute the mask for fixing the bit width.
1945
+ @mask = (2 ** @type.width)-1
1946
+ # puts "@type=#{@type} name=#{@type.name} @type.width=#{@type.width} @mask=#{@mask}"
1947
+ # Compute xor mask for handling the sign.
1948
+ # Make it as a string so that no addition computation is required
1949
+ # if no sign is required.
1950
+ @sign_fix = ""
1951
+ if type.signed? then
1952
+ @sign_fix = " ^ #{2**(@type.width-1)}"
1953
+ end
1848
1954
  end
1849
1955
 
1850
1956
  # Convert to Ruby code.
1851
1957
  def to_ruby
1852
- return RUBY_OPERATOR[@operator] % [ @left.to_ruby, @right.to_ruby ]
1958
+ # return RUBY_OPERATOR[@operator] % [ @left.to_ruby, @right.to_ruby ]
1959
+ return RUBY_OPERATOR[@operator] %
1960
+ { l: @left.to_ruby, r: @right.to_ruby, m: @mask, s: @sign_fix }
1853
1961
  end
1854
1962
 
1855
1963
  # Convert to C code.
@@ -2062,10 +2170,27 @@ module RubyHDL::High
2062
2170
  end
2063
2171
  end
2064
2172
 
2065
-
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
+
2066
2191
 
2067
2192
  # Describes a SW implementation of a transmit statement.
2068
- class Transmit
2193
+ class Transmit < Statement
2069
2194
  using RubyHDL::High
2070
2195
 
2071
2196
  attr_reader :left, :right
@@ -2132,12 +2257,11 @@ module RubyHDL::High
2132
2257
  else
2133
2258
  return "#{@left.to_c} = #{@right.to_c};"
2134
2259
  end
2135
- end
2136
-
2260
+ end
2137
2261
  end
2138
2262
 
2139
2263
  # Describes a SW implementation of a if statement.
2140
- class Sif
2264
+ class Sif < Statement
2141
2265
  # Create a new if statement in sequencer +sequencer+
2142
2266
  # with +cond+ condition and +ruby_block+
2143
2267
  # for generating the block that is taken if the condition is met.
@@ -2159,9 +2283,33 @@ module RubyHDL::High
2159
2283
  @else_blk = Sblock.new(@sequencer,&ruby_block)
2160
2284
  end
2161
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
+
2162
2310
  # Convert to Ruby code.
2163
2311
  def to_ruby
2164
- 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"
2165
2313
  @elsifs.each do |(cond,blk)|
2166
2314
  res << "elsif(#{cond.to_ruby})\n#{blk.to_ruby}\n"
2167
2315
  end
@@ -2185,7 +2333,7 @@ module RubyHDL::High
2185
2333
  end
2186
2334
 
2187
2335
  # Describes a SW implementation of a loop statement.
2188
- class Sloop
2336
+ class Sloop < Statement
2189
2337
  # Create a new infinite loop statement in sequencer +sequencer+
2190
2338
  # with +ruby_block+ for generating the block that is taken.
2191
2339
  def initialize(sequencer, &ruby_block)
@@ -2193,6 +2341,22 @@ module RubyHDL::High
2193
2341
  @blk = Sblock.new(sequencer,&ruby_block)
2194
2342
  end
2195
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
+
2196
2360
  # Convert to Ruby code.
2197
2361
  def to_ruby
2198
2362
  return "loop do\n#{@blk.to_ruby}\n#{@sequencer.clk_up}\nend"
@@ -2205,7 +2369,7 @@ module RubyHDL::High
2205
2369
  end
2206
2370
 
2207
2371
  # Describes a SW implementation of a while statement.
2208
- class Swhile
2372
+ class Swhile < Statement
2209
2373
  # Create a new while statement in sequencer +sequencer+
2210
2374
  # with +cond+ condition and +ruby_block+
2211
2375
  # for generating the block that is taken while the condition is met.
@@ -2215,6 +2379,22 @@ module RubyHDL::High
2215
2379
  @yes_blk = Sblock.new(sequencer,&ruby_block)
2216
2380
  end
2217
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
+
2218
2398
  # Convert to Ruby code.
2219
2399
  def to_ruby
2220
2400
  return @sequencer.clk_up +
@@ -2228,7 +2408,7 @@ module RubyHDL::High
2228
2408
  end
2229
2409
 
2230
2410
  # Describes a SW implementation of a step statement.
2231
- class Step
2411
+ class Step < Statement
2232
2412
  # Create a new step statement in sequencer +sequencer+.
2233
2413
  def initialize(sequencer)
2234
2414
  @sequencer = sequencer
@@ -2246,7 +2426,7 @@ module RubyHDL::High
2246
2426
  end
2247
2427
 
2248
2428
  # Describes a SW implementation of a break statement.
2249
- class Sbreak
2429
+ class Sbreak < Statement
2250
2430
  # Create a new break statement in sequencer +sequencer+.
2251
2431
  def initialize(sequencer)
2252
2432
  @sequencer = sequencer
@@ -2264,7 +2444,7 @@ module RubyHDL::High
2264
2444
  end
2265
2445
 
2266
2446
  # Describes a SW implementation of a continue statement.
2267
- class Scontinue
2447
+ class Scontinue < Statement
2268
2448
  # Create a new break statement in sequencer +sequencer+.
2269
2449
  def initialize
2270
2450
  @sequencer = sequencer
@@ -2281,10 +2461,32 @@ module RubyHDL::High
2281
2461
  end
2282
2462
  end
2283
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
+
2284
2486
  # Describes a SW implementation of a terminate statement.
2285
- class Sterminate
2487
+ class Sterminate < Statement
2286
2488
  # Create a new break statement in sequencer +sequencer+.
2287
- def initialize
2489
+ def initialize(sequencer)
2288
2490
  @sequencer = sequencer
2289
2491
  end
2290
2492
 
@@ -2302,13 +2504,25 @@ module RubyHDL::High
2302
2504
  end
2303
2505
 
2304
2506
  # Describes a SW synchronization of a signal.
2305
- class Sync
2306
- def initialize
2507
+ class Sync < Statement
2508
+ def initialize(sequencer)
2509
+ @sequencer = sequencer
2307
2510
  end
2308
2511
 
2309
2512
  # Convert to Ruby code.
2310
2513
  def to_ruby
2311
- 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
2312
2526
  end
2313
2527
 
2314
2528
  # Convert to C code.
@@ -2344,6 +2558,19 @@ module RubyHDL::High
2344
2558
  return self
2345
2559
  end
2346
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
+
2347
2574
  # Execute a ruby code block for +ruby_block+.
2348
2575
  def self.call(id)
2349
2576
  # puts "id=#{id}"
@@ -2368,27 +2595,39 @@ module RubyHDL::High
2368
2595
 
2369
2596
 
2370
2597
  # Describes a SW implementation of an call statement.
2371
- class Scall
2598
+ class Scall < Expression
2372
2599
  using RubyHDL::High
2373
2600
 
2374
- # Create a new call statement in sequencer +sequencer+ for function
2375
- # named +name+ with arguments +args+.
2376
- 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)
2377
2605
  @sequencer = sequencer
2378
- @name = name.to_sym
2606
+ @name = func.name
2379
2607
  @args = args
2380
2608
  end
2381
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
+
2382
2623
  # Convert to Ruby code.
2383
2624
  def to_ruby
2384
- return @sequencer.clk_up + "\n#{name}(" +
2385
- @args.map {|arg| arg.to_ruby}.join(",") + ")"
2625
+ return "__#{@name}(" + @args.map {|arg| arg.to_ruby}.join(",") + ")"
2386
2626
  end
2387
2627
 
2388
2628
  # Convert to C code.
2389
2629
  def to_c
2390
- return @sequencer.clk_up + "\n#{name}(" +
2391
- @args.map {|arg| arg.to_ruby}.join(",") + ");"
2630
+ return "\n__#{name}(" + @args.map {|arg| arg.to_ruby}.join(",") + ");"
2392
2631
  end
2393
2632
 
2394
2633
  # Create an iterator for a given method +meth+.
@@ -2725,7 +2964,7 @@ module RubyHDL::High
2725
2964
 
2726
2965
 
2727
2966
  # Describes a SW implementation of an iterator statement.
2728
- class Siter
2967
+ class Siter < Statement
2729
2968
  using RubyHDL::High
2730
2969
 
2731
2970
  # Create a new iteration statement in sequencer +sequencer+
@@ -2748,12 +2987,31 @@ module RubyHDL::High
2748
2987
  end
2749
2988
  alias_method :each, :each_command
2750
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
+
2751
3006
  # Convert to Ruby code.
2752
3007
  def to_ruby
2753
3008
  # puts "to_ruby with blk=#{@blk} commands=#{@commands}"
2754
3009
  res = @sequencer.clk_up + "\n" +
2755
3010
  @commands.map { |command| command.to_ruby }.join(".")
2756
- 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"
2757
3015
  end
2758
3016
 
2759
3017
  # Convert to C code.
@@ -3105,11 +3363,26 @@ module RubyHDL::High
3105
3363
  # Describes a SW implementation of a signal.
3106
3364
  class SignalI < Expression
3107
3365
  using RubyHDL::High
3108
- attr_reader :type, :name #, :content
3366
+ attr_reader :name, :type, :dir
3109
3367
  # Create a new signal with type +type+ and name +name+.
3110
- def initialize(type,name)
3111
- @type = type.to_type
3368
+ def initialize(name,type,dir)
3112
3369
  @name = name.to_sym
3370
+ @type = type.to_type
3371
+ @dir = dir.to_sym
3372
+ # Compute the mask for adjusting the value to the type.
3373
+ @mask = (2 ** @type.width)-1
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 = "$"
3113
3386
  end
3114
3387
 
3115
3388
  # Tell if the signal is an array.
@@ -3119,7 +3392,7 @@ module RubyHDL::High
3119
3392
 
3120
3393
  # Convert to Ruby code.
3121
3394
  def to_ruby
3122
- return "__" + self.name.to_s
3395
+ return @global + "__" + self.name.to_s
3123
3396
  end
3124
3397
 
3125
3398
  # Convert to C code.
@@ -3127,12 +3400,40 @@ module RubyHDL::High
3127
3400
 
3128
3401
  # Check if a value is defined for the signal.
3129
3402
  def value?
3130
- 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
3131
3408
  end
3132
3409
 
3133
3410
  # Gets the value of the signal.
3134
3411
  def value
3135
- return TOPLEVEL_BINDING.eval(self.to_ruby)
3412
+ # return TOPLEVEL_BINDING.eval(self.to_ruby)
3413
+ res = TOPLEVEL_BINDING.eval(self.to_ruby)
3414
+ if res.is_a?(Integer) then
3415
+ res = res & @mask
3416
+ if @type.signed? then
3417
+ if res & @sign != 0 then
3418
+ return res - (@mask+1)
3419
+ end
3420
+ end
3421
+ end
3422
+ return res
3423
+ end
3424
+
3425
+ # Generate a Ruby/C string code for accessing the value of the
3426
+ # signal with proper bit width and sign.
3427
+ def value_text
3428
+ unless self.array? then
3429
+ if @type.signed? then
3430
+ return "(#{self.to_ruby} & #{@sign} != 0 ? #{self.to_ruby} & #{@mask} - #{@mask+1} : #{self.to_ruby} & #{@mask})"
3431
+ else
3432
+ return "(#{self.to_ruby} & #{@mask})"
3433
+ end
3434
+ else
3435
+ return self.to_ruby
3436
+ end
3136
3437
  end
3137
3438
 
3138
3439
  # Sets the value of the signal.
@@ -3156,7 +3457,6 @@ module RubyHDL::High
3156
3457
  end
3157
3458
  end
3158
3459
 
3159
-
3160
3460
  # Describes a SW implementation of a block.
3161
3461
  class Sblock < SblockTop
3162
3462
  using RubyHDL::High
@@ -3174,9 +3474,11 @@ module RubyHDL::High
3174
3474
  # Push the new sblock on top of the stack.
3175
3475
  RubyHDL::High.push_sblock(self)
3176
3476
  # Make signals from the arguments of the ruby block.
3477
+ # unsigned 32-bit integers by default.
3177
3478
  @args = []
3178
3479
  ruby_block.parameters.each do |typ,arg|
3179
- @args << SignalI.new(Void,arg)
3480
+ # @args << SignalI.new(arg,Void,:inner)
3481
+ @args << SignalI.new(arg,bit[32],:inner)
3180
3482
  end
3181
3483
  # Fill it.
3182
3484
  self.instance_exec(*@args,&ruby_block)
@@ -3197,6 +3499,21 @@ module RubyHDL::High
3197
3499
  end
3198
3500
  alias_method :<<, :add
3199
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
+
3200
3517
  # Delete a statement.
3201
3518
  def delete(statement)
3202
3519
  @statements.delete(statement)
@@ -3212,14 +3529,20 @@ module RubyHDL::High
3212
3529
  return @statements[-1]
3213
3530
  end
3214
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
3215
3537
 
3216
3538
  # Convert to Ruby code.
3217
3539
  def to_ruby
3218
3540
  res = ""
3219
- # Generate the arguments if any.
3220
- if @args.any? then
3221
- res = "|#{@args.map(&:to_ruby).join(",")}|\n"
3222
- 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
3223
3546
  # Generate the statements.
3224
3547
  res += @statements.map do |stmnt|
3225
3548
  stmnt.to_ruby + "\n"
@@ -3263,6 +3586,11 @@ module RubyHDL::High
3263
3586
  self << RubyHDL::High::Scontinue.new(@sequencer)
3264
3587
  end
3265
3588
 
3589
+ # Create a return statement.
3590
+ def sreturn(val)
3591
+ self << RubyHDL::High::Sreturn.new(@sequencer,val)
3592
+ end
3593
+
3266
3594
  # Terminates the sequencer.
3267
3595
  def sterminate
3268
3596
  self << RubyHDL::High::Sterminate.new(@sequencer)
@@ -3272,16 +3600,19 @@ module RubyHDL::High
3272
3600
  def sif(cond, &ruby_block)
3273
3601
  self << RubyHDL::High::Sif.new(@sequencer,cond,&ruby_block)
3274
3602
  end
3603
+ alias_method :hif, :sif
3275
3604
 
3276
3605
  # Create a sequential elsif statement on +cond+.
3277
3606
  def selsif(cond, &ruby_block)
3278
3607
  self.last_statement.selsif(&ruby_block)
3279
3608
  end
3609
+ alias_method :helsif, :selsif
3280
3610
 
3281
3611
  # Create a sequential else statement.
3282
3612
  def selse(&ruby_block)
3283
3613
  self.last_statement.selse(&ruby_block)
3284
3614
  end
3615
+ alias_method :helse, :selse
3285
3616
 
3286
3617
  # Wait a given condition.
3287
3618
  def swait(cond)
@@ -3313,7 +3644,7 @@ module RubyHDL::High
3313
3644
  # For software only: stop the current sequencer for allowing
3314
3645
  # sharing of variables with other ones.
3315
3646
  def sync
3316
- self << RubyHDL::High::Sync.new
3647
+ self << RubyHDL::High::Sync.new(@sequencer)
3317
3648
  end
3318
3649
 
3319
3650
  # Some arbirary Ruby code as a string +str+ or as a proc
@@ -3321,29 +3652,47 @@ module RubyHDL::High
3321
3652
  def ruby(str = nil, &ruby_block)
3322
3653
  self << RubyHDL::High::Ruby.new(str,&ruby_block)
3323
3654
  end
3655
+
3656
+ # Some arbitrary code whose text is to add direction.
3657
+ def text(str)
3658
+ self << str.to_s
3659
+ end
3324
3660
  end
3325
3661
 
3326
3662
 
3327
3663
  # Describes a SW implementation of a sequencer function.
3328
3664
  class SfunctionT
3329
3665
  using RubyHDL::High
3330
- attr_reader :name
3666
+ attr_reader :name, :type
3331
3667
  # Create a new named +name+ with arguments +args+ and
3332
3668
  # executing the content of block +sblock+
3333
- def initialize(type,name,sblock,*args)
3669
+ def initialize(name,sblock,*args)
3334
3670
  @name = name.to_sym
3335
3671
  @args = args
3336
3672
  @blk = sblock
3673
+ @type = self.make_return_type(@blk)
3674
+ end
3675
+
3676
+ # Compute the return type from current sblock +sblock+
3677
+ def make_return_type(sblock)
3678
+ # Locate a return statement.
3679
+ sblock.each_statement_deep do |statement|
3680
+ if statement.is_a?(RubyHDL::High::Sreturn) then
3681
+ return statement.value.type
3682
+ end
3683
+ end
3684
+ # No return, so void type.
3685
+ return RubyHDL::High::Void
3337
3686
  end
3338
3687
 
3339
3688
  # Convert to Ruby code.
3340
3689
  def to_ruby
3341
- return "def #{name}(#{@args.map {|arg| arg.to_ruby}.join(",")}\n#{@blk.to_ruby}\nend\n"
3690
+ return "def __#{name}(#{@args.map {|arg| "__" + arg.to_ruby}.join(",")})\n#{@blk.sequencer.clk_up}\n#{@blk.to_ruby}\nend\n"
3342
3691
  end
3343
3692
 
3344
3693
  # Convert to C code.
3345
3694
  def to_c
3346
- return "unsigned long long #{name}(#{@args.map {|arg| "unsigned long long " + arg.to_c}.join(",")} {\n#{@blk.to_c}\n}\n"
3695
+ 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"
3347
3696
  end
3348
3697
  end
3349
3698
 
@@ -3376,7 +3725,7 @@ module RubyHDL::High
3376
3725
  # Create a set of sfunction used in the sequencer.
3377
3726
  @sfunctions = {}
3378
3727
  # Create the main block.
3379
- @sblock = RubyHDL::High::Sblock.new(self,&ruby_block)
3728
+ @blk = RubyHDL::High::Sblock.new(self,&ruby_block)
3380
3729
  # Build the Ruby code.
3381
3730
  @source = ""
3382
3731
  @code = nil
@@ -3403,15 +3752,24 @@ module RubyHDL::High
3403
3752
  this = self
3404
3753
  @source = <<-BUILD
3405
3754
  #{RubyHDL::High.global_sblock.each_signal.map do |signal|
3406
- signal.to_ruby + " ||= " +
3407
- (signal.array? ? "[]" : signal.value? ? signal.value.inspect : "nil")
3755
+ # puts "for signal=#{signal.name} with type=#{signal.type}"
3756
+ case signal.dir
3757
+ when :input
3758
+ signal.to_ruby + " = RubyHDL.#{signal.name}"
3759
+ else
3760
+ signal.to_ruby + " ||= " +
3761
+ (signal.array? ? "[]" : signal.value? ? signal.value.inspect : "0")
3762
+ end
3408
3763
  end.join("\n")}
3764
+
3765
+ #{@sfunctions.map {|n,f| f.to_ruby }.join("\n\n")}
3766
+
3409
3767
  Fiber.new do
3410
- #{@sblock.to_ruby}
3768
+ #{@blk.to_ruby}
3411
3769
  end
3412
3770
  BUILD
3413
3771
  # puts "building code_txt=" + @source
3414
- @code = TOPLEVEL_BINDING.eval(@source)
3772
+ self.reset!
3415
3773
  end
3416
3774
 
3417
3775
  # Get the Ruby code.
@@ -3462,6 +3820,11 @@ BUILDC
3462
3820
  end
3463
3821
  alias_method :call, :resume
3464
3822
 
3823
+ # Resets the sequencer.
3824
+ def reset!
3825
+ @code = TOPLEVEL_BINDING.eval(@source)
3826
+ end
3827
+
3465
3828
  # Check is the sequencer can still be resumed.
3466
3829
  def alive?
3467
3830
  @code.alive?
@@ -3476,38 +3839,60 @@ BUILDC
3476
3839
  # Create a new sequencer block, with clock counter +clk+ and
3477
3840
  # run control +start+
3478
3841
  def sequencer(clk = nil, start = nil, &ruby_block)
3842
+ # Ensure the clock is global.
3843
+ clk.global! if clk
3479
3844
  return SequencerT.new(clk,start,&ruby_block)
3480
3845
  end
3481
3846
 
3847
+ # Create a 1-bit input signal.
3848
+ def input(*names)
3849
+ return [1].input(*names)
3850
+ end
3851
+
3852
+ # Create a 1-bit output signal.
3853
+ def output(*names)
3854
+ return [1].output(*names)
3855
+ end
3856
+
3857
+ # Create a 1-bit inner signal.
3858
+ def inner(*names)
3859
+ return [1].inner(*names)
3860
+ end
3861
+
3482
3862
  # Create a new function named +name+, built using block +ruby_block+.
3483
3863
  def sdef(name,&ruby_block)
3484
3864
  name = name.to_sym
3485
3865
  # Get the arguments of the ruby_block.
3486
- args = ruby_block.parameters.map {|typ,name| name.to_s }
3487
- # Register the call to the function.
3488
- RubyHDL::High.register(name.to_sym) do |args|
3489
- cur_seq = Ruby::HDL::High.top_sblock.sequencer
3490
- unless cur_seq.sfunction?(name) then
3491
- # Need to create a new sfunction.
3492
- # Push a new empty sblock for building the function.
3493
- RubyHDL::High.push_sblock(SblockTop.new)
3494
- args.each do |arg|
3495
- RubyHDL::High.top_sblock.make_inners(Void,arg.to_sym)
3496
- end
3866
+ block_args = ruby_block.parameters.map {|typ,name| name.to_s }
3867
+ # Create function.
3868
+ cur_sblock = RubyHDL::High.top_sblock
3869
+ # Register the call.
3870
+ cur_sblock.register(name.to_sym) do |*args|
3871
+ # Create the function.
3872
+ # Get the current sequencer.
3873
+ cur_seq = RubyHDL::High.top_sblock.sequencer
3874
+ # Get the function from the sequencer if any.
3875
+ function = cur_seq.sfunction(name)
3876
+ unless function then
3877
+ # There were no function for the sequencer, create it.
3497
3878
  # Execute the ruby block in a sequencer environment for building
3498
3879
  # the sblock.
3499
3880
  sblock = Sblock.new(cur_seq,&ruby_block)
3500
- RubyHDL::High.pop_sblock
3881
+ # Create the arguments.
3882
+ block_args.each_with_index do |block_arg,i|
3883
+ # puts "args[#{i}]=(#{args[i].name},#{args[i].type})"
3884
+ sblock.make_inners(args[i].type,block_arg.to_sym)
3885
+ end
3501
3886
  # Create the function.
3502
- function = SfunctionT.new(name,args,sblock)
3503
- # Add it to the sequencer.
3504
- cur_seq.add_sfunction(name)
3887
+ function = SfunctionT.new(name,sblock,*block_args)
3888
+ # Add it to the current sequencer.
3889
+ cur_seq.add_sfunction(name,function)
3505
3890
  end
3506
- Scall.new(cur_seq,name,args)
3891
+ # And create the call
3892
+ Scall.new(function,cur_seq,*args)
3507
3893
  end
3508
3894
  end
3509
3895
 
3510
-
3511
3896
  end
3512
3897
 
3513
3898