HDLRuby 3.7.0 → 3.7.2

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.
@@ -1,5 +1,7 @@
1
1
  require "hruby_types.rb"
2
2
 
3
+ # Note: Fiber in C: https://github.com/higan-emu/libco
4
+
3
5
  module RubyHDL
4
6
  end
5
7
 
@@ -52,6 +54,7 @@ module RubyHDL::High
52
54
 
53
55
  # Generate inner signals with type +type+ and names from +names+ list.
54
56
  def make_inners(type,*names)
57
+ # puts "make_inners with names=#{names.join(",")}"
55
58
  type = type.to_type
56
59
  last_sig = nil
57
60
  names.each do |name|
@@ -60,6 +63,7 @@ module RubyHDL::High
60
63
  sig = SignalI.new(type,name)
61
64
  @signals << sig
62
65
  # Register it.
66
+ # self.register(name) { puts("sig=",sig.inspect); sig }
63
67
  self.register(name) { sig }
64
68
  last_sig = sig
65
69
  end
@@ -147,8 +151,48 @@ module RubyHDL::High
147
151
  # end
148
152
 
149
153
 
150
- # The translation of operators into ruby code.
154
+ # RUBY_OPERATOR = {
155
+ # # Unary operators.
156
+ # :"-@" => "-(%s)", :"+@" => "+(%s)", :"~" => "~(%s)",
157
+ # :abs => "(%s).abs",
158
+ # :boolean => "%s", :bit => "%s",
159
+ # :signed => "%s", :unsigned => "(%s) & 0xFFFFFFFFFFFFFFFF",
160
+
161
+ # # Binary operators.
162
+ # :"+" => "(%s)+(%s)", :"-" => "(%s)-(%s)", :"*" => "(%s)*(%s)",
163
+ # :"/" => "(%s)/(%s)", :"%" => "(%s)%%(%s)", :"**" => "(%s)**(%s)",
164
+ # :"&" => "(%s)&(%s)", :"|" => "(%s)|(%s)", :"^" => "(%s)^(%s)",
165
+ # :"<<" => "(%s)<<(%s)", :">>" => "(%s)>>(%s)",
166
+ # :"==" => "(%s)==(%s)", :"!=" => "(%s)!=(%s)",
167
+ # :"<" => "(%s)<(%s)", :">" => "(%s)>(%s)",
168
+ # :"<=" => "(%s)<=(%s)",:">=" => "(%s)>=(%s)"
169
+ # }
170
+
171
+ # The translation of operators into Ruby code.
151
172
  RUBY_OPERATOR = {
173
+ # Unary operators.
174
+ :"-@" => "-(%{l})", :"+@" => "+(%{l})", :"~" => "~(%{l})",
175
+ :abs => "(%{l}).abs",
176
+ :boolean => "%{l}", :bit => "%{l}",
177
+ :signed => "%{l}", :unsigned => "(%{l}) & 0xFFFFFFFFFFFFFFFF",
178
+
179
+ # Binary operators.
180
+ :"+" => "(%{l})+(%{r})", :"-" => "(%{l})-(%{r})",
181
+ :"*" => "(%{l})*(%{r})", :"/" => "(%{l})/(%{r})",
182
+ :"%" => "(%{l})%%(%{r})", :"**" => "(%{l})**(%{r})",
183
+ :"&" => "(%{l})&(%{r})", :"|" => "(%{l})|(%{r})",
184
+ :"^" => "(%{l})^(%{r})",
185
+ :"<<" => "(%{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}"
192
+ }
193
+
194
+ # The translation of operators into C code.
195
+ C_OPERATOR = {
152
196
  # Unary operators.
153
197
  :"-@" => "-(%s)", :"+@" => "+(%s)", :"~" => "~(%s)",
154
198
  :abs => "(%s).abs",
@@ -157,7 +201,7 @@ module RubyHDL::High
157
201
 
158
202
  # Binary operators.
159
203
  :"+" => "(%s)+(%s)", :"-" => "(%s)-(%s)", :"*" => "(%s)*(%s)",
160
- :"/" => "(%s)/(%s)", :"%" => "(%s)%%(%s)", :"**" => "(%s)**(%s)",
204
+ :"/" => "(%s)/(%s)", :"%" => "(%s)%%(%s)", :"**" => "pow((%s),(%s))",
161
205
  :"&" => "(%s)&(%s)", :"|" => "(%s)|(%s)", :"^" => "(%s)^(%s)",
162
206
  :"<<" => "(%s)<<(%s)", :">>" => "(%s)>>(%s)",
163
207
  :"==" => "(%s)==(%s)", :"!=" => "(%s)!=(%s)",
@@ -486,11 +530,15 @@ module RubyHDL::High
486
530
  end
487
531
 
488
532
 
489
- # Modify String to act as ruby code generator.
533
+ # Modify String to act as Ruby code generator.
490
534
  refine ::String do
535
+ # Convert to Ruby code.
491
536
  def to_ruby
492
537
  self
493
538
  end
539
+
540
+ # Convert to C code.
541
+ alias_method :to_c, :to_ruby
494
542
  end
495
543
 
496
544
 
@@ -501,6 +549,14 @@ module RubyHDL::High
501
549
  end
502
550
  alias_method :to_expr, :to_value
503
551
 
552
+ def to_ruby
553
+ return self
554
+ end
555
+
556
+ def to_c
557
+ return self.to_s
558
+ end
559
+
504
560
  # Enhance the Integer class with sequencer iterations.
505
561
 
506
562
  # HW times iteration.
@@ -527,12 +583,19 @@ module RubyHDL::High
527
583
  alias_method :to_expr, :to_value
528
584
  end
529
585
 
586
+ # Modify Range to act as RubyHDL object.
587
+ refine ::Range do
588
+ def to_ruby
589
+ return "(#{self})"
590
+ end
591
+ end
592
+
530
593
  # Modify Range to support HW iterators.
531
594
  refine ::Enumerable do
532
595
  import_methods SEnumerable
533
596
  # HW iteration on each element.
534
597
  def seach(&ruby_block)
535
- RubyHDL::High.top_sblock << SeachEnumerable.new(self,&ruby_block)
598
+ return Siter.new(RubyHDL::High.top_sblock.sequencer,self,"each",&ruby_block)
536
599
  end
537
600
  end
538
601
 
@@ -901,6 +964,30 @@ module RubyHDL::High
901
964
  # A block? Apply it on each overload if any.
902
965
  @overloads.each(&ruby_block) if @overloads
903
966
  end
967
+
968
+ # Convert to C code.
969
+ def to_c
970
+ case @name
971
+ when :void
972
+ return "void"
973
+ when :bit, :unsigned
974
+ return "unsigned"
975
+ when :signed
976
+ return "signed"
977
+ when :float
978
+ return "double"
979
+ when :string
980
+ return "char*"
981
+ else
982
+ return @name.to_s
983
+ end
984
+ end
985
+
986
+ # Convert to C initialization code.
987
+ def to_c_init
988
+ # By default: 0
989
+ return "0"
990
+ end
904
991
  end
905
992
 
906
993
 
@@ -920,12 +1007,30 @@ module RubyHDL::High
920
1007
 
921
1008
  # The signed bit type.
922
1009
  Signed = define_type(:signed)
1010
+ class << Signed
1011
+ # Tells if the type signed.
1012
+ def signed?
1013
+ return true
1014
+ end
1015
+ end
923
1016
 
924
1017
  # The unsigned bit type.
925
1018
  Unsigned = define_type(:unsigned)
1019
+ class << Unsigned
1020
+ # Tells if the type unsigned.
1021
+ def unsigned?
1022
+ return true
1023
+ end
1024
+ end
926
1025
 
927
1026
  # The float bit type
928
1027
  Float = define_type(:float)
1028
+ class << Float
1029
+ # Tells if the type signed.
1030
+ def signed?
1031
+ return true
1032
+ end
1033
+ end
929
1034
 
930
1035
  # The string type
931
1036
  StringT = define_type(:string)
@@ -1143,6 +1248,32 @@ module RubyHDL::High
1143
1248
  end
1144
1249
 
1145
1250
  alias_method :each_deep, :each_type_deep
1251
+
1252
+ # Convert to C code.
1253
+ def to_c
1254
+ if @base.is_a?(TypeVector) then
1255
+ # Array type case.
1256
+ return @base.to_c + "[#{self.size.to_i}]"
1257
+ else
1258
+ # Simple vector type case.
1259
+ if float? then
1260
+ return @base.to_c
1261
+ else
1262
+ return @base + " long long"
1263
+ end
1264
+ end
1265
+ end
1266
+
1267
+ # Convert to C initialization code.
1268
+ def to_c_init
1269
+ if @base.is_a?(TypeVector) then
1270
+ # Array type case.
1271
+ base_init = @base.to_c_init
1272
+ return "[" + ([base_init] * self.size.to_i).join(",") + "]"
1273
+ else
1274
+ return "0"
1275
+ end
1276
+ end
1146
1277
  end
1147
1278
 
1148
1279
 
@@ -1558,11 +1689,16 @@ module RubyHDL::High
1558
1689
  raise "to_value not defined here."
1559
1690
  end
1560
1691
 
1561
- # Convert to ruby code.
1692
+ # Convert to Ruby code.
1562
1693
  def to_ruby
1563
1694
  raise "to_ruby not defined for class: #{self.class}."
1564
1695
  end
1565
1696
 
1697
+ # Convert to C code.
1698
+ def to_c
1699
+ raise "to_c not defined for class: #{self.class}."
1700
+ end
1701
+
1566
1702
  # Convert to ruby code for left value.
1567
1703
  # By default: the same as to_ruby
1568
1704
  alias_method :to_ruby_left, :to_ruby
@@ -1709,10 +1845,13 @@ module RubyHDL::High
1709
1845
  return self
1710
1846
  end
1711
1847
 
1712
- # Convert to ruby code.
1848
+ # Convert to Ruby code.
1713
1849
  def to_ruby
1714
1850
  return @content.to_s
1715
1851
  end
1852
+
1853
+ # Convert to C code.
1854
+ alias_method :to_c, :to_ruby
1716
1855
  end
1717
1856
 
1718
1857
 
@@ -1724,11 +1863,18 @@ module RubyHDL::High
1724
1863
  super(type)
1725
1864
  @operator = operator.to_sym
1726
1865
  @child = child.to_expr
1866
+ @mask = (2 ** @type.width)-1
1727
1867
  end
1728
1868
 
1729
- # Convert to ruby code.
1869
+ # Convert to Ruby code.
1730
1870
  def to_ruby
1731
- return RUBY_OPERATOR[@operator] % @child.to_ruby
1871
+ # return RUBY_OPERATOR[@operator] % @child.to_ruby
1872
+ return RUBY_OPERATOR[@operator] % { l: @child.to_ruby }
1873
+ end
1874
+
1875
+ # Convert to C code.
1876
+ def to_c
1877
+ return C_OPERATOR[@operator] % @child.to_c
1732
1878
  end
1733
1879
  end
1734
1880
 
@@ -1741,11 +1887,27 @@ module RubyHDL::High
1741
1887
  @operator = operator.to_sym
1742
1888
  @left = left.to_expr
1743
1889
  @right = right.to_expr
1890
+ # Compute the mask for fixing the bit width.
1891
+ @mask = (2 ** @type.width)-1
1892
+ # Compute xor mask for handling the sign.
1893
+ # Make it as a string so that no addition computation is required
1894
+ # if no sign is required.
1895
+ @sign_fix = ""
1896
+ if type.signed? then
1897
+ @sign_fix = " ^ #{2**(@type.width-1)}"
1898
+ end
1744
1899
  end
1745
1900
 
1746
- # Convert to ruby code.
1901
+ # Convert to Ruby code.
1747
1902
  def to_ruby
1748
- return RUBY_OPERATOR[@operator] % [ @left.to_ruby, @right.to_ruby ]
1903
+ # return RUBY_OPERATOR[@operator] % [ @left.to_ruby, @right.to_ruby ]
1904
+ return RUBY_OPERATOR[@operator] %
1905
+ { l: @left.to_ruby, r: @right.to_ruby, m: @mask, s: @sign_fix }
1906
+ end
1907
+
1908
+ # Convert to C code.
1909
+ def to_c
1910
+ return C_OPERATOR[@operator] % [ @left.to_c, @right.to_c ]
1749
1911
  end
1750
1912
  end
1751
1913
 
@@ -1759,13 +1921,21 @@ module RubyHDL::High
1759
1921
  @choices = choices.map(&:to_expr)
1760
1922
  end
1761
1923
 
1762
- # Convert to ruby code.
1924
+ # Convert to Ruby code.
1763
1925
  def to_ruby
1764
1926
  return "case(#{@sel.to_}) ; " +
1765
1927
  @choices.map.with_index do |choice,i|
1766
1928
  "when #{i} ; #{choice.to_ruby} ; "
1767
1929
  end.join + "end"
1768
1930
  end
1931
+
1932
+ # Convert to C code.
1933
+ def to_c
1934
+ return "switch(#{@sel.to_c}) {\n" +
1935
+ @choices.map.with_index do |choice,i|
1936
+ "case #{i}:\n#{choice.to_c}\nbreak;"
1937
+ end.join("\n") + "\n}"
1938
+ end
1769
1939
  end
1770
1940
 
1771
1941
  # Describes a SW implementation of a reference.
@@ -1798,10 +1968,13 @@ module RubyHDL::High
1798
1968
  @name = name.to_sym
1799
1969
  end
1800
1970
 
1801
- # Convert to ruby code.
1971
+ # Convert to Ruby code.
1802
1972
  def to_ruby
1803
1973
  return @name.to_s
1804
1974
  end
1975
+
1976
+ # Convert to C code.
1977
+ alias_method :to_c, :to_ruby
1805
1978
  end
1806
1979
 
1807
1980
  # Describes a SW implementation of an index reference.
@@ -1857,10 +2030,15 @@ module RubyHDL::High
1857
2030
  return @idx..@idx
1858
2031
  end
1859
2032
 
1860
- # Convert to ruby code.
2033
+ # Convert to Ruby code.
1861
2034
  def to_ruby
1862
2035
  return "#{@base.to_ruby}[#{@idx.to_ruby}]"
1863
2036
  end
2037
+
2038
+ # Convert to C code.
2039
+ def to_c
2040
+ return "#{@base.to_c}[#{@idx.to_c}]"
2041
+ end
1864
2042
  end
1865
2043
 
1866
2044
  # Describes a SW implementation of an range reference.
@@ -1916,10 +2094,25 @@ module RubyHDL::High
1916
2094
  # return rng
1917
2095
  # end
1918
2096
 
1919
- # Convert to ruby code.
2097
+ # Convert to Ruby code.
1920
2098
  def to_ruby
1921
2099
  return "#{@base.to_ruby}[#{@rng.first.to_ruby}..#{@rng.last.to_ruby}]"
1922
2100
  end
2101
+
2102
+ # Convert to C code.
2103
+ def to_c
2104
+ if @base.type.base.is_a?(TypeVector) then
2105
+ raise "Range access not supported yet for arrays."
2106
+ else
2107
+ # Compute the writing and clearing masks
2108
+ smask = (1.to_value<<(@rng.first+1-@rng.last))-1
2109
+ cmask = ~(smask << @rng.last)
2110
+ # Get the final base.
2111
+ base = @base.final_base.to_c
2112
+ # Generate the ruby code.
2113
+ return "(#{base} & #{cmask.to_c}) >> (#{@rng.last.to_c})"
2114
+ end
2115
+ end
1923
2116
  end
1924
2117
 
1925
2118
 
@@ -1948,7 +2141,7 @@ module RubyHDL::High
1948
2141
  return Binary.new(@left.type,@left,@right)
1949
2142
  end
1950
2143
 
1951
- # Convert to ruby code.
2144
+ # Convert to Ruby code.
1952
2145
  def to_ruby
1953
2146
  if (@left.is_a?(RefIndex) or @left.is_a?(RefRange)) then
1954
2147
  if @left.base.type.base.is_a?(TypeVector) then
@@ -1956,8 +2149,6 @@ module RubyHDL::High
1956
2149
  base = @left.final_base.to_ruby
1957
2150
  return "#{base} ||= []; #{@left.to_ruby} = #{@right.to_ruby}"
1958
2151
  else
1959
- # # Compute the final access range.
1960
- # rng = @left.final_range
1961
2152
  # Get the access range.
1962
2153
  rng = @left.range
1963
2154
  # Compute the writing and clearing masks
@@ -1973,6 +2164,29 @@ module RubyHDL::High
1973
2164
  return "#{@left.to_ruby} = #{@right.to_ruby}"
1974
2165
  end
1975
2166
  end
2167
+
2168
+ # Convert to C code.
2169
+ def to_c
2170
+ if (@left.is_a?(RefIndex) or @left.is_a?(RefRange)) then
2171
+ if @left.base.type.base.is_a?(TypeVector) then
2172
+ return "#{@left.to_c} = #{@right.to_c}"
2173
+ else
2174
+ # Get the access range.
2175
+ rng = @left.range
2176
+ # Compute the writing and clearing masks
2177
+ smask = (1.to_value<<(rng.first+1-rng.last))-1
2178
+ cmask = ~(smask << rng.last)
2179
+ # Get the final base.
2180
+ base = left.final_base.to_c
2181
+ # Generate the ruby code.
2182
+ return "#{base} &= #{cmask.to_c}; " +
2183
+ "#{base} |= (((#{@right.to_c} & #{smask.to_c}) << (#{rng.last.to_c})))"
2184
+ end
2185
+ else
2186
+ return "#{@left.to_c} = #{@right.to_c};"
2187
+ end
2188
+ end
2189
+
1976
2190
  end
1977
2191
 
1978
2192
  # Describes a SW implementation of a if statement.
@@ -1998,16 +2212,28 @@ module RubyHDL::High
1998
2212
  @else_blk = Sblock.new(@sequencer,&ruby_block)
1999
2213
  end
2000
2214
 
2001
- # Convert to ruby code.
2215
+ # Convert to Ruby code.
2002
2216
  def to_ruby
2003
- res = @sequencer.clk_up + "\nif(#{@cond.to_ruby})\n#{@yes.to_ruby}\n"
2217
+ res = @sequencer.clk_up + "\nif(#{@condition.to_ruby})\n#{@yes_blk.to_ruby}\n"
2004
2218
  @elsifs.each do |(cond,blk)|
2005
2219
  res << "elsif(#{cond.to_ruby})\n#{blk.to_ruby}\n"
2006
2220
  end
2007
2221
  if @else_blk then
2008
2222
  res << "else\n#{@else_blk.to_ruby}\n"
2009
2223
  end
2010
- return res + @sequencer.clk_up
2224
+ return res + "end\n" + @sequencer.clk_up
2225
+ end
2226
+
2227
+ # Convert to C code.
2228
+ def to_c
2229
+ res = @sequencer.clk_up + "\nif(#{@condition.to_c}) {\n#{@yes_blk.to_c}\n}"
2230
+ @elsifs.each do |(cond,blk)|
2231
+ res << "\nelse if(#{cond.to_c}) {\n#{blk.to_c}\n}"
2232
+ end
2233
+ if @else_blk then
2234
+ res << "\nelse {\n#{@else_blk.to_c}\n}"
2235
+ end
2236
+ return res + @sequencer.clk_up_c
2011
2237
  end
2012
2238
  end
2013
2239
 
@@ -2020,9 +2246,14 @@ module RubyHDL::High
2020
2246
  @blk = Sblock.new(sequencer,&ruby_block)
2021
2247
  end
2022
2248
 
2023
- # Convert to ruby code.
2249
+ # Convert to Ruby code.
2024
2250
  def to_ruby
2025
- return "loop do\n#{@blk.to_ruby}\n#{@sequencer.clk_up}\nend\n"
2251
+ return "loop do\n#{@blk.to_ruby}\n#{@sequencer.clk_up}\nend"
2252
+ end
2253
+
2254
+ # Convert to C code.
2255
+ def to_c
2256
+ return "for(;;){\n#{@blk.to_ruby}\n#{@sequencer.clk_up_c}\n}"
2026
2257
  end
2027
2258
  end
2028
2259
 
@@ -2037,10 +2268,15 @@ module RubyHDL::High
2037
2268
  @yes_blk = Sblock.new(sequencer,&ruby_block)
2038
2269
  end
2039
2270
 
2040
- # Convert to ruby code.
2271
+ # Convert to Ruby code.
2041
2272
  def to_ruby
2042
2273
  return @sequencer.clk_up +
2043
- "\nwhile(#{@condition.to_ruby}) do\n#{@yes_blk.to_ruby}\n#{@sequencer.clk_up}\nend\n"
2274
+ "\nwhile(#{@condition.to_ruby}) do\n#{@yes_blk.to_ruby}\n#{@sequencer.clk_up}\nend"
2275
+ end
2276
+
2277
+ # Convert to C code.
2278
+ def to_c
2279
+ "\nwhile(#{@condition.to_c}) {\n#{@yes_blk.to_c}\n#{@sequencer.clk_up_c}\n}"
2044
2280
  end
2045
2281
  end
2046
2282
 
@@ -2051,10 +2287,15 @@ module RubyHDL::High
2051
2287
  @sequencer = sequencer
2052
2288
  end
2053
2289
 
2054
- # Convert to ruby code.
2290
+ # Convert to Ruby code.
2055
2291
  def to_ruby
2056
2292
  return @sequencer.clk_up
2057
2293
  end
2294
+
2295
+ # Convert to C code.
2296
+ def to_c
2297
+ return @sequencer.clk_up_c
2298
+ end
2058
2299
  end
2059
2300
 
2060
2301
  # Describes a SW implementation of a break statement.
@@ -2064,10 +2305,15 @@ module RubyHDL::High
2064
2305
  @sequencer = sequencer
2065
2306
  end
2066
2307
 
2067
- # Convert to ruby code.
2308
+ # Convert to Ruby code.
2068
2309
  def to_ruby
2069
2310
  return @sequencer.clk_up + "\nbreak"
2070
2311
  end
2312
+
2313
+ # Convert to C code.
2314
+ def to_c
2315
+ return @sequencer.clk_up_c + "\nbreak;"
2316
+ end
2071
2317
  end
2072
2318
 
2073
2319
  # Describes a SW implementation of a continue statement.
@@ -2077,10 +2323,15 @@ module RubyHDL::High
2077
2323
  @sequencer = sequencer
2078
2324
  end
2079
2325
 
2080
- # Convert to ruby code.
2326
+ # Convert to Ruby code.
2081
2327
  def to_ruby
2082
2328
  return @sequencer.clk_up + "\ncontinue"
2083
2329
  end
2330
+
2331
+ # Convert to Ruby code.
2332
+ def to_c
2333
+ return @sequencer.clk_up_c + "\ncontinue;"
2334
+ end
2084
2335
  end
2085
2336
 
2086
2337
  # Describes a SW implementation of a terminate statement.
@@ -2090,12 +2341,17 @@ module RubyHDL::High
2090
2341
  @sequencer = sequencer
2091
2342
  end
2092
2343
 
2093
- # Convert to ruby code.
2344
+ # Convert to Ruby code.
2094
2345
  def to_ruby
2095
2346
  # Implemented as returning from a function since a sequencer
2096
2347
  # is implemented as one.
2097
2348
  return @sequencer.clk_up + "\nreturn"
2098
2349
  end
2350
+
2351
+ # Convert to C code.
2352
+ def to_c
2353
+ return @sequencer.clk_up_c + "\nreturn;"
2354
+ end
2099
2355
  end
2100
2356
 
2101
2357
  # Describes a SW synchronization of a signal.
@@ -2103,23 +2359,34 @@ module RubyHDL::High
2103
2359
  def initialize
2104
2360
  end
2105
2361
 
2106
- # Convert to ruby code.
2362
+ # Convert to Ruby code.
2107
2363
  def to_ruby
2108
2364
  return "Fiber.yield"
2109
2365
  end
2366
+
2367
+ # Convert to C code.
2368
+ def to_c
2369
+ return "yield();"
2370
+ end
2110
2371
  end
2111
2372
 
2112
2373
  # Describes arbitrary code.
2113
2374
  class Ruby < Expression
2114
2375
  @@ruby_blocks = []
2115
2376
 
2116
- # Create a new ruby code block for +ruby_block+.
2117
- def initialize(&ruby_block)
2377
+ # Create a new ruby code block for either +ruby_block+ or
2378
+ # string +str+.
2379
+ def initialize(str = nil, &ruby_block)
2380
+ @str = str
2118
2381
  # puts "ruby_block=#{ruby_block}"
2119
2382
  # Create the id for the block.
2120
2383
  @id = @@ruby_blocks.size
2121
2384
  # Adds the block.
2122
- @@ruby_blocks << ruby_block
2385
+ if ruby_block then
2386
+ @@ruby_blocks << ruby_block
2387
+ else
2388
+ @@ruby_blocks << proc { TOPLEVEL_BINDING.eval(@str.to_s) }
2389
+ end
2123
2390
  end
2124
2391
 
2125
2392
  # Convert to expression: does not change but remove from the
@@ -2136,39 +2403,45 @@ module RubyHDL::High
2136
2403
  @@ruby_blocks[id].call
2137
2404
  end
2138
2405
 
2139
- # Convert to ruby code.
2406
+ # Convert to Ruby code.
2140
2407
  def to_ruby
2141
- puts caller[0]
2142
- return "RubyHDL::High::Ruby.call(#{@id})"
2408
+ # puts caller[0]
2409
+ if @str then
2410
+ return TOPLEVEL_BINDING.eval(@str)
2411
+ else
2412
+ return "RubyHDL::High::Ruby.call(#{@id})"
2413
+ end
2414
+ end
2415
+
2416
+ # Convert to C code.
2417
+ def to_c
2418
+ return "rb_eval_string(\"#{@str.to_s}\");"
2143
2419
  end
2144
2420
  end
2145
2421
 
2146
- # Describes a SW implementation of an iterator statement.
2147
- class Siter
2422
+
2423
+ # Describes a SW implementation of an call statement.
2424
+ class Scall
2148
2425
  using RubyHDL::High
2149
2426
 
2150
- # Create a new iteration statement in sequencer +sequencer+
2151
- # for chain of commands +commands+ to interate while
2152
- # executing +ruby_block+.
2153
- def initialize(sequencer,*commands, &ruby_block)
2427
+ # Create a new call statement in sequencer +sequencer+ for function
2428
+ # named +name+ with arguments +args+.
2429
+ def initialize(sequencer, name, *args)
2154
2430
  @sequencer = sequencer
2155
- puts "@sequencer=#{@sequencer}"
2156
- @commands = commands
2157
- @blk = Sblock.new(sequencer,&ruby_block)
2431
+ @name = name.to_sym
2432
+ @args = args
2158
2433
  end
2159
2434
 
2160
- # Iterate on the commands.
2161
- def each_command(&ruby_block)
2162
- return to_enum(:each_command) unless ruby_block
2163
- @commands.each(&ruby_block)
2435
+ # Convert to Ruby code.
2436
+ def to_ruby
2437
+ return @sequencer.clk_up + "\n#{name}(" +
2438
+ @args.map {|arg| arg.to_ruby}.join(",") + ")"
2164
2439
  end
2165
- alias_method :each, :each_command
2166
2440
 
2167
- # Convert to ruby code.
2168
- def to_ruby
2169
- res = @sequencer.clk_up + "\n" +
2170
- @commands.map { |command| command.to_ruby }.join(".")
2171
- return res + " do\n#{@blk.to_ruby}\n#{@sequencer.clk_up}\nend"
2441
+ # Convert to C code.
2442
+ def to_c
2443
+ return @sequencer.clk_up + "\n#{name}(" +
2444
+ @args.map {|arg| arg.to_ruby}.join(",") + ");"
2172
2445
  end
2173
2446
 
2174
2447
  # Create an iterator for a given method +meth+.
@@ -2504,122 +2777,548 @@ module RubyHDL::High
2504
2777
  end
2505
2778
 
2506
2779
 
2507
- # Describes a SW implementation of a signal.
2508
- class SignalI < Expression
2780
+ # Describes a SW implementation of an iterator statement.
2781
+ class Siter
2509
2782
  using RubyHDL::High
2510
- attr_reader :type, :name #, :content
2511
- # Create a new signal with type +type+ and name +name+.
2512
- def initialize(type,name)
2513
- @type = type.to_type
2514
- @name = name.to_sym
2515
- # @content = nil # The content is the Ruby value, not the HW description one!
2516
- end
2517
2783
 
2518
- # Tell if the signal is an array.
2519
- def array?
2520
- return @type.base.is_a?(TypeVector)
2784
+ # Create a new iteration statement in sequencer +sequencer+
2785
+ # for chain of commands +commands+ to interate while
2786
+ # executing +ruby_block+.
2787
+ def initialize(sequencer,*commands, &ruby_block)
2788
+ @sequencer = sequencer
2789
+ @commands = commands
2790
+ if ruby_block then
2791
+ # The iterator is finalized.
2792
+ @blk = Sblock.new(sequencer,&ruby_block)
2793
+ end
2794
+ # puts "New iterator with blk=#{@blk} commands=#{@commands}"
2521
2795
  end
2522
2796
 
2523
- # # Convert to a value.
2524
- # def to_value
2525
- # return @content.to_value
2526
- # end
2527
-
2528
- # Sets the content of the signal.
2529
- # def content=(value)
2530
- # @content = value
2531
- # end
2797
+ # Iterate on the commands.
2798
+ def each_command(&ruby_block)
2799
+ return to_enum(:each_command) unless ruby_block
2800
+ @commands.each(&ruby_block)
2801
+ end
2802
+ alias_method :each, :each_command
2532
2803
 
2533
- # Convert to ruby code.
2804
+ # Convert to Ruby code.
2534
2805
  def to_ruby
2535
- # return self.name.to_s + ".content"
2536
- return "__" + self.name.to_s
2806
+ # puts "to_ruby with blk=#{@blk} commands=#{@commands}"
2807
+ res = @sequencer.clk_up + "\n" +
2808
+ @commands.map { |command| command.to_ruby }.join(".")
2809
+ return res + " do\n#{@blk.to_ruby}\n#{@sequencer.clk_up}\nend"
2537
2810
  end
2538
2811
 
2539
- # Gets the value of the signal.
2540
- def value
2541
- return TOPLEVEL_BINDING.eval(self.to_ruby)
2812
+ # Convert to C code.
2813
+ def to_c
2814
+ res = @sequencer.clk_up_c + "\n" +
2815
+ @commands.map { |command| command.to_c }.join("_")
2816
+ return res + "(#{@blk.to_c})"
2542
2817
  end
2543
2818
 
2544
- # Sets the value of the signal.
2545
- def value=(val)
2546
- return TOPLEVEL_BINDING.eval("#{self.to_ruby} = #{val}")
2819
+ # Create an iterator for a given method +meth+.
2820
+ def make_iterator(meth,*args,&ruby_block)
2821
+ # if ruby_block then
2822
+ # blk = Sblock.new(@sequencer,&ruby_block)
2823
+ # command = RubyHDL::High::Ruby.new do
2824
+ # "#{meth}(#{args.map{|arg| arg.to_ruby}.join(",")}) { #{blk.to_ruby} }"
2825
+ # end
2826
+ # else
2827
+ # command = RubyHDL::High::Ruby.new do
2828
+ # "#{meth}(#{args.map{|arg| arg.to_ruby}.join(",")})"
2829
+ # end
2830
+ # end
2831
+ command = "#{meth}"
2832
+ if args.any? then
2833
+ command += "(*#{RubyHDL::High::Ruby.new {
2834
+ "#{args.map{|arg| arg.to_ruby}.join(",")}"}})"
2835
+ end
2836
+ return Siter.new(@sequencer,*@commands,command,&ruby_block)
2547
2837
  end
