HDLRuby 3.7.0 → 3.7.1

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,7 +151,7 @@ module RubyHDL::High
147
151
  # end
148
152
 
149
153
 
150
- # The translation of operators into ruby code.
154
+ # The translation of operators into Ruby code.
151
155
  RUBY_OPERATOR = {
152
156
  # Unary operators.
153
157
  :"-@" => "-(%s)", :"+@" => "+(%s)", :"~" => "~(%s)",
@@ -165,6 +169,24 @@ module RubyHDL::High
165
169
  :"<=" => "(%s)<=(%s)",:">=" => "(%s)>=(%s)"
166
170
  }
167
171
 
172
+ # The translation of operators into C code.
173
+ C_OPERATOR = {
174
+ # Unary operators.
175
+ :"-@" => "-(%s)", :"+@" => "+(%s)", :"~" => "~(%s)",
176
+ :abs => "(%s).abs",
177
+ :boolean => "%s", :bit => "%s",
178
+ :signed => "%s", :unsigned => "(%s) & 0xFFFFFFFFFFFFFFFF",
179
+
180
+ # Binary operators.
181
+ :"+" => "(%s)+(%s)", :"-" => "(%s)-(%s)", :"*" => "(%s)*(%s)",
182
+ :"/" => "(%s)/(%s)", :"%" => "(%s)%%(%s)", :"**" => "pow((%s),(%s))",
183
+ :"&" => "(%s)&(%s)", :"|" => "(%s)|(%s)", :"^" => "(%s)^(%s)",
184
+ :"<<" => "(%s)<<(%s)", :">>" => "(%s)>>(%s)",
185
+ :"==" => "(%s)==(%s)", :"!=" => "(%s)!=(%s)",
186
+ :"<" => "(%s)<(%s)", :">" => "(%s)>(%s)",
187
+ :"<=" => "(%s)<=(%s)",:">=" => "(%s)>=(%s)"
188
+ }
189
+
168
190
 
169
191
 
170
192
  # Module adding functionalities to object including the +seach+ method.
@@ -486,11 +508,15 @@ module RubyHDL::High
486
508
  end
487
509
 
488
510
 
489
- # Modify String to act as ruby code generator.
511
+ # Modify String to act as Ruby code generator.
490
512
  refine ::String do
513
+ # Convert to Ruby code.
491
514
  def to_ruby
492
515
  self
493
516
  end
517
+
518
+ # Convert to C code.
519
+ alias_method :to_c, :to_ruby
494
520
  end
495
521
 
496
522
 
@@ -501,6 +527,14 @@ module RubyHDL::High
501
527
  end
502
528
  alias_method :to_expr, :to_value
503
529
 
530
+ def to_ruby
531
+ return self
532
+ end
533
+
534
+ def to_c
535
+ return self.to_s
536
+ end
537
+
504
538
  # Enhance the Integer class with sequencer iterations.
505
539
 
506
540
  # HW times iteration.
@@ -527,12 +561,19 @@ module RubyHDL::High
527
561
  alias_method :to_expr, :to_value
528
562
  end
529
563
 
564
+ # Modify Range to act as RubyHDL object.
565
+ refine ::Range do
566
+ def to_ruby
567
+ return "(#{self})"
568
+ end
569
+ end
570
+
530
571
  # Modify Range to support HW iterators.
531
572
  refine ::Enumerable do
532
573
  import_methods SEnumerable
533
574
  # HW iteration on each element.
534
575
  def seach(&ruby_block)
535
- RubyHDL::High.top_sblock << SeachEnumerable.new(self,&ruby_block)
576
+ return Siter.new(RubyHDL::High.top_sblock.sequencer,self,"each",&ruby_block)
536
577
  end
537
578
  end
538
579
 
@@ -901,6 +942,30 @@ module RubyHDL::High
901
942
  # A block? Apply it on each overload if any.
902
943
  @overloads.each(&ruby_block) if @overloads
903
944
  end
945
+
946
+ # Convert to C code.
947
+ def to_c
948
+ case @name
949
+ when :void
950
+ return "void"
951
+ when :bit, :unsigned
952
+ return "unsigned"
953
+ when :signed
954
+ return "signed"
955
+ when :float
956
+ return "double"
957
+ when :string
958
+ return "char*"
959
+ else
960
+ return @name.to_s
961
+ end
962
+ end
963
+
964
+ # Convert to C initialization code.
965
+ def to_c_init
966
+ # By default: 0
967
+ return "0"
968
+ end
904
969
  end
905
970
 
906
971
 
@@ -1143,6 +1208,32 @@ module RubyHDL::High
1143
1208
  end
1144
1209
 
1145
1210
  alias_method :each_deep, :each_type_deep
1211
+
1212
+ # Convert to C code.
1213
+ def to_c
1214
+ if @base.is_a?(TypeVector) then
1215
+ # Array type case.
1216
+ return @base.to_c + "[#{self.size.to_i}]"
1217
+ else
1218
+ # Simple vector type case.
1219
+ if float? then
1220
+ return @base.to_c
1221
+ else
1222
+ return @base + " long long"
1223
+ end
1224
+ end
1225
+ end
1226
+
1227
+ # Convert to C initialization code.
1228
+ def to_c_init
1229
+ if @base.is_a?(TypeVector) then
1230
+ # Array type case.
1231
+ base_init = @base.to_c_init
1232
+ return "[" + ([base_init] * self.size.to_i).join(",") + "]"
1233
+ else
1234
+ return "0"
1235
+ end
1236
+ end
1146
1237
  end
1147
1238
 
1148
1239
 
@@ -1558,11 +1649,16 @@ module RubyHDL::High
1558
1649
  raise "to_value not defined here."
1559
1650
  end
1560
1651
 
1561
- # Convert to ruby code.
1652
+ # Convert to Ruby code.
1562
1653
  def to_ruby
1563
1654
  raise "to_ruby not defined for class: #{self.class}."
1564
1655
  end
1565
1656
 
1657
+ # Convert to C code.
1658
+ def to_c
1659
+ raise "to_c not defined for class: #{self.class}."
1660
+ end
1661
+
1566
1662
  # Convert to ruby code for left value.
1567
1663
  # By default: the same as to_ruby
1568
1664
  alias_method :to_ruby_left, :to_ruby
@@ -1709,10 +1805,13 @@ module RubyHDL::High
1709
1805
  return self
1710
1806
  end
1711
1807
 
1712
- # Convert to ruby code.
1808
+ # Convert to Ruby code.
1713
1809
  def to_ruby
1714
1810
  return @content.to_s
1715
1811
  end
