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.
- checksums.yaml +4 -4
- data/README.md +93 -15
- data/lib/HDLRuby/hdr_samples/ruby_program/with_sw_hruby.rb +15 -5
- data/lib/HDLRuby/hdr_samples/ruby_program/with_sw_hruby_hruby_test.rb +6 -3
- data/lib/HDLRuby/hruby_high.rb +15 -0
- data/lib/HDLRuby/hruby_rcsim.rb +1 -1
- data/lib/HDLRuby/std/sequencer.rb +10 -0
- data/lib/HDLRuby/std/sequencer_sw.rb +965 -179
- data/lib/HDLRuby/version.rb +1 -1
- data/tuto/tutorial_sw.html +6 -0
- data/tuto/tutorial_sw.md +12 -0
- metadata +3 -3
@@ -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
|
-
#
|
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)
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
2215
|
+
# Convert to Ruby code.
|
2002
2216
|
def to_ruby
|
2003
|
-
res = @sequencer.clk_up + "\nif(#{@
|
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
|
2249
|
+
# Convert to Ruby code.
|
2024
2250
|
def to_ruby
|
2025
|
-
return "loop do\n#{@blk.to_ruby}\n#{@sequencer.clk_up}\nend
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
-
|
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
|
-
|
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
|
2406
|
+
# Convert to Ruby code.
|
2140
2407
|
def to_ruby
|
2141
|
-
puts caller[0]
|
2142
|
-
|
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
|
-
|
2147
|
-
|
2422
|
+
|
2423
|
+
# Describes a SW implementation of an call statement.
|
2424
|
+
class Scall
|
2148
2425
|
using RubyHDL::High
|
2149
2426
|
|
2150
|
-
# Create a new
|
2151
|
-
#
|
2152
|
-
|
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
|
-
|
2156
|
-
@
|
2157
|
-
@blk = Sblock.new(sequencer,&ruby_block)
|
2431
|
+
@name = name.to_sym
|
2432
|
+
@args = args
|
2158
2433
|
end
|
2159
2434
|
|
2160
|
-
#
|
2161
|
-
def
|
2162
|
-
return
|
2163
|
-
|
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
|
2168
|
-
def
|
2169
|
-
|
2170
|
-
@
|
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
|
2508
|
-
class
|
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
|
-
#
|
2519
|
-
|
2520
|
-
|
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
|
-
#
|
2524
|
-
|
2525
|
-
|
2526
|
-
|
2527
|
-
|
2528
|
-
|
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
|
2804
|
+
# Convert to Ruby code.
|
2534
2805
|
def to_ruby
|
2535
|
-
#
|
2536
|
-
|
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
|
-
#
|
2540
|
-
def
|
2541
|
-
|
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
|
-
#
|
2545
|
-
def
|
2546
|
-
|
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
|
-
#
|
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
|
-
#
|
2557
|
-
|
2558
|
-
|
2559
|
-
|
2560
|
-
|
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
|
-
#
|
2564
|
-
|
2565
|
-
|
2566
|
-
|
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
|
-
|
2577
|
-
|
2578
|
-
|
2579
|
-
|
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
|
-
#
|
2595
|
-
def
|
2596
|
-
|
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
|
-
#
|
2608
|
-
|
2609
|
-
|
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
|
-
#
|
2613
|
-
|
2614
|
-
|
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
|
-
#
|
2619
|
-
|
2620
|
-
|
2621
|
-
|
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.
|
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.
|
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
|
-
|
2702
|
-
|
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
|
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
|
-
#
|
2733
|
-
|
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.
|
3471
|
+
self.build_ruby
|
2740
3472
|
end
|
2741
3473
|
|
2742
|
-
#
|
2743
|
-
|
2744
|
-
|
2745
|
-
|
2746
|
-
# end
|
3474
|
+
# Add a sfunction.
|
3475
|
+
def add_sfunction(name,sfunction)
|
3476
|
+
@sfunctions[name.to_sym] = sfunction
|
3477
|
+
end
|
2747
3478
|
|
2748
|
-
#
|
2749
|
-
|
2750
|
-
|
2751
|
-
|
2752
|
-
|
2753
|
-
#
|
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
|
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 + "
|
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
|
-
|
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
|
-
#
|
2810
|
-
|
2811
|
-
|
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
|
-
|
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
|
|