2548
2838
 
2549
- # Convert to an integer.
2550
- def to_i
2551
- # return @content.to_i
2552
- # return binding.local_variable_get(to_ruby.to_sym).to_i
2553
- return self.value.to_i
2554
- end
2839
+ # The iterator methods.
2555
2840
 
2556
- # Convert to an float.
2557
- def to_f
2558
- # return @content.to_f
2559
- # return binding.local_variable_get(to_ruby.to_sym).to_f
2560
- return self.value.to_f
2841
+ # Iterator on each of the elements in range +rng+.
2842
+ # *NOTE*:
2843
+ # - Stop iteration when the end of the range is reached or when there
2844
+ # are no elements left
2845
+ # - This is not a method from Ruby but one specific for hardware where
2846
+ # creating a array is very expensive.
2847
+ def seach_range(rng,&ruby_block)
2848
+ return self.make_iterator("each_range",rng,&ruby_block)
2561
2849
  end
2562
2850
 
2563
- # Convert to a string.
2564
- def to_s
2565
- # return @content.to_s
2566
- # return binding.local_variable_get(to_ruby.to_sym).to_s
2567
- return self.value.to_s
2851
+ # Tell if all the elements respect a given criterion given either
2852
+ # as +arg+ or as block.
2853
+ def sall?(arg = nil,&ruby_block)
2854
+ return self.make_iterator("all?",arg,&ruby_block)
2568
2855
  end