1812
+
1813
+ # Convert to C code.
1814
+ alias_method :to_c, :to_ruby
1716
1815
  end
1717
1816
 
1718
1817
 
@@ -1726,10 +1825,15 @@ module RubyHDL::High
1726
1825
  @child = child.to_expr
1727
1826
  end
1728
1827
 
1729
- # Convert to ruby code.
1828
+ # Convert to Ruby code.
1730
1829
  def to_ruby
1731
1830
  return RUBY_OPERATOR[@operator] % @child.to_ruby
1732
1831
  end
1832
+
1833
+ # Convert to C code.
1834
+ def to_c
1835
+ return C_OPERATOR[@operator] % @child.to_c
1836
+ end
1733
1837
  end
1734
1838
 
1735
1839
  # Describes the software implementation of an binary operation.
@@ -1743,10 +1847,15 @@ module RubyHDL::High
1743
1847
  @right = right.to_expr
1744
1848
  end
1745
1849
 
1746
- # Convert to ruby code.
1850
+ # Convert to Ruby code.
1747
1851
  def to_ruby
1748
1852
  return RUBY_OPERATOR[@operator] % [ @left.to_ruby, @right.to_ruby ]
1749
1853
  end
1854
+
1855
+ # Convert to C code.
1856
+ def to_c
1857
+ return C_OPERATOR[@operator] % [ @left.to_c, @right.to_c ]
1858
+ end
1750
1859
  end
1751
1860
 
1752
1861
  # Describes the software implementation of an select operation.
@@ -1759,13 +1868,21 @@ module RubyHDL::High
1759
1868
  @choices = choices.map(&:to_expr)
1760
1869
  end
1761
1870
 
1762
- # Convert to ruby code.
1871
+ # Convert to Ruby code.
1763
1872
  def to_ruby
1764
1873
  return "case(#{@sel.to_}) ; " +
1765
1874
  @choices.map.with_index do |choice,i|
1766
1875
  "when #{i} ; #{choice.to_ruby} ; "
1767
1876
  end.join + "end"
1768
1877
  end
1878
+
1879
+ # Convert to C code.
1880
+ def to_c
1881
+ return "switch(#{@sel.to_c}) {\n" +
1882
+ @choices.map.with_index do |choice,i|
1883
+ "case #{i}:\n#{choice.to_c}\nbreak;"
1884
+ end.join("\n") + "\n}"
1885
+ end
1769
1886
  end
1770
1887
 
1771
1888
  # Describes a SW implementation of a reference.
@@ -1798,10 +1915,13 @@ module RubyHDL::High
1798
1915
  @name = name.to_sym
1799
1916
  end
1800
1917
 
1801
- # Convert to ruby code.
1918
+ # Convert to Ruby code.
1802
1919
  def to_ruby
1803
1920
  return @name.to_s
1804
1921
  end
1922
+
1923
+ # Convert to C code.
1924
+ alias_method :to_c, :to_ruby
1805
1925
  end
1806
1926
 
1807
1927
  # Describes a SW implementation of an index reference.
@@ -1857,10 +1977,15 @@ module RubyHDL::High
1857
1977
  return @idx..@idx
1858
1978
  end
1859
1979
 
1860
- # Convert to ruby code.
1980
+ # Convert to Ruby code.
1861
1981
  def to_ruby
1862
1982
  return "#{@base.to_ruby}[#{@idx.to_ruby}]"
1863
1983
  end
1984
+
1985
+ # Convert to C code.
1986
+ def to_c
1987
+ return "#{@base.to_c}[#{@idx.to_c}]"
1988
+ end
1864
1989
  end
1865
1990
 
1866
1991
  # Describes a SW implementation of an range reference.
@@ -1916,10 +2041,25 @@ module RubyHDL::High
1916
2041
  # return rng
1917
2042
  # end
1918
2043
 
1919
- # Convert to ruby code.
2044
+ # Convert to Ruby code.
1920
2045
  def to_ruby
1921
2046
  return "#{@base.to_ruby}[#{@rng.first.to_ruby}..#{@rng.last.to_ruby}]"
1922
2047
  end
2048
+
2049
+ # Convert to C code.
2050
+ def to_c
2051
+ if @base.type.base.is_a?(TypeVector) then
2052
+ raise "Range access not supported yet for arrays."
2053
+ else
2054
+ # Compute the writing and clearing masks
2055
+ smask = (1.to_value<<(@rng.first+1-@rng.last))-1
2056
+ cmask = ~(smask << @rng.last)
2057
+ # Get the final base.
2058
+ base = @base.final_base.to_c
2059
+ # Generate the ruby code.
2060
+ return "(#{base} & #{cmask.to_c}) >> (#{@rng.last.to_c})"
2061
+ end
2062
+ end
1923
2063
  end
1924
2064
 
1925
2065
 
@@ -1948,7 +2088,7 @@ module RubyHDL::High
1948
2088
  return Binary.new(@left.type,@left,@right)
1949
2089
  end
1950
2090
 
1951
- # Convert to ruby code.
2091
+ # Convert to Ruby code.
1952
2092
  def to_ruby
1953
2093
  if (@left.is_a?(RefIndex) or @left.is_a?(RefRange)) then
1954
2094
  if @left.base.type.base.is_a?(TypeVector) then
@@ -1956,8 +2096,6 @@ module RubyHDL::High
1956
2096
  base = @left.final_base.to_ruby
1957
2097
  return "#{base} ||= []; #{@left.to_ruby} = #{@right.to_ruby}"
1958
2098
  else
1959
- # # Compute the final access range.
1960
- # rng = @left.final_range
1961
2099
  # Get the access range.
1962
2100
  rng = @left.range
1963
2101
  # Compute the writing and clearing masks
@@ -1973,6 +2111,29 @@ module RubyHDL::High
1973
2111
  return "#{@left.to_ruby} = #{@right.to_ruby}"
1974
2112
  end
1975
2113
  end
2114
+
2115
+ # Convert to C code.
2116
+ def to_c
2117
+ if (@left.is_a?(RefIndex) or @left.is_a?(RefRange)) then
2118
+ if @left.base.type.base.is_a?(TypeVector) then
2119
+ return "#{@left.to_c} = #{@right.to_c}"
2120
+ else
2121
+ # Get the access range.
2122
+ rng = @left.range
2123
+ # Compute the writing and clearing masks
2124
+ smask = (1.to_value<<(rng.first+1-rng.last))-1
2125
+ cmask = ~(smask << rng.last)
2126
+ # Get the final base.
2127
+ base = left.final_base.to_c
2128
+ # Generate the ruby code.
2129
+ return "#{base} &= #{cmask.to_c}; " +
2130
+ "#{base} |= (((#{@right.to_c} & #{smask.to_c}) << (#{rng.last.to_c})))"
2131
+ end
2132
+ else
2133
+ return "#{@left.to_c} = #{@right.to_c};"
2134
+ end
2135
+ end
2136
+
1976
2137
  end
