HDLRuby 3.7.2 → 3.7.4
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 +27 -0
- 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_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 +23 -0
- data/lib/HDLRuby/hruby_low.rb +25 -0
- data/lib/HDLRuby/hruby_rcsim.rb +8 -0
- data/lib/HDLRuby/std/sequencer.rb +5 -0
- data/lib/HDLRuby/std/sequencer_sw.rb +404 -104
- data/lib/HDLRuby/version.rb +1 -1
- data/lib/rubyHDL.rb +26 -0
- metadata +6 -3
@@ -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,6 +54,42 @@ 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
95
|
# puts "make_inners with names=#{names.join(",")}"
|
@@ -60,7 +98,7 @@ module RubyHDL::High
|
|
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
|
|
@@ -183,12 +221,12 @@ module RubyHDL::High
|
|
183
221
|
:"&" => "(%{l})&(%{r})", :"|" => "(%{l})|(%{r})",
|
184
222
|
:"^" => "(%{l})^(%{r})",
|
185
223
|
:"<<" => "(%{l})<<(%{r})", :">>" => "(%{l})>>(%{r})",
|
186
|
-
:"==" => "(%{l}) & %{m}==(%{r}) & %{m}",
|
187
|
-
:"!=" => "(%{l}) & %{m}!=(%{r}) %{m}",
|
188
|
-
:"<" => "(%{l}) & %{m}%{s} < (%{r}) & %{m}%{s}",
|
189
|
-
:">" => "(%{l}) & %{m}%{s} > (%{r}) & %{m}%{s}",
|
190
|
-
:"<=" => "(%{l}) & %{m}%{s} <=(%{r}) & %{m}%{s}",
|
191
|
-
:">=" => "(%{l}) & %{m}%{s} >=(%{r}) & %{m}%{s}"
|
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"
|
192
230
|
}
|
193
231
|
|
194
232
|
# The translation of operators into C code.
|
@@ -618,7 +656,23 @@ module RubyHDL::High
|
|
618
656
|
return TypeVector.new(:"",base,self[0])
|
619
657
|
end
|
620
658
|
|
621
|
-
# 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+.
|
622
676
|
def inner(*names)
|
623
677
|
# Generate the type.
|
624
678
|
type = self.to_type
|
@@ -639,6 +693,8 @@ module RubyHDL::High
|
|
639
693
|
using RubyHDL::High
|
640
694
|
include HDLRuby::Tprocess
|
641
695
|
|
696
|
+
attr_reader :name
|
697
|
+
|
642
698
|
# Type creation.
|
643
699
|
|
644
700
|
# Creates a new type named +name+.
|
@@ -707,13 +763,13 @@ module RubyHDL::High
|
|
707
763
|
# Gets the type max value if any.
|
708
764
|
# Default: not defined.
|
709
765
|
def max
|
710
|
-
raise
|
766
|
+
raise "No max value for type #{self} (#{self.name})"
|
711
767
|
end
|
712
768
|
|
713
769
|
# Gets the type min value if any.
|
714
770
|
# Default: not defined.
|
715
771
|
def min
|
716
|
-
raise
|
772
|
+
raise "No min value for type #{self} (#{self.name})"
|
717
773
|
end
|
718
774
|
|
719
775
|
# Get the direction of the type, little or big endian.
|
@@ -729,7 +785,7 @@ module RubyHDL::High
|
|
729
785
|
|
730
786
|
# Gets the range of the type, by default range is not defined.
|
731
787
|
def range
|
732
|
-
raise
|
788
|
+
raise "No range for type #{self} (#{self.name})"
|
733
789
|
end
|
734
790
|
|
735
791
|
# Tells if the type has a base.
|
@@ -739,7 +795,7 @@ module RubyHDL::High
|
|
739
795
|
|
740
796
|
# Gets the base type, by default base type is not defined.
|
741
797
|
def base
|
742
|
-
raise
|
798
|
+
raise "No base type for type #{self} (#{self.name})"
|
743
799
|
end
|
744
800
|
|
745
801
|
# Tells if the type has sub types.
|
@@ -802,12 +858,12 @@ module RubyHDL::High
|
|
802
858
|
# NOTE: can only be done if the name is not already set.
|
803
859
|
def name=(name)
|
804
860
|
unless @name.empty? then
|
805
|
-
raise
|
861
|
+
raise "Name of type already set to: #{@name}."
|
806
862
|
end
|
807
863
|
# Checks and sets the name.
|
808
864
|
name = name.to_sym
|
809
865
|
if name.empty? then
|
810
|
-
raise
|
866
|
+
raise "Cannot set an empty name."
|
811
867
|
end
|
812
868
|
@name = name
|
813
869
|
# Registers the name.
|
@@ -857,17 +913,17 @@ module RubyHDL::High
|
|
857
913
|
|
858
914
|
# SignalI creation through the type.
|
859
915
|
|
860
|
-
#
|
861
|
-
|
862
|
-
|
863
|
-
|
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
|
864
920
|
|
865
|
-
#
|
866
|
-
#
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
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
|
871
927
|
|
872
928
|
# # Declares high-level untyped inout signals named +names+ of the
|
873
929
|
# # current type.
|
@@ -1076,7 +1132,7 @@ module RubyHDL::High
|
|
1076
1132
|
# Ensures a type has been produced.
|
1077
1133
|
gtype = gtype.to_type if gtype.respond_to?(:to_type)
|
1078
1134
|
unless gtype.is_a?(Type) then
|
1079
|
-
raise
|
1135
|
+
raise "Generic type #{self.name} did not produce a valid type: #{gtype.class}"
|
1080
1136
|
end
|
1081
1137
|
# Create a new type definition from it.
|
1082
1138
|
gtype = TypeDef.new(self.name.to_s + "_#{args.join(':')}",
|
@@ -1121,8 +1177,7 @@ module RubyHDL::High
|
|
1121
1177
|
|
1122
1178
|
# Check and set the base
|
1123
1179
|
unless base.is_a?(Type)
|
1124
|
-
raise
|
1125
|
-
"Invalid class for VectorType base: #{base.class}."
|
1180
|
+
raise "Invalid class for VectorType base: #{base.class}."
|
1126
1181
|
end
|
1127
1182
|
@base = base
|
1128
1183
|
|
@@ -1335,13 +1390,13 @@ module RubyHDL::High
|
|
1335
1390
|
# Set the direction.
|
1336
1391
|
@direction = direction.to_sym
|
1337
1392
|
unless [:little, :big].include?(@direction)
|
1338
|
-
raise
|
1393
|
+
raise "Invalid direction for a type: #{direction}"
|
1339
1394
|
end
|
1340
1395
|
|
1341
1396
|
# Check and set the content.
|
1342
1397
|
content.each do |sub|
|
1343
1398
|
unless sub.is_a?(Type) then
|
1344
|
-
raise
|
1399
|
+
raise "Invalid class for a type: #{sub.class}"
|
1345
1400
|
end
|
1346
1401
|
end
|
1347
1402
|
@types = content
|
@@ -1385,8 +1440,7 @@ module RubyHDL::High
|
|
1385
1440
|
# Adds a sub +type+.
|
1386
1441
|
def add_type(type)
|
1387
1442
|
unless type.is_a?(Type) then
|
1388
|
-
raise
|
1389
|
-
"Invalid class for a type: #{type.class} (#{type})"
|
1443
|
+
raise "Invalid class for a type: #{type.class} (#{type})"
|
1390
1444
|
end
|
1391
1445
|
@types << type
|
1392
1446
|
end
|
@@ -1454,7 +1508,7 @@ module RubyHDL::High
|
|
1454
1508
|
# Regular tuple, return its range as if it was an array.
|
1455
1509
|
return 0..@types.size-1
|
1456
1510
|
else
|
1457
|
-
raise
|
1511
|
+
raise "No range for type #{self}"
|
1458
1512
|
end
|
1459
1513
|
end
|
1460
1514
|
|
@@ -1475,7 +1529,7 @@ module RubyHDL::High
|
|
1475
1529
|
# Regular tuple, return the type of its first element.
|
1476
1530
|
return @types[0]
|
1477
1531
|
else
|
1478
|
-
raise
|
1532
|
+
raise "No base type for type #{self}"
|
1479
1533
|
end
|
1480
1534
|
end
|
1481
1535
|
|
@@ -1503,14 +1557,14 @@ module RubyHDL::High
|
|
1503
1557
|
# Set the direction.
|
1504
1558
|
@direction = dir.to_sym
|
1505
1559
|
unless [:little, :big].include?(@direction)
|
1506
|
-
raise
|
1560
|
+
raise "Invalid direction for a type: #{dir}"
|
1507
1561
|
end
|
1508
1562
|
|
1509
1563
|
# Check and set the content.
|
1510
1564
|
content = Hash[content]
|
1511
1565
|
@types = content.map do |k,v|
|
1512
1566
|
unless v.is_a?(Type) then
|
1513
|
-
raise
|
1567
|
+
raise "Invalid class for a type: #{v.class}"
|
1514
1568
|
end
|
1515
1569
|
[ k.to_sym, v ]
|
1516
1570
|
end.to_h
|
@@ -1889,6 +1943,7 @@ module RubyHDL::High
|
|
1889
1943
|
@right = right.to_expr
|
1890
1944
|
# Compute the mask for fixing the bit width.
|
1891
1945
|
@mask = (2 ** @type.width)-1
|
1946
|
+
# puts "@type=#{@type} name=#{@type.name} @type.width=#{@type.width} @mask=#{@mask}"
|
1892
1947
|
# Compute xor mask for handling the sign.
|
1893
1948
|
# Make it as a string so that no addition computation is required
|
1894
1949
|
# if no sign is required.
|
@@ -1923,7 +1978,7 @@ module RubyHDL::High
|
|
1923
1978
|
|
1924
1979
|
# Convert to Ruby code.
|
1925
1980
|
def to_ruby
|
1926
|
-
return "case(#{@sel.
|
1981
|
+
return "case(#{@sel.to_ruby}) ; " +
|
1927
1982
|
@choices.map.with_index do |choice,i|
|
1928
1983
|
"when #{i} ; #{choice.to_ruby} ; "
|
1929
1984
|
end.join + "end"
|
@@ -2115,10 +2170,27 @@ module RubyHDL::High
|
|
2115
2170
|
end
|
2116
2171
|
end
|
2117
2172
|
|
2118
|
-
|
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
|
+
|
2119
2191
|
|
2120
2192
|
# Describes a SW implementation of a transmit statement.
|
2121
|
-
class Transmit
|
2193
|
+
class Transmit < Statement
|
2122
2194
|
using RubyHDL::High
|
2123
2195
|
|
2124
2196
|
attr_reader :left, :right
|
@@ -2185,12 +2257,11 @@ module RubyHDL::High
|
|
2185
2257
|
else
|
2186
2258
|
return "#{@left.to_c} = #{@right.to_c};"
|
2187
2259
|
end
|
2188
|
-
end
|
2189
|
-
|
2260
|
+
end
|
2190
2261
|
end
|
2191
2262
|
|
2192
2263
|
# Describes a SW implementation of a if statement.
|
2193
|
-
class Sif
|
2264
|
+
class Sif < Statement
|
2194
2265
|
# Create a new if statement in sequencer +sequencer+
|
2195
2266
|
# with +cond+ condition and +ruby_block+
|
2196
2267
|
# for generating the block that is taken if the condition is met.
|
@@ -2212,9 +2283,33 @@ module RubyHDL::High
|
|
2212
2283
|
@else_blk = Sblock.new(@sequencer,&ruby_block)
|
2213
2284
|
end
|
2214
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
|
+
|
2215
2310
|
# Convert to Ruby code.
|
2216
2311
|
def to_ruby
|
2217
|
-
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"
|
2218
2313
|
@elsifs.each do |(cond,blk)|
|
2219
2314
|
res << "elsif(#{cond.to_ruby})\n#{blk.to_ruby}\n"
|
2220
2315
|
end
|
@@ -2238,7 +2333,7 @@ module RubyHDL::High
|
|
2238
2333
|
end
|
2239
2334
|
|
2240
2335
|
# Describes a SW implementation of a loop statement.
|
2241
|
-
class Sloop
|
2336
|
+
class Sloop < Statement
|
2242
2337
|
# Create a new infinite loop statement in sequencer +sequencer+
|
2243
2338
|
# with +ruby_block+ for generating the block that is taken.
|
2244
2339
|
def initialize(sequencer, &ruby_block)
|
@@ -2246,6 +2341,22 @@ module RubyHDL::High
|
|
2246
2341
|
@blk = Sblock.new(sequencer,&ruby_block)
|
2247
2342
|
end
|
2248
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
|
+
|
2249
2360
|
# Convert to Ruby code.
|
2250
2361
|
def to_ruby
|
2251
2362
|
return "loop do\n#{@blk.to_ruby}\n#{@sequencer.clk_up}\nend"
|
@@ -2258,7 +2369,7 @@ module RubyHDL::High
|
|
2258
2369
|
end
|
2259
2370
|
|
2260
2371
|
# Describes a SW implementation of a while statement.
|
2261
|
-
class Swhile
|
2372
|
+
class Swhile < Statement
|
2262
2373
|
# Create a new while statement in sequencer +sequencer+
|
2263
2374
|
# with +cond+ condition and +ruby_block+
|
2264
2375
|
# for generating the block that is taken while the condition is met.
|
@@ -2268,6 +2379,22 @@ module RubyHDL::High
|
|
2268
2379
|
@yes_blk = Sblock.new(sequencer,&ruby_block)
|
2269
2380
|
end
|
2270
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
|
+
|
2271
2398
|
# Convert to Ruby code.
|
2272
2399
|
def to_ruby
|
2273
2400
|
return @sequencer.clk_up +
|
@@ -2281,7 +2408,7 @@ module RubyHDL::High
|
|
2281
2408
|
end
|
2282
2409
|
|
2283
2410
|
# Describes a SW implementation of a step statement.
|
2284
|
-
class Step
|
2411
|
+
class Step < Statement
|
2285
2412
|
# Create a new step statement in sequencer +sequencer+.
|
2286
2413
|
def initialize(sequencer)
|
2287
2414
|
@sequencer = sequencer
|
@@ -2299,7 +2426,7 @@ module RubyHDL::High
|
|
2299
2426
|
end
|
2300
2427
|
|
2301
2428
|
# Describes a SW implementation of a break statement.
|
2302
|
-
class Sbreak
|
2429
|
+
class Sbreak < Statement
|
2303
2430
|
# Create a new break statement in sequencer +sequencer+.
|
2304
2431
|
def initialize(sequencer)
|
2305
2432
|
@sequencer = sequencer
|
@@ -2317,7 +2444,7 @@ module RubyHDL::High
|
|
2317
2444
|
end
|
2318
2445
|
|
2319
2446
|
# Describes a SW implementation of a continue statement.
|
2320
|
-
class Scontinue
|
2447
|
+
class Scontinue < Statement
|
2321
2448
|
# Create a new break statement in sequencer +sequencer+.
|
2322
2449
|
def initialize
|
2323
2450
|
@sequencer = sequencer
|
@@ -2334,10 +2461,32 @@ module RubyHDL::High
|
|
2334
2461
|
end
|
2335
2462
|
end
|
2336
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
|
+
|
2337
2486
|
# Describes a SW implementation of a terminate statement.
|
2338
|
-
class Sterminate
|
2487
|
+
class Sterminate < Statement
|
2339
2488
|
# Create a new break statement in sequencer +sequencer+.
|
2340
|
-
def initialize
|
2489
|
+
def initialize(sequencer)
|
2341
2490
|
@sequencer = sequencer
|
2342
2491
|
end
|
2343
2492
|
|
@@ -2355,13 +2504,25 @@ module RubyHDL::High
|
|
2355
2504
|
end
|
2356
2505
|
|
2357
2506
|
# Describes a SW synchronization of a signal.
|
2358
|
-
class Sync
|
2359
|
-
def initialize
|
2507
|
+
class Sync < Statement
|
2508
|
+
def initialize(sequencer)
|
2509
|
+
@sequencer = sequencer
|
2360
2510
|
end
|
2361
2511
|
|
2362
2512
|
# Convert to Ruby code.
|
2363
2513
|
def to_ruby
|
2364
|
-
|
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
|
2365
2526
|
end
|
2366
2527
|
|
2367
2528
|
# Convert to C code.
|
@@ -2397,6 +2558,19 @@ module RubyHDL::High
|
|
2397
2558
|
return self
|
2398
2559
|
end
|
2399
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
|
+
|
2400
2574
|
# Execute a ruby code block for +ruby_block+.
|
2401
2575
|
def self.call(id)
|
2402
2576
|
# puts "id=#{id}"
|
@@ -2421,27 +2595,39 @@ module RubyHDL::High
|
|
2421
2595
|
|
2422
2596
|
|
2423
2597
|
# Describes a SW implementation of an call statement.
|
2424
|
-
class Scall
|
2598
|
+
class Scall < Expression
|
2425
2599
|
using RubyHDL::High
|
2426
2600
|
|
2427
|
-
# Create a new call
|
2428
|
-
#
|
2429
|
-
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)
|
2430
2605
|
@sequencer = sequencer
|
2431
|
-
@name = name
|
2606
|
+
@name = func.name
|
2432
2607
|
@args = args
|
2433
2608
|
end
|
2434
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
|
+
|
2435
2623
|
# Convert to Ruby code.
|
2436
2624
|
def to_ruby
|
2437
|
-
return @
|
2438
|
-
@args.map {|arg| arg.to_ruby}.join(",") + ")"
|
2625
|
+
return "__#{@name}(" + @args.map {|arg| arg.to_ruby}.join(",") + ")"
|
2439
2626
|
end
|
2440
2627
|
|
2441
2628
|
# Convert to C code.
|
2442
2629
|
def to_c
|
2443
|
-
return
|
2444
|
-
@args.map {|arg| arg.to_ruby}.join(",") + ");"
|
2630
|
+
return "\n__#{name}(" + @args.map {|arg| arg.to_ruby}.join(",") + ");"
|
2445
2631
|
end
|
2446
2632
|
|
2447
2633
|
# Create an iterator for a given method +meth+.
|
@@ -2778,7 +2964,7 @@ module RubyHDL::High
|
|
2778
2964
|
|
2779
2965
|
|
2780
2966
|
# Describes a SW implementation of an iterator statement.
|
2781
|
-
class Siter
|
2967
|
+
class Siter < Statement
|
2782
2968
|
using RubyHDL::High
|
2783
2969
|
|
2784
2970
|
# Create a new iteration statement in sequencer +sequencer+
|
@@ -2801,12 +2987,31 @@ module RubyHDL::High
|
|
2801
2987
|
end
|
2802
2988
|
alias_method :each, :each_command
|
2803
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
|
+
|
2804
3006
|
# Convert to Ruby code.
|
2805
3007
|
def to_ruby
|
2806
3008
|
# puts "to_ruby with blk=#{@blk} commands=#{@commands}"
|
2807
3009
|
res = @sequencer.clk_up + "\n" +
|
2808
3010
|
@commands.map { |command| command.to_ruby }.join(".")
|
2809
|
-
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"
|
2810
3015
|
end
|
2811
3016
|
|
2812
3017
|
# Convert to C code.
|
@@ -3158,14 +3363,26 @@ module RubyHDL::High
|
|
3158
3363
|
# Describes a SW implementation of a signal.
|
3159
3364
|
class SignalI < Expression
|
3160
3365
|
using RubyHDL::High
|
3161
|
-
attr_reader :
|
3366
|
+
attr_reader :name, :type, :dir
|
3162
3367
|
# Create a new signal with type +type+ and name +name+.
|
3163
|
-
def initialize(type,
|
3164
|
-
@type = type.to_type
|
3368
|
+
def initialize(name,type,dir)
|
3165
3369
|
@name = name.to_sym
|
3370
|
+
@type = type.to_type
|
3371
|
+
@dir = dir.to_sym
|
3166
3372
|
# Compute the mask for adjusting the value to the type.
|
3167
3373
|
@mask = (2 ** @type.width)-1
|
3168
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 = "$"
|
3169
3386
|
end
|
3170
3387
|
|
3171
3388
|
# Tell if the signal is an array.
|
@@ -3175,7 +3392,7 @@ module RubyHDL::High
|
|
3175
3392
|
|
3176
3393
|
# Convert to Ruby code.
|
3177
3394
|
def to_ruby
|
3178
|
-
return "__" + self.name.to_s
|
3395
|
+
return @global + "__" + self.name.to_s
|
3179
3396
|
end
|
3180
3397
|
|
3181
3398
|
# Convert to C code.
|
@@ -3183,7 +3400,11 @@ module RubyHDL::High
|
|
3183
3400
|
|
3184
3401
|
# Check if a value is defined for the signal.
|
3185
3402
|
def value?
|
3186
|
-
|
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
|
3187
3408
|
end
|
3188
3409
|
|
3189
3410
|
# Gets the value of the signal.
|
@@ -3236,7 +3457,6 @@ module RubyHDL::High
|
|
3236
3457
|
end
|
3237
3458
|
end
|
3238
3459
|
|
3239
|
-
|
3240
3460
|
# Describes a SW implementation of a block.
|
3241
3461
|
class Sblock < SblockTop
|
3242
3462
|
using RubyHDL::High
|
@@ -3254,9 +3474,11 @@ module RubyHDL::High
|
|
3254
3474
|
# Push the new sblock on top of the stack.
|
3255
3475
|
RubyHDL::High.push_sblock(self)
|
3256
3476
|
# Make signals from the arguments of the ruby block.
|
3477
|
+
# unsigned 32-bit integers by default.
|
3257
3478
|
@args = []
|
3258
3479
|
ruby_block.parameters.each do |typ,arg|
|
3259
|
-
@args << SignalI.new(Void
|
3480
|
+
# @args << SignalI.new(arg,Void,:inner)
|
3481
|
+
@args << SignalI.new(arg,bit[32],:inner)
|
3260
3482
|
end
|
3261
3483
|
# Fill it.
|
3262
3484
|
self.instance_exec(*@args,&ruby_block)
|
@@ -3277,6 +3499,21 @@ module RubyHDL::High
|
|
3277
3499
|
end
|
3278
3500
|
alias_method :<<, :add
|
3279
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
|
+
|
3280
3517
|
# Delete a statement.
|
3281
3518
|
def delete(statement)
|
3282
3519
|
@statements.delete(statement)
|
@@ -3292,14 +3529,20 @@ module RubyHDL::High
|
|
3292
3529
|
return @statements[-1]
|
3293
3530
|
end
|
3294
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
|
3295
3537
|
|
3296
3538
|
# Convert to Ruby code.
|
3297
3539
|
def to_ruby
|
3298
3540
|
res = ""
|
3299
|
-
#
|
3300
|
-
if
|
3301
|
-
|
3302
|
-
|
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
|
3303
3546
|
# Generate the statements.
|
3304
3547
|
res += @statements.map do |stmnt|
|
3305
3548
|
stmnt.to_ruby + "\n"
|
@@ -3343,6 +3586,11 @@ module RubyHDL::High
|
|
3343
3586
|
self << RubyHDL::High::Scontinue.new(@sequencer)
|
3344
3587
|
end
|
3345
3588
|
|
3589
|
+
# Create a return statement.
|
3590
|
+
def sreturn(val)
|
3591
|
+
self << RubyHDL::High::Sreturn.new(@sequencer,val)
|
3592
|
+
end
|
3593
|
+
|
3346
3594
|
# Terminates the sequencer.
|
3347
3595
|
def sterminate
|
3348
3596
|
self << RubyHDL::High::Sterminate.new(@sequencer)
|
@@ -3390,13 +3638,26 @@ module RubyHDL::High
|
|
3390
3638
|
self << expr.seach.with_index(&ruby_block)
|
3391
3639
|
end
|
3392
3640
|
|
3641
|
+
# Implements a multiplexer.
|
3642
|
+
def mux(cond, *choices)
|
3643
|
+
return Select.new(choices[0].type,:mux,cond,*choices)
|
3644
|
+
end
|
3645
|
+
|
3646
|
+
# Displays a string for debugging purpose.
|
3647
|
+
def hprint(*args)
|
3648
|
+
args.each do |arg|
|
3649
|
+
arg = arg.to_value if arg.is_a?(RubyHDL::High::Expression)
|
3650
|
+
print arg
|
3651
|
+
end
|
3652
|
+
end
|
3653
|
+
|
3393
3654
|
# The SW-specific statements and expressions.
|
3394
3655
|
|
3395
3656
|
# Mark a synchronisation.
|
3396
3657
|
# For software only: stop the current sequencer for allowing
|
3397
3658
|
# sharing of variables with other ones.
|
3398
3659
|
def sync
|
3399
|
-
self << RubyHDL::High::Sync.new
|
3660
|
+
self << RubyHDL::High::Sync.new(@sequencer)
|
3400
3661
|
end
|
3401
3662
|
|
3402
3663
|
# Some arbirary Ruby code as a string +str+ or as a proc
|
@@ -3415,23 +3676,36 @@ module RubyHDL::High
|
|
3415
3676
|
# Describes a SW implementation of a sequencer function.
|
3416
3677
|
class SfunctionT
|
3417
3678
|
using RubyHDL::High
|
3418
|
-
attr_reader :name
|
3679
|
+
attr_reader :name, :type
|
3419
3680
|
# Create a new named +name+ with arguments +args+ and
|
3420
3681
|
# executing the content of block +sblock+
|
3421
|
-
def initialize(
|
3682
|
+
def initialize(name,sblock,*args)
|
3422
3683
|
@name = name.to_sym
|
3423
3684
|
@args = args
|
3424
3685
|
@blk = sblock
|
3686
|
+
@type = self.make_return_type(@blk)
|
3687
|
+
end
|
3688
|
+
|
3689
|
+
# Compute the return type from current sblock +sblock+
|
3690
|
+
def make_return_type(sblock)
|
3691
|
+
# Locate a return statement.
|
3692
|
+
sblock.each_statement_deep do |statement|
|
3693
|
+
if statement.is_a?(RubyHDL::High::Sreturn) then
|
3694
|
+
return statement.value.type
|
3695
|
+
end
|
3696
|
+
end
|
3697
|
+
# No return, so void type.
|
3698
|
+
return RubyHDL::High::Void
|
3425
3699
|
end
|
3426
3700
|
|
3427
3701
|
# Convert to Ruby code.
|
3428
3702
|
def to_ruby
|
3429
|
-
return "def #{name}(#{@args.map {|arg| arg.to_ruby}.join(",")}\n#{@blk.to_ruby}\nend\n"
|
3703
|
+
return "def __#{name}(#{@args.map {|arg| "__" + arg.to_ruby}.join(",")})\n#{@blk.sequencer.clk_up}\n#{@blk.to_ruby}\nend\n"
|
3430
3704
|
end
|
3431
3705
|
|
3432
3706
|
# Convert to C code.
|
3433
3707
|
def to_c
|
3434
|
-
return "unsigned long long #{name}(#{@args.map {|arg| "unsigned long long " + arg.to_c}.join(",")} {\n#{@blk.to_c}\n}\n"
|
3708
|
+
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"
|
3435
3709
|
end
|
3436
3710
|
end
|
3437
3711
|
|
@@ -3464,7 +3738,7 @@ module RubyHDL::High
|
|
3464
3738
|
# Create a set of sfunction used in the sequencer.
|
3465
3739
|
@sfunctions = {}
|
3466
3740
|
# Create the main block.
|
3467
|
-
@
|
3741
|
+
@blk = RubyHDL::High::Sblock.new(self,&ruby_block)
|
3468
3742
|
# Build the Ruby code.
|
3469
3743
|
@source = ""
|
3470
3744
|
@code = nil
|
@@ -3491,11 +3765,20 @@ module RubyHDL::High
|
|
3491
3765
|
this = self
|
3492
3766
|
@source = <<-BUILD
|
3493
3767
|
#{RubyHDL::High.global_sblock.each_signal.map do |signal|
|
3494
|
-
|
3495
|
-
|
3768
|
+
# puts "for signal=#{signal.name} with type=#{signal.type}"
|
3769
|
+
case signal.dir
|
3770
|
+
when :input
|
3771
|
+
signal.to_ruby + " = RubyHDL.#{signal.name}"
|
3772
|
+
else
|
3773
|
+
signal.to_ruby + " ||= " +
|
3774
|
+
(signal.array? ? "[]" : signal.value? ? signal.value.inspect : "0")
|
3775
|
+
end
|
3496
3776
|
end.join("\n")}
|
3777
|
+
|
3778
|
+
#{@sfunctions.map {|n,f| f.to_ruby }.join("\n\n")}
|
3779
|
+
|
3497
3780
|
Fiber.new do
|
3498
|
-
#{@
|
3781
|
+
#{@blk.to_ruby}
|
3499
3782
|
end
|
3500
3783
|
BUILD
|
3501
3784
|
# puts "building code_txt=" + @source
|
@@ -3569,10 +3852,22 @@ BUILDC
|
|
3569
3852
|
# Create a new sequencer block, with clock counter +clk+ and
|
3570
3853
|
# run control +start+
|
3571
3854
|
def sequencer(clk = nil, start = nil, &ruby_block)
|
3855
|
+
# Ensure the clock is global.
|
3856
|
+
clk.global! if clk
|
3572
3857
|
return SequencerT.new(clk,start,&ruby_block)
|
3573
3858
|
end
|
3574
3859
|
|
3575
|
-
# Create a 1-bit signal.
|
3860
|
+
# Create a 1-bit input signal.
|
3861
|
+
def input(*names)
|
3862
|
+
return [1].input(*names)
|
3863
|
+
end
|
3864
|
+
|
3865
|
+
# Create a 1-bit output signal.
|
3866
|
+
def output(*names)
|
3867
|
+
return [1].output(*names)
|
3868
|
+
end
|
3869
|
+
|
3870
|
+
# Create a 1-bit inner signal.
|
3576
3871
|
def inner(*names)
|
3577
3872
|
return [1].inner(*names)
|
3578
3873
|
end
|
@@ -3581,31 +3876,36 @@ BUILDC
|
|
3581
3876
|
def sdef(name,&ruby_block)
|
3582
3877
|
name = name.to_sym
|
3583
3878
|
# Get the arguments of the ruby_block.
|
3584
|
-
|
3585
|
-
#
|
3586
|
-
RubyHDL::High.
|
3587
|
-
|
3588
|
-
|
3589
|
-
|
3590
|
-
|
3591
|
-
|
3592
|
-
|
3593
|
-
|
3594
|
-
|
3879
|
+
block_args = ruby_block.parameters.map {|typ,name| name.to_s }
|
3880
|
+
# Create function.
|
3881
|
+
cur_sblock = RubyHDL::High.top_sblock
|
3882
|
+
# Register the call.
|
3883
|
+
cur_sblock.register(name.to_sym) do |*args|
|
3884
|
+
# Create the function.
|
3885
|
+
# Get the current sequencer.
|
3886
|
+
cur_seq = RubyHDL::High.top_sblock.sequencer
|
3887
|
+
# Get the function from the sequencer if any.
|
3888
|
+
function = cur_seq.sfunction(name)
|
3889
|
+
unless function then
|
3890
|
+
# There were no function for the sequencer, create it.
|
3595
3891
|
# Execute the ruby block in a sequencer environment for building
|
3596
3892
|
# the sblock.
|
3597
3893
|
sblock = Sblock.new(cur_seq,&ruby_block)
|
3598
|
-
|
3894
|
+
# Create the arguments.
|
3895
|
+
block_args.each_with_index do |block_arg,i|
|
3896
|
+
# puts "args[#{i}]=(#{args[i].name},#{args[i].type})"
|
3897
|
+
sblock.make_inners(args[i].type,block_arg.to_sym)
|
3898
|
+
end
|
3599
3899
|
# Create the function.
|
3600
|
-
function = SfunctionT.new(name,
|
3601
|
-
# Add it to the sequencer.
|
3602
|
-
cur_seq.add_sfunction(name)
|
3900
|
+
function = SfunctionT.new(name,sblock,*block_args)
|
3901
|
+
# Add it to the current sequencer.
|
3902
|
+
cur_seq.add_sfunction(name,function)
|
3603
3903
|
end
|
3604
|
-
|
3904
|
+
# And create the call
|
3905
|
+
Scall.new(function,cur_seq,*args)
|
3605
3906
|
end
|
3606
3907
|
end
|
3607
3908
|
|
3608
|
-
|
3609
3909
|
end
|
3610
3910
|
|
3611
3911
|
|