2569
- end
2570
-
2571
-
2572
- # Describes a SW implementation of a block.
2573
- class Sblock < SblockTop
2574
- using RubyHDL::High
2575
2856
 
2576
- attr_reader :sequencer
2577
-
2578
- # Create a new block for sequencer +sequencer+ and fill it by
2579
- # executing +ruby_block+
2580
- def initialize(sequencer,&ruby_block)
2581
- super()
2582
- # Sets the sequencer.
2583
- @sequencer = sequencer
2584
- # Initialize the statements.
2585
- @statements = []
2586
- # Push the new sblock on top of the stack.
2587
- RubyHDL::High.push_sblock(self)
2588
- # Fill it.
2589
- self.instance_eval(&ruby_block)
2590
- # Pop the new sblock.
2591
- RubyHDL::High.pop_sblock
2857
+ # Tell if any of the elements respects a given criterion given either
2858
+ # as +arg+ or as block.
2859
+ def sany?(arg = nil,&ruby_block)
2860
+ return self.make_iterator("any?",arg,&ruby_block)
2592
2861
  end
2593
2862
 
2594
- # Add a new statement to the block.
2595
- def add(statement)
2596
- # Add the statement.
2597
- @statements.push(statement)
2598
- # # If the statement is a transmit, schedule the corresponding
2599
- # # signal for final update.
2600
- # if statement.is_a?(Transmit) then
2601
- # @sequencer.to_update(statement.left)
2602
- # end
2603
- statement
2863
+ # Returns an SEnumerator generated from current enumerable and +arg+
2864
+ def schain(arg)
2865
+ return self.make_iterator("chain",arg)
2604
2866
  end