1977
2138
 
1978
2139
  # Describes a SW implementation of a if statement.
@@ -1998,16 +2159,28 @@ module RubyHDL::High
1998
2159
  @else_blk = Sblock.new(@sequencer,&ruby_block)
1999
2160
  end
2000
2161
 
2001
- # Convert to ruby code.
2162
+ # Convert to Ruby code.
2002
2163
  def to_ruby
2003
- res = @sequencer.clk_up + "\nif(#{@cond.to_ruby})\n#{@yes.to_ruby}\n"
2164
+ res = @sequencer.clk_up + "\nif(#{@condition.to_ruby})\n#{@yes_blk.to_ruby}\n"
2004
2165
  @elsifs.each do |(cond,blk)|
2005
2166
  res << "elsif(#{cond.to_ruby})\n#{blk.to_ruby}\n"
2006
2167
  end
2007
2168
  if @else_blk then
2008
2169
  res << "else\n#{@else_blk.to_ruby}\n"
2009
2170
  end
2010
- return res + @sequencer.clk_up
2171
+ return res + "end\n" + @sequencer.clk_up
2172
+ end
2173
+
2174
+ # Convert to C code.
2175
+ def to_c
2176
+ res = @sequencer.clk_up + "\nif(#{@condition.to_c}) {\n#{@yes_blk.to_c}\n}"
2177
+ @elsifs.each do |(cond,blk)|
2178
+ res << "\nelse if(#{cond.to_c}) {\n#{blk.to_c}\n}"
2179
+ end
2180
+ if @else_blk then
2181
+ res << "\nelse {\n#{@else_blk.to_c}\n}"
2182
+ end
2183
+ return res + @sequencer.clk_up_c
2011
2184
  end
2012
2185
  end
2013
2186
 
@@ -2020,9 +2193,14 @@ module RubyHDL::High
2020
2193
  @blk = Sblock.new(sequencer,&ruby_block)
2021
2194
  end
2022
2195
 
2023
- # Convert to ruby code.
2196
+ # Convert to Ruby code.
2024
2197
  def to_ruby
2025
- return "loop do\n#{@blk.to_ruby}\n#{@sequencer.clk_up}\nend\n"
2198
+ return "loop do\n#{@blk.to_ruby}\n#{@sequencer.clk_up}\nend"
2199
+ end
2200
+
2201
+ # Convert to C code.
2202
+ def to_c
2203
+ return "for(;;){\n#{@blk.to_ruby}\n#{@sequencer.clk_up_c}\n}"
2026
2204
  end
2027
2205
  end
2028
2206
 
@@ -2037,10 +2215,15 @@ module RubyHDL::High
2037
2215
  @yes_blk = Sblock.new(sequencer,&ruby_block)
2038
2216
  end
2039
2217
 
2040
- # Convert to ruby code.
2218
+ # Convert to Ruby code.
2041
2219
  def to_ruby
2042
2220
  return @sequencer.clk_up +
2043
- "\nwhile(#{@condition.to_ruby}) do\n#{@yes_blk.to_ruby}\n#{@sequencer.clk_up}\nend\n"
2221
+ "\nwhile(#{@condition.to_ruby}) do\n#{@yes_blk.to_ruby}\n#{@sequencer.clk_up}\nend"
2222
+ end
2223
+
2224
+ # Convert to C code.
2225
+ def to_c
2226
+ "\nwhile(#{@condition.to_c}) {\n#{@yes_blk.to_c}\n#{@sequencer.clk_up_c}\n}"
2044
2227
  end
2045
2228
  end
2046
2229
 
@@ -2051,10 +2234,15 @@ module RubyHDL::High
2051
2234
  @sequencer = sequencer
2052
2235
  end
2053
2236
 
2054
- # Convert to ruby code.
2237
+ # Convert to Ruby code.
2055
2238
  def to_ruby
2056
2239
  return @sequencer.clk_up
2057
2240
  end
2241
+
2242
+ # Convert to C code.
2243
+ def to_c
2244
+ return @sequencer.clk_up_c
2245
+ end
2058
2246
  end
2059
2247
 
2060
2248
  # Describes a SW implementation of a break statement.
@@ -2064,10 +2252,15 @@ module RubyHDL::High
2064
2252
  @sequencer = sequencer
2065
2253
  end
2066
2254
 
2067
- # Convert to ruby code.
2255
+ # Convert to Ruby code.
2068
2256
  def to_ruby
2069
2257
  return @sequencer.clk_up + "\nbreak"
2070
2258
  end
2259
+
2260
+ # Convert to C code.
2261
+ def to_c
2262
+ return @sequencer.clk_up_c + "\nbreak;"
2263
+ end
2071
2264
  end
2072
2265
 
2073
2266
  # Describes a SW implementation of a continue statement.
@@ -2077,10 +2270,15 @@ module RubyHDL::High
2077
2270
  @sequencer = sequencer
2078
2271
  end
2079
2272
 
2080
- # Convert to ruby code.
2273
+ # Convert to Ruby code.
2081
2274
  def to_ruby
2082
2275
  return @sequencer.clk_up + "\ncontinue"
2083
2276
  end
2277
+
2278
+ # Convert to Ruby code.
2279
+ def to_c
2280
+ return @sequencer.clk_up_c + "\ncontinue;"
2281
+ end
2084
2282
  end
2085
2283
 
2086
2284
  # Describes a SW implementation of a terminate statement.
@@ -2090,12 +2288,17 @@ module RubyHDL::High
2090
2288
  @sequencer = sequencer
2091
2289
  end
2092
2290
 
2093
- # Convert to ruby code.
2291
+ # Convert to Ruby code.
2094
2292
  def to_ruby
2095
2293
  # Implemented as returning from a function since a sequencer
2096
2294
  # is implemented as one.
2097
2295
  return @sequencer.clk_up + "\nreturn"
2098
2296
  end
2297
+
2298
+ # Convert to C code.
2299
+ def to_c
2300
+ return @sequencer.clk_up_c + "\nreturn;"
2301
+ end
2099
2302
  end
2100
2303
 
2101
2304
  # Describes a SW synchronization of a signal.
@@ -2103,23 +2306,34 @@ module RubyHDL::High
2103
2306
  def initialize
2104
2307
  end
2105
2308
 
2106
- # Convert to ruby code.
2309
+ # Convert to Ruby code.
2107
2310
  def to_ruby
