HDLRuby 2.0.8
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 +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +5 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/HDLRuby.gemspec +36 -0
- data/LICENSE.txt +21 -0
- data/README.md +2774 -0
- data/README.pdf +0 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/hdrcc +3 -0
- data/lib/HDLRuby/alcc.rb +137 -0
- data/lib/HDLRuby/backend/hruby_allocator.rb +69 -0
- data/lib/HDLRuby/backend/hruby_c_allocator.rb +76 -0
- data/lib/HDLRuby/hdr_samples/adder.rb +7 -0
- data/lib/HDLRuby/hdr_samples/adder_assign_error.rb +11 -0
- data/lib/HDLRuby/hdr_samples/adder_bench.rb +27 -0
- data/lib/HDLRuby/hdr_samples/adder_gen.rb +7 -0
- data/lib/HDLRuby/hdr_samples/adder_nodef_error.rb +7 -0
- data/lib/HDLRuby/hdr_samples/addsub.rb +19 -0
- data/lib/HDLRuby/hdr_samples/addsubz.rb +22 -0
- data/lib/HDLRuby/hdr_samples/alu.rb +47 -0
- data/lib/HDLRuby/hdr_samples/calculator.rb +48 -0
- data/lib/HDLRuby/hdr_samples/counter_bench.rb +83 -0
- data/lib/HDLRuby/hdr_samples/dff.rb +9 -0
- data/lib/HDLRuby/hdr_samples/dff_bench.rb +66 -0
- data/lib/HDLRuby/hdr_samples/dff_counter.rb +20 -0
- data/lib/HDLRuby/hdr_samples/include.rb +14 -0
- data/lib/HDLRuby/hdr_samples/instance_open.rb +23 -0
- data/lib/HDLRuby/hdr_samples/mei8.rb +256 -0
- data/lib/HDLRuby/hdr_samples/mei8_bench.rb +309 -0
- data/lib/HDLRuby/hdr_samples/multer_gen.rb +8 -0
- data/lib/HDLRuby/hdr_samples/multer_seq.rb +29 -0
- data/lib/HDLRuby/hdr_samples/neural/a.rb +9 -0
- data/lib/HDLRuby/hdr_samples/neural/a_sub.rb +5 -0
- data/lib/HDLRuby/hdr_samples/neural/bw.rb +23 -0
- data/lib/HDLRuby/hdr_samples/neural/counter.rb +16 -0
- data/lib/HDLRuby/hdr_samples/neural/dadz.rb +9 -0
- data/lib/HDLRuby/hdr_samples/neural/dadz_sub.rb +4 -0
- data/lib/HDLRuby/hdr_samples/neural/forward.rb +153 -0
- data/lib/HDLRuby/hdr_samples/neural/forward_sub.rb +62 -0
- data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand.rb +41 -0
- data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand_typedef.rb +47 -0
- data/lib/HDLRuby/hdr_samples/neural/mem.rb +30 -0
- data/lib/HDLRuby/hdr_samples/neural/random.rb +23 -0
- data/lib/HDLRuby/hdr_samples/neural/selector.rb +29 -0
- data/lib/HDLRuby/hdr_samples/neural/sigmoid.rb +20 -0
- data/lib/HDLRuby/hdr_samples/neural/z.rb +33 -0
- data/lib/HDLRuby/hdr_samples/prog.obj +256 -0
- data/lib/HDLRuby/hdr_samples/ram.rb +18 -0
- data/lib/HDLRuby/hdr_samples/register_with_code_bench.rb +98 -0
- data/lib/HDLRuby/hdr_samples/rom.rb +10 -0
- data/lib/HDLRuby/hdr_samples/struct.rb +14 -0
- data/lib/HDLRuby/hdr_samples/sumprod.rb +29 -0
- data/lib/HDLRuby/hdr_samples/sw_encrypt_bench.rb +103 -0
- data/lib/HDLRuby/hdr_samples/sw_encrypt_cpu_bench.rb +261 -0
- data/lib/HDLRuby/hdr_samples/sw_encrypt_cpusim_bench.rb +302 -0
- data/lib/HDLRuby/hdr_samples/system_open.rb +11 -0
- data/lib/HDLRuby/hdr_samples/tuple.rb +16 -0
- data/lib/HDLRuby/hdr_samples/with_channel.rb +118 -0
- data/lib/HDLRuby/hdr_samples/with_class.rb +199 -0
- data/lib/HDLRuby/hdr_samples/with_decoder.rb +17 -0
- data/lib/HDLRuby/hdr_samples/with_fsm.rb +34 -0
- data/lib/HDLRuby/hdr_samples/with_reconf.rb +103 -0
- data/lib/HDLRuby/hdrcc.rb +623 -0
- data/lib/HDLRuby/high_samples/_adder_fault.rb +23 -0
- data/lib/HDLRuby/high_samples/_generic_transmission2.rb +146 -0
- data/lib/HDLRuby/high_samples/adder.rb +21 -0
- data/lib/HDLRuby/high_samples/adder_common_errors.rb +25 -0
- data/lib/HDLRuby/high_samples/addsub.rb +33 -0
- data/lib/HDLRuby/high_samples/addsubz.rb +37 -0
- data/lib/HDLRuby/high_samples/after.rb +28 -0
- data/lib/HDLRuby/high_samples/all_signals.rb +29 -0
- data/lib/HDLRuby/high_samples/alu.rb +61 -0
- data/lib/HDLRuby/high_samples/anonymous.rb +41 -0
- data/lib/HDLRuby/high_samples/before.rb +28 -0
- data/lib/HDLRuby/high_samples/blockblock.rb +26 -0
- data/lib/HDLRuby/high_samples/bugs/dadz.rb +22 -0
- data/lib/HDLRuby/high_samples/bugs/misample_instan.rb +20 -0
- data/lib/HDLRuby/high_samples/bugs/misample_updown.rb +22 -0
- data/lib/HDLRuby/high_samples/bugs/sample_add.rb +16 -0
- data/lib/HDLRuby/high_samples/bugs/sample_barrel.rb +13 -0
- data/lib/HDLRuby/high_samples/bugs/sample_daice.rb +57 -0
- data/lib/HDLRuby/high_samples/bugs/sample_kumiawase.rb +52 -0
- data/lib/HDLRuby/high_samples/bugs/sample_multi.rb +18 -0
- data/lib/HDLRuby/high_samples/bugs/sample_sub.rb +14 -0
- data/lib/HDLRuby/high_samples/bugs/z2.rb +32 -0
- data/lib/HDLRuby/high_samples/case.rb +32 -0
- data/lib/HDLRuby/high_samples/case2.rb +30 -0
- data/lib/HDLRuby/high_samples/change.rb +23 -0
- data/lib/HDLRuby/high_samples/clocks.rb +35 -0
- data/lib/HDLRuby/high_samples/comparer.rb +21 -0
- data/lib/HDLRuby/high_samples/conditionals.rb +29 -0
- data/lib/HDLRuby/high_samples/dff.rb +23 -0
- data/lib/HDLRuby/high_samples/each.rb +28 -0
- data/lib/HDLRuby/high_samples/exporter.rb +42 -0
- data/lib/HDLRuby/high_samples/functions.rb +60 -0
- data/lib/HDLRuby/high_samples/if_seq.rb +26 -0
- data/lib/HDLRuby/high_samples/inherit_as_dff.rb +32 -0
- data/lib/HDLRuby/high_samples/inherit_dff.rb +36 -0
- data/lib/HDLRuby/high_samples/instance.rb +37 -0
- data/lib/HDLRuby/high_samples/memory.rb +64 -0
- data/lib/HDLRuby/high_samples/multi_file.rb +27 -0
- data/lib/HDLRuby/high_samples/overload.rb +32 -0
- data/lib/HDLRuby/high_samples/paper_after.rb +49 -0
- data/lib/HDLRuby/high_samples/ram.rb +27 -0
- data/lib/HDLRuby/high_samples/registers.rb +139 -0
- data/lib/HDLRuby/high_samples/rom.rb +23 -0
- data/lib/HDLRuby/high_samples/scopeblockname.rb +37 -0
- data/lib/HDLRuby/high_samples/scopescope.rb +26 -0
- data/lib/HDLRuby/high_samples/shift.rb +31 -0
- data/lib/HDLRuby/high_samples/shift2.rb +40 -0
- data/lib/HDLRuby/high_samples/simple_instance.rb +31 -0
- data/lib/HDLRuby/high_samples/test_all.sh +10 -0
- data/lib/HDLRuby/high_samples/typedef.rb +24 -0
- data/lib/HDLRuby/high_samples/values.rb +70 -0
- data/lib/HDLRuby/high_samples/vector.rb +22 -0
- data/lib/HDLRuby/high_samples/with_decoder.rb +30 -0
- data/lib/HDLRuby/high_samples/with_fsm.rb +46 -0
- data/lib/HDLRuby/high_samples/with_pipe.rb +43 -0
- data/lib/HDLRuby/high_samples/with_seq.rb +25 -0
- data/lib/HDLRuby/hruby_bstr.rb +1085 -0
- data/lib/HDLRuby/hruby_check.rb +317 -0
- data/lib/HDLRuby/hruby_db.rb +432 -0
- data/lib/HDLRuby/hruby_error.rb +44 -0
- data/lib/HDLRuby/hruby_high.rb +4103 -0
- data/lib/HDLRuby/hruby_low.rb +4735 -0
- data/lib/HDLRuby/hruby_low2c.rb +1986 -0
- data/lib/HDLRuby/hruby_low2high.rb +738 -0
- data/lib/HDLRuby/hruby_low2seq.rb +248 -0
- data/lib/HDLRuby/hruby_low2sym.rb +126 -0
- data/lib/HDLRuby/hruby_low2vhd.rb +1437 -0
- data/lib/HDLRuby/hruby_low_bool2select.rb +295 -0
- data/lib/HDLRuby/hruby_low_cleanup.rb +193 -0
- data/lib/HDLRuby/hruby_low_fix_types.rb +437 -0
- data/lib/HDLRuby/hruby_low_mutable.rb +1803 -0
- data/lib/HDLRuby/hruby_low_resolve.rb +165 -0
- data/lib/HDLRuby/hruby_low_skeleton.rb +129 -0
- data/lib/HDLRuby/hruby_low_with_bool.rb +141 -0
- data/lib/HDLRuby/hruby_low_with_port.rb +167 -0
- data/lib/HDLRuby/hruby_low_with_var.rb +302 -0
- data/lib/HDLRuby/hruby_low_without_bit2vector.rb +88 -0
- data/lib/HDLRuby/hruby_low_without_concat.rb +162 -0
- data/lib/HDLRuby/hruby_low_without_connection.rb +113 -0
- data/lib/HDLRuby/hruby_low_without_namespace.rb +718 -0
- data/lib/HDLRuby/hruby_low_without_outread.rb +107 -0
- data/lib/HDLRuby/hruby_low_without_select.rb +206 -0
- data/lib/HDLRuby/hruby_serializer.rb +398 -0
- data/lib/HDLRuby/hruby_tools.rb +37 -0
- data/lib/HDLRuby/hruby_types.rb +239 -0
- data/lib/HDLRuby/hruby_values.rb +64 -0
- data/lib/HDLRuby/hruby_verilog.rb +1888 -0
- data/lib/HDLRuby/hruby_verilog_name.rb +52 -0
- data/lib/HDLRuby/low_samples/adder.yaml +97 -0
- data/lib/HDLRuby/low_samples/after.yaml +228 -0
- data/lib/HDLRuby/low_samples/before.yaml +223 -0
- data/lib/HDLRuby/low_samples/blockblock.yaml +48 -0
- data/lib/HDLRuby/low_samples/bugs/sample_add.yaml +97 -0
- data/lib/HDLRuby/low_samples/bugs/sample_daice.yaml +444 -0
- data/lib/HDLRuby/low_samples/bugs/sample_kumiawase.yaml +332 -0
- data/lib/HDLRuby/low_samples/bugs/sample_sub.yaml +97 -0
- data/lib/HDLRuby/low_samples/bugs/seqpar.yaml +184 -0
- data/lib/HDLRuby/low_samples/case.yaml +327 -0
- data/lib/HDLRuby/low_samples/change.yaml +135 -0
- data/lib/HDLRuby/low_samples/clocks.yaml +674 -0
- data/lib/HDLRuby/low_samples/cloner.rb +22 -0
- data/lib/HDLRuby/low_samples/comparer.yaml +85 -0
- data/lib/HDLRuby/low_samples/conditionals.yaml +133 -0
- data/lib/HDLRuby/low_samples/dff.yaml +107 -0
- data/lib/HDLRuby/low_samples/each.yaml +1328 -0
- data/lib/HDLRuby/low_samples/exporter.yaml +226 -0
- data/lib/HDLRuby/low_samples/functions.yaml +298 -0
- data/lib/HDLRuby/low_samples/generic_transmission.yaml +597 -0
- data/lib/HDLRuby/low_samples/inherit_as_dff.yaml +125 -0
- data/lib/HDLRuby/low_samples/inherit_dff.yaml +107 -0
- data/lib/HDLRuby/low_samples/load_yaml.rb +11 -0
- data/lib/HDLRuby/low_samples/memory.yaml +678 -0
- data/lib/HDLRuby/low_samples/namespace_extractor.rb +23 -0
- data/lib/HDLRuby/low_samples/overload.yaml +226 -0
- data/lib/HDLRuby/low_samples/paper_after.yaml +431 -0
- data/lib/HDLRuby/low_samples/port_maker.rb +14 -0
- data/lib/HDLRuby/low_samples/ram.yaml +207 -0
- data/lib/HDLRuby/low_samples/registers.yaml +228 -0
- data/lib/HDLRuby/low_samples/rom.yaml +2950 -0
- data/lib/HDLRuby/low_samples/shift.yaml +230 -0
- data/lib/HDLRuby/low_samples/shift2.yaml +2095 -0
- data/lib/HDLRuby/low_samples/simple_instance.yaml +102 -0
- data/lib/HDLRuby/low_samples/test_all.sh +43 -0
- data/lib/HDLRuby/low_samples/typedef.yaml +115 -0
- data/lib/HDLRuby/low_samples/values.yaml +577 -0
- data/lib/HDLRuby/low_samples/variable_maker.rb +14 -0
- data/lib/HDLRuby/low_samples/vector.yaml +56 -0
- data/lib/HDLRuby/low_samples/with_seq.yaml +188 -0
- data/lib/HDLRuby/low_samples/yaml2hdr.rb +10 -0
- data/lib/HDLRuby/low_samples/yaml2vhd.rb +19 -0
- data/lib/HDLRuby/sim/Makefile +19 -0
- data/lib/HDLRuby/sim/hruby_sim.h +590 -0
- data/lib/HDLRuby/sim/hruby_sim_calc.c +2362 -0
- data/lib/HDLRuby/sim/hruby_sim_core.c +589 -0
- data/lib/HDLRuby/sim/hruby_sim_list.c +93 -0
- data/lib/HDLRuby/sim/hruby_sim_vizualize.c +91 -0
- data/lib/HDLRuby/sim/hruby_value_pool.c +64 -0
- data/lib/HDLRuby/std/channel.rb +354 -0
- data/lib/HDLRuby/std/clocks.rb +165 -0
- data/lib/HDLRuby/std/counters.rb +82 -0
- data/lib/HDLRuby/std/decoder.rb +214 -0
- data/lib/HDLRuby/std/fsm.rb +516 -0
- data/lib/HDLRuby/std/pipeline.rb +220 -0
- data/lib/HDLRuby/std/reconf.rb +309 -0
- data/lib/HDLRuby/test_hruby_bstr.rb +2259 -0
- data/lib/HDLRuby/test_hruby_high.rb +594 -0
- data/lib/HDLRuby/test_hruby_high_low.rb +99 -0
- data/lib/HDLRuby/test_hruby_low.rb +934 -0
- data/lib/HDLRuby/v_samples/adder.v +10 -0
- data/lib/HDLRuby/v_samples/dff.v +12 -0
- data/lib/HDLRuby/v_samples/ram.v +20 -0
- data/lib/HDLRuby/v_samples/rom.v +270 -0
- data/lib/HDLRuby/version.rb +3 -0
- data/lib/HDLRuby.rb +11 -0
- data/makedoc +1 -0
- data/metadata.yaml +4 -0
- metadata +299 -0
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
require "HDLRuby/hruby_error"
|
|
2
|
+
require "HDLRuby/hruby_low_mutable"
|
|
3
|
+
require "HDLRuby/hruby_low2sym"
|
|
4
|
+
require "HDLRuby/hruby_low2seq"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
# Explicitely seperate variables from signals in an HDLRuby::Low
|
|
9
|
+
# description.
|
|
10
|
+
#
|
|
11
|
+
# NOTE: variable and signal are to be taken in the VHDL meaning.
|
|
12
|
+
#
|
|
13
|
+
########################################################################
|
|
14
|
+
module HDLRuby::Low
|
|
15
|
+
|
|
16
|
+
## Extends the SystemT class with separation between signals and variables.
|
|
17
|
+
class SystemT
|
|
18
|
+
# Converts to a variable-compatible system.
|
|
19
|
+
#
|
|
20
|
+
# NOTE: the result is the same systemT.
|
|
21
|
+
def with_var!
|
|
22
|
+
self.each_behavior { |behavior| behavior.with_var! }
|
|
23
|
+
return self
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
## Extends the SystemI class with separation between signals and variables.
|
|
29
|
+
class SystemI
|
|
30
|
+
# Converts to a variable-compatible system.
|
|
31
|
+
#
|
|
32
|
+
# NOTE: the result is the same systemT.
|
|
33
|
+
def with_var!
|
|
34
|
+
self.systemT.with_var!
|
|
35
|
+
return self
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
## Extends the Behavior class with separation between signals and variables.
|
|
41
|
+
class Behavior
|
|
42
|
+
# Converts to a variable-compatible behavior.
|
|
43
|
+
#
|
|
44
|
+
# NOTE: the result is the same systemT.
|
|
45
|
+
def with_var!(upper = nil)
|
|
46
|
+
@block = @block.with_var
|
|
47
|
+
@block.parent = self
|
|
48
|
+
return self
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
## Extends the Block class with separation between signals and variables.
|
|
54
|
+
class Block
|
|
55
|
+
|
|
56
|
+
# Converts a variable to a reference to it.
|
|
57
|
+
def var2ref(var)
|
|
58
|
+
return RefName.new(var.type,RefThis.new,var.name)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Converts symbol +sym+ representing an HDLRuby reference to a variable
|
|
62
|
+
# name.
|
|
63
|
+
def sym2var_name(sym)
|
|
64
|
+
return ("%" + sym.to_s).to_sym
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Converts a variable +name+ to the symbol giving the corresponding
|
|
68
|
+
# HDLRuby reference.
|
|
69
|
+
def var_name2sym(name)
|
|
70
|
+
return name[1..-1].to_sym
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Tell if a name is a variable one.
|
|
74
|
+
def variable_name?(name)
|
|
75
|
+
name[0] == "%"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Extract the variables corresponding to external signals from
|
|
79
|
+
# block-based statement +stmnt+, and put the extraction result is
|
|
80
|
+
# table +sym2var+ that associate variable with corresponding signal
|
|
81
|
+
# name.
|
|
82
|
+
def extract_from_externals!(stmnt,sym2var)
|
|
83
|
+
if (stmnt.is_a?(Block)) then
|
|
84
|
+
# Block case, gather its declared and signals variables.
|
|
85
|
+
vars = {}
|
|
86
|
+
sigs = {}
|
|
87
|
+
stmnt.each_inner do |inner|
|
|
88
|
+
if variable_name?(inner.name) then
|
|
89
|
+
vars[inner.name] = inner
|
|
90
|
+
else
|
|
91
|
+
sigs[inner.name] = inner
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
# Select the variables that correspond to external signals.
|
|
95
|
+
vars.each do |name,inner|
|
|
96
|
+
sym = var_name2sym(name)
|
|
97
|
+
unless sigs.key?(sym) then
|
|
98
|
+
# The variable correspond to an external signal,
|
|
99
|
+
# extract it.
|
|
100
|
+
sym2var[sym] = inner
|
|
101
|
+
stmnt.delete_inner(inner)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
elsif
|
|
105
|
+
# Other case, recurse on the sub blocks.
|
|
106
|
+
stmnt.each_block do |block|
|
|
107
|
+
extract_from_externals!(block,sym2var)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
# Replaces the references by corresponding variables in +stmnt+ from
|
|
114
|
+
# +sym2var+ table.
|
|
115
|
+
def refs_by_variables!(stmnt,sym2var)
|
|
116
|
+
# First, recurse.
|
|
117
|
+
if stmnt.respond_to?(:each_node) then
|
|
118
|
+
stmnt.each_node {|elem| refs_by_variables!(elem,sym2var) }
|
|
119
|
+
end
|
|
120
|
+
# Now replace an element if required.
|
|
121
|
+
if stmnt.respond_to?(:map_nodes!) then
|
|
122
|
+
stmnt.map_nodes! do |elem|
|
|
123
|
+
var = sym2var[elem.to_sym]
|
|
124
|
+
var ? var2ref(var) : elem
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Get access to the variables
|
|
130
|
+
def variables
|
|
131
|
+
# Initializes the set of variables if required.
|
|
132
|
+
@variables ||= {}
|
|
133
|
+
return @variables
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Adds variable +name+ with +type+.
|
|
137
|
+
def add_variable(name,type)
|
|
138
|
+
# Ensure name is a symbol.
|
|
139
|
+
name = name.to_sym
|
|
140
|
+
# Declares the variable as an inner.
|
|
141
|
+
inner = add_inner(SignalI.new(name,type))
|
|
142
|
+
# And register it as a variable.
|
|
143
|
+
variables[name] = inner
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Gets a variable by +name+.
|
|
147
|
+
def get_variable(name)
|
|
148
|
+
# Ensure name is a symbol.
|
|
149
|
+
name = name.to_sym
|
|
150
|
+
# Get the variable.
|
|
151
|
+
return variables[name]
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
# Converts to a variable-compatible block where +upper+ is
|
|
156
|
+
# the upper block if any.
|
|
157
|
+
#
|
|
158
|
+
# NOTE: the result is a new block.
|
|
159
|
+
def with_var(upper = nil)
|
|
160
|
+
# puts "with_var for #{self} with upper=#{upper}"
|
|
161
|
+
# Recurse on the statements.
|
|
162
|
+
new_stmnts = []
|
|
163
|
+
self.each_statement do |stmnt|
|
|
164
|
+
# Process stmnt
|
|
165
|
+
if stmnt.respond_to?(:with_var) then
|
|
166
|
+
# Can be converted
|
|
167
|
+
stmnt = stmnt.with_var(self)
|
|
168
|
+
else
|
|
169
|
+
# Cannot be converted, simply clone.
|
|
170
|
+
stmnt = stmnt.clone
|
|
171
|
+
end
|
|
172
|
+
# Adds the result.
|
|
173
|
+
new_stmnts << stmnt
|
|
174
|
+
end
|
|
175
|
+
# Handle the cases that does not need directly a variable
|
|
176
|
+
# convertion
|
|
177
|
+
# Is the block a par?
|
|
178
|
+
if self.mode == :par then
|
|
179
|
+
# Yes, creates a new block with the new statements.
|
|
180
|
+
block = Block.new(self.mode)
|
|
181
|
+
self.each_inner { |inner| block.add_inner(inner.clone) }
|
|
182
|
+
new_stmnts.each {|stmnt| block.add_statement(stmnt) }
|
|
183
|
+
# Is the block within a seq?
|
|
184
|
+
if upper && upper.mode == :seq then
|
|
185
|
+
# Yes, converts to seq.
|
|
186
|
+
# return self.to_seq
|
|
187
|
+
return block.blocks2seq!
|
|
188
|
+
end
|
|
189
|
+
# No, simply return the block.
|
|
190
|
+
# block = self.clone
|
|
191
|
+
return block
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# The block is a seq, convert it.
|
|
195
|
+
# Treat the block
|
|
196
|
+
sym2var = {} # The table of variable by corresponding signal name
|
|
197
|
+
# Generate and replace the variables
|
|
198
|
+
new_stmnts.each do |stmnt|
|
|
199
|
+
unless stmnt.is_a?(Transmit) then
|
|
200
|
+
# The statement is not a transmission, extract the
|
|
201
|
+
# variables that correspond to external signals.
|
|
202
|
+
extract_from_externals!(stmnt,sym2var)
|
|
203
|
+
else
|
|
204
|
+
# Other case: transmission, the left value is to convert
|
|
205
|
+
# to a variable, and the right values are to be updated
|
|
206
|
+
# with the existing variables.
|
|
207
|
+
# First convert the left value to the corresponding symbol.
|
|
208
|
+
sym = stmnt.left.to_sym
|
|
209
|
+
# puts "sym=#{sym}"
|
|
210
|
+
var = sym2var[sym]
|
|
211
|
+
unless var then
|
|
212
|
+
var = SignalI.new(sym2var_name(sym),stmnt.left.type)
|
|
213
|
+
sym2var[sym] = var
|
|
214
|
+
end
|
|
215
|
+
# Then replace the relevant references by corresponding
|
|
216
|
+
# variables
|
|
217
|
+
refs_by_variables!(stmnt,sym2var)
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
# puts "sym2var=#{sym2var}"
|
|
221
|
+
# Declare the variables in the top block.
|
|
222
|
+
top = self.top_block
|
|
223
|
+
# puts "top=#{top}"
|
|
224
|
+
sym2var.each_value do |var|
|
|
225
|
+
# puts "Adding var=#{var.name}"
|
|
226
|
+
top.add_inner(var.clone) unless top.each_inner.find {|v| v.eql?(var) }
|
|
227
|
+
end
|
|
228
|
+
# Generate the new block.
|
|
229
|
+
result = self.class.new(self.mode,self.name)
|
|
230
|
+
# Adds the inner signals of current block.
|
|
231
|
+
self.each_inner do |inner|
|
|
232
|
+
result.add_inner(inner.clone)
|
|
233
|
+
end
|
|
234
|
+
# Adds the new statements.
|
|
235
|
+
new_stmnts.each do |stmnt|
|
|
236
|
+
result.add_statement(stmnt)
|
|
237
|
+
end
|
|
238
|
+
# Adds final statements assigning variables back to the orginal
|
|
239
|
+
# signals.
|
|
240
|
+
sym2var.each do |sym,var|
|
|
241
|
+
result.add_statement(
|
|
242
|
+
Transmit.new(sym.to_hdr.clone,var2ref(var)))
|
|
243
|
+
end
|
|
244
|
+
# End of the conversion.
|
|
245
|
+
return result
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
## Extends the If class with separation between signals and variables.
|
|
251
|
+
class If
|
|
252
|
+
# Converts to a variable-compatible if where +upper+ is
|
|
253
|
+
# the upper block if any.
|
|
254
|
+
#
|
|
255
|
+
# NOTE: the result is a new if.
|
|
256
|
+
def with_var(upper = nil)
|
|
257
|
+
# Treat the sub nodes.
|
|
258
|
+
# Condition.
|
|
259
|
+
ncond = self.condition.clone
|
|
260
|
+
# Yes.
|
|
261
|
+
nyes =self.yes.with_var(upper)
|
|
262
|
+
# Noifs.
|
|
263
|
+
noifs = self.each_noif.map do |cond,stmnt|
|
|
264
|
+
[cond.clone,stmnt.with_var(upper)]
|
|
265
|
+
end
|
|
266
|
+
# No.
|
|
267
|
+
nno = self.no ? self.no.with_var(upper) : nil
|
|
268
|
+
# Create the resulting If.
|
|
269
|
+
res= If.new(ncond,nyes, nno)
|
|
270
|
+
noifs.each do |cond,stmnt|
|
|
271
|
+
res.add_noif(cond,stmnt)
|
|
272
|
+
end
|
|
273
|
+
return res
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
## Extends the When class with separation between signals and variables.
|
|
279
|
+
class When
|
|
280
|
+
# Converts to a variable-compatible case where +upper+ is
|
|
281
|
+
# the upper block if any.
|
|
282
|
+
#
|
|
283
|
+
# NOTE: the result is a new case.
|
|
284
|
+
def with_var(upper = nil)
|
|
285
|
+
return When.new(self.match.clone,self.statement.with_var(upper))
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
## Extends the Case class with separation between signals and variables.
|
|
291
|
+
class Case
|
|
292
|
+
# Converts to a variable-compatible case where +upper+ is
|
|
293
|
+
# the upper block if any.
|
|
294
|
+
#
|
|
295
|
+
# NOTE: the result is a new case.
|
|
296
|
+
def with_var(upper = nil)
|
|
297
|
+
ndefault = self.default ? self.default.clone : nil
|
|
298
|
+
return Case.new(self.value.clone,ndefault,
|
|
299
|
+
self.each_when.map {|w| w.with_var(upper) })
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
require "HDLRuby/hruby_error"
|
|
2
|
+
require "HDLRuby/hruby_low_mutable"
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
##
|
|
6
|
+
# Ensures that there is no conversion of bit types to vector types.
|
|
7
|
+
#
|
|
8
|
+
#
|
|
9
|
+
# NOTE: Used for instance for converting to old versions of VHDL where
|
|
10
|
+
# bit types cannot be casted to vector types.
|
|
11
|
+
#
|
|
12
|
+
########################################################################
|
|
13
|
+
module HDLRuby::Low
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## Extends the SystemT class for removing bit to vector conversions.
|
|
18
|
+
class SystemT
|
|
19
|
+
# Replace bit to vector conversions by assignment to on bit of
|
|
20
|
+
# an intermediate inner vector.
|
|
21
|
+
#
|
|
22
|
+
# NOTE: the result is the same systemT.
|
|
23
|
+
def bit2vector2inner!
|
|
24
|
+
# puts "For system: #{self.name}"
|
|
25
|
+
# First gather the bit conversions to vector.
|
|
26
|
+
bits2vectors = Set.new
|
|
27
|
+
gather_bits2vectors = proc do |node|
|
|
28
|
+
if node.is_a?(Expression) && node.type == Bit &&
|
|
29
|
+
node.parent.is_a?(Expression) &&
|
|
30
|
+
# References are not relevant parents
|
|
31
|
+
!node.parent.is_a?(Ref) &&
|
|
32
|
+
# Neither do concat that are processed separatly
|
|
33
|
+
!node.parent.is_a?(Concat) &&
|
|
34
|
+
node.parent.type != Bit then
|
|
35
|
+
# puts "node=#{node.to_high}, node.parent=#{node.parent}"
|
|
36
|
+
bits2vectors.add(node)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
# Apply the procedure for gathering the read on outputs signals.
|
|
40
|
+
self.scope.each_scope_deep do |scope|
|
|
41
|
+
scope.each_connection do |connection|
|
|
42
|
+
# Recurse on the connection.
|
|
43
|
+
connection.each_node_deep(&gather_bits2vectors)
|
|
44
|
+
end
|
|
45
|
+
scope.each_behavior do |behavior|
|
|
46
|
+
behavior.each_event do |event|
|
|
47
|
+
gather_bits2vectors.(event.ref)
|
|
48
|
+
end
|
|
49
|
+
behavior.each_statement do |statement|
|
|
50
|
+
# puts "statement=#{statement.class}"
|
|
51
|
+
statement.each_node_deep(&gather_bits2vectors)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
# puts "bits2vectors=#{bits2vectors.size}"
|
|
56
|
+
|
|
57
|
+
# Create the 1-bit-vector type.
|
|
58
|
+
vec1T = TypeVector.new(:"bit1",Bit,0..0)
|
|
59
|
+
# Generate one inner 1-bit-vector signal per read output.
|
|
60
|
+
bit2inner = {}
|
|
61
|
+
bits2vectors.each do |node|
|
|
62
|
+
# Generate the inner variable.
|
|
63
|
+
sig = self.scope.add_inner(SignalI.new(HDLRuby::uniq_name,vec1T))
|
|
64
|
+
ref = RefName.new(vec1T,RefThis.new,sig.name)
|
|
65
|
+
bit2inner[node] =
|
|
66
|
+
[ ref, RefIndex.new(Bit,ref,Value.new(Integer,0)) ]
|
|
67
|
+
# puts "new inner=#{out2inner[name].name}"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Apply the replacement procedure on the code
|
|
71
|
+
self.scope.each_scope_deep do |scope|
|
|
72
|
+
scope.each_connection.to_a.each do |connection|
|
|
73
|
+
connection.reassign_expressions!(bit2inner)
|
|
74
|
+
end
|
|
75
|
+
scope.each_behavior do |behavior|
|
|
76
|
+
behavior.each_event do |event|
|
|
77
|
+
event.reassign_expressions!(bit2inner)
|
|
78
|
+
end
|
|
79
|
+
behavior.block.reassign_expressions!(bit2inner)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
return self
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
end
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
require 'HDLRuby'
|
|
2
|
+
require 'HDLRuby/hruby_tools'
|
|
3
|
+
require 'HDLRuby/hruby_low_mutable'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
module HDLRuby::Low
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
##
|
|
10
|
+
# Breaks the concat assigments.
|
|
11
|
+
# Makes handling by some synthesis tools easier.
|
|
12
|
+
#
|
|
13
|
+
########################################################################
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## Extends the SystemT class with functionality for breaking assingments
|
|
17
|
+
# to concats.
|
|
18
|
+
class SystemT
|
|
19
|
+
|
|
20
|
+
# Breaks the assignments to concats.
|
|
21
|
+
def break_concat_assigns!
|
|
22
|
+
self.scope.break_concat_assigns!
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
## Extends the Scope class with functionality for breaking assingments
|
|
28
|
+
# to concats.
|
|
29
|
+
class Scope
|
|
30
|
+
# Breaks the assignments to concats.
|
|
31
|
+
def break_concat_assigns!
|
|
32
|
+
# Recruse on the sub scopes.
|
|
33
|
+
self.each_scope(&:break_concat_assigns!)
|
|
34
|
+
# Recurse on the statements.
|
|
35
|
+
self.each_behavior do |behavior|
|
|
36
|
+
behavior.block.each_block_deep(&:break_concat_assigns!)
|
|
37
|
+
end
|
|
38
|
+
# Work on the connections.
|
|
39
|
+
self.each_connection.to_a.each do |connection|
|
|
40
|
+
nconnection = connection.break_concat_assigns
|
|
41
|
+
if nconnection.is_a?(Block) then
|
|
42
|
+
# The connection has been broken, remove the former
|
|
43
|
+
# version and add the generated block as a behavior.
|
|
44
|
+
self.remove_connection(connection)
|
|
45
|
+
self.add_behavior(Behavior.new(nconnection))
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
## Extends the Block class with functionality for breaking assingments
|
|
52
|
+
# to concats.
|
|
53
|
+
class Block
|
|
54
|
+
# Breaks the assignments to concats.
|
|
55
|
+
#
|
|
56
|
+
# NOTE: work on the direct sub statement only, not deeply.
|
|
57
|
+
def break_concat_assigns!
|
|
58
|
+
# Check each transmit.
|
|
59
|
+
self.each_statement.each.with_index do |stmnt,i|
|
|
60
|
+
if stmnt.is_a?(Transmit) then
|
|
61
|
+
# Transmit, breaking may be necessary.
|
|
62
|
+
nstmnt = stmnt.break_concat_assigns
|
|
63
|
+
if nstmnt.is_a?(Block) then
|
|
64
|
+
# The transmit has been broken, remove the former
|
|
65
|
+
# version and add the generated block as a behavior.
|
|
66
|
+
self.set_statement!(i,nstmnt)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
## Extends the Transmit class with functionality for breaking assingments
|
|
75
|
+
# to concats.
|
|
76
|
+
class Transmit
|
|
77
|
+
# Break the assignments to concats.
|
|
78
|
+
#
|
|
79
|
+
# NOTE: when breaking generates a new Block containing the broken
|
|
80
|
+
# assignments.
|
|
81
|
+
def break_concat_assigns
|
|
82
|
+
# puts "break_concat_assigns with self=#{self}"
|
|
83
|
+
# Is the left value a RefConcat?
|
|
84
|
+
self.left.each_node_deep do |node|
|
|
85
|
+
if node.is_a?(RefConcat) then
|
|
86
|
+
# Yes, must break. Create the resulting sequential
|
|
87
|
+
# block that will contain the new assignements.
|
|
88
|
+
block = Block.new(:seq)
|
|
89
|
+
# Create an intermediate signal for storing the
|
|
90
|
+
# right value. Put it in the top scope.
|
|
91
|
+
top_block = self.top_block
|
|
92
|
+
top_scope = top_block.top_scope
|
|
93
|
+
aux = top_scope.add_inner(
|
|
94
|
+
SignalI.new(HDLRuby.uniq_name,self.right.type) )
|
|
95
|
+
# puts "new signal: #{aux.name}"
|
|
96
|
+
aux = RefName.new(aux.type,RefThis.new,aux.name)
|
|
97
|
+
# Is a default value required to avoid latch generation?
|
|
98
|
+
unless top_block.parent.each_event.
|
|
99
|
+
find {|ev| ev.type!=:change} then
|
|
100
|
+
# Yes, generate it.
|
|
101
|
+
top_block.insert_statement!(0,
|
|
102
|
+
Transmit.new(aux.clone,Value.new(aux.type,0)))
|
|
103
|
+
end
|
|
104
|
+
# Replace the concat in the copy of the left value.
|
|
105
|
+
if left.eql?(node) then
|
|
106
|
+
# node was the top of left, replace here.
|
|
107
|
+
nleft = aux
|
|
108
|
+
else
|
|
109
|
+
# node was inside left, replace within left.
|
|
110
|
+
nleft = self.left.clone
|
|
111
|
+
nleft.each_node_deep do |ref|
|
|
112
|
+
ref.map_nodes! do |sub|
|
|
113
|
+
sub.eql?(node) ? aux.clone : sub
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
# Recreate the transmit and add it to the block.
|
|
118
|
+
block.add_statement(
|
|
119
|
+
Transmit.new(nleft,self.right.clone) )
|
|
120
|
+
# And assign its part to each reference of the
|
|
121
|
+
# concat.
|
|
122
|
+
pos = 0
|
|
123
|
+
node.each_ref.reverse_each do |ref|
|
|
124
|
+
# Compute the range to assign.
|
|
125
|
+
range = ref.type.width-1+pos .. pos
|
|
126
|
+
# Single or multi-bit range?
|
|
127
|
+
sbit = range.first == range.last
|
|
128
|
+
# Convert the range to an HDLRuby range for
|
|
129
|
+
# using is the resulting statement.
|
|
130
|
+
# Create and add the statement.
|
|
131
|
+
if sbit then
|
|
132
|
+
# Single bit.
|
|
133
|
+
# Generate the index.
|
|
134
|
+
idx = Value.new(Integer,range.first)
|
|
135
|
+
# Generate the assignment.
|
|
136
|
+
block.add_statement(
|
|
137
|
+
Transmit.new(ref.clone,
|
|
138
|
+
RefIndex.new(aux.type.base, aux.clone, idx)))
|
|
139
|
+
else
|
|
140
|
+
# Multi-bits.
|
|
141
|
+
# Compute the type of the right value.
|
|
142
|
+
rtype = TypeVector.new(:"",aux.type.base,range)
|
|
143
|
+
# Generate the range.
|
|
144
|
+
range = Value.new(Integer,range.first) ..
|
|
145
|
+
Value.new(Integer,range.last)
|
|
146
|
+
# Generate the assignment.
|
|
147
|
+
block.add_statement(
|
|
148
|
+
Transmit.new(ref.clone,
|
|
149
|
+
RefRange.new(rtype, aux.clone, range)))
|
|
150
|
+
end
|
|
151
|
+
pos += ref.type.width
|
|
152
|
+
end
|
|
153
|
+
# puts "Resulting block=#{block.to_vhdl}"
|
|
154
|
+
# Return the resulting block
|
|
155
|
+
return block
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
# No, nothing to do.
|
|
159
|
+
return self
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
require 'HDLRuby'
|
|
2
|
+
require 'HDLRuby/hruby_tools'
|
|
3
|
+
require 'HDLRuby/hruby_low_resolve'
|
|
4
|
+
require 'HDLRuby/hruby_low_mutable'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
module HDLRuby::Low
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
##
|
|
11
|
+
# Convert the connections to transmit statement within a behavior.
|
|
12
|
+
# Used by the HDLRuby simulator.
|
|
13
|
+
#
|
|
14
|
+
########################################################################
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## Extends the SystemT class with functionality for breaking assingments
|
|
18
|
+
# to concats.
|
|
19
|
+
class SystemT
|
|
20
|
+
|
|
21
|
+
## Remove the connections and replace them by behaviors.
|
|
22
|
+
# NOTE: one behavior is created for input connections and
|
|
23
|
+
# one for output ones while inout/inner-only connections
|
|
24
|
+
# are copied in both behaviors.
|
|
25
|
+
def connections_to_behaviors!
|
|
26
|
+
# Process the connections: create a behavior containing
|
|
27
|
+
# them all within a par block.
|
|
28
|
+
self.scope.each_scope_deep do |scope|
|
|
29
|
+
if scope.each_connection.to_a.any? then
|
|
30
|
+
inputs_blk = Block.new(:par)
|
|
31
|
+
outputs_blk = Block.new(:par)
|
|
32
|
+
scope.each_connection do |connection|
|
|
33
|
+
# Check the left and right of the connection
|
|
34
|
+
# for input or output port.
|
|
35
|
+
left = connection.left
|
|
36
|
+
left_r = left.resolve
|
|
37
|
+
# puts "left_r=#{left_r.name}" if left_r
|
|
38
|
+
# puts "left_r.parent=#{left_r.parent.name}" if left_r && left_r.parent
|
|
39
|
+
right = connection.right
|
|
40
|
+
right_r = right.resolve if right.respond_to?(:resolve)
|
|
41
|
+
# puts "right_r=#{right_r.name}" if right_r
|
|
42
|
+
# puts "right_r.parent=#{right_r.parent.name}" if right_r && right_r.parent
|
|
43
|
+
# Check if left is an input or an output.
|
|
44
|
+
left_is_i = left_is_o = false
|
|
45
|
+
if left_r && left_r.parent.is_a?(SystemT) then
|
|
46
|
+
if left_r.parent.each_input.include?(left_r) then
|
|
47
|
+
# puts "Left is input."
|
|
48
|
+
# puts "Left is from systemI: #{left.from_systemI?}"
|
|
49
|
+
left_is_i = left.from_systemI?
|
|
50
|
+
left_is_o = !left_is_i
|
|
51
|
+
elsif left_r.parent.each_output.include?(left_r) then
|
|
52
|
+
# puts "Left is output."
|
|
53
|
+
# puts "Left is from systemI: #{left.from_systemI?}"
|
|
54
|
+
left_is_o = left.from_systemI?
|
|
55
|
+
left_is_i = !left_is_o
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
# Check if right is an input or an output.
|
|
59
|
+
right_is_i = right_is_o = false
|
|
60
|
+
if right_r && right_r.parent.is_a?(SystemT) then
|
|
61
|
+
if right_r.parent.each_input.include?(right_r) then
|
|
62
|
+
# puts "Right is input."
|
|
63
|
+
# puts "Right is from systemI: #{right.from_systemI?}"
|
|
64
|
+
right_is_i = right.from_systemI?
|
|
65
|
+
right_is_o = !right_is_i
|
|
66
|
+
elsif right_r.parent.each_output.include?(right_r) then
|
|
67
|
+
# puts "Right is output."
|
|
68
|
+
# puts "Right is from systemI: #{right.from_systemI?}"
|
|
69
|
+
right_is_o = right.from_systemI?
|
|
70
|
+
right_is_i = !right_is_o
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
# puts "left_is_i=#{left_is_i} left_is_o=#{left_is_o}"
|
|
74
|
+
# puts "right_is_i=#{right_is_i} right_is_o=#{right_is_o}"
|
|
75
|
+
# Fills the relevant block.
|
|
76
|
+
if (left_is_i) then
|
|
77
|
+
inputs_blk.add_statement(
|
|
78
|
+
Transmit.new(left.clone,right.clone))
|
|
79
|
+
elsif (right_is_i) then
|
|
80
|
+
inputs_blk.add_statement(
|
|
81
|
+
Transmit.new(right.clone,left.clone))
|
|
82
|
+
elsif (left_is_o) then
|
|
83
|
+
outputs_blk.add_statement(
|
|
84
|
+
Transmit.new(right.clone,left.clone))
|
|
85
|
+
elsif (right_is_o) then
|
|
86
|
+
outputs_blk.add_statement(
|
|
87
|
+
Transmit.new(left.clone,right.clone))
|
|
88
|
+
else
|
|
89
|
+
# puts "left/right is inout"
|
|
90
|
+
if (left.is_a?(Ref)) then
|
|
91
|
+
inputs_blk.add_statement(
|
|
92
|
+
Transmit.new(left.clone,right.clone))
|
|
93
|
+
end
|
|
94
|
+
if (right.is_a?(Ref)) then
|
|
95
|
+
outputs_blk.add_statement(
|
|
96
|
+
Transmit.new(right.clone,left.clone))
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
# Adds the behaviors.
|
|
101
|
+
if inputs_blk.each_statement.any? then
|
|
102
|
+
scope.add_behavior(Behavior.new(inputs_blk))
|
|
103
|
+
end
|
|
104
|
+
if outputs_blk.each_statement.any? then
|
|
105
|
+
scope.add_behavior(Behavior.new(outputs_blk))
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
end
|