2605
- alias_method :<<, :add
2606
2867
 
2607
- # Delete a statement.
2608
- def delete(statement)
2609
- @statements.delete(statement)
2868
+ # HW implementation of the Ruby chunk.
2869
+ # NOTE: to do, or may be not.
2870
+ def schunk(*args,&ruby_block)
2871
+ raise "schunk is not supported yet."
2610
2872
  end
2611
2873
 
2612
- # Unshift a new statement.
2613
- def unshift(statement)
2614
- @statements.unshift(statement)
2874
+ # HW implementation of the Ruby chunk_while.
2875
+ # NOTE: to do, or may be not.
2876
+ def schunk_while(*args,&ruby_block)
2877
+ raise "schunk_while is not supported yet."
2615
2878
  end
2616
2879
 
2880
+ # Returns a vector containing the execution result of the given block
2881
+ # on each element. If no block is given, return an SEnumerator.
2882
+ # NOTE: be carful that the resulting vector can become huge if there
2883
+ # are many element.
2884
+ def smap(&ruby_block)
2885
+ return self.make_iterator("map",&ruby_block)
2886
+ end
2617
2887
 
2618
- # Convert to ruby code.
2619
- def to_ruby
2620
- return @statements.map do |stmnt|
2621
- stmnt.to_ruby + "\n"
2888
+ # HW implementation of the Ruby flat_map.
2889
+ # NOTE: actually due to the way HDLRuby handles vectors, should work
2890
+ # like smap
2891
+ def sflat_map(&ruby_block)
2892
+ return self.make_iterator("flat_map",&ruby_block)
2893
+ end
2894
+
2895
+ # HW implementation of the Ruby compact, but remove 0 values instead
2896
+ # on nil (since nil that does not have any meaning in HW).
2897
+ def scompact
2898
+ return self.make_iterator("compact",&ruby_block)
2899
+ end
2900
+
2901
+
2902
+ # WH implementation of the Ruby count.
2903
+ def scount(obj = nil, &ruby_block)
2904
+ return self.make_iterator("count",obj,&ruby_block)
2905
+ end
2906
+
2907
+ # HW implementation of the Ruby cycle.
2908
+ def scycle(n = nil,&ruby_block)
2909
+ return self.make_iterator("cycle",n,&ruby_block)
2910
+ end
2911
+
2912
+ # HW implementation of the Ruby find.
2913
+ # NOTE: contrary to Ruby, if_none_proc is mandatory since there is no
2914
+ # nil in HW. Moreover, the argument can also be a value.
2915
+ def sfind(if_none_proc, &ruby_block)
2916
+ return self.make_iterator("find",if_none_proc,&ruby_block)
2917
+ end
2918
+
2919
+ # HW implementation of the Ruby drop.
2920
+ def sdrop(n)
2921
+ return self.make_iterator("drop",n)
2922
+ end
2923
+
2924
+ # HW implementation of the Ruby drop_while.
2925
+ def sdrop_while(&ruby_block)
2926
+ return self.make_iterator("drop_while",&ruby_block)
2927
+ end
2928
+
2929
+ # HW implementation of the Ruby each_cons
2930
+ def seach_cons(n,&ruby_block)
2931
+ return self.make_iterator("each_cons",n,&ruby_block)
2932
+ end
2933
+
2934
+ # HW implementation of the Ruby each_entry.
2935
+ # NOTE: to do, or may be not.
2936
+ def seach_entry(*args,&ruby_block)
2937
+ raise "seach_entry is not supported yet."
2938
+ end
2939
+
2940
+ # HW implementation of the Ruby each_slice
2941
+ def seach_slice(n,&ruby_block)
2942
+ return self.make_iterator("each_slice",n,&ruby_block)
2943
+ end
2944
+
2945
+ # HW implementation of the Ruby each_with_index.
2946
+ def seach_with_index(*args,&ruby_block)
2947
+ return self.make_iterator("each_with_index",*args,&ruby_block)
2948
+ end
2949
+ alias_method :with_index, :seach_with_index
2950
+
2951
+ # HW implementation of the Ruby each_with_object.
2952
+ def seach_with_object(obj,&ruby_block)
2953
+ return self.make_iterator("each_with_object",obj,&ruby_block)
2954
+ end
2955
+
2956
+ # HW implementation of the Ruby to_a.
2957
+ def sto_a
2958
+ return self.make_iterator("to_a")
2959
+ end
2960
+
2961
+ # HW implementation of the Ruby select.
2962
+ def sselect(&ruby_block)
2963
+ return self.make_iterator("select",&ruby_block)
2964
+ end
2965
+
2966
+ # HW implementation of the Ruby find_index.
2967
+ def sfind_index(obj = nil, &ruby_block)
2968
+ return self.make_iterator("find_index",obj,&ruby_block)
2969
+ end
2970
+
2971
+ # HW implementation of the Ruby first.
2972
+ def sfirst(n=1)
2973
+ return self.make_iterator("first",n)
2974
+ end
2975
+
2976
+ # HW implementation of the Ruby grep.
2977
+ # NOTE: to do, or may be not.
2978
+ def sgrep(*args,&ruby_block)
2979
+ raise "sgrep is not supported yet."
2980
+ end
2981
+
2982
+ # HW implementation of the Ruby grep_v.
2983
+ # NOTE: to do, or may be not.
2984
+ def sgrep_v(*args,&ruby_block)
2985
+ raise "sgrep_v is not supported yet."
2986
+ end
2987
+
2988
+ # HW implementation of the Ruby group_by.
2989
+ # NOTE: to do, or may be not.
2990
+ def sgroup_by(*args,&ruby_block)
2991
+ raise "sgroup_by is not supported yet."
2992
+ end
2993
+
2994
+ # HW implementation of the Ruby include?
2995
+ def sinclude?(obj)
2996
+ return self.make_iterator("include?",obj)
2997
+ end
2998
+
2999
+ # HW implementation of the Ruby inject.
3000
+ def sinject(*args,&ruby_block)
3001
+ return self.make_iterator("inject",*args,&ruby_block)
3002
+ end
3003
+
3004
+ # HW implementation of the Ruby reduce.
3005
+ def sreduce
3006
+ return self.make_iterator("reduce",*args,&ruby_block)
3007
+ end
3008
+
3009
+
3010
+ # HW implementation of the Ruby lazy.
3011
+ # NOTE: to do, or may be not.
3012
+ def slazy(*args,&ruby_block)
3013
+ raise "slazy is not supported yet."
3014
+ end
3015
+
3016
+ # HW implementation of the Ruby max.
3017
+ def smax(n = nil, &ruby_block)
3018
+ return self.make_iterator("max",n,&ruby_block)
3019
+ end
3020
+
3021
+ # HW implementation of the Ruby max_by.
3022
+ def smax_by(n = nil, &ruby_block)
3023
+ return self.make_iterator("max_by",n,&ruby_block)
3024
+ end
3025
+
3026
+ # HW implementation of the Ruby min.
3027
+ def smin(n = nil, &ruby_block)
3028
+ return self.make_iterator("min",n,&ruby_block)
3029
+ end
3030
+
3031
+ # HW implementation of the Ruby min_by.
3032
+ def smin_by(n = nil, &ruby_block)
3033
+ return self.make_iterator("min_by",n,&ruby_block)
3034
+ end
3035
+
3036
+ # HW implementation of the Ruby minmax.
3037
+ def sminmax(&ruby_block)
3038
+ return self.make_iterator("minmax",&ruby_block)
3039
+ end
3040
+
3041
+ # HW implementation of the Ruby minmax_by.
3042
+ def sminmax_by(&ruby_block)
3043
+ return self.make_iterator("minmax_by",&ruby_block)
3044
+ end
3045
+
3046
+ # Tell if none of the elements respects a given criterion given either
3047
+ # as +arg+ or as block.
3048
+ def snone?(arg = nil,&ruby_block)
3049
+ return self.make_iterator("none?",arg,&ruby_block)
3050
+ end
3051
+
3052
+ # Tell if one and only one of the elements respects a given criterion
3053
+ # given either as +arg+ or as block.
3054
+ def sone?(arg = nil,&ruby_block)
3055
+ return self.make_iterator("one?",arg,&ruby_block)
3056
+ end
3057
+
3058
+ # HW implementation of the Ruby partition.
3059
+ # NOTE: to do, or may be not.
3060
+ def spartition(*args,&ruby_block)
3061
+ raise "spartition is not supported yet."
3062
+ end
3063
+
3064
+ # HW implementatiob of the Ruby reject.
3065
+ def sreject(&ruby_block)
3066
+ return self.make_iterator("reject",&ruby_block)
3067
+ end
3068
+
3069
+ # HW implementatiob of the Ruby reverse_each.
3070
+ def sreverse_each(*args,&ruby_block)
3071
+ return self.make_iterator("reverse_each",*args,&ruby_block)
3072
+ end
3073
+
3074
+ # HW implementation of the Ruby slice_after.
3075
+ # NOTE: to do, or may be not.
3076
+ def sslice_after(pattern = nil,&ruby_block)
3077
+ raise "sslice_after is not supported yet."
3078
+ end
3079
+
3080
+ # HW implementation of the Ruby slice_before.
3081
+ # NOTE: to do, or may be not.
3082
+ def sslice_before(*args,&ruby_block)
3083
+ raise "sslice_before is not supported yet."
3084
+ end
3085
+
3086
+ # HW implementation of the Ruby slice_when.
3087
+ # NOTE: to do, or may be not.
3088
+ def sslice_when(*args,&ruby_block)
3089
+ raise "sslice_before is not supported yet."
3090
+ end
3091
+
3092
+ # Merge two arrays in order, for ssort only.
3093
+ def ssort_merge(arI, arO, first, middle, last, &ruby_block)
3094
+ return self.make_iterator("sort_merge",arI,arO,first,middle,last,&ruby_block)
3095
+ end
3096
+
3097
+ # HW implementation of the Ruby sort.
3098
+ def ssort(&ruby_block)
3099
+ return self.make_iterator("sort",&ruby_block)
3100
+ end
3101
+
3102
+ # HW implementation of the Ruby sort.
3103
+ def ssort_by(&ruby_block)
3104
+ return self.make_iterator("sort_by",&ruby_block)
3105
+ end
3106
+
3107
+ # HW implementation of the Ruby sum.
3108
+ def ssum(initial_value = nil,&ruby_block)
3109
+ return self.make_iterator("sum",initial_value,&ruby_block)
3110
+ end
3111
+
3112
+ # The HW implementation of the Ruby take.
3113
+ def stake(n)
3114
+ return self.make_iterator("take",n)
3115
+ end
3116
+
3117
+ # The HW implementation of the Ruby take_while.
3118
+ def stake_while(&ruby_block)
3119
+ return self.make_iterator("take_while",&ruby_block)
3120
+ end
3121
+
3122
+ # HW implementation of the Ruby tally.
3123
+ # NOTE: to do, or may be not.
3124
+ def stally(h = nil)
3125
+ raise "stally is not supported yet."
3126
+ end
3127
+
3128
+ # HW implementation of the Ruby to_h.
3129
+ # NOTE: to do, or may be not.
3130
+ def sto_h(h = nil)
3131
+ raise "sto_h is not supported yet."
3132
+ end
3133
+
3134
+ # HW implementation of the Ruby uniq.
3135
+ def suniq(&ruby_block)
3136
+ return self.make_iterator("uniq",&ruby_block)
3137
+ end
3138
+
3139
+ # HW implementation of the Ruby zip.
3140
+ # NOTE: for now szip is deactivated untile tuples are properly
3141
+ # handled by HDLRuby.
3142
+ def szip(obj,&ruby_block)
3143
+ return self.make_iterator("zip",obj,&ruby_block)
3144
+ end
3145
+
3146
+ # Iterator on the +num+ next elements.
3147
+ # *NOTE*:
3148
+ # - Stop iteration when the end of the range is reached or when there
3149
+ # are no elements left
3150
+ # - This is not a method from Ruby but one specific for hardware where
3151
+ # creating a array is very expensive.
3152
+ def seach_nexts(num,&ruby_block)
3153
+ return self.seach.snexts(num,&ruby_block)
3154
+ end
3155
+ end
3156
+
3157
+
3158
+ # Describes a SW implementation of a signal.
3159
+ class SignalI < Expression
3160
+ using RubyHDL::High
3161
+ attr_reader :type, :name #, :content
3162
+ # Create a new signal with type +type+ and name +name+.
3163
+ def initialize(type,name)
3164
+ @type = type.to_type
3165
+ @name = name.to_sym
3166
+ # Compute the mask for adjusting the value to the type.
3167
+ @mask = (2 ** @type.width)-1
3168
+ @sign = 2 ** (@type.width-1)
3169
+ end
3170
+
3171
+ # Tell if the signal is an array.
3172
+ def array?
3173
+ return @type.base.is_a?(TypeVector)
3174
+ end
3175
+
3176
+ # Convert to Ruby code.
3177
+ def to_ruby
3178
+ return "__" + self.name.to_s
3179
+ end
3180
+
3181
+ # Convert to C code.
3182
+ alias_method :to_c, :to_ruby
3183
+
3184
+ # Check if a value is defined for the signal.
3185
+ def value?
3186
+ return TOPLEVEL_BINDING.local_variable_defined?(self.to_ruby)
3187
+ end
3188
+
3189
+ # Gets the value of the signal.
3190
+ def value
3191
+ # return TOPLEVEL_BINDING.eval(self.to_ruby)
3192
+ res = TOPLEVEL_BINDING.eval(self.to_ruby)
3193
+ if res.is_a?(Integer) then
3194
+ res = res & @mask
3195
+ if @type.signed? then
3196
+ if res & @sign != 0 then
3197
+ return res - (@mask+1)
3198
+ end
3199
+ end
3200
+ end
3201
+ return res
3202
+ end
3203
+
3204
+ # Generate a Ruby/C string code for accessing the value of the
3205
+ # signal with proper bit width and sign.
3206
+ def value_text
3207
+ unless self.array? then
3208
+ if @type.signed? then
3209
+ return "(#{self.to_ruby} & #{@sign} != 0 ? #{self.to_ruby} & #{@mask} - #{@mask+1} : #{self.to_ruby} & #{@mask})"
3210
+ else
3211
+ return "(#{self.to_ruby} & #{@mask})"
3212
+ end
3213
+ else
3214
+ return self.to_ruby
3215
+ end
3216
+ end
3217
+
3218
+ # Sets the value of the signal.
3219
+ def value=(val)
3220
+ return TOPLEVEL_BINDING.eval("#{self.to_ruby} = #{val}")
3221
+ end
3222
+
3223
+ # Convert to an integer.
3224
+ def to_i
3225
+ return self.value.to_i
3226
+ end
3227
+
3228
+ # Convert to an float.
3229
+ def to_f
3230
+ return self.value.to_f
3231
+ end
3232
+
3233
+ # Convert to a string.
3234
+ def to_s
3235
+ return self.value.to_s
3236
+ end
3237
+ end
3238
+
3239
+
3240
+ # Describes a SW implementation of a block.
3241
+ class Sblock < SblockTop
3242
+ using RubyHDL::High
3243
+
3244
+ attr_reader :sequencer
3245
+
3246
+ # Create a new block for sequencer +sequencer+ and fill it by
3247
+ # executing +ruby_block+
3248
+ def initialize(sequencer,&ruby_block)
3249
+ super()
3250
+ # Sets the sequencer.
3251
+ @sequencer = sequencer
3252
+ # Initialize the statements.
3253
+ @statements = []
3254
+ # Push the new sblock on top of the stack.
3255
+ RubyHDL::High.push_sblock(self)
3256
+ # Make signals from the arguments of the ruby block.
3257
+ @args = []
3258
+ ruby_block.parameters.each do |typ,arg|
3259
+ @args << SignalI.new(Void,arg)
3260
+ end
3261
+ # Fill it.
3262
+ self.instance_exec(*@args,&ruby_block)
3263
+ # Pop the new sblock.
3264
+ RubyHDL::High.pop_sblock
3265
+ end
3266
+
3267
+ # Add a new statement to the block.
3268
+ def add(statement)
3269
+ # Add the statement.
3270
+ @statements.push(statement)
3271
+ # # If the statement is a transmit, schedule the corresponding
3272
+ # # signal for final update.
3273
+ # if statement.is_a?(Transmit) then
3274
+ # @sequencer.to_update(statement.left)
3275
+ # end
3276
+ statement
3277
+ end
3278
+ alias_method :<<, :add
3279
+
3280
+ # Delete a statement.
3281
+ def delete(statement)
3282
+ @statements.delete(statement)
3283
+ end
3284
+
3285
+ # Unshift a new statement.
3286
+ def unshift(statement)
3287
+ @statements.unshift(statement)
3288
+ end
3289
+
3290
+ # Get the last statement.
3291
+ def last_statement
3292
+ return @statements[-1]
3293
+ end
3294
+
3295
+
3296
+ # Convert to Ruby code.
3297
+ def to_ruby
3298
+ res = ""
3299
+ # Generate the arguments if any.
3300
+ if @args.any? then
3301
+ res = "|#{@args.map(&:to_ruby).join(",")}|\n"
3302
+ end
3303
+ # Generate the statements.
3304
+ res += @statements.map do |stmnt|
3305
+ stmnt.to_ruby + "\n"
2622
3306
  end.join