2108
2311
  return "Fiber.yield"
2109
2312
  end
2313
+
2314
+ # Convert to C code.
2315
+ def to_c
2316
+ return "yield();"
2317
+ end
2110
2318
  end
2111
2319
 
2112
2320
  # Describes arbitrary code.
2113
2321
  class Ruby < Expression
2114
2322
  @@ruby_blocks = []
2115
2323
 
2116
- # Create a new ruby code block for +ruby_block+.
2117
- def initialize(&ruby_block)
2324
+ # Create a new ruby code block for either +ruby_block+ or
2325
+ # string +str+.
2326
+ def initialize(str = nil, &ruby_block)
2327
+ @str = str
2118
2328
  # puts "ruby_block=#{ruby_block}"
2119
2329
  # Create the id for the block.
2120
2330
  @id = @@ruby_blocks.size
2121
2331
  # Adds the block.
2122
- @@ruby_blocks << ruby_block
2332
+ if ruby_block then
2333
+ @@ruby_blocks << ruby_block
2334
+ else
2335
+ @@ruby_blocks << proc { TOPLEVEL_BINDING.eval(@str.to_s) }
2336
+ end
2123
2337
  end
2124
2338
 
2125
2339
  # Convert to expression: does not change but remove from the
@@ -2136,39 +2350,45 @@ module RubyHDL::High
2136
2350
  @@ruby_blocks[id].call
2137
2351
  end
2138
2352
 
2139
- # Convert to ruby code.
2353
+ # Convert to Ruby code.
2140
2354
  def to_ruby
2141
- puts caller[0]
2142
- return "RubyHDL::High::Ruby.call(#{@id})"
2355
+ # puts caller[0]
2356
+ if @str then
2357
+ return TOPLEVEL_BINDING.eval(@str)
2358
+ else
2359
+ return "RubyHDL::High::Ruby.call(#{@id})"
2360
+ end
2361
+ end
2362
+
2363
+ # Convert to C code.
2364
+ def to_c
2365
+ return "rb_eval_string(\"#{@str.to_s}\");"
2143
2366
  end
2144
2367
  end
2145
2368
 
2146
- # Describes a SW implementation of an iterator statement.
2147
- class Siter
2369
+
2370
+ # Describes a SW implementation of an call statement.
2371
+ class Scall
2148
2372
  using RubyHDL::High
2149
2373
 
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)
2374
+ # Create a new call statement in sequencer +sequencer+ for function
2375
+ # named +name+ with arguments +args+.
2376
+ def initialize(sequencer, name, *args)
2154
2377
  @sequencer = sequencer
2155
- puts "@sequencer=#{@sequencer}"
2156
- @commands = commands
2157
- @blk = Sblock.new(sequencer,&ruby_block)
2378
+ @name = name.to_sym
2379
+ @args = args
2158
2380
  end
2159
2381
 
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)
2382
+ # Convert to Ruby code.
2383
+ def to_ruby
2384
+ return @sequencer.clk_up + "\n#{name}(" +
2385
+ @args.map {|arg| arg.to_ruby}.join(",") + ")"
2164
2386
  end
2165
- alias_method :each, :each_command
2166
2387
 
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"
2388
+ # Convert to C code.
2389
+ def to_c
2390
+ return @sequencer.clk_up + "\n#{name}(" +
2391
+ @args.map {|arg| arg.to_ruby}.join(",") + ");"
2172
2392
  end
2173
2393
 
2174
2394
  # Create an iterator for a given method +meth+.
@@ -2504,127 +2724,526 @@ module RubyHDL::High
2504
2724
  end
2505
2725
 
2506
2726
 
2507
- # Describes a SW implementation of a signal.
2508
- class SignalI < Expression
2727
+ # Describes a SW implementation of an iterator statement.
2728
+ class Siter
2509
2729
  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
2730
 
2518
- # Tell if the signal is an array.
2519
- def array?
2520
- return @type.base.is_a?(TypeVector)
2731
+ # Create a new iteration statement in sequencer +sequencer+
2732
+ # for chain of commands +commands+ to interate while
2733
+ # executing +ruby_block+.
2734
+ def initialize(sequencer,*commands, &ruby_block)
2735
+ @sequencer = sequencer
2736
+ @commands = commands
2737
+ if ruby_block then
2738
+ # The iterator is finalized.
2739
+ @blk = Sblock.new(sequencer,&ruby_block)
2740
+ end
2741
+ # puts "New iterator with blk=#{@blk} commands=#{@commands}"
2521
2742
  end
2522
2743
 
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
2744
+ # Iterate on the commands.
2745
+ def each_command(&ruby_block)
2746
+ return to_enum(:each_command) unless ruby_block
2747
+ @commands.each(&ruby_block)
2748
+ end
2749
+ alias_method :each, :each_command
2532
2750
 
2533
- # Convert to ruby code.
2751
+ # Convert to Ruby code.
2534
2752
  def to_ruby
2535
- # return self.name.to_s + ".content"
2536
- return "__" + self.name.to_s
2753
+ # puts "to_ruby with blk=#{@blk} commands=#{@commands}"
2754
+ res = @sequencer.clk_up + "\n" +
2755
+ @commands.map { |command| command.to_ruby }.join(".")
2756
+ return res + " do\n#{@blk.to_ruby}\n#{@sequencer.clk_up}\nend"
2537
2757
  end
2538
2758
 
2539
- # Gets the value of the signal.
2540
- def value
2541
- return TOPLEVEL_BINDING.eval(self.to_ruby)
2759
+ # Convert to C code.
2760
+ def to_c
2761
+ res = @sequencer.clk_up_c + "\n" +
2762
+ @commands.map { |command| command.to_c }.join("_")
2763
+ return res + "(#{@blk.to_c})"
2542
2764
  end
2543
2765
 
2544
- # Sets the value of the signal.
2545
- def value=(val)
2546
- return TOPLEVEL_BINDING.eval("#{self.to_ruby} = #{val}")
2766
+ # Create an iterator for a given method +meth+.
2767
+ def make_iterator(meth,*args,&ruby_block)
2768
+ # if ruby_block then
2769
+ # blk = Sblock.new(@sequencer,&ruby_block)
2770
+ # command = RubyHDL::High::Ruby.new do
2771
+ # "#{meth}(#{args.map{|arg| arg.to_ruby}.join(",")}) { #{blk.to_ruby} }"
2772
+ # end
2773
+ # else
2774
+ # command = RubyHDL::High::Ruby.new do
2775
+ # "#{meth}(#{args.map{|arg| arg.to_ruby}.join(",")})"
2776
+ # end
2777
+ # end
2778
+ command = "#{meth}"
2779
+ if args.any? then
2780
+ command += "(*#{RubyHDL::High::Ruby.new {
2781
+ "#{args.map{|arg| arg.to_ruby}.join(",")}"}})"
2782
+ end
2783
+ return Siter.new(@sequencer,*@commands,command,&ruby_block)
2547
2784
  end
