HDLRuby 3.1.0 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/HDLRuby.gemspec +1 -0
- data/README.md +10 -0
- data/ext/hruby_sim/hruby_rcsim_build.c +2 -0
- data/ext/hruby_sim/hruby_sim_calc.c +33 -6
- data/ext/hruby_sim/hruby_sim_tree_calc.c +111 -22
- data/lib/HDLRuby/hdr_samples/comparison_bench.rb +2 -2
- data/lib/HDLRuby/hdr_samples/counter_bench.rb +1 -1
- data/lib/HDLRuby/hdr_samples/counter_dff_bench.rb +8 -7
- data/lib/HDLRuby/hdr_samples/dff_properties.rb +2 -0
- data/lib/HDLRuby/hdr_samples/enum_as_param.rb +52 -0
- data/lib/HDLRuby/hdr_samples/linear_test.rb +2 -0
- data/lib/HDLRuby/hdr_samples/logic_bench.rb +6 -0
- data/lib/HDLRuby/hdr_samples/mei8.rb +6 -6
- data/lib/HDLRuby/hdr_samples/mei8_bench.rb +6 -6
- data/lib/HDLRuby/hdr_samples/memory_test.rb +2 -0
- data/lib/HDLRuby/hdr_samples/named_sub.rb +9 -5
- data/lib/HDLRuby/hdr_samples/ram.rb +7 -6
- data/lib/HDLRuby/hdr_samples/ruby_fir_hw.rb +2 -0
- data/lib/HDLRuby/hdr_samples/struct.rb +15 -3
- data/lib/HDLRuby/hdr_samples/with_bram.rb +1 -1
- data/lib/HDLRuby/hdr_samples/with_bram_frame_stack.rb +1 -1
- data/lib/HDLRuby/hdr_samples/with_bram_stack.rb +1 -1
- data/lib/HDLRuby/hdr_samples/with_channel.rb +2 -0
- data/lib/HDLRuby/hdr_samples/with_channel_other.rb +2 -0
- data/lib/HDLRuby/hdr_samples/with_class.rb +3 -1
- data/lib/HDLRuby/hdr_samples/with_connector.rb +2 -0
- data/lib/HDLRuby/hdr_samples/with_connector_memory.rb +2 -0
- data/lib/HDLRuby/hdr_samples/with_fixpoint.rb +6 -0
- data/lib/HDLRuby/hdr_samples/with_fixpoint_adv.rb +73 -0
- data/lib/HDLRuby/hdr_samples/with_leftright.rb +1 -1
- data/lib/HDLRuby/hdr_samples/with_sequencer.rb +17 -0
- data/lib/HDLRuby/hdr_samples/with_sequencer_channel.rb +58 -0
- data/lib/HDLRuby/hdr_samples/with_sequencer_enumerable.rb +10 -0
- data/lib/HDLRuby/hdr_samples/with_sequencer_enumerator.rb +18 -4
- data/lib/HDLRuby/hdr_samples/with_sequencer_sync.rb +2 -1
- data/lib/HDLRuby/hdrcc.rb +12 -0
- data/lib/HDLRuby/hruby_high.rb +82 -26
- data/lib/HDLRuby/hruby_low.rb +127 -3
- data/lib/HDLRuby/hruby_low2programs.rb +47 -0
- data/lib/HDLRuby/hruby_low_resolve.rb +3 -2
- data/lib/HDLRuby/hruby_low_without_namespace.rb +133 -5
- data/lib/HDLRuby/hruby_low_without_subsignals.rb +1 -1
- data/lib/HDLRuby/hruby_rcsim.rb +24 -1
- data/lib/HDLRuby/hruby_serializer.rb +2 -1
- data/lib/HDLRuby/hruby_verilog.rb +94 -20
- data/lib/HDLRuby/hruby_verilog_name.rb +3 -17
- data/lib/HDLRuby/std/fixpoint.rb +2 -2
- data/lib/HDLRuby/std/function_generator.rb +1 -1
- data/lib/HDLRuby/std/linear.rb +7 -7
- data/lib/HDLRuby/std/sequencer.rb +263 -13
- data/lib/HDLRuby/std/sequencer_channel.rb +90 -0
- data/lib/HDLRuby/std/sequencer_func.rb +28 -15
- data/lib/HDLRuby/std/std.rb +1 -0
- data/lib/HDLRuby/version.rb +1 -1
- metadata +22 -3
@@ -338,17 +338,19 @@ module HDLRuby::High::Std
|
|
338
338
|
@@old_make_inners_proc = self.instance_method(:make_inners)
|
339
339
|
|
340
340
|
def make_inners(typ,*names)
|
341
|
+
res = nil
|
341
342
|
if SequencerT.current then
|
342
343
|
unames = names.map {|name| HDLRuby.uniq_name(name) }
|
343
|
-
HDLRuby::High.cur_scope.make_inners(typ, *unames)
|
344
|
+
res = HDLRuby::High.cur_scope.make_inners(typ, *unames)
|
344
345
|
names.zip(unames).each do |name,uname|
|
345
346
|
HDLRuby::High.space_reg(name) { send(uname) }
|
346
347
|
end
|
347
348
|
else
|
348
349
|
# self.old_make_inners(typ,*names)
|
349
350
|
# Call the old make_inners.
|
350
|
-
@@old_make_inners_proc.bind(self).call(typ,*names)
|
351
|
+
res = @@old_make_inners_proc.bind(self).call(typ,*names)
|
351
352
|
end
|
353
|
+
return res
|
352
354
|
end
|
353
355
|
end
|
354
356
|
|
@@ -357,7 +359,17 @@ module HDLRuby::High::Std
|
|
357
359
|
|
358
360
|
# Module adding functionalities to object including the +seach+ method.
|
359
361
|
module SEnumerable
|
360
|
-
|
362
|
+
|
363
|
+
# Iterator on each of the elements in range +rng+.
|
364
|
+
# *NOTE*:
|
365
|
+
# - Stop iteration when the end of the range is reached or when there
|
366
|
+
# are no elements left
|
367
|
+
# - This is not a method from Ruby but one specific for hardware where
|
368
|
+
# creating a array is very expensive.
|
369
|
+
def seach_range(rng,&ruby_block)
|
370
|
+
return self.seach.seach_range(rng,&ruby_block)
|
371
|
+
end
|
372
|
+
|
361
373
|
# Tell if all the elements respect a given criterion given either
|
362
374
|
# as +arg+ or as block.
|
363
375
|
def sall?(arg = nil,&ruby_block)
|
@@ -1659,6 +1671,55 @@ module HDLRuby::High::Std
|
|
1659
1671
|
end
|
1660
1672
|
end
|
1661
1673
|
|
1674
|
+
# Iterator on the +num+ next elements.
|
1675
|
+
# *NOTE*:
|
1676
|
+
# - Stop iteration when the end of the range is reached or when there
|
1677
|
+
# are no elements left
|
1678
|
+
# - This is not a method from Ruby but one specific for hardware where
|
1679
|
+
# creating a array is very expensive.
|
1680
|
+
def seach_nexts(num,&ruby_block)
|
1681
|
+
# # No block given, returns a new enumerator.
|
1682
|
+
# unless ruby_block then
|
1683
|
+
# res = SEnumeratorWrapper.new(self,:seach_nexts,num)
|
1684
|
+
# res.size = num
|
1685
|
+
# return res
|
1686
|
+
# end
|
1687
|
+
# # A block is given, iterate.
|
1688
|
+
# enum = self.seach
|
1689
|
+
# # Create a counter.
|
1690
|
+
# count = nil
|
1691
|
+
# zero = nil
|
1692
|
+
# one = nil
|
1693
|
+
# HDLRuby::High.cur_system.open do
|
1694
|
+
# if num.respond_to?(:width) then
|
1695
|
+
# count = [num.width].inner(HDLRuby.uniq_name(:"snexts_count"))
|
1696
|
+
# else
|
1697
|
+
# count = num.to_expr.type.inner(HDLRuby.uniq_name(:"snexts_count"))
|
1698
|
+
# end
|
1699
|
+
# zero = _b0
|
1700
|
+
# one = _b1
|
1701
|
+
# end
|
1702
|
+
# count <= num
|
1703
|
+
# SequencerT.current.swhile(count > zero) do
|
1704
|
+
# ruby_block.call(enum.snext)
|
1705
|
+
# count <= count - one
|
1706
|
+
# end
|
1707
|
+
zero = nil
|
1708
|
+
one = nil
|
1709
|
+
HDLRuby::High.cur_system.open do
|
1710
|
+
zero = _b0.as(num.to_expr.type)
|
1711
|
+
one = _b1.as(num.to_expr.type)
|
1712
|
+
end
|
1713
|
+
subE = SEnumeratorSub.new(self,zero..num-one)
|
1714
|
+
if ruby_block then
|
1715
|
+
# A block is given, iterate immediatly.
|
1716
|
+
subE.seach(&ruby_block)
|
1717
|
+
else
|
1718
|
+
# No block given, return the new sub iterator.
|
1719
|
+
return subE
|
1720
|
+
end
|
1721
|
+
end
|
1722
|
+
|
1662
1723
|
end
|
1663
1724
|
|
1664
1725
|
|
@@ -1682,10 +1743,30 @@ module HDLRuby::High::Std
|
|
1682
1743
|
return self unless ruby_block
|
1683
1744
|
# A block is given, iterate.
|
1684
1745
|
this = self
|
1685
|
-
#
|
1746
|
+
# Reinitialize the iteration.
|
1686
1747
|
this.srewind
|
1687
|
-
#
|
1748
|
+
# Perform the iteration.
|
1688
1749
|
SequencerT.current.swhile(self.index < self.size) do
|
1750
|
+
# ruby_block.call(this.snext)
|
1751
|
+
HDLRuby::High.top_user.instance_exec(this.snext,&ruby_block)
|
1752
|
+
end
|
1753
|
+
end
|
1754
|
+
|
1755
|
+
# Iterator on each of the elements in range +rng+.
|
1756
|
+
# *NOTE*:
|
1757
|
+
# - Stop iteration when the end of the range is reached or when there
|
1758
|
+
# are no elements left
|
1759
|
+
# - This is not a method from Ruby but one specific for hardware where
|
1760
|
+
# creating a array is very expensive.
|
1761
|
+
def seach_range(rng,&ruby_block)
|
1762
|
+
# No block given, returns a new enumerator.
|
1763
|
+
return SEnumeratorWrapper.new(self,:seach_range) unless ruby_block
|
1764
|
+
# A block is given, iterate.
|
1765
|
+
this = self
|
1766
|
+
# Perform the iteration.
|
1767
|
+
self.index <= rng.first
|
1768
|
+
SequencerT.current.swhile((self.index < self.size) &
|
1769
|
+
(self.index <= rng.last) ) do
|
1689
1770
|
ruby_block.call(this.snext)
|
1690
1771
|
end
|
1691
1772
|
end
|
@@ -1770,7 +1851,7 @@ module HDLRuby::High::Std
|
|
1770
1851
|
|
1771
1852
|
# The directly delegate methods.
|
1772
1853
|
def size
|
1773
|
-
return @
|
1854
|
+
return @enumertor.size
|
1774
1855
|
end
|
1775
1856
|
|
1776
1857
|
def type
|
@@ -1798,13 +1879,32 @@ module HDLRuby::High::Std
|
|
1798
1879
|
end
|
1799
1880
|
|
1800
1881
|
def snext?
|
1882
|
+
# if @size then
|
1883
|
+
# return @enumerator.index < @size
|
1884
|
+
# else
|
1885
|
+
# return @enumerator.snext?
|
1886
|
+
# end
|
1801
1887
|
return @enumerator.snext?
|
1802
1888
|
end
|
1803
1889
|
|
1890
|
+
def snext!(val)
|
1891
|
+
return @enumerator.snext!(val)
|
1892
|
+
end
|
1893
|
+
|
1804
1894
|
def srewind
|
1805
1895
|
return @enumerator.srewind
|
1806
1896
|
end
|
1807
1897
|
|
1898
|
+
# Iterator on each of the elements in range +rng+.
|
1899
|
+
# *NOTE*:
|
1900
|
+
# - Stop iteration when the end of the range is reached or when there
|
1901
|
+
# are no elements left
|
1902
|
+
# - This is not a method from Ruby but one specific for hardware where
|
1903
|
+
# creating a array is very expensive.
|
1904
|
+
def seach_range(rng,&ruby_block)
|
1905
|
+
return @enumerator.seach_range(rng,&ruby_block)
|
1906
|
+
end
|
1907
|
+
|
1808
1908
|
# Clones the enumerator.
|
1809
1909
|
def clone
|
1810
1910
|
return SEnumeratorWrapper.new(@enumerator,@iterator,*@arguments)
|
@@ -1820,6 +1920,92 @@ module HDLRuby::High::Std
|
|
1820
1920
|
end
|
1821
1921
|
|
1822
1922
|
|
1923
|
+
# Describes a sequencer enumerator class that allows to generate HW iterations
|
1924
|
+
# over HW or SW objects within sequencers.
|
1925
|
+
# This is the sub Enumerator over an other one for interating inside the
|
1926
|
+
# enumerator.
|
1927
|
+
# This is specific the HDLRuby for avoiding creation of array which are
|
1928
|
+
# expensive in HW. Used by seach_next for example.
|
1929
|
+
# Will change the index position of the initial iterator without reseting
|
1930
|
+
# it.
|
1931
|
+
class SEnumeratorSub < SEnumerator
|
1932
|
+
|
1933
|
+
# Create a new SEnumerator wrapper over +enum+ among +rng+ indexes.
|
1934
|
+
def initialize(enum,rng,*args)
|
1935
|
+
@enumerator = enum.seach
|
1936
|
+
@range = rng.first..rng.last
|
1937
|
+
# Declare the sub index.
|
1938
|
+
idx = nil
|
1939
|
+
siz = @range.last-@range.first+1
|
1940
|
+
HDLRuby::High.cur_system.open do
|
1941
|
+
idx = [siz.width].inner({
|
1942
|
+
HDLRuby.uniq_name("sub_idx") => 0 })
|
1943
|
+
end
|
1944
|
+
@index = idx
|
1945
|
+
@size = siz
|
1946
|
+
end
|
1947
|
+
|
1948
|
+
# The directly delegate methods.
|
1949
|
+
def size
|
1950
|
+
return @size
|
1951
|
+
end
|
1952
|
+
|
1953
|
+
def type
|
1954
|
+
return @enumerator.type
|
1955
|
+
end
|
1956
|
+
|
1957
|
+
def result
|
1958
|
+
return @enumerator.result
|
1959
|
+
end
|
1960
|
+
|
1961
|
+
def index
|
1962
|
+
return @index
|
1963
|
+
end
|
1964
|
+
|
1965
|
+
def access(idx)
|
1966
|
+
return @enumerator.access(@index+@range.first)
|
1967
|
+
end
|
1968
|
+
|
1969
|
+
def speek
|
1970
|
+
return @enumerator.speek
|
1971
|
+
end
|
1972
|
+
|
1973
|
+
def snext
|
1974
|
+
@index <= @index + 1
|
1975
|
+
return @enumerator.snext
|
1976
|
+
end
|
1977
|
+
|
1978
|
+
def snext?
|
1979
|
+
return @index < self.size
|
1980
|
+
end
|
1981
|
+
|
1982
|
+
def snext!(val)
|
1983
|
+
return @enumerator.snext!(val)
|
1984
|
+
end
|
1985
|
+
|
1986
|
+
def srewind
|
1987
|
+
@index <= 0
|
1988
|
+
end
|
1989
|
+
|
1990
|
+
# Clones the enumerator.
|
1991
|
+
def clone
|
1992
|
+
return SEnumeratorSub.new(@enumerator,@range)
|
1993
|
+
end
|
1994
|
+
|
1995
|
+
# Iterate over each element.
|
1996
|
+
def seach(&ruby_block)
|
1997
|
+
# No block given, returns self.
|
1998
|
+
return self unless ruby_block
|
1999
|
+
# A block is given, iterate.
|
2000
|
+
this = self
|
2001
|
+
SequencerT.current.swhile(this.snext?) do
|
2002
|
+
ruby_block.call(this.snext)
|
2003
|
+
end
|
2004
|
+
end
|
2005
|
+
end
|
2006
|
+
|
2007
|
+
|
2008
|
+
|
1823
2009
|
# Describes a sequencer enumerator class that allows to generate HW
|
1824
2010
|
# iterations over HW or SW objects within sequencers.
|
1825
2011
|
# This is the base Enumerator that directly iterates.
|
@@ -1880,9 +2066,17 @@ module HDLRuby::High::Std
|
|
1880
2066
|
|
1881
2067
|
# Tell if there is a next element.
|
1882
2068
|
def snext?
|
2069
|
+
# puts "@index=#{index}, @size=#{@size}"
|
1883
2070
|
return @index < @size
|
1884
2071
|
end
|
1885
2072
|
|
2073
|
+
# Set the next element.
|
2074
|
+
def snext!(val)
|
2075
|
+
@access.call(@index,val)
|
2076
|
+
@index <= @index + 1
|
2077
|
+
return val
|
2078
|
+
end
|
2079
|
+
|
1886
2080
|
# Restart the iteration.
|
1887
2081
|
def srewind
|
1888
2082
|
@index <= 0
|
@@ -1890,6 +2084,8 @@ module HDLRuby::High::Std
|
|
1890
2084
|
end
|
1891
2085
|
|
1892
2086
|
|
2087
|
+
|
2088
|
+
|
1893
2089
|
module HDLRuby::High::HExpression
|
1894
2090
|
# Enhance the HExpression module with sequencer iteration.
|
1895
2091
|
|
@@ -1897,8 +2093,14 @@ module HDLRuby::High::Std
|
|
1897
2093
|
def seach(&ruby_block)
|
1898
2094
|
# Create the hardware iterator.
|
1899
2095
|
this = self
|
1900
|
-
hw_enum = SEnumeratorBase.new(this.type.base,this.type.size) do |idx|
|
1901
|
-
|
2096
|
+
hw_enum = SEnumeratorBase.new(this.type.base,this.type.size) do |idx,val = nil|
|
2097
|
+
if val then
|
2098
|
+
# Write access
|
2099
|
+
this[idx] <= val
|
2100
|
+
else
|
2101
|
+
# Read access
|
2102
|
+
this[idx]
|
2103
|
+
end
|
1902
2104
|
end
|
1903
2105
|
# Is there a ruby block?
|
1904
2106
|
if(ruby_block) then
|
@@ -1917,23 +2119,27 @@ module HDLRuby::High::Std
|
|
1917
2119
|
end
|
1918
2120
|
|
1919
2121
|
|
1920
|
-
class HDLRuby::High::Value
|
2122
|
+
# class HDLRuby::High::Value
|
2123
|
+
module HDLRuby::High::HExpression
|
1921
2124
|
# Enhance the Value class with sequencer iterations.
|
1922
2125
|
|
1923
2126
|
# HW times iteration.
|
1924
2127
|
def stimes(&ruby_block)
|
1925
|
-
return (0..self-1).seach(&ruby_block)
|
2128
|
+
# return (0..self-1).seach(&ruby_block)
|
2129
|
+
return AnyRange.new(0,self-1).seach(&ruby_block)
|
1926
2130
|
end
|
1927
2131
|
|
1928
2132
|
# HW upto iteration.
|
1929
2133
|
def supto(val,&ruby_block)
|
1930
|
-
return (self..val).seach(&ruby_block)
|
2134
|
+
# return (self..val).seach(&ruby_block)
|
2135
|
+
return AnyRange.new(self,val).seach(&ruby_block)
|
1931
2136
|
end
|
1932
2137
|
|
1933
2138
|
# HW downto iteration.
|
1934
2139
|
def sdownto(val,&ruby_block)
|
1935
2140
|
# Create the hardware iterator.
|
1936
|
-
range = val..(self.to_i)
|
2141
|
+
# range = val..(self.to_i)
|
2142
|
+
range = AnyRange.new(val,self)
|
1937
2143
|
hw_enum = SEnumeratorBase.new(signed[32],range.size) do |idx|
|
1938
2144
|
range.last - idx
|
1939
2145
|
end
|
@@ -2034,6 +2240,51 @@ module HDLRuby::High::Std
|
|
2034
2240
|
end
|
2035
2241
|
|
2036
2242
|
|
2243
|
+
# Range substitute class for sequencers that supports any kind of bounds.
|
2244
|
+
class AnyRange
|
2245
|
+
# Enhance the AnyRange class with sequencer iteration.
|
2246
|
+
include SEnumerable
|
2247
|
+
|
2248
|
+
attr_reader :first, :last
|
2249
|
+
|
2250
|
+
def initialize(first,last)
|
2251
|
+
@first = first
|
2252
|
+
@last = last
|
2253
|
+
end
|
2254
|
+
|
2255
|
+
# HW iteration on each element.
|
2256
|
+
def seach(&ruby_block)
|
2257
|
+
# Create the iteration type: selection of the larger HDLRuby type
|
2258
|
+
# between first and last. If one of first and last is a Numeric,
|
2259
|
+
# priority to the non Numeric one.
|
2260
|
+
if (self.last.is_a?(Numeric)) then
|
2261
|
+
typ = self.first.to_expr.type
|
2262
|
+
elsif (self.first.is_a?(Numeric)) then
|
2263
|
+
typ = self.last.to_expr.type
|
2264
|
+
else
|
2265
|
+
typ = self.first.type.width > self.last.type.width ?
|
2266
|
+
self.first.type : self.last.type
|
2267
|
+
end
|
2268
|
+
# Create the hardware iterator.
|
2269
|
+
this = self
|
2270
|
+
# size = this.size ? this.size : this.last - this.first + 1
|
2271
|
+
size = this.last - this.first + 1
|
2272
|
+
size = size.to_expr.as(typ)
|
2273
|
+
hw_enum = SEnumeratorBase.new(typ,size) do |idx|
|
2274
|
+
idx.as(typ) + this.first.to_expr.as(typ)
|
2275
|
+
end
|
2276
|
+
# Is there a ruby block?
|
2277
|
+
if(ruby_block) then
|
2278
|
+
# Yes, apply it.
|
2279
|
+
return hw_enum.seach(&ruby_block)
|
2280
|
+
else
|
2281
|
+
# No, return the resulting enumerator.
|
2282
|
+
return hw_enum
|
2283
|
+
end
|
2284
|
+
end
|
2285
|
+
end
|
2286
|
+
|
2287
|
+
|
2037
2288
|
class ::Integer
|
2038
2289
|
# Enhance the Integer class with sequencer iterations.
|
2039
2290
|
|
@@ -2081,5 +2332,4 @@ module HDLRuby::High::Std
|
|
2081
2332
|
end
|
2082
2333
|
|
2083
2334
|
|
2084
|
-
|
2085
2335
|
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'std/sequencer'
|
2
|
+
|
3
|
+
module HDLRuby::High::Std
|
4
|
+
|
5
|
+
##
|
6
|
+
# Standard HDLRuby::High library: channel generator.
|
7
|
+
# The idea is to have abstract communication interface whose
|
8
|
+
# implementation can be seamlessly modified.
|
9
|
+
#
|
10
|
+
########################################################################
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
# Creates an abstract channel over an accessing method.
|
17
|
+
# NOTE: Works like an enumerator, but can be passed as generic arguments and
|
18
|
+
# generates a different enumerator per sequencer.
|
19
|
+
# - +typ+ is the data type of the elements.
|
20
|
+
# - +size+ is the number of elements.
|
21
|
+
# - +access+ is the block implementing the access method.
|
22
|
+
class SequencerChannel < SEnumerator
|
23
|
+
|
24
|
+
# Create a new channel for +size+ elements of type +type+ with an JW
|
25
|
+
# array-like accesser +access+.
|
26
|
+
def initialize(typ,size,&access)
|
27
|
+
@type = typ
|
28
|
+
@size = size
|
29
|
+
@access = access
|
30
|
+
@enums = {} # The enumerator per sequencer.
|
31
|
+
end
|
32
|
+
|
33
|
+
# Get the enumerator for current sequencer.
|
34
|
+
# If does not exist create a new one.
|
35
|
+
def senumerator
|
36
|
+
unless SequencerT.current then
|
37
|
+
raise "Cannot get a channel enumerator from outside a sequencer."
|
38
|
+
end
|
39
|
+
enum = @enums[SequencerT.current]
|
40
|
+
unless enum then
|
41
|
+
enum = @enums[SequencerT.current] =
|
42
|
+
SEnumeratorBase.new(@type,@size,&@access)
|
43
|
+
end
|
44
|
+
return enum
|
45
|
+
end
|
46
|
+
|
47
|
+
# Clones is ambigous here, so deactivated.
|
48
|
+
def clone
|
49
|
+
raise "clone not supported for channels."
|
50
|
+
end
|
51
|
+
|
52
|
+
# The array read accesses.
|
53
|
+
def [](addr)
|
54
|
+
return @access.call(addr)
|
55
|
+
end
|
56
|
+
|
57
|
+
# The array write access.
|
58
|
+
def []=(addr,val)
|
59
|
+
return @access.call(addr,val)
|
60
|
+
end
|
61
|
+
|
62
|
+
# The access to the already defined elements.
|
63
|
+
attr_reader :type
|
64
|
+
attr_reader :size
|
65
|
+
|
66
|
+
# Delegate the enumeration methods to the enumerator of the current
|
67
|
+
# system.
|
68
|
+
|
69
|
+
[:result,:index,:access,:speek,
|
70
|
+
:snext,:snext?,:snext!,:srewind].each do |sym|
|
71
|
+
define_method(sym) do |*args,&ruby_block|
|
72
|
+
senumerator.send(sym,*args,&ruby_block)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
# Creates an abstract channel over an accessing method.
|
80
|
+
# NOTE: Works like an enumerator or a memory access, but can be passed as
|
81
|
+
# generic arguments and generates a different enumerator per sequencer
|
82
|
+
# (memory access is identical for now though).
|
83
|
+
# - +typ+ is the data type of the elements.
|
84
|
+
# - +size+ is the number of elements.
|
85
|
+
# - +access+ is the block implementing the access method.
|
86
|
+
def schannel(typ,size,&access)
|
87
|
+
return SequencerChannel.new(typ,size,&access)
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
@@ -16,6 +16,12 @@ module HDLRuby::High::Std
|
|
16
16
|
# their are set when the function is called.
|
17
17
|
# This is handle by the eigen functions (see SequencerFunctionE).
|
18
18
|
class SequencerFunctionT
|
19
|
+
|
20
|
+
ZERO = :_b0.to_value
|
21
|
+
ONE = :_sb01.to_value
|
22
|
+
# ZERO = 0
|
23
|
+
# ONE = 1
|
24
|
+
|
19
25
|
# The name of the function.
|
20
26
|
attr_reader :name
|
21
27
|
|
@@ -69,7 +75,7 @@ module HDLRuby::High::Std
|
|
69
75
|
# hprint("returning with stack_ptr=",stack_ptr,"\n")
|
70
76
|
hif(stack_ptr <= depth) do
|
71
77
|
# hprint("poking recursive return value at idx=",funcI.returnIdx," with value=",st_call.value+1,"\n")
|
72
|
-
funcI.poke(funcI.returnIdx,st_call.value +
|
78
|
+
funcI.poke(funcI.returnIdx,st_call.value + ONE)
|
73
79
|
end
|
74
80
|
end
|
75
81
|
end
|
@@ -89,7 +95,7 @@ module HDLRuby::High::Std
|
|
89
95
|
old_code.call
|
90
96
|
HDLRuby::High.top_user.instance_exec do
|
91
97
|
# hprint("poking return value at idx=",funcI.returnIdx," with value=",st_func.value+1,"\n")
|
92
|
-
funcI.poke(funcI.returnIdx,st_func.value +
|
98
|
+
funcI.poke(funcI.returnIdx,st_func.value + ONE)
|
93
99
|
end
|
94
100
|
end
|
95
101
|
end
|
@@ -151,6 +157,11 @@ module HDLRuby::High::Std
|
|
151
157
|
|
152
158
|
# Describes a sequencer function instance.
|
153
159
|
class SequencerFunctionI
|
160
|
+
|
161
|
+
ZERO = SequencerFunctionT::ZERO
|
162
|
+
ONE = SequencerFunctionT::ONE
|
163
|
+
|
164
|
+
|
154
165
|
@@current_stack = [] # The stack of current function instance.
|
155
166
|
|
156
167
|
# Get the function instance currently processing.
|
@@ -194,7 +205,7 @@ module HDLRuby::High::Std
|
|
194
205
|
# Create the stacks for the arguments.
|
195
206
|
@funcE.each_argT { |argT| self.make_stack(argT) }
|
196
207
|
# @argsIdx = @returnIdx + 2
|
197
|
-
@argsIdx = @returnIdx +
|
208
|
+
@argsIdx = @returnIdx + ONE
|
198
209
|
|
199
210
|
# Create the return value, however, at first their type is unknown
|
200
211
|
# to set it as a simple bit.
|
@@ -296,7 +307,7 @@ module HDLRuby::High::Std
|
|
296
307
|
|
297
308
|
# Get the state value of the function: it is the state
|
298
309
|
# following the first function call.
|
299
|
-
func_state_value = call_state.value +
|
310
|
+
func_state_value = call_state.value + ONE
|
300
311
|
# Do the call.
|
301
312
|
call_state.gotos << proc do
|
302
313
|
HDLRuby::High.top_user.instance_exec do
|
@@ -329,7 +340,7 @@ module HDLRuby::High::Std
|
|
329
340
|
# Since not pushed the stack yet for not loosing the previous
|
330
341
|
# arguments, add +1 to the offset when poking the new arguments.
|
331
342
|
# args.each_with_index { |arg,i| self.poke(@argsIdx + i,arg,1) }
|
332
|
-
args.each_with_index { |arg,i| this.poke(argsIdx + i,arg,
|
343
|
+
args.each_with_index { |arg,i| this.poke(argsIdx + i,arg,ONE) }
|
333
344
|
end
|
334
345
|
|
335
346
|
# Push a new frame.
|
@@ -349,7 +360,7 @@ module HDLRuby::High::Std
|
|
349
360
|
|
350
361
|
# Get the state value of the function: it is the state
|
351
362
|
# following the first function call.
|
352
|
-
func_state_value = @state.value +
|
363
|
+
func_state_value = @state.value + ONE
|
353
364
|
# Do the call.
|
354
365
|
call_state.gotos << proc do
|
355
366
|
HDLRuby::High.top_user.instance_exec do
|
@@ -358,7 +369,7 @@ module HDLRuby::High::Std
|
|
358
369
|
end
|
359
370
|
helse do
|
360
371
|
# Overflow! Skip the call.
|
361
|
-
next_state_sig <= call_state_value +
|
372
|
+
next_state_sig <= call_state_value + ONE
|
362
373
|
# if overflow then
|
363
374
|
# # There is some overflow code to execute.
|
364
375
|
# HDLRuby::High.top_user.instance_exec(&overflow)
|
@@ -395,32 +406,32 @@ module HDLRuby::High::Std
|
|
395
406
|
@stack_sigs << stack_sig
|
396
407
|
|
397
408
|
# Returns the index of the newly created stack.
|
398
|
-
return @stack_sigs.size-
|
409
|
+
return @stack_sigs.size - ONE
|
399
410
|
end
|
400
411
|
|
401
412
|
## Pushes a new frame to the top of the stacks.
|
402
413
|
def push_all
|
403
414
|
# HDLRuby::High.cur_system.hprint("push_all\n")
|
404
|
-
@stack_ptr <= @stack_ptr +
|
415
|
+
@stack_ptr <= @stack_ptr + ONE
|
405
416
|
end
|
406
417
|
|
407
418
|
## Remove the top frame from the stacks.
|
408
419
|
def pop_all
|
409
420
|
# HDLRuby::High.cur_system.hprint("pop_all\n")
|
410
|
-
@stack_ptr <= @stack_ptr -
|
421
|
+
@stack_ptr <= @stack_ptr - ONE
|
411
422
|
end
|
412
423
|
|
413
424
|
## Get a value from the top of stack number +idx+
|
414
425
|
# If +off+ is the offeset in the stack.
|
415
426
|
def peek(idx, off = 0)
|
416
|
-
return @stack_sigs[idx][@stack_ptr-
|
427
|
+
return @stack_sigs[idx][(@stack_ptr-ONE)+off]
|
417
428
|
end
|
418
429
|
|
419
430
|
## Sets value +val+ to the top of stack number +idx+.
|
420
431
|
# If +off+ is the offeset in the stack.
|
421
432
|
def poke(idx,val, off = 0)
|
422
433
|
# puts "idx=#{idx} val=#{val} sig=#{@stack_sigs[idx].name}"
|
423
|
-
@stack_sigs[idx][@stack_ptr-
|
434
|
+
@stack_sigs[idx][@stack_ptr-ONE+off] <= val
|
424
435
|
end
|
425
436
|
|
426
437
|
## Access the return value signal.
|
@@ -449,7 +460,7 @@ module HDLRuby::High::Std
|
|
449
460
|
# ret_state_value = self.peek(@returnIdx, HDLRuby::High.top_user.mux(@stack_ptr < @depth,-1,0))
|
450
461
|
# Peek before the stack pointer value to account from the fact that
|
451
462
|
# the pop is performed beforehand.
|
452
|
-
ret_state_value = self.peek(@returnIdx, HDLRuby::High.top_user.mux(@stack_ptr < @depth,
|
463
|
+
ret_state_value = self.peek(@returnIdx, HDLRuby::High.top_user.mux(@stack_ptr < @depth,ZERO,ONE))
|
453
464
|
# Return.
|
454
465
|
this = self
|
455
466
|
state.gotos << proc do
|
@@ -483,15 +494,17 @@ module HDLRuby::High::Std
|
|
483
494
|
alias_method :old_make_inners, :make_inners
|
484
495
|
|
485
496
|
def make_inners(typ,*names)
|
497
|
+
res = nil
|
486
498
|
if SequencerFunctionI.current then
|
487
499
|
unames = names.map {|name| HDLRuby.uniq_name(name) }
|
488
|
-
HDLRuby::High.cur_scope.make_inners(typ, *unames)
|
500
|
+
res = HDLRuby::High.cur_scope.make_inners(typ, *unames)
|
489
501
|
names.zip(unames).each do |name,uname|
|
490
502
|
HDLRuby::High.space_reg(name) { send(uname) }
|
491
503
|
end
|
492
504
|
else
|
493
|
-
self.old_make_inners(typ,*names)
|
505
|
+
res = self.old_make_inners(typ,*names)
|
494
506
|
end
|
507
|
+
return res
|
495
508
|
end
|
496
509
|
end
|
497
510
|
|
data/lib/HDLRuby/std/std.rb
CHANGED
data/lib/HDLRuby/version.rb
CHANGED