3307
+ return res
3308
+ end
3309
+
3310
+ # Convert to C code.
3311
+ def to_c
3312
+ res = ""
3313
+ # Generate the arguments if any.
3314
+ if @args.any? then
3315
+ res = "(#{@args.map(&:to_c).join(",")})\n"
3316
+ end
3317
+ # Generate the statements.
3318
+ res += "{" + @statements.map do |stmnt|
3319
+ stmnt.to_ruby + "\n"
3320
+ end.join + "}"
3321
+ return res
2623
3322
  end
2624
3323
 
2625
3324
  # The interface for describing statements and expressions.
@@ -2653,16 +3352,19 @@ module RubyHDL::High
2653
3352
  def sif(cond, &ruby_block)
2654
3353
  self << RubyHDL::High::Sif.new(@sequencer,cond,&ruby_block)
2655
3354
  end
3355
+ alias_method :hif, :sif
2656
3356
 
2657
3357
  # Create a sequential elsif statement on +cond+.
2658
3358
  def selsif(cond, &ruby_block)
2659
- self.statements[-1].selsif(&ruby_block)
3359
+ self.last_statement.selsif(&ruby_block)
2660
3360
  end
3361
+ alias_method :helsif, :selsif
2661
3362
 
2662
3363
  # Create a sequential else statement.