2548
2785
 
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
2786
+ # The iterator methods.
2555
2787
 
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
2788
+ # Iterator on each of the elements in range +rng+.
2789
+ # *NOTE*:
2790
+ # - Stop iteration when the end of the range is reached or when there
2791
+ # are no elements left
2792
+ # - This is not a method from Ruby but one specific for hardware where
2793
+ # creating a array is very expensive.
2794
+ def seach_range(rng,&ruby_block)
2795
+ return self.make_iterator("each_range",rng,&ruby_block)
2561
2796
  end
2562
2797
 
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
2798
+ # Tell if all the elements respect a given criterion given either
2799
+ # as +arg+ or as block.
2800
+ def sall?(arg = nil,&ruby_block)
2801
+ return self.make_iterator("all?",arg,&ruby_block)
2568
2802
  end
2569
- end
2570
-
2571
2803
 
2572
- # Describes a SW implementation of a block.
2573
- class Sblock < SblockTop
2574
- using RubyHDL::High
2575
-
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
2804
+ # Tell if any of the elements respects a given criterion given either
2805
+ # as +arg+ or as block.
2806
+ def sany?(arg = nil,&ruby_block)
2807
+ return self.make_iterator("any?",arg,&ruby_block)
2592
2808
  end
2593
2809
 
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
2810
+ # Returns an SEnumerator generated from current enumerable and +arg+
2811
+ def schain(arg)
2812
+ return self.make_iterator("chain",arg)
2604
2813
  end
2605
- alias_method :<<, :add
2606
2814
 
2607
- # Delete a statement.
2608
- def delete(statement)
2609
- @statements.delete(statement)
2815
+ # HW implementation of the Ruby chunk.
2816
+ # NOTE: to do, or may be not.
2817
+ def schunk(*args,&ruby_block)
2818
+ raise "schunk is not supported yet."
2610
2819
  end
2611
2820
 
2612
- # Unshift a new statement.
2613
- def unshift(statement)
2614
- @statements.unshift(statement)
2821
+ # HW implementation of the Ruby chunk_while.
2822
+ # NOTE: to do, or may be not.
2823
+ def schunk_while(*args,&ruby_block)
2824
+ raise "schunk_while is not supported yet."
2615
2825
  end
2616
2826
 
2617
-
2618
- # Convert to ruby code.
2619
- def to_ruby
2620
- return @statements.map do |stmnt|
2621
- stmnt.to_ruby + "\n"
2622
- end.join
2827
+ # Returns a vector containing the execution result of the given block
2828
+ # on each element. If no block is given, return an SEnumerator.
2829
+ # NOTE: be carful that the resulting vector can become huge if there
2830
+ # are many element.
2831
+ def smap(&ruby_block)
2832
+ return self.make_iterator("map",&ruby_block)
2623
2833
  end
2624
2834
 
