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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
2162
|
+
# Convert to Ruby code.
|
2002
2163
|
def to_ruby
|
2003
|
-
res = @sequencer.clk_up + "\nif(#{@
|
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
|
2196
|
+
# Convert to Ruby code.
|
2024
2197
|
def to_ruby
|
2025
|
-
return "loop do\n#{@blk.to_ruby}\n#{@sequencer.clk_up}\nend
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
-
|
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
|
-
|
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
|
2353
|
+
# Convert to Ruby code.
|
2140
2354
|
def to_ruby
|
2141
|
-
puts caller[0]
|
2142
|
-
|
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
|
-
|
2147
|
-
|
2369
|
+
|
2370
|
+
# Describes a SW implementation of an call statement.
|
2371
|
+
class Scall
|
2148
2372
|
using RubyHDL::High
|
2149
2373
|
|
2150
|
-
# Create a new
|
2151
|
-
#
|
2152
|
-
|
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
|
-
|
2156
|
-
@
|
2157
|
-
@blk = Sblock.new(sequencer,&ruby_block)
|
2378
|
+
@name = name.to_sym
|
2379
|
+
@args = args
|
2158
2380
|
end
|
2159
2381
|
|
2160
|
-
#
|
2161
|
-
def
|
2162
|
-
return
|
2163
|
-
|
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
|
2168
|
-
def
|
2169
|
-
|
2170
|
-
@
|
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
|
2508
|
-
class
|
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
|
-
#
|
2519
|
-
|
2520
|
-
|
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
|
-
#
|
2524
|
-
|
2525
|
-
|
2526
|
-
|
2527
|
-
|
2528
|
-
|
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
|
2751
|
+
# Convert to Ruby code.
|
2534
2752
|
def to_ruby
|
2535
|
-
#
|
2536
|
-
|
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
|
-
#
|
2540
|
-
def
|
2541
|
-
|
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
|
-
#
|
2545
|
-
def
|
2546
|
-
|
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
|
-
#
|
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
|
-
#
|
2557
|
-
|
2558
|
-
|
2559
|
-
|
2560
|
-
|
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
|
-
#
|
2564
|
-
|
2565
|
-
|
2566
|
-
|
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
|
-
|
2573
|
-
|
2574
|
-
|
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
|
-
#
|
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
|
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
|
-
#
|
2608
|
-
|
2609
|
-
|
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
|
-
#
|
2613
|
-
|
2614
|
-
|
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
|
-
#
|
2619
|
-
|
2620
|
-
|
2621
|
-
|
2622
|
-
|
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
|
-
#
|
2626
|
-
|
2627
|
-
#
|
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.
|
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.
|
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
|
-
|
2702
|
-
|
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
|
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
|
-
#
|
2733
|
-
|
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.
|
3383
|
+
self.build_ruby
|
2740
3384
|
end
|
2741
3385
|
|
2742
|
-
#
|
2743
|
-
|
2744
|
-
|
2745
|
-
|
2746
|
-
# end
|
3386
|
+
# Add a sfunction.
|
3387
|
+
def add_sfunction(name,sfunction)
|
3388
|
+
@sfunctions[name.to_sym] = sfunction
|
3389
|
+
end
|
2747
3390
|
|
2748
|
-
#
|
2749
|
-
|
2750
|
-
|
2751
|
-
|
2752
|
-
|
2753
|
-
#
|
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
|
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 + "
|
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
|
-
#
|
2810
|
-
|
2811
|
-
|
2812
|
-
|
2813
|
-
|
2814
|
-
|
2815
|
-
|
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
|
-
|