2663
3364
  def selse(&ruby_block)
2664
- self.statements[-1].selse(&ruby_block)
3365
+ self.last_statement.selse(&ruby_block)
2665
3366
  end
3367
+ alias_method :helse, :selse
2666
3368
 
2667
3369
  # Wait a given condition.
2668
3370
  def swait(cond)
@@ -2685,7 +3387,7 @@ module RubyHDL::High
2685
3387
  # Ensures there is a ruby block to avoid returning an enumerator
2686
3388
  # (returning an enumerator would be confusing for a for statement).
2687
3389
  ruby_block = proc {} unless ruby_block
2688
- expr.seach.with_index(&ruby_block)
3390
+ self << expr.seach.with_index(&ruby_block)
2689
3391
  end
2690
3392
 
2691
3393
  # The SW-specific statements and expressions.
@@ -2697,16 +3399,46 @@ module RubyHDL::High
2697
3399
  self << RubyHDL::High::Sync.new
2698
3400
  end
2699
3401
 
2700
- # Some arbirary Ruby code.
2701
- def ruby(&ruby_block)
2702
- self << RubyHDL::High::Ruby.new(&ruby_block)
3402
+ # Some arbirary Ruby code as a string +str+ or as a proc
3403
+ # +ruby_block+.
3404
+ def ruby(str = nil, &ruby_block)
3405
+ self << RubyHDL::High::Ruby.new(str,&ruby_block)
3406
+ end
3407
+
3408
+ # Some arbitrary code whose text is to add direction.
3409
+ def text(str)
3410
+ self << str.to_s
3411
+ end
3412
+ end
3413
+
3414
+
3415
+ # Describes a SW implementation of a sequencer function.
3416
+ class SfunctionT
3417
+ using RubyHDL::High
3418
+ attr_reader :name
3419
+ # Create a new named +name+ with arguments +args+ and
3420
+ # executing the content of block +sblock+
3421
+ def initialize(type,name,sblock,*args)
3422
+ @name = name.to_sym
3423
+ @args = args
3424
+ @blk = sblock
3425
+ end
3426
+
3427
+ # Convert to Ruby code.
3428
+ def to_ruby
3429
+ return "def #{name}(#{@args.map {|arg| arg.to_ruby}.join(",")}\n#{@blk.to_ruby}\nend\n"
3430
+ end
3431
+
3432
+ # Convert to C code.
3433
+ 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"
2703
3435
  end