2625
- # The interface for describing statements and expressions.
2626
-
2627
- # Mark a step.
2835
+ # HW implementation of the Ruby flat_map.
2836
+ # NOTE: actually due to the way HDLRuby handles vectors, should work
2837
+ # like smap
2838
+ def sflat_map(&ruby_block)
2839
+ return self.make_iterator("flat_map",&ruby_block)
2840
+ end
2841
+
2842
+ # HW implementation of the Ruby compact, but remove 0 values instead
2843
+ # on nil (since nil that does not have any meaning in HW).
2844
+ def scompact
2845
+ return self.make_iterator("compact",&ruby_block)
2846
+ end
2847
+
2848
+
2849
+ # WH implementation of the Ruby count.
2850
+ def scount(obj = nil, &ruby_block)
2851
+ return self.make_iterator("count",obj,&ruby_block)
2852
+ end
2853
+
2854
+ # HW implementation of the Ruby cycle.
2855
+ def scycle(n = nil,&ruby_block)
2856
+ return self.make_iterator("cycle",n,&ruby_block)
2857
+ end
2858
+
2859
+ # HW implementation of the Ruby find.
2860
+ # NOTE: contrary to Ruby, if_none_proc is mandatory since there is no
2861
+ # nil in HW. Moreover, the argument can also be a value.
2862
+ def sfind(if_none_proc, &ruby_block)
2863
+ return self.make_iterator("find",if_none_proc,&ruby_block)
2864
+ end
2865
+
2866
+ # HW implementation of the Ruby drop.
2867
+ def sdrop(n)
2868
+ return self.make_iterator("drop",n)
2869
+ end
2870
+
2871
+ # HW implementation of the Ruby drop_while.
2872
+ def sdrop_while(&ruby_block)
2873
+ return self.make_iterator("drop_while",&ruby_block)
2874
+ end
2875
+
2876
+ # HW implementation of the Ruby each_cons
2877
+ def seach_cons(n,&ruby_block)
2878
+ return self.make_iterator("each_cons",n,&ruby_block)
2879
+ end
2880
+
2881
+ # HW implementation of the Ruby each_entry.
2882
+ # NOTE: to do, or may be not.
2883
+ def seach_entry(*args,&ruby_block)
2884
+ raise "seach_entry is not supported yet."
2885
+ end
2886
+
2887
+ # HW implementation of the Ruby each_slice
2888
+ def seach_slice(n,&ruby_block)
2889
+ return self.make_iterator("each_slice",n,&ruby_block)
2890
+ end
2891
+
2892
+ # HW implementation of the Ruby each_with_index.
2893
+ def seach_with_index(*args,&ruby_block)
2894
+ return self.make_iterator("each_with_index",*args,&ruby_block)
2895
+ end
2896
+ alias_method :with_index, :seach_with_index
2897
+
2898
+ # HW implementation of the Ruby each_with_object.
2899
+ def seach_with_object(obj,&ruby_block)
2900
+ return self.make_iterator("each_with_object",obj,&ruby_block)
2901
+ end
2902
+
2903
+ # HW implementation of the Ruby to_a.
2904
+ def sto_a
2905
+ return self.make_iterator("to_a")
2906
+ end
2907
+
2908
+ # HW implementation of the Ruby select.
2909
+ def sselect(&ruby_block)
2910
+ return self.make_iterator("select",&ruby_block)
2911
+ end
2912
+
2913
+ # HW implementation of the Ruby find_index.
2914
+ def sfind_index(obj = nil, &ruby_block)
2915
+ return self.make_iterator("find_index",obj,&ruby_block)
2916
+ end
2917
+
2918
+ # HW implementation of the Ruby first.
2919
+ def sfirst(n=1)
2920
+ return self.make_iterator("first",n)
2921
+ end
2922
+
2923
+ # HW implementation of the Ruby grep.
2924
+ # NOTE: to do, or may be not.
2925
+ def sgrep(*args,&ruby_block)
2926
+ raise "sgrep is not supported yet."
2927
+ end
2928
+
2929
+ # HW implementation of the Ruby grep_v.
2930
+ # NOTE: to do, or may be not.
2931
+ def sgrep_v(*args,&ruby_block)
2932
+ raise "sgrep_v is not supported yet."
2933
+ end
2934
+
2935
+ # HW implementation of the Ruby group_by.
2936
+ # NOTE: to do, or may be not.
2937
+ def sgroup_by(*args,&ruby_block)
2938
+ raise "sgroup_by is not supported yet."
2939
+ end
2940
+
2941
+ # HW implementation of the Ruby include?
2942
+ def sinclude?(obj)
2943
+ return self.make_iterator("include?",obj)
2944
+ end
2945
+
2946
+ # HW implementation of the Ruby inject.
2947
+ def sinject(*args,&ruby_block)
2948
+ return self.make_iterator("inject",*args,&ruby_block)
2949
+ end
2950
+
2951
+ # HW implementation of the Ruby reduce.
2952
+ def sreduce
2953
+ return self.make_iterator("reduce",*args,&ruby_block)
2954
+ end
2955
+
2956
+
2957
+ # HW implementation of the Ruby lazy.
2958
+ # NOTE: to do, or may be not.
2959
+ def slazy(*args,&ruby_block)
2960
+ raise "slazy is not supported yet."
2961
+ end
2962
+
2963
+ # HW implementation of the Ruby max.
2964
+ def smax(n = nil, &ruby_block)
2965
+ return self.make_iterator("max",n,&ruby_block)
2966
+ end
2967
+
2968
+ # HW implementation of the Ruby max_by.
2969
+ def smax_by(n = nil, &ruby_block)
2970
+ return self.make_iterator("max_by",n,&ruby_block)
2971
+ end
2972
+
2973
+ # HW implementation of the Ruby min.
2974
+ def smin(n = nil, &ruby_block)
2975
+ return self.make_iterator("min",n,&ruby_block)
2976
+ end
2977
+
2978
+ # HW implementation of the Ruby min_by.
2979
+ def smin_by(n = nil, &ruby_block)
2980
+ return self.make_iterator("min_by",n,&ruby_block)
2981
+ end
2982
+
2983
+ # HW implementation of the Ruby minmax.
2984
+ def sminmax(&ruby_block)
2985
+ return self.make_iterator("minmax",&ruby_block)
2986
+ end
2987
+
2988
+ # HW implementation of the Ruby minmax_by.
2989
+ def sminmax_by(&ruby_block)
2990
+ return self.make_iterator("minmax_by",&ruby_block)
2991
+ end
2992
+
2993
+ # Tell if none of the elements respects a given criterion given either
2994
+ # as +arg+ or as block.
2995
+ def snone?(arg = nil,&ruby_block)
2996
+ return self.make_iterator("none?",arg,&ruby_block)
2997
+ end
2998
+
2999
+ # Tell if one and only one of the elements respects a given criterion
3000
+ # given either as +arg+ or as block.
3001
+ def sone?(arg = nil,&ruby_block)
3002
+ return self.make_iterator("one?",arg,&ruby_block)
3003
+ end
3004
+
3005
+ # HW implementation of the Ruby partition.
3006
+ # NOTE: to do, or may be not.
3007
+ def spartition(*args,&ruby_block)
3008
+ raise "spartition is not supported yet."
3009
+ end
3010
+
3011
+ # HW implementatiob of the Ruby reject.
3012
+ def sreject(&ruby_block)
3013
+ return self.make_iterator("reject",&ruby_block)
3014
+ end
3015
+
3016
+ # HW implementatiob of the Ruby reverse_each.
3017
+ def sreverse_each(*args,&ruby_block)
3018
+ return self.make_iterator("reverse_each",*args,&ruby_block)
3019
+ end
3020
+
3021
+ # HW implementation of the Ruby slice_after.
3022
+ # NOTE: to do, or may be not.
3023
+ def sslice_after(pattern = nil,&ruby_block)
3024
+ raise "sslice_after is not supported yet."
3025
+ end
3026
+
3027
+ # HW implementation of the Ruby slice_before.
3028
+ # NOTE: to do, or may be not.
3029
+ def sslice_before(*args,&ruby_block)
3030
+ raise "sslice_before is not supported yet."
3031
+ end
3032
+
3033
+ # HW implementation of the Ruby slice_when.
3034
+ # NOTE: to do, or may be not.
3035
+ def sslice_when(*args,&ruby_block)
3036
+ raise "sslice_before is not supported yet."
3037
+ end
3038
+
3039
+ # Merge two arrays in order, for ssort only.
3040
+ def ssort_merge(arI, arO, first, middle, last, &ruby_block)
3041
+ return self.make_iterator("sort_merge",arI,arO,first,middle,last,&ruby_block)
3042
+ end
3043
+
3044
+ # HW implementation of the Ruby sort.
3045
+ def ssort(&ruby_block)
3046
+ return self.make_iterator("sort",&ruby_block)
3047
+ end
3048
+
3049
+ # HW implementation of the Ruby sort.
3050
+ def ssort_by(&ruby_block)
3051
+ return self.make_iterator("sort_by",&ruby_block)
3052
+ end
3053
+
3054
+ # HW implementation of the Ruby sum.
3055
+ def ssum(initial_value = nil,&ruby_block)
3056
+ return self.make_iterator("sum",initial_value,&ruby_block)
3057
+ end
3058
+
3059
+ # The HW implementation of the Ruby take.
3060
+ def stake(n)
3061
+ return self.make_iterator("take",n)
3062
+ end
3063
+
3064
+ # The HW implementation of the Ruby take_while.
3065
+ def stake_while(&ruby_block)
3066
+ return self.make_iterator("take_while",&ruby_block)
3067
+ end
3068
+
3069
+ # HW implementation of the Ruby tally.
3070
+ # NOTE: to do, or may be not.
3071
+ def stally(h = nil)
3072
+ raise "stally is not supported yet."
3073
+ end
3074
+
3075
+ # HW implementation of the Ruby to_h.
3076
+ # NOTE: to do, or may be not.
3077
+ def sto_h(h = nil)
3078
+ raise "sto_h is not supported yet."
3079
+ end
3080
+
3081
+ # HW implementation of the Ruby uniq.
3082
+ def suniq(&ruby_block)
3083
+ return self.make_iterator("uniq",&ruby_block)
3084
+ end
3085
+
3086
+ # HW implementation of the Ruby zip.
3087
+ # NOTE: for now szip is deactivated untile tuples are properly
3088
+ # handled by HDLRuby.
3089
+ def szip(obj,&ruby_block)
3090
+ return self.make_iterator("zip",obj,&ruby_block)
3091
+ end
3092
+
3093
+ # Iterator on the +num+ next elements.
3094
+ # *NOTE*:
3095
+ # - Stop iteration when the end of the range is reached or when there
3096
+ # are no elements left
3097
+ # - This is not a method from Ruby but one specific for hardware where
3098
+ # creating a array is very expensive.
3099
+ def seach_nexts(num,&ruby_block)
3100
+ return self.seach.snexts(num,&ruby_block)
3101
+ end
3102
+ end
3103
+
3104
+
3105
+ # Describes a SW implementation of a signal.
3106
+ class SignalI < Expression
3107
+ using RubyHDL::High
3108
+ attr_reader :type, :name #, :content
3109
+ # Create a new signal with type +type+ and name +name+.
3110
+ def initialize(type,name)
3111
+ @type = type.to_type
3112
+ @name = name.to_sym
3113
+ end
3114
+
3115
+ # Tell if the signal is an array.
3116
+ def array?
3117
+ return @type.base.is_a?(TypeVector)
3118
+ end
3119
+
3120
+ # Convert to Ruby code.
3121
+ def to_ruby
3122
+ return "__" + self.name.to_s
3123
+ end
3124
+
3125
+ # Convert to C code.
3126
+ alias_method :to_c, :to_ruby
3127
+
3128
+ # Check if a value is defined for the signal.
3129
+ def value?
3130
+ return TOPLEVEL_BINDING.local_variable_defined?(self.to_ruby)
3131
+ end
3132
+
3133
+ # Gets the value of the signal.
3134
+ def value
3135
+ return TOPLEVEL_BINDING.eval(self.to_ruby)
3136
+ end
3137
+
3138
+ # Sets the value of the signal.
3139
+ def value=(val)
3140
+ return TOPLEVEL_BINDING.eval("#{self.to_ruby} = #{val}")
3141
+ end
3142
+
3143
+ # Convert to an integer.
3144
+ def to_i
3145
+ return self.value.to_i
3146
+ end
3147
+
3148
+ # Convert to an float.
3149
+ def to_f
3150
+ return self.value.to_f
3151
+ end
3152
+
3153
+ # Convert to a string.
3154
+ def to_s
3155
+ return self.value.to_s
3156
+ end
3157
+ end
3158
+
3159
+
3160
+ # Describes a SW implementation of a block.
3161
+ class Sblock < SblockTop
3162
+ using RubyHDL::High
3163
+
3164
+ attr_reader :sequencer
3165
+
3166
+ # Create a new block for sequencer +sequencer+ and fill it by
3167
+ # executing +ruby_block+
3168
+ def initialize(sequencer,&ruby_block)
3169
+ super()
3170
+ # Sets the sequencer.
3171
+ @sequencer = sequencer
3172
+ # Initialize the statements.
3173
+ @statements = []
3174
+ # Push the new sblock on top of the stack.
3175
+ RubyHDL::High.push_sblock(self)
3176
+ # Make signals from the arguments of the ruby block.
3177
+ @args = []
3178
+ ruby_block.parameters.each do |typ,arg|
3179
+ @args << SignalI.new(Void,arg)
3180
+ end
3181
+ # Fill it.
3182
+ self.instance_exec(*@args,&ruby_block)
3183
+ # Pop the new sblock.
3184
+ RubyHDL::High.pop_sblock
3185
+ end
3186
+
3187
+ # Add a new statement to the block.
3188
+ def add(statement)
3189
+ # Add the statement.
3190
+ @statements.push(statement)
3191
+ # # If the statement is a transmit, schedule the corresponding
3192
+ # # signal for final update.
3193
+ # if statement.is_a?(Transmit) then
3194
+ # @sequencer.to_update(statement.left)
3195
+ # end
3196
+ statement
3197
+ end
3198
+ alias_method :<<, :add
3199
+
3200
+ # Delete a statement.
3201
+ def delete(statement)
3202
+ @statements.delete(statement)
3203
+ end
3204
+
3205
+ # Unshift a new statement.
3206
+ def unshift(statement)
3207
+ @statements.unshift(statement)
3208
+ end
3209
+
3210
+ # Get the last statement.
3211
+ def last_statement
3212
+ return @statements[-1]
3213
+ end
3214
+
3215
+
3216
+ # Convert to Ruby code.
3217
+ def to_ruby
3218
+ res = ""
3219
+ # Generate the arguments if any.
3220
+ if @args.any? then
3221
+ res = "|#{@args.map(&:to_ruby).join(",")}|\n"
3222
+ end
3223
+ # Generate the statements.
3224
+ res += @statements.map do |stmnt|
3225
+ stmnt.to_ruby + "\n"
3226
+ end.join
3227
+ return res
3228
+ end
3229
+
3230
+ # Convert to C code.
3231
+ def to_c
3232
+ res = ""
3233
+ # Generate the arguments if any.
3234
+ if @args.any? then
3235
+ res = "(#{@args.map(&:to_c).join(",")})\n"
3236
+ end
3237
+ # Generate the statements.
3238
+ res += "{" + @statements.map do |stmnt|
3239
+ stmnt.to_ruby + "\n"
3240
+ end.join + "}"
3241
+ return res
3242
+ end
3243
+
3244
+ # The interface for describing statements and expressions.
3245
+
3246
+ # Mark a step.
2628
3247
  def step
