HDLRuby 3.7.1 → 3.7.3
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 +83 -5
- data/ext/hruby_sim/hruby_rcsim_build.c +47 -2
- data/ext/hruby_sim/hruby_sim.h +8 -0
- data/ext/hruby_sim/hruby_sim_calc.c +3 -2
- data/ext/hruby_sim/hruby_sim_core.c +24 -7
- data/lib/HDLRuby/hdr_samples/ruby_program/with_sw_hruby.rb +1 -0
- data/lib/HDLRuby/hdr_samples/ruby_program/with_sw_hruby_function.rb +31 -0
- data/lib/HDLRuby/hdr_samples/with_program_ruby_array.rb +48 -0
- data/lib/HDLRuby/hdr_samples/with_program_ruby_sequencer.rb +49 -0
- data/lib/HDLRuby/hruby_high.rb +38 -0
- data/lib/HDLRuby/hruby_low.rb +25 -0
- data/lib/HDLRuby/hruby_rcsim.rb +9 -1
- data/lib/HDLRuby/std/sequencer.rb +15 -0
- data/lib/HDLRuby/std/sequencer_sw.rb +497 -112
- data/lib/HDLRuby/version.rb +1 -1
- data/lib/rubyHDL.rb +26 -0
- data/tuto/tutorial_sw.html +6 -0
- data/tuto/tutorial_sw.md +12 -0
- metadata +5 -2
@@ -15,6 +15,8 @@ module RubyHDL::High
|
|
15
15
|
########################################################################
|
16
16
|
|
17
17
|
|
18
|
+
|
19
|
+
|
18
20
|
@@absoluteCounter = -1 # The absolute name counter.
|
19
21
|
|
20
22
|
@@uniq_names = Set.new(Symbol.all_symbols.map {|sym| sym.to_s})
|
@@ -52,15 +54,51 @@ module RubyHDL::High
|
|
52
54
|
nil
|
53
55
|
end
|
54
56
|
|
57
|
+
# Generate input signals with type +type+ and names from +names+ list.
|
58
|
+
def make_inputs(type,*names)
|
59
|
+
# puts "make_inputs with names=#{names.join(",")}"
|
60
|
+
type = type.to_type
|
61
|
+
last_sig = nil
|
62
|
+
names.each do |name|
|
63
|
+
name = name.to_sym
|
64
|
+
# Create and add the signal.
|
65
|
+
sig = SignalI.new(name,type,:input)
|
66
|
+
@signals << sig
|
67
|
+
# Register it.
|
68
|
+
# self.register(name) { puts("sig=",sig.inspect); sig }
|
69
|
+
self.register(name) { sig }
|
70
|
+
last_sig = sig
|
71
|
+
end
|
72
|
+
return last_sig
|
73
|
+
end
|
74
|
+
|
75
|
+
# Generate output signals with type +type+ and names from +names+ list.
|
76
|
+
def make_outputs(type,*names)
|
77
|
+
# puts "make_outputs with names=#{names.join(",")}"
|
78
|
+
type = type.to_type
|
79
|
+
last_sig = nil
|
80
|
+
names.each do |name|
|
81
|
+
name = name.to_sym
|
82
|
+
# Create and add the signal.
|
83
|
+
sig = SignalI.new(name,type,:output)
|
84
|
+
@signals << sig
|
85
|
+
# Register it.
|
86
|
+
# self.register(name) { puts("sig=",sig.inspect); sig }
|
87
|
+
self.register(name) { sig }
|
88
|
+
last_sig = sig
|
89
|
+
end
|
90
|
+
return last_sig
|
91
|
+
end
|
92
|
+
|
55
93
|
# Generate inner signals with type +type+ and names from +names+ list.
|
56
94
|
def make_inners(type,*names)
|
57
|
-
puts "make_inners with names=#{names.join(",")}"
|
95
|
+
# puts "make_inners with names=#{names.join(",")}"
|
58
96
|
type = type.to_type
|
59
97
|
last_sig = nil
|
60
98
|
names.each do |name|
|
61
99
|
name = name.to_sym
|
62
100
|
# Create and add the signal.
|
63
|
-
sig = SignalI.new(type
|
101
|
+
sig = SignalI.new(name,type,:inner)
|
64
102
|
@signals << sig
|
65
103
|
# Register it.
|
66
104
|
# self.register(name) { puts("sig=",sig.inspect); sig }
|
@@ -73,12 +111,12 @@ module RubyHDL::High
|
|
73
111
|
# Register a new object named +name+ generated by +ruby_block+.
|
74
112
|
def register(name,&ruby_block)
|
75
113
|
# Add a way to call it from the stack of SW blocks.
|
76
|
-
::Object.define_method(name) do
|
77
|
-
RubyHDL::High.call_sblock(name)
|
114
|
+
::Object.define_method(name) do |*args|
|
115
|
+
RubyHDL::High.call_sblock(name,*args)
|
78
116
|
end
|
79
117
|
# Add a method for accessing the object.
|
80
118
|
# self.define_singleton_method(name,&ruby_block)
|
81
|
-
res = ruby_block.call
|
119
|
+
# res = ruby_block.call
|
82
120
|
@callables[name] = ruby_block
|
83
121
|
end
|
84
122
|
|
@@ -151,22 +189,44 @@ module RubyHDL::High
|
|
151
189
|
# end
|
152
190
|
|
153
191
|
|
192
|
+
# RUBY_OPERATOR = {
|
193
|
+
# # Unary operators.
|
194
|
+
# :"-@" => "-(%s)", :"+@" => "+(%s)", :"~" => "~(%s)",
|
195
|
+
# :abs => "(%s).abs",
|
196
|
+
# :boolean => "%s", :bit => "%s",
|
197
|
+
# :signed => "%s", :unsigned => "(%s) & 0xFFFFFFFFFFFFFFFF",
|
198
|
+
|
199
|
+
# # Binary operators.
|
200
|
+
# :"+" => "(%s)+(%s)", :"-" => "(%s)-(%s)", :"*" => "(%s)*(%s)",
|
201
|
+
# :"/" => "(%s)/(%s)", :"%" => "(%s)%%(%s)", :"**" => "(%s)**(%s)",
|
202
|
+
# :"&" => "(%s)&(%s)", :"|" => "(%s)|(%s)", :"^" => "(%s)^(%s)",
|
203
|
+
# :"<<" => "(%s)<<(%s)", :">>" => "(%s)>>(%s)",
|
204
|
+
# :"==" => "(%s)==(%s)", :"!=" => "(%s)!=(%s)",
|
205
|
+
# :"<" => "(%s)<(%s)", :">" => "(%s)>(%s)",
|
206
|
+
# :"<=" => "(%s)<=(%s)",:">=" => "(%s)>=(%s)"
|
207
|
+
# }
|
208
|
+
|
154
209
|
# The translation of operators into Ruby code.
|
155
210
|
RUBY_OPERATOR = {
|
156
211
|
# Unary operators.
|
157
|
-
:"-@" => "-(%
|
158
|
-
:abs => "(%
|
159
|
-
:boolean => "%
|
160
|
-
:signed => "%
|
212
|
+
:"-@" => "-(%{l})", :"+@" => "+(%{l})", :"~" => "~(%{l})",
|
213
|
+
:abs => "(%{l}).abs",
|
214
|
+
:boolean => "%{l}", :bit => "%{l}",
|
215
|
+
:signed => "%{l}", :unsigned => "(%{l}) & 0xFFFFFFFFFFFFFFFF",
|
161
216
|
|
162
217
|
# Binary operators.
|
163
|
-
:"+" => "(%
|
164
|
-
:"
|
165
|
-
:"
|
166
|
-
:"
|
167
|
-
:"
|
168
|
-
:"
|
169
|
-
:"
|
218
|
+
:"+" => "(%{l})+(%{r})", :"-" => "(%{l})-(%{r})",
|
219
|
+
:"*" => "(%{l})*(%{r})", :"/" => "(%{l})/(%{r})",
|
220
|
+
:"%" => "(%{l})%%(%{r})", :"**" => "(%{l})**(%{r})",
|
221
|
+
:"&" => "(%{l})&(%{r})", :"|" => "(%{l})|(%{r})",
|
222
|
+
:"^" => "(%{l})^(%{r})",
|
223
|
+
:"<<" => "(%{l})<<(%{r})", :">>" => "(%{l})>>(%{r})",
|
224
|
+
:"==" => "((%{l}) & %{m}==(%{r}) & %{m}) ? 1:0",
|
225
|
+
:"!=" => "((%{l}) & %{m}!=(%{r}) %{m}) ? 1:0",
|
226
|
+
:"<" => "((%{l}) & %{m}%{s} < (%{r}) & %{m}%{s}) ? 1:0",
|
227
|
+
:">" => "((%{l}) & %{m}%{s} > (%{r}) & %{m}%{s}) ? 1:0",
|
228
|
+
:"<=" => "((%{l}) & %{m}%{s} <=(%{r}) & %{m}%{s}) ? 1:0",
|
229
|
+
:">=" => "((%{l}) & %{m}%{s} >=(%{r}) & %{m}%{s}) ? 1:0"
|
170
230
|
}
|
171
231
|
|
172
232
|
# The translation of operators into C code.
|
@@ -596,7 +656,23 @@ module RubyHDL::High
|
|
596
656
|
return TypeVector.new(:"",base,self[0])
|
597
657
|
end
|
598
658
|
|
599
|
-
# Generate signals from +names+.
|
659
|
+
# Generate input signals from +names+.
|
660
|
+
def input(*names)
|
661
|
+
# Generate the type.
|
662
|
+
type = self.to_type
|
663
|
+
# Generate the resulting signals.
|
664
|
+
return type.input(*names)
|
665
|
+
end
|
666
|
+
|
667
|
+
# Generate output signals from +names+.
|
668
|
+
def output(*names)
|
669
|
+
# Generate the type.
|
670
|
+
type = self.to_type
|
671
|
+
# Generate the resulting signals.
|
672
|
+
return type.output(*names)
|
673
|
+
end
|
674
|
+
|
675
|
+
# Generate inner signals from +names+.
|
600
676
|
def inner(*names)
|
601
677
|
# Generate the type.
|
602
678
|
type = self.to_type
|
@@ -617,6 +693,8 @@ module RubyHDL::High
|
|
617
693
|
using RubyHDL::High
|
618
694
|
include HDLRuby::Tprocess
|
619
695
|
|
696
|
+
attr_reader :name
|
697
|
+
|
620
698
|
# Type creation.
|
621
699
|
|
622
700
|
# Creates a new type named +name+.
|
@@ -685,13 +763,13 @@ module RubyHDL::High
|
|
685
763
|
# Gets the type max value if any.
|
686
764
|
# Default: not defined.
|
687
765
|
def max
|
688
|
-
raise
|
766
|
+
raise "No max value for type #{self} (#{self.name})"
|
689
767
|
end
|
690
768
|
|
691
769
|
# Gets the type min value if any.
|
692
770
|
# Default: not defined.
|
693
771
|
def min
|
694
|
-
raise
|
772
|
+
raise "No min value for type #{self} (#{self.name})"
|
695
773
|
end
|
696
774
|
|
697
775
|
# Get the direction of the type, little or big endian.
|
@@ -707,7 +785,7 @@ module RubyHDL::High
|
|
707
785
|
|
708
786
|
# Gets the range of the type, by default range is not defined.
|
709
787
|
def range
|
710
|
-
raise
|
788
|
+
raise "No range for type #{self} (#{self.name})"
|
711
789
|
end
|
712
790
|
|
713
791
|
# Tells if the type has a base.
|
@@ -717,7 +795,7 @@ module RubyHDL::High
|
|
717
795
|
|
718
796
|
# Gets the base type, by default base type is not defined.
|
719
797
|
def base
|
720
|
-
raise
|
798
|
+
raise "No base type for type #{self} (#{self.name})"
|
721
799
|
end
|
722
800
|
|
723
801
|
# Tells if the type has sub types.
|
@@ -780,12 +858,12 @@ module RubyHDL::High
|
|
780
858
|
# NOTE: can only be done if the name is not already set.
|
781
859
|
def name=(name)
|
782
860
|
unless @name.empty? then
|
783
|
-
raise
|
861
|
+
raise "Name of type already set to: #{@name}."
|
784
862
|
end
|
785
863
|
# Checks and sets the name.
|
786
864
|
name = name.to_sym
|
787
865
|
if name.empty? then
|
788
|
-
raise
|
866
|
+
raise "Cannot set an empty name."
|
789
867
|
end
|
790
868
|
@name = name
|
791
869
|
# Registers the name.
|
@@ -835,17 +913,17 @@ module RubyHDL::High
|
|
835
913
|
|
836
914
|
# SignalI creation through the type.
|
837
915
|
|
838
|
-
#
|
839
|
-
|
840
|
-
|
841
|
-
|
916
|
+
# Declares high-level input signals named +names+ of the current type.
|
917
|
+
def input(*names)
|
918
|
+
RubyHDL::High.top_sblock.make_inputs(self,*names)
|
919
|
+
end
|
842
920
|
|
843
|
-
#
|
844
|
-
#
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
921
|
+
# Declares high-level untyped output signals named +names+ of the
|
922
|
+
# current type.
|
923
|
+
def output(*names)
|
924
|
+
# High.top_user.make_outputs(self.instantiate,*names)
|
925
|
+
RubyHDL::High.top_sblock.make_outputs(self,*names)
|
926
|
+
end
|
849
927
|
|
850
928
|
# # Declares high-level untyped inout signals named +names+ of the
|
851
929
|
# # current type.
|
@@ -985,12 +1063,30 @@ module RubyHDL::High
|
|
985
1063
|
|
986
1064
|
# The signed bit type.
|
987
1065
|
Signed = define_type(:signed)
|
1066
|
+
class << Signed
|
1067
|
+
# Tells if the type signed.
|
1068
|
+
def signed?
|
1069
|
+
return true
|
1070
|
+
end
|
1071
|
+
end
|
988
1072
|
|
989
1073
|
# The unsigned bit type.
|
990
1074
|
Unsigned = define_type(:unsigned)
|
1075
|
+
class << Unsigned
|
1076
|
+
# Tells if the type unsigned.
|
1077
|
+
def unsigned?
|
1078
|
+
return true
|
1079
|
+
end
|
1080
|
+
end
|
991
1081
|
|
992
1082
|
# The float bit type
|
993
1083
|
Float = define_type(:float)
|
1084
|
+
class << Float
|
1085
|
+
# Tells if the type signed.
|
1086
|
+
def signed?
|
1087
|
+
return true
|
1088
|
+
end
|
1089
|
+
end
|
994
1090
|
|
995
1091
|
# The string type
|
996
1092
|
StringT = define_type(:string)
|
@@ -1036,7 +1132,7 @@ module RubyHDL::High
|
|
1036
1132
|
# Ensures a type has been produced.
|
1037
1133
|
gtype = gtype.to_type if gtype.respond_to?(:to_type)
|
1038
1134
|
unless gtype.is_a?(Type) then
|
1039
|
-
raise
|
1135
|
+
raise "Generic type #{self.name} did not produce a valid type: #{gtype.class}"
|
1040
1136
|
end
|
1041
1137
|
# Create a new type definition from it.
|
1042
1138
|
gtype = TypeDef.new(self.name.to_s + "_#{args.join(':')}",
|
@@ -1081,8 +1177,7 @@ module RubyHDL::High
|
|
1081
1177
|
|
1082
1178
|
# Check and set the base
|
1083
1179
|
unless base.is_a?(Type)
|
1084
|
-
raise
|
1085
|
-
"Invalid class for VectorType base: #{base.class}."
|
1180
|
+
raise "Invalid class for VectorType base: #{base.class}."
|
1086
1181
|
end
|
1087
1182
|
@base = base
|
1088
1183
|
|
@@ -1295,13 +1390,13 @@ module RubyHDL::High
|
|
1295
1390
|
# Set the direction.
|
1296
1391
|
@direction = direction.to_sym
|
1297
1392
|
unless [:little, :big].include?(@direction)
|
1298
|
-
raise
|
1393
|
+
raise "Invalid direction for a type: #{direction}"
|
1299
1394
|
end
|
1300
1395
|
|
1301
1396
|
# Check and set the content.
|
1302
1397
|
content.each do |sub|
|
1303
1398
|
unless sub.is_a?(Type) then
|
1304
|
-
raise
|
1399
|
+
raise "Invalid class for a type: #{sub.class}"
|
1305
1400
|
end
|
1306
1401
|
end
|
1307
1402
|
@types = content
|
@@ -1345,8 +1440,7 @@ module RubyHDL::High
|
|
1345
1440
|
# Adds a sub +type+.
|
1346
1441
|
def add_type(type)
|
1347
1442
|
unless type.is_a?(Type) then
|
1348
|
-
raise
|
1349
|
-
"Invalid class for a type: #{type.class} (#{type})"
|
1443
|
+
raise "Invalid class for a type: #{type.class} (#{type})"
|
1350
1444
|
end
|
1351
1445
|
@types << type
|
1352
1446
|
end
|
@@ -1414,7 +1508,7 @@ module RubyHDL::High
|
|
1414
1508
|
# Regular tuple, return its range as if it was an array.
|
1415
1509
|
return 0..@types.size-1
|
1416
1510
|
else
|
1417
|
-
raise
|
1511
|
+
raise "No range for type #{self}"
|
1418
1512
|
end
|
1419
1513
|
end
|
1420
1514
|
|
@@ -1435,7 +1529,7 @@ module RubyHDL::High
|
|
1435
1529
|
# Regular tuple, return the type of its first element.
|
1436
1530
|
return @types[0]
|
1437
1531
|
else
|
1438
|
-
raise
|
1532
|
+
raise "No base type for type #{self}"
|
1439
1533
|
end
|
1440
1534
|
end
|
1441
1535
|
|
@@ -1463,14 +1557,14 @@ module RubyHDL::High
|
|
1463
1557
|
# Set the direction.
|
1464
1558
|
@direction = dir.to_sym
|
1465
1559
|
unless [:little, :big].include?(@direction)
|
1466
|
-
raise
|
1560
|
+
raise "Invalid direction for a type: #{dir}"
|
1467
1561
|
end
|
1468
1562
|
|
1469
1563
|
# Check and set the content.
|
1470
1564
|
content = Hash[content]
|
1471
1565
|
@types = content.map do |k,v|
|
1472
1566
|
unless v.is_a?(Type) then
|
1473
|
-
raise
|
1567
|
+
raise "Invalid class for a type: #{v.class}"
|
1474
1568
|
end
|
1475
1569
|
[ k.to_sym, v ]
|
1476
1570
|
end.to_h
|
@@ -1823,11 +1917,13 @@ module RubyHDL::High
|
|
1823
1917
|
super(type)
|
1824
1918
|
@operator = operator.to_sym
|
1825
1919
|
@child = child.to_expr
|
1920
|
+
@mask = (2 ** @type.width)-1
|
1826
1921
|
end
|
1827
1922
|
|
1828
1923
|
# Convert to Ruby code.
|
1829
1924
|
def to_ruby
|
1830
|
-
return RUBY_OPERATOR[@operator] % @child.to_ruby
|
1925
|
+
# return RUBY_OPERATOR[@operator] % @child.to_ruby
|
1926
|
+
return RUBY_OPERATOR[@operator] % { l: @child.to_ruby }
|
1831
1927
|
end
|
1832
1928
|
|
1833
1929
|
# Convert to C code.
|
@@ -1845,11 +1941,23 @@ module RubyHDL::High
|
|
1845
1941
|
@operator = operator.to_sym
|
1846
1942
|
@left = left.to_expr
|
1847
1943
|
@right = right.to_expr
|
1944
|
+
# Compute the mask for fixing the bit width.
|
1945
|
+
@mask = (2 ** @type.width)-1
|
1946
|
+
# puts "@type=#{@type} name=#{@type.name} @type.width=#{@type.width} @mask=#{@mask}"
|
1947
|
+
# Compute xor mask for handling the sign.
|
1948
|
+
# Make it as a string so that no addition computation is required
|
1949
|
+
# if no sign is required.
|
1950
|
+
@sign_fix = ""
|
1951
|
+
if type.signed? then
|
1952
|
+
@sign_fix = " ^ #{2**(@type.width-1)}"
|
1953
|
+
end
|
1848
1954
|
end
|
1849
1955
|
|
1850
1956
|
# Convert to Ruby code.
|
1851
1957
|
def to_ruby
|
1852
|
-
return RUBY_OPERATOR[@operator] % [ @left.to_ruby, @right.to_ruby ]
|
1958
|
+
# return RUBY_OPERATOR[@operator] % [ @left.to_ruby, @right.to_ruby ]
|
1959
|
+
return RUBY_OPERATOR[@operator] %
|
1960
|
+
{ l: @left.to_ruby, r: @right.to_ruby, m: @mask, s: @sign_fix }
|
1853
1961
|
end
|
1854
1962
|
|
1855
1963
|
# Convert to C code.
|
@@ -2062,10 +2170,27 @@ module RubyHDL::High
|
|
2062
2170
|
end
|
2063
2171
|
end
|
2064
2172
|
|
2065
|
-
|
2173
|
+
|
2174
|
+
# Describes a SW implementation of a statement.
|
2175
|
+
class Statement
|
2176
|
+
|
2177
|
+
# Iterate on the statements.
|
2178
|
+
def each_statement(&ruby_block)
|
2179
|
+
return to_enum(:each_statement) unless ruby_block
|
2180
|
+
# By default nothing to do.
|
2181
|
+
end
|
2182
|
+
|
2183
|
+
# Iterate deeply on the statements.
|
2184
|
+
def each_statement_deep(&ruby_block)
|
2185
|
+
return to_enum(:each_statement_deep) unless ruby_block
|
2186
|
+
# Just apply ruby_block on self.
|
2187
|
+
ruby_block.call(self)
|
2188
|
+
end
|
2189
|
+
end
|
2190
|
+
|
2066
2191
|
|
2067
2192
|
# Describes a SW implementation of a transmit statement.
|
2068
|
-
class Transmit
|
2193
|
+
class Transmit < Statement
|
2069
2194
|
using RubyHDL::High
|
2070
2195
|
|
2071
2196
|
attr_reader :left, :right
|
@@ -2132,12 +2257,11 @@ module RubyHDL::High
|
|
2132
2257
|
else
|
2133
2258
|
return "#{@left.to_c} = #{@right.to_c};"
|
2134
2259
|
end
|
2135
|
-
end
|
2136
|
-
|
2260
|
+
end
|
2137
2261
|
end
|
2138
2262
|
|
2139
2263
|
# Describes a SW implementation of a if statement.
|
2140
|
-
class Sif
|
2264
|
+
class Sif < Statement
|
2141
2265
|
# Create a new if statement in sequencer +sequencer+
|
2142
2266
|
# with +cond+ condition and +ruby_block+
|
2143
2267
|
# for generating the block that is taken if the condition is met.
|
@@ -2159,9 +2283,33 @@ module RubyHDL::High
|
|
2159
2283
|
@else_blk = Sblock.new(@sequencer,&ruby_block)
|
2160
2284
|
end
|
2161
2285
|
|
2286
|
+
# Iterate on the statements.
|
2287
|
+
def each_statement(&ruby_block)
|
2288
|
+
return to_enum(:each_statement) unless ruby_block
|
2289
|
+
# Apply ruby_block on the yes block.
|
2290
|
+
ruby_block.call(@yes_blk)
|
2291
|
+
# On the elsifs.
|
2292
|
+
@elsifs.each { |cond,statement| ruby_block.call(statement) }
|
2293
|
+
# On the else if any.
|
2294
|
+
ruby_block.call(@else_blk) if @else_blk
|
2295
|
+
end
|
2296
|
+
|
2297
|
+
# Iterate deeply on the statements.
|
2298
|
+
def each_statement_deep(&ruby_block)
|
2299
|
+
return to_enum(:each_statement_deep) unless ruby_block
|
2300
|
+
# Recurse on the yes block.
|
2301
|
+
@yes_blk.each_statement_deep
|
2302
|
+
# On the elsifs.
|
2303
|
+
@elsifs.each { |cond,statement| statement.each_statement_deep }
|
2304
|
+
# On the else if any.
|
2305
|
+
@else_blk.each_statement_deep if @else_blk
|
2306
|
+
# And apply ruby_block on self.
|
2307
|
+
ruby_block.call(self)
|
2308
|
+
end
|
2309
|
+
|
2162
2310
|
# Convert to Ruby code.
|
2163
2311
|
def to_ruby
|
2164
|
-
res = @sequencer.clk_up + "\nif(#{@condition.to_ruby})\n#{@yes_blk.to_ruby}\n"
|
2312
|
+
res = @sequencer.clk_up + "\nif(#{@condition.to_ruby} != 0)\n#{@yes_blk.to_ruby}\n"
|
2165
2313
|
@elsifs.each do |(cond,blk)|
|
2166
2314
|
res << "elsif(#{cond.to_ruby})\n#{blk.to_ruby}\n"
|
2167
2315
|
end
|
@@ -2185,7 +2333,7 @@ module RubyHDL::High
|
|
2185
2333
|
end
|
2186
2334
|
|
2187
2335
|
# Describes a SW implementation of a loop statement.
|
2188
|
-
class Sloop
|
2336
|
+
class Sloop < Statement
|
2189
2337
|
# Create a new infinite loop statement in sequencer +sequencer+
|
2190
2338
|
# with +ruby_block+ for generating the block that is taken.
|
2191
2339
|
def initialize(sequencer, &ruby_block)
|
@@ -2193,6 +2341,22 @@ module RubyHDL::High
|
|
2193
2341
|
@blk = Sblock.new(sequencer,&ruby_block)
|
2194
2342
|
end
|
2195
2343
|
|
2344
|
+
# Iterate on the statements.
|
2345
|
+
def each_statement(&ruby_block)
|
2346
|
+
return to_enum(:each_statement) unless ruby_block
|
2347
|
+
# Apply ruby_block on the block.
|
2348
|
+
ruby_block.call(@blk)
|
2349
|
+
end
|
2350
|
+
|
2351
|
+
# Iterate deeply on the statements.
|
2352
|
+
def each_statement_deep(&ruby_block)
|
2353
|
+
return to_enum(:each_statement_deep) unless ruby_block
|
2354
|
+
# Recurse on the block.
|
2355
|
+
@blk.each_statement_deep
|
2356
|
+
# And apply ruby_block on self.
|
2357
|
+
ruby_block.call(self)
|
2358
|
+
end
|
2359
|
+
|
2196
2360
|
# Convert to Ruby code.
|
2197
2361
|
def to_ruby
|
2198
2362
|
return "loop do\n#{@blk.to_ruby}\n#{@sequencer.clk_up}\nend"
|
@@ -2205,7 +2369,7 @@ module RubyHDL::High
|
|
2205
2369
|
end
|
2206
2370
|
|
2207
2371
|
# Describes a SW implementation of a while statement.
|
2208
|
-
class Swhile
|
2372
|
+
class Swhile < Statement
|
2209
2373
|
# Create a new while statement in sequencer +sequencer+
|
2210
2374
|
# with +cond+ condition and +ruby_block+
|
2211
2375
|
# for generating the block that is taken while the condition is met.
|
@@ -2215,6 +2379,22 @@ module RubyHDL::High
|
|
2215
2379
|
@yes_blk = Sblock.new(sequencer,&ruby_block)
|
2216
2380
|
end
|
2217
2381
|
|
2382
|
+
# Iterate on the statements.
|
2383
|
+
def each_statement(&ruby_block)
|
2384
|
+
return to_enum(:each_statement) unless ruby_block
|
2385
|
+
# Apply ruby_block on the block.
|
2386
|
+
ruby_block.call(@yes_blk)
|
2387
|
+
end
|
2388
|
+
|
2389
|
+
# Iterate deeply on the statements.
|
2390
|
+
def each_statement_deep(&ruby_block)
|
2391
|
+
return to_enum(:each_statement_deep) unless ruby_block
|
2392
|
+
# Recurse on the yes block.
|
2393
|
+
@yes_blk.each_statement_deep
|
2394
|
+
# And apply ruby_block on self.
|
2395
|
+
ruby_block.call(self)
|
2396
|
+
end
|
2397
|
+
|
2218
2398
|
# Convert to Ruby code.
|
2219
2399
|
def to_ruby
|
2220
2400
|
return @sequencer.clk_up +
|
@@ -2228,7 +2408,7 @@ module RubyHDL::High
|
|
2228
2408
|
end
|
2229
2409
|
|
2230
2410
|
# Describes a SW implementation of a step statement.
|
2231
|
-
class Step
|
2411
|
+
class Step < Statement
|
2232
2412
|
# Create a new step statement in sequencer +sequencer+.
|
2233
2413
|
def initialize(sequencer)
|
2234
2414
|
@sequencer = sequencer
|
@@ -2246,7 +2426,7 @@ module RubyHDL::High
|
|
2246
2426
|
end
|
2247
2427
|
|
2248
2428
|
# Describes a SW implementation of a break statement.
|
2249
|
-
class Sbreak
|
2429
|
+
class Sbreak < Statement
|
2250
2430
|
# Create a new break statement in sequencer +sequencer+.
|
2251
2431
|
def initialize(sequencer)
|
2252
2432
|
@sequencer = sequencer
|
@@ -2264,7 +2444,7 @@ module RubyHDL::High
|
|
2264
2444
|
end
|
2265
2445
|
|
2266
2446
|
# Describes a SW implementation of a continue statement.
|
2267
|
-
class Scontinue
|
2447
|
+
class Scontinue < Statement
|
2268
2448
|
# Create a new break statement in sequencer +sequencer+.
|
2269
2449
|
def initialize
|
2270
2450
|
@sequencer = sequencer
|
@@ -2281,10 +2461,32 @@ module RubyHDL::High
|
|
2281
2461
|
end
|
2282
2462
|
end
|
2283
2463
|
|
2464
|
+
# Describes a SW implementation of a return statement.
|
2465
|
+
class Sreturn < Statement
|
2466
|
+
attr_reader :value
|
2467
|
+
|
2468
|
+
# Create a new break statement in sequencer +sequencer+
|
2469
|
+
# returning value +val+.
|
2470
|
+
def initialize(sequencer,val)
|
2471
|
+
@sequencer = sequencer
|
2472
|
+
@value = val
|
2473
|
+
end
|
2474
|
+
|
2475
|
+
# Convert to Ruby code.
|
2476
|
+
def to_ruby
|
2477
|
+
return @sequencer.clk_up + "\nreturn #{@value.to_ruby}"
|
2478
|
+
end
|
2479
|
+
|
2480
|
+
# Convert to Ruby code.
|
2481
|
+
def to_c
|
2482
|
+
return @sequencer.clk_up_c + "\nreturn #{val.to_c};"
|
2483
|
+
end
|
2484
|
+
end
|
2485
|
+
|
2284
2486
|
# Describes a SW implementation of a terminate statement.
|
2285
|
-
class Sterminate
|
2487
|
+
class Sterminate < Statement
|
2286
2488
|
# Create a new break statement in sequencer +sequencer+.
|
2287
|
-
def initialize
|
2489
|
+
def initialize(sequencer)
|
2288
2490
|
@sequencer = sequencer
|
2289
2491
|
end
|
2290
2492
|
|
@@ -2302,13 +2504,25 @@ module RubyHDL::High
|
|
2302
2504
|
end
|
2303
2505
|
|
2304
2506
|
# Describes a SW synchronization of a signal.
|
2305
|
-
class Sync
|
2306
|
-
def initialize
|
2507
|
+
class Sync < Statement
|
2508
|
+
def initialize(sequencer)
|
2509
|
+
@sequencer = sequencer
|
2307
2510
|
end
|
2308
2511
|
|
2309
2512
|
# Convert to Ruby code.
|
2310
2513
|
def to_ruby
|
2311
|
-
|
2514
|
+
# Update the inputs and outputs.
|
2515
|
+
res = ""
|
2516
|
+
RubyHDL::High.global_sblock.each_signal do |signal|
|
2517
|
+
case signal.dir
|
2518
|
+
when :input
|
2519
|
+
res << signal.to_ruby + " = RubyHDL.#{signal.name}\n"
|
2520
|
+
when :output
|
2521
|
+
res << "RubyHDL.#{signal.name} = " + signal.to_ruby + "\n"
|
2522
|
+
end
|
2523
|
+
end
|
2524
|
+
res << "Fiber.yield"
|
2525
|
+
return res
|
2312
2526
|
end
|
2313
2527
|
|
2314
2528
|
# Convert to C code.
|
@@ -2344,6 +2558,19 @@ module RubyHDL::High
|
|
2344
2558
|
return self
|
2345
2559
|
end
|
2346
2560
|
|
2561
|
+
# Iterate on the statements.
|
2562
|
+
def each_statement(&ruby_block)
|
2563
|
+
return to_enum(:each_statement) unless ruby_block
|
2564
|
+
# By default nothing to do.
|
2565
|
+
end
|
2566
|
+
|
2567
|
+
# Iterate deeply on the statements.
|
2568
|
+
def each_statement_deep(&ruby_block)
|
2569
|
+
return to_enum(:each_statement_deep) unless ruby_block
|
2570
|
+
# Just apply ruby_block on self.
|
2571
|
+
ruby_block.call(self)
|
2572
|
+
end
|
2573
|
+
|
2347
2574
|
# Execute a ruby code block for +ruby_block+.
|
2348
2575
|
def self.call(id)
|
2349
2576
|
# puts "id=#{id}"
|
@@ -2368,27 +2595,39 @@ module RubyHDL::High
|
|
2368
2595
|
|
2369
2596
|
|
2370
2597
|
# Describes a SW implementation of an call statement.
|
2371
|
-
class Scall
|
2598
|
+
class Scall < Expression
|
2372
2599
|
using RubyHDL::High
|
2373
2600
|
|
2374
|
-
# Create a new call
|
2375
|
-
#
|
2376
|
-
def initialize(
|
2601
|
+
# Create a new call to function named +func+ statement in
|
2602
|
+
# sequencer +sequencer+ with arguments +args+.
|
2603
|
+
def initialize(func, sequencer, *args)
|
2604
|
+
super(func.type)
|
2377
2605
|
@sequencer = sequencer
|
2378
|
-
@name = name
|
2606
|
+
@name = func.name
|
2379
2607
|
@args = args
|
2380
2608
|
end
|
2381
2609
|
|
2610
|
+
# Iterate on the statements.
|
2611
|
+
def each_statement(&ruby_block)
|
2612
|
+
return to_enum(:each_statement) unless ruby_block
|
2613
|
+
# By default nothing to do.
|
2614
|
+
end
|
2615
|
+
|
2616
|
+
# Iterate deeply on the statements.
|
2617
|
+
def each_statement_deep(&ruby_block)
|
2618
|
+
return to_enum(:each_statement_deep) unless ruby_block
|
2619
|
+
# Just apply ruby_block on self.
|
2620
|
+
ruby_block.call(self)
|
2621
|
+
end
|
2622
|
+
|
2382
2623
|
# Convert to Ruby code.
|
2383
2624
|
def to_ruby
|
2384
|
-
return @
|
2385
|
-
@args.map {|arg| arg.to_ruby}.join(",") + ")"
|
2625
|
+
return "__#{@name}(" + @args.map {|arg| arg.to_ruby}.join(",") + ")"
|
2386
2626
|
end
|
2387
2627
|
|
2388
2628
|
# Convert to C code.
|
2389
2629
|
def to_c
|
2390
|
-
return
|
2391
|
-
@args.map {|arg| arg.to_ruby}.join(",") + ");"
|
2630
|
+
return "\n__#{name}(" + @args.map {|arg| arg.to_ruby}.join(",") + ");"
|
2392
2631
|
end
|
2393
2632
|
|
2394
2633
|
# Create an iterator for a given method +meth+.
|
@@ -2725,7 +2964,7 @@ module RubyHDL::High
|
|
2725
2964
|
|
2726
2965
|
|
2727
2966
|
# Describes a SW implementation of an iterator statement.
|
2728
|
-
class Siter
|
2967
|
+
class Siter < Statement
|
2729
2968
|
using RubyHDL::High
|
2730
2969
|
|
2731
2970
|
# Create a new iteration statement in sequencer +sequencer+
|
@@ -2748,12 +2987,31 @@ module RubyHDL::High
|
|
2748
2987
|
end
|
2749
2988
|
alias_method :each, :each_command
|
2750
2989
|
|
2990
|
+
# Iterate on the statements.
|
2991
|
+
def each_statement(&ruby_block)
|
2992
|
+
return to_enum(:each_statement) unless ruby_block
|
2993
|
+
# Apply ruby_block on the block.
|
2994
|
+
@blk.each_statement(&ruby_block)
|
2995
|
+
end
|
2996
|
+
|
2997
|
+
# Iterate deeply on the statements.
|
2998
|
+
def each_statement_deep(&ruby_block)
|
2999
|
+
return to_enum(:each_statement_deep) unless ruby_block
|
3000
|
+
# Recurse on the yes block.
|
3001
|
+
@blk.each_statement_deep
|
3002
|
+
# And apply ruby_block on self.
|
3003
|
+
ruby_block.call(self)
|
3004
|
+
end
|
3005
|
+
|
2751
3006
|
# Convert to Ruby code.
|
2752
3007
|
def to_ruby
|
2753
3008
|
# puts "to_ruby with blk=#{@blk} commands=#{@commands}"
|
2754
3009
|
res = @sequencer.clk_up + "\n" +
|
2755
3010
|
@commands.map { |command| command.to_ruby }.join(".")
|
2756
|
-
return res + " do
|
3011
|
+
return res + " do" +
|
3012
|
+
(@blk.each_arg.any? ?
|
3013
|
+
"|#{@blk.each_arg.map(&:to_ruby).join(",")}|" : "") +
|
3014
|
+
"\n#{@blk.to_ruby}\n#{@sequencer.clk_up}\nend"
|
2757
3015
|
end
|
2758
3016
|
|
2759
3017
|
# Convert to C code.
|
@@ -3105,11 +3363,26 @@ module RubyHDL::High
|
|
3105
3363
|
# Describes a SW implementation of a signal.
|
3106
3364
|
class SignalI < Expression
|
3107
3365
|
using RubyHDL::High
|
3108
|
-
attr_reader :
|
3366
|
+
attr_reader :name, :type, :dir
|
3109
3367
|
# Create a new signal with type +type+ and name +name+.
|
3110
|
-
def initialize(type,
|
3111
|
-
@type = type.to_type
|
3368
|
+
def initialize(name,type,dir)
|
3112
3369
|
@name = name.to_sym
|
3370
|
+
@type = type.to_type
|
3371
|
+
@dir = dir.to_sym
|
3372
|
+
# Compute the mask for adjusting the value to the type.
|
3373
|
+
@mask = (2 ** @type.width)-1
|
3374
|
+
@sign = 2 ** (@type.width-1)
|
3375
|
+
@global = "" # The global indicator: empty or '$'
|
3376
|
+
end
|
3377
|
+
|
3378
|
+
# Tell if the signal is global or not.
|
3379
|
+
def global?
|
3380
|
+
return @global == "$"
|
3381
|
+
end
|
3382
|
+
|
3383
|
+
# Set the signal to be a global.
|
3384
|
+
def global!
|
3385
|
+
@global = "$"
|
3113
3386
|
end
|
3114
3387
|
|
3115
3388
|
# Tell if the signal is an array.
|
@@ -3119,7 +3392,7 @@ module RubyHDL::High
|
|
3119
3392
|
|
3120
3393
|
# Convert to Ruby code.
|
3121
3394
|
def to_ruby
|
3122
|
-
return "__" + self.name.to_s
|
3395
|
+
return @global + "__" + self.name.to_s
|
3123
3396
|
end
|
3124
3397
|
|
3125
3398
|
# Convert to C code.
|
@@ -3127,12 +3400,40 @@ module RubyHDL::High
|
|
3127
3400
|
|
3128
3401
|
# Check if a value is defined for the signal.
|
3129
3402
|
def value?
|
3130
|
-
|
3403
|
+
if global? then
|
3404
|
+
return global_variables.include?(self.to_ruby)
|
3405
|
+
else
|
3406
|
+
return TOPLEVEL_BINDING.local_variable_defined?(self.to_ruby)
|
3407
|
+
end
|
3131
3408
|
end
|
3132
3409
|
|
3133
3410
|
# Gets the value of the signal.
|
3134
3411
|
def value
|
3135
|
-
return TOPLEVEL_BINDING.eval(self.to_ruby)
|
3412
|
+
# return TOPLEVEL_BINDING.eval(self.to_ruby)
|
3413
|
+
res = TOPLEVEL_BINDING.eval(self.to_ruby)
|
3414
|
+
if res.is_a?(Integer) then
|
3415
|
+
res = res & @mask
|
3416
|
+
if @type.signed? then
|
3417
|
+
if res & @sign != 0 then
|
3418
|
+
return res - (@mask+1)
|
3419
|
+
end
|
3420
|
+
end
|
3421
|
+
end
|
3422
|
+
return res
|
3423
|
+
end
|
3424
|
+
|
3425
|
+
# Generate a Ruby/C string code for accessing the value of the
|
3426
|
+
# signal with proper bit width and sign.
|
3427
|
+
def value_text
|
3428
|
+
unless self.array? then
|
3429
|
+
if @type.signed? then
|
3430
|
+
return "(#{self.to_ruby} & #{@sign} != 0 ? #{self.to_ruby} & #{@mask} - #{@mask+1} : #{self.to_ruby} & #{@mask})"
|
3431
|
+
else
|
3432
|
+
return "(#{self.to_ruby} & #{@mask})"
|
3433
|
+
end
|
3434
|
+
else
|
3435
|
+
return self.to_ruby
|
3436
|
+
end
|
3136
3437
|
end
|
3137
3438
|
|
3138
3439
|
# Sets the value of the signal.
|
@@ -3156,7 +3457,6 @@ module RubyHDL::High
|
|
3156
3457
|
end
|
3157
3458
|
end
|
3158
3459
|
|
3159
|
-
|
3160
3460
|
# Describes a SW implementation of a block.
|
3161
3461
|
class Sblock < SblockTop
|
3162
3462
|
using RubyHDL::High
|
@@ -3174,9 +3474,11 @@ module RubyHDL::High
|
|
3174
3474
|
# Push the new sblock on top of the stack.
|
3175
3475
|
RubyHDL::High.push_sblock(self)
|
3176
3476
|
# Make signals from the arguments of the ruby block.
|
3477
|
+
# unsigned 32-bit integers by default.
|
3177
3478
|
@args = []
|
3178
3479
|
ruby_block.parameters.each do |typ,arg|
|
3179
|
-
@args << SignalI.new(Void
|
3480
|
+
# @args << SignalI.new(arg,Void,:inner)
|
3481
|
+
@args << SignalI.new(arg,bit[32],:inner)
|
3180
3482
|
end
|
3181
3483
|
# Fill it.
|
3182
3484
|
self.instance_exec(*@args,&ruby_block)
|
@@ -3197,6 +3499,21 @@ module RubyHDL::High
|
|
3197
3499
|
end
|
3198
3500
|
alias_method :<<, :add
|
3199
3501
|
|
3502
|
+
# Iterate on the statements.
|
3503
|
+
def each_statement(&ruby_block)
|
3504
|
+
return to_enum(:each_statement) unless ruby_block
|
3505
|
+
@statements.each { |statement| ruby_block(statement) }
|
3506
|
+
end
|
3507
|
+
|
3508
|
+
# Iterate deeply on the statements.
|
3509
|
+
def each_statement_deep(&ruby_block)
|
3510
|
+
return to_enum(:each_statement_deep) unless ruby_block
|
3511
|
+
@statements.each do |statement|
|
3512
|
+
statement.each_statement_deep(&ruby_block)
|
3513
|
+
ruby_block(statement)
|
3514
|
+
end
|
3515
|
+
end
|
3516
|
+
|
3200
3517
|
# Delete a statement.
|
3201
3518
|
def delete(statement)
|
3202
3519
|
@statements.delete(statement)
|
@@ -3212,14 +3529,20 @@ module RubyHDL::High
|
|
3212
3529
|
return @statements[-1]
|
3213
3530
|
end
|
3214
3531
|
|
3532
|
+
# Iterate on the arguments if any.
|
3533
|
+
def each_arg(&ruby_block)
|
3534
|
+
return to_enum(:each_arg) unless ruby_block
|
3535
|
+
@args.each(&ruby_block)
|
3536
|
+
end
|
3215
3537
|
|
3216
3538
|
# Convert to Ruby code.
|
3217
3539
|
def to_ruby
|
3218
3540
|
res = ""
|
3219
|
-
#
|
3220
|
-
if
|
3221
|
-
|
3222
|
-
|
3541
|
+
# The arguments are ignored, as they are handled in SfunctionT.
|
3542
|
+
# # Generate the arguments if any.
|
3543
|
+
# if @args.any? then
|
3544
|
+
# res = "|#{@args.map(&:to_ruby).join(",")}|\n"
|
3545
|
+
# end
|
3223
3546
|
# Generate the statements.
|
3224
3547
|
res += @statements.map do |stmnt|
|
3225
3548
|
stmnt.to_ruby + "\n"
|
@@ -3263,6 +3586,11 @@ module RubyHDL::High
|
|
3263
3586
|
self << RubyHDL::High::Scontinue.new(@sequencer)
|
3264
3587
|
end
|
3265
3588
|
|
3589
|
+
# Create a return statement.
|
3590
|
+
def sreturn(val)
|
3591
|
+
self << RubyHDL::High::Sreturn.new(@sequencer,val)
|
3592
|
+
end
|
3593
|
+
|
3266
3594
|
# Terminates the sequencer.
|
3267
3595
|
def sterminate
|
3268
3596
|
self << RubyHDL::High::Sterminate.new(@sequencer)
|
@@ -3272,16 +3600,19 @@ module RubyHDL::High
|
|
3272
3600
|
def sif(cond, &ruby_block)
|
3273
3601
|
self << RubyHDL::High::Sif.new(@sequencer,cond,&ruby_block)
|
3274
3602
|
end
|
3603
|
+
alias_method :hif, :sif
|
3275
3604
|
|
3276
3605
|
# Create a sequential elsif statement on +cond+.
|
3277
3606
|
def selsif(cond, &ruby_block)
|
3278
3607
|
self.last_statement.selsif(&ruby_block)
|
3279
3608
|
end
|
3609
|
+
alias_method :helsif, :selsif
|
3280
3610
|
|
3281
3611
|
# Create a sequential else statement.
|
3282
3612
|
def selse(&ruby_block)
|
3283
3613
|
self.last_statement.selse(&ruby_block)
|
3284
3614
|
end
|
3615
|
+
alias_method :helse, :selse
|
3285
3616
|
|
3286
3617
|
# Wait a given condition.
|
3287
3618
|
def swait(cond)
|
@@ -3313,7 +3644,7 @@ module RubyHDL::High
|
|
3313
3644
|
# For software only: stop the current sequencer for allowing
|
3314
3645
|
# sharing of variables with other ones.
|
3315
3646
|
def sync
|
3316
|
-
self << RubyHDL::High::Sync.new
|
3647
|
+
self << RubyHDL::High::Sync.new(@sequencer)
|
3317
3648
|
end
|
3318
3649
|
|
3319
3650
|
# Some arbirary Ruby code as a string +str+ or as a proc
|
@@ -3321,29 +3652,47 @@ module RubyHDL::High
|
|
3321
3652
|
def ruby(str = nil, &ruby_block)
|
3322
3653
|
self << RubyHDL::High::Ruby.new(str,&ruby_block)
|
3323
3654
|
end
|
3655
|
+
|
3656
|
+
# Some arbitrary code whose text is to add direction.
|
3657
|
+
def text(str)
|
3658
|
+
self << str.to_s
|
3659
|
+
end
|
3324
3660
|
end
|
3325
3661
|
|
3326
3662
|
|
3327
3663
|
# Describes a SW implementation of a sequencer function.
|
3328
3664
|
class SfunctionT
|
3329
3665
|
using RubyHDL::High
|
3330
|
-
attr_reader :name
|
3666
|
+
attr_reader :name, :type
|
3331
3667
|
# Create a new named +name+ with arguments +args+ and
|
3332
3668
|
# executing the content of block +sblock+
|
3333
|
-
def initialize(
|
3669
|
+
def initialize(name,sblock,*args)
|
3334
3670
|
@name = name.to_sym
|
3335
3671
|
@args = args
|
3336
3672
|
@blk = sblock
|
3673
|
+
@type = self.make_return_type(@blk)
|
3674
|
+
end
|
3675
|
+
|
3676
|
+
# Compute the return type from current sblock +sblock+
|
3677
|
+
def make_return_type(sblock)
|
3678
|
+
# Locate a return statement.
|
3679
|
+
sblock.each_statement_deep do |statement|
|
3680
|
+
if statement.is_a?(RubyHDL::High::Sreturn) then
|
3681
|
+
return statement.value.type
|
3682
|
+
end
|
3683
|
+
end
|
3684
|
+
# No return, so void type.
|
3685
|
+
return RubyHDL::High::Void
|
3337
3686
|
end
|
3338
3687
|
|
3339
3688
|
# Convert to Ruby code.
|
3340
3689
|
def to_ruby
|
3341
|
-
return "def #{name}(#{@args.map {|arg| arg.to_ruby}.join(",")}\n#{@blk.to_ruby}\nend\n"
|
3690
|
+
return "def __#{name}(#{@args.map {|arg| "__" + arg.to_ruby}.join(",")})\n#{@blk.sequencer.clk_up}\n#{@blk.to_ruby}\nend\n"
|
3342
3691
|
end
|
3343
3692
|
|
3344
3693
|
# Convert to C code.
|
3345
3694
|
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"
|
3695
|
+
return "unsigned long long __#{name}(#{@args.map {|arg| "unsigned long long " + arg.to_c}.join(",")} {\n#{@blk.sequencer.clk_up_c}\n#{@blk.to_c}\n}\n"
|
3347
3696
|
end
|
3348
3697
|
end
|
3349
3698
|
|
@@ -3376,7 +3725,7 @@ module RubyHDL::High
|
|
3376
3725
|
# Create a set of sfunction used in the sequencer.
|
3377
3726
|
@sfunctions = {}
|
3378
3727
|
# Create the main block.
|
3379
|
-
@
|
3728
|
+
@blk = RubyHDL::High::Sblock.new(self,&ruby_block)
|
3380
3729
|
# Build the Ruby code.
|
3381
3730
|
@source = ""
|
3382
3731
|
@code = nil
|
@@ -3403,15 +3752,24 @@ module RubyHDL::High
|
|
3403
3752
|
this = self
|
3404
3753
|
@source = <<-BUILD
|
3405
3754
|
#{RubyHDL::High.global_sblock.each_signal.map do |signal|
|
3406
|
-
|
3407
|
-
|
3755
|
+
# puts "for signal=#{signal.name} with type=#{signal.type}"
|
3756
|
+
case signal.dir
|
3757
|
+
when :input
|
3758
|
+
signal.to_ruby + " = RubyHDL.#{signal.name}"
|
3759
|
+
else
|
3760
|
+
signal.to_ruby + " ||= " +
|
3761
|
+
(signal.array? ? "[]" : signal.value? ? signal.value.inspect : "0")
|
3762
|
+
end
|
3408
3763
|
end.join("\n")}
|
3764
|
+
|
3765
|
+
#{@sfunctions.map {|n,f| f.to_ruby }.join("\n\n")}
|
3766
|
+
|
3409
3767
|
Fiber.new do
|
3410
|
-
#{@
|
3768
|
+
#{@blk.to_ruby}
|
3411
3769
|
end
|
3412
3770
|
BUILD
|
3413
3771
|
# puts "building code_txt=" + @source
|
3414
|
-
|
3772
|
+
self.reset!
|
3415
3773
|
end
|
3416
3774
|
|
3417
3775
|
# Get the Ruby code.
|
@@ -3462,6 +3820,11 @@ BUILDC
|
|
3462
3820
|
end
|
3463
3821
|
alias_method :call, :resume
|
3464
3822
|
|
3823
|
+
# Resets the sequencer.
|
3824
|
+
def reset!
|
3825
|
+
@code = TOPLEVEL_BINDING.eval(@source)
|
3826
|
+
end
|
3827
|
+
|
3465
3828
|
# Check is the sequencer can still be resumed.
|
3466
3829
|
def alive?
|
3467
3830
|
@code.alive?
|
@@ -3476,38 +3839,60 @@ BUILDC
|
|
3476
3839
|
# Create a new sequencer block, with clock counter +clk+ and
|
3477
3840
|
# run control +start+
|
3478
3841
|
def sequencer(clk = nil, start = nil, &ruby_block)
|
3842
|
+
# Ensure the clock is global.
|
3843
|
+
clk.global! if clk
|
3479
3844
|
return SequencerT.new(clk,start,&ruby_block)
|
3480
3845
|
end
|
3481
3846
|
|
3847
|
+
# Create a 1-bit input signal.
|
3848
|
+
def input(*names)
|
3849
|
+
return [1].input(*names)
|
3850
|
+
end
|
3851
|
+
|
3852
|
+
# Create a 1-bit output signal.
|
3853
|
+
def output(*names)
|
3854
|
+
return [1].output(*names)
|
3855
|
+
end
|
3856
|
+
|
3857
|
+
# Create a 1-bit inner signal.
|
3858
|
+
def inner(*names)
|
3859
|
+
return [1].inner(*names)
|
3860
|
+
end
|
3861
|
+
|
3482
3862
|
# Create a new function named +name+, built using block +ruby_block+.
|
3483
3863
|
def sdef(name,&ruby_block)
|
3484
3864
|
name = name.to_sym
|
3485
3865
|
# Get the arguments of the ruby_block.
|
3486
|
-
|
3487
|
-
#
|
3488
|
-
RubyHDL::High.
|
3489
|
-
|
3490
|
-
|
3491
|
-
|
3492
|
-
|
3493
|
-
|
3494
|
-
|
3495
|
-
|
3496
|
-
|
3866
|
+
block_args = ruby_block.parameters.map {|typ,name| name.to_s }
|
3867
|
+
# Create function.
|
3868
|
+
cur_sblock = RubyHDL::High.top_sblock
|
3869
|
+
# Register the call.
|
3870
|
+
cur_sblock.register(name.to_sym) do |*args|
|
3871
|
+
# Create the function.
|
3872
|
+
# Get the current sequencer.
|
3873
|
+
cur_seq = RubyHDL::High.top_sblock.sequencer
|
3874
|
+
# Get the function from the sequencer if any.
|
3875
|
+
function = cur_seq.sfunction(name)
|
3876
|
+
unless function then
|
3877
|
+
# There were no function for the sequencer, create it.
|
3497
3878
|
# Execute the ruby block in a sequencer environment for building
|
3498
3879
|
# the sblock.
|
3499
3880
|
sblock = Sblock.new(cur_seq,&ruby_block)
|
3500
|
-
|
3881
|
+
# Create the arguments.
|
3882
|
+
block_args.each_with_index do |block_arg,i|
|
3883
|
+
# puts "args[#{i}]=(#{args[i].name},#{args[i].type})"
|
3884
|
+
sblock.make_inners(args[i].type,block_arg.to_sym)
|
3885
|
+
end
|
3501
3886
|
# Create the function.
|
3502
|
-
function = SfunctionT.new(name,
|
3503
|
-
# Add it to the sequencer.
|
3504
|
-
cur_seq.add_sfunction(name)
|
3887
|
+
function = SfunctionT.new(name,sblock,*block_args)
|
3888
|
+
# Add it to the current sequencer.
|
3889
|
+
cur_seq.add_sfunction(name,function)
|
3505
3890
|
end
|
3506
|
-
|
3891
|
+
# And create the call
|
3892
|
+
Scall.new(function,cur_seq,*args)
|
3507
3893
|
end
|
3508
3894
|
end
|
3509
3895
|
|
3510
|
-
|
3511
3896
|
end
|
3512
3897
|
|
3513
3898
|
|