2704
3436
  end
2705
3437
 
2706
3438
 
2707
3439
 
2708
3440
 
2709
- # Describes a SW implmentation of a sequencer.
3441
+ # Describes a SW implementation of a sequencer.
2710
3442
  class SequencerT
2711
3443
 
2712
3444
  # The source code (in ruby).
@@ -2729,43 +3461,63 @@ module RubyHDL::High
2729
3461
  this.resume if val.to_i == 1
2730
3462
  end
2731
3463
  end
2732
- # # Create the set of signals to update.
2733
- # @to_updates = []
3464
+ # Create a set of sfunction used in the sequencer.
3465
+ @sfunctions = {}
2734
3466
  # Create the main block.
2735
3467
  @sblock = RubyHDL::High::Sblock.new(self,&ruby_block)
2736
3468
  # Build the Ruby code.
2737
3469
  @source = ""
2738
3470
  @code = nil
2739
- self.build
3471
+ self.build_ruby
2740
3472
  end
2741
3473
 
2742
- # # Set a signal to be updated at the end of the sequencer.
2743
- # def to_update(signal)
2744
- # signal = signal.final_base unless signal.is_a?(SignalI)
2745
- # @to_updates << signal
2746
- # end
3474
+ # Add a sfunction.
3475
+ def add_sfunction(name,sfunction)
3476
+ @sfunctions[name.to_sym] = sfunction
3477
+ end
2747
3478
 