2629
3248
  self << RubyHDL::High::Step.new(@sequencer)
2630
3249
  end
@@ -2656,12 +3275,12 @@ module RubyHDL::High
2656
3275
 
2657
3276
  # Create a sequential elsif statement on +cond+.
2658
3277
  def selsif(cond, &ruby_block)
2659
- self.statements[-1].selsif(&ruby_block)
3278
+ self.last_statement.selsif(&ruby_block)
2660
3279
  end
2661
3280
 
2662
3281
  # Create a sequential else statement.
2663
3282
  def selse(&ruby_block)
2664
- self.statements[-1].selse(&ruby_block)
3283
+ self.last_statement.selse(&ruby_block)
2665
3284
  end
2666
3285
 
2667
3286
  # Wait a given condition.
@@ -2685,7 +3304,7 @@ module RubyHDL::High
2685
3304
  # Ensures there is a ruby block to avoid returning an enumerator
2686
3305
  # (returning an enumerator would be confusing for a for statement).
2687
3306
  ruby_block = proc {} unless ruby_block
2688
- expr.seach.with_index(&ruby_block)
3307
+ self << expr.seach.with_index(&ruby_block)
2689
3308
  end
2690
3309
 
2691
3310
  # The SW-specific statements and expressions.
@@ -2697,16 +3316,41 @@ module RubyHDL::High
2697
3316
  self << RubyHDL::High::Sync.new