2748
- # # Iterator on the updates.
2749
- # def each_to_update(&ruby_block)
2750
- # # No ruby block? Return an enumerator.
2751
- # return to_enum(:each_to_update) unless ruby_block
2752
- # @to_updates.each(&ruby_block)
2753
- # end
2754
- #
3479
+ # Check if a sfunction is present.
3480
+ def sfunction?(name)
3481
+ return @sfunctions.key?(name.to_sym)
3482
+ end
3483
+
3484
+ # Get a sfunction by name.
3485
+ def sfunction(name)
3486
+ return @sfunctions[name.to_sym]
3487
+ end
2755
3488
 
2756
3489
  # Build the ruby code.
2757
- def build
3490
+ def build_ruby
2758
3491
  this = self
2759
3492
  @source = <<-BUILD
2760
3493
  #{RubyHDL::High.global_sblock.each_signal.map do |signal|
2761
- signal.to_ruby + " = " + (signal.array? ? "[]" : "nil") + " unless defined?(" + signal.to_ruby + ")"
3494
+ signal.to_ruby + " ||= " +
3495
+ (signal.array? ? "[]" : signal.value? ? signal.value.inspect : "nil")
2762
3496
  end.join("\n")}
2763
3497
  Fiber.new do
2764
3498
  #{@sblock.to_ruby}
2765
3499
  end
2766
3500
  BUILD
2767
3501
  # puts "building code_txt=" + @source
2768
- @code = TOPLEVEL_BINDING.eval(@source)
3502
+ self.reset!
3503
+ end
3504
+
3505
+ # Get the Ruby code.
3506
+ def to_ruby
3507
+ return @code
3508
+ end
3509
+
3510
+ # Convert to C code.
3511
+ def to_c
3512
+ typ = nil
3513
+ res = <<-BUILDC
3514
+ #{RubyHDL::High.global_sblock.each_signal.map do |signal|
3515
+ typ = signal.type
3516
+ typ.to_c + " " + signal.to_c + "=" + typ.to_c_init + ";"
3517
+ end.join("\n")}
3518
+ #{sblock.to_c}
3519
+ BUILDC
3520
+ return res
2769
3521
  end
2770
3522
 
2771
3523
  # Handling of the clock if any.
@@ -2779,6 +3531,15 @@ BUILD
2779
3531
  end
2780
3532
  end
2781
3533
 
3534
+ # Generate a clock up of +count+ cycles if any clock for C code.
3535
+ def clk_up_c(count = 1)
3536
+ if @clk then
3537
+ return "#{clk.to_c} += #{count.to_i};"
3538
+ else
3539
+ return ""
3540
+ end
3541
+ end
3542
+
2782
3543
 
2783
3544
  # Control of the sequencer.
2784
3545
 
@@ -2789,6 +3550,11 @@ BUILD
2789
3550
  end
2790
3551
  alias_method :call, :resume
2791
3552
 
3553
+ # Resets the sequencer.
3554
+ def reset!
3555
+ @code = TOPLEVEL_BINDING.eval(@source)
3556
+ end
3557
+
2792
3558
  # Check is the sequencer can still be resumed.
2793
3559
  def alive?
2794
3560
  @code.alive?
@@ -2806,20 +3572,40 @@ BUILD
2806
3572
  return SequencerT.new(clk,start,&ruby_block)
2807
3573
  end
2808
3574
 
2809
- # Creates an sequencer enumerator using a specific block access.
2810
- # - +typ+ is the data type of the elements.
2811
- # - +size+ is the number of elements, nil if not relevant.
2812
- # - +access+ is the block implementing the access method.
2813
- # def senumerator(typ,size,&access)
2814
- def senumerator(typ,size = nil,&access)
2815
- return SEnumeratorBase.new(typ,size,&access)
3575
+ # Create a 1-bit signal.
3576
+ def inner(*names)
3577
+ return [1].inner(*names)
2816
3578
  end
2817
3579
 
2818
-
2819
- end
3580
+ # Create a new function named +name+, built using block +ruby_block+.
3581
+ def sdef(name,&ruby_block)
3582
+ name = name.to_sym
3583
+ # 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
3595
+ # Execute the ruby block in a sequencer environment for building
3596
+ # the sblock.
3597
+ sblock = Sblock.new(cur_seq,&ruby_block)
3598
+ RubyHDL::High.pop_sblock
3599
+ # Create the function.
3600
+ function = SfunctionT.new(name,args,sblock)
3601
+ # Add it to the sequencer.
3602
+ cur_seq.add_sfunction(name)
3603
+ end
3604
+ Scall.new(cur_seq,name,args)
3605
+ end
3606
+ end
2820
3607
 
2821
3608
 
3609
+ end
2822
3610
 
2823
- include RubyHDL::High
2824
- using RubyHDL::High
2825
3611