2698
3317
  end
2699
3318
 
2700
- # Some arbirary Ruby code.
2701
- def ruby(&ruby_block)
2702
- self << RubyHDL::High::Ruby.new(&ruby_block)
3319
+ # Some arbirary Ruby code as a string +str+ or as a proc
3320
+ # +ruby_block+.
3321
+ def ruby(str = nil, &ruby_block)
3322
+ self << RubyHDL::High::Ruby.new(str,&ruby_block)
3323
+ end
3324
+ end
3325
+
3326
+
3327
+ # Describes a SW implementation of a sequencer function.
3328
+ class SfunctionT
3329
+ using RubyHDL::High
3330
+ attr_reader :name
3331
+ # Create a new named +name+ with arguments +args+ and
3332
+ # executing the content of block +sblock+
3333
+ def initialize(type,name,sblock,*args)
3334
+ @name = name.to_sym
3335
+ @args = args
3336
+ @blk = sblock
3337
+ end
3338
+
3339
+ # Convert to Ruby code.
3340
+ def to_ruby
3341
+ return "def #{name}(#{@args.map {|arg| arg.to_ruby}.join(",")}\n#{@blk.to_ruby}\nend\n"
3342
+ end
3343
+
3344
+ # Convert to C code.
3345
+ 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"
2703
3347
  end
2704
3348
  end
2705
3349
 
2706
3350
 
2707
3351
 
2708
3352
 
2709
- # Describes a SW implmentation of a sequencer.
3353
+ # Describes a SW implementation of a sequencer.
2710
3354
  class SequencerT
2711
3355
 
2712
3356
  # The source code (in ruby).
@@ -2729,36 +3373,38 @@ module RubyHDL::High
2729
3373
  this.resume if val.to_i == 1
2730
3374
  end
2731
3375
  end
2732
- # # Create the set of signals to update.
2733
- # @to_updates = []
3376
+ # Create a set of sfunction used in the sequencer.
3377
+ @sfunctions = {}
2734
3378
  # Create the main block.
2735
3379
  @sblock = RubyHDL::High::Sblock.new(self,&ruby_block)
2736
3380
  # Build the Ruby code.
2737
3381
  @source = ""
2738
3382
  @code = nil
2739
- self.build
3383
+ self.build_ruby
2740
3384
  end
2741
3385
 
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
3386
+ # Add a sfunction.
3387
+ def add_sfunction(name,sfunction)
3388
+ @sfunctions[name.to_sym] = sfunction
3389
+ end
2747
3390
 
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
- #
3391
+ # Check if a sfunction is present.
3392
+ def sfunction?(name)
3393
+ return @sfunctions.key?(name.to_sym)
3394
+ end
3395
+
3396
+ # Get a sfunction by name.
3397
+ def sfunction(name)
3398
+ return @sfunctions[name.to_sym]
3399
+ end
2755
3400
 
2756
3401
  # Build the ruby code.
2757
- def build
3402
+ def build_ruby
2758
3403
  this = self
2759
3404
  @source = <<-BUILD
2760
3405
  #{RubyHDL::High.global_sblock.each_signal.map do |signal|
2761
- signal.to_ruby + " = " + (signal.array? ? "[]" : "nil") + " unless defined?(" + signal.to_ruby + ")"
3406
+ signal.to_ruby + " ||= " +
3407
+ (signal.array? ? "[]" : signal.value? ? signal.value.inspect : "nil")
2762
3408
  end.join("\n")}
2763
3409
  Fiber.new do
2764
3410
  #{@sblock.to_ruby}
@@ -2768,6 +3414,24 @@ BUILD
2768
3414
  @code = TOPLEVEL_BINDING.eval(@source)
2769
3415
  end
2770
3416
 
3417
+ # Get the Ruby code.
3418
+ def to_ruby
3419
+ return @code
3420
+ end
3421
+
3422
+ # Convert to C code.
3423
+ def to_c
3424
+ typ = nil
3425
+ res = <<-BUILDC
3426
+ #{RubyHDL::High.global_sblock.each_signal.map do |signal|
3427
+ typ = signal.type
3428
+ typ.to_c + " " + signal.to_c + "=" + typ.to_c_init + ";"
3429
+ end.join("\n")}
3430
+ #{sblock.to_c}
3431
+ BUILDC
3432
+ return res
3433
+ end
3434
+
2771
3435
  # Handling of the clock if any.
2772
3436
 
2773
3437
  # Generate a clock up of +count+ cycles if any clock.
@@ -2779,6 +3443,15 @@ BUILD
2779
3443
  end
2780
3444
  end
2781
3445
 
3446
+ # Generate a clock up of +count+ cycles if any clock for C code.
3447
+ def clk_up_c(count = 1)
3448
+ if @clk then
3449
+ return "#{clk.to_c} += #{count.to_i};"
3450
+ else
3451
+ return ""
3452
+ end
3453
+ end
3454
+
2782
3455
 
2783
3456
  # Control of the sequencer.
2784
3457
 
@@ -2806,20 +3479,35 @@ BUILD
2806
3479
  return SequencerT.new(clk,start,&ruby_block)
2807
3480
  end
2808
3481
 
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)
3482
+ # Create a new function named +name+, built using block +ruby_block+.
3483
+ def sdef(name,&ruby_block)
3484
+ name = name.to_sym
3485
+ # 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
3497
+ # Execute the ruby block in a sequencer environment for building
3498
+ # the sblock.
3499
+ sblock = Sblock.new(cur_seq,&ruby_block)
3500
+ RubyHDL::High.pop_sblock
3501
+ # Create the function.
3502
+ function = SfunctionT.new(name,args,sblock)
3503
+ # Add it to the sequencer.
3504
+ cur_seq.add_sfunction(name)
3505
+ end
3506
+ Scall.new(cur_seq,name,args)
3507
+ end
2816
3508
  end
2817
3509
 
2818
3510
 
2819
3511
  end
2820
3512
 
2821
3513
 
2822
-
2823
- include RubyHDL::High
2824
- using RubyHDL::High
2825
-