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,1986 @@
|
|
|
1
|
+
require 'set'
|
|
2
|
+
require 'HDLRuby'
|
|
3
|
+
require 'HDLRuby/hruby_low_resolve'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
module HDLRuby::Low
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
##
|
|
10
|
+
# Converts a HDLRuby::Low description to a C text description.
|
|
11
|
+
# When compiled, the description is executable an can be used for
|
|
12
|
+
# simulation.
|
|
13
|
+
#
|
|
14
|
+
########################################################################
|
|
15
|
+
|
|
16
|
+
## Provides tools for converting HDLRuby::Low objects to C.
|
|
17
|
+
module Low2C
|
|
18
|
+
|
|
19
|
+
## Generates the includes for a C file, with +names+ for extra
|
|
20
|
+
# h files.
|
|
21
|
+
def self.includes(*names)
|
|
22
|
+
res = '#include <stdlib.h>' + "\n" +
|
|
23
|
+
'#include "hruby_sim.h"' + "\n"
|
|
24
|
+
names.each { |name| res << "#include \"#{name}\"\n" }
|
|
25
|
+
res << "\n"
|
|
26
|
+
return res
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
## Gives the width of an int in the current computer.
|
|
30
|
+
def self.int_width
|
|
31
|
+
# puts "int_width=#{[1.to_i].pack("i").size*8}"
|
|
32
|
+
return [1.to_i].pack("i").size*8
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
## Tells if a +name+ is C-compatible.
|
|
36
|
+
# To ensure compatibile, assume all the character must have the
|
|
37
|
+
# same case.
|
|
38
|
+
def self.c_name?(name)
|
|
39
|
+
name = name.to_s
|
|
40
|
+
# First: character check.
|
|
41
|
+
return false unless name =~ /^[a-zA-Z]|([a-zA-Z][a-zA-Z_0-9]*[a-zA-Z0-9])$/
|
|
42
|
+
return true
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
## Converts a +name+ to a C-compatible name.
|
|
46
|
+
def self.c_name(name)
|
|
47
|
+
name = name.to_s
|
|
48
|
+
# Convert special characters.
|
|
49
|
+
name = name.each_char.map do |c|
|
|
50
|
+
if c=~ /[a-z0-9]/ then
|
|
51
|
+
c
|
|
52
|
+
elsif c == "_" then
|
|
53
|
+
"__"
|
|
54
|
+
else
|
|
55
|
+
"_" + c.ord.to_s
|
|
56
|
+
end
|
|
57
|
+
end.join
|
|
58
|
+
# First character: only letter is possible.
|
|
59
|
+
unless name[0] =~ /[a-z_]/ then
|
|
60
|
+
name = "_" + name
|
|
61
|
+
end
|
|
62
|
+
return name
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
## Generates a uniq name for an object.
|
|
66
|
+
def self.obj_name(obj)
|
|
67
|
+
if obj.respond_to?(:name) then
|
|
68
|
+
return Low2C.c_name(obj.name.to_s) +
|
|
69
|
+
Low2C.c_name(obj.object_id.to_s)
|
|
70
|
+
else
|
|
71
|
+
return "_" + Low2C.c_name(obj.object_id.to_s)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
## Generates the name of a makeer for an object.
|
|
76
|
+
def self.make_name(obj)
|
|
77
|
+
return "make#{Low2C.obj_name(obj)}"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
## Generates the name of a executable function for an object.
|
|
81
|
+
def self.code_name(obj)
|
|
82
|
+
return "code#{Low2C.obj_name(obj)}"
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
## Generates the name of a type.
|
|
86
|
+
def self.type_name(obj)
|
|
87
|
+
return "type#{Low2C.obj_name(obj)}"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
## Generates the name of a unit.
|
|
91
|
+
def self.unit_name(obj)
|
|
92
|
+
return "#{obj.to_s.upcase}"
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
## Generates a prototype from a function +name+.
|
|
96
|
+
def self.prototype(name)
|
|
97
|
+
return "void #{name}();\n"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
## Generates the code of a thread calling +name+ function
|
|
101
|
+
# and register it to the simulator.
|
|
102
|
+
def self.thread(name)
|
|
103
|
+
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
## Generates the main for making the objects of +objs+ and
|
|
108
|
+
# for starting the simulation and including the files from +hnames+
|
|
109
|
+
def self.main(top,objs,hnames)
|
|
110
|
+
res = Low2C.includes(*hnames)
|
|
111
|
+
res << "int main(int argc, char* argv[]) {\n"
|
|
112
|
+
# Build the objects.
|
|
113
|
+
objs.each { |obj| res << " #{Low2C.make_name(obj)}();\n" }
|
|
114
|
+
# Starts the simulation.
|
|
115
|
+
res << " hruby_sim_core(-1);\n"
|
|
116
|
+
# Close the main.
|
|
117
|
+
res << "}\n"
|
|
118
|
+
return res
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
## Gets the structure of the behavior containing object +obj+.
|
|
123
|
+
def self.behavior_access(obj)
|
|
124
|
+
until obj.is_a?(Behavior)
|
|
125
|
+
obj = obj.parent
|
|
126
|
+
end
|
|
127
|
+
return Low2C.obj_name(obj)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
## Generates the code for a wait for time object +obj+ with +level+
|
|
132
|
+
# identation.
|
|
133
|
+
def self.wait(obj,level)
|
|
134
|
+
return "hw_wait(#{obj.delay.to_c(level+1)}," +
|
|
135
|
+
"#{Low2C.behavior_access(obj)});\n"
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
## Extends the SystemT class with generation of HDLRuby::High C text.
|
|
141
|
+
class SystemT
|
|
142
|
+
|
|
143
|
+
# Generates the text of the equivalent HDLRuby::High code.
|
|
144
|
+
# +level+ is the hierachical level of the object and +hnames+
|
|
145
|
+
# is the list of extra h files to include.
|
|
146
|
+
def to_c(level = 0, *hnames)
|
|
147
|
+
# The header
|
|
148
|
+
res = Low2C.includes(*hnames)
|
|
149
|
+
|
|
150
|
+
# Declare the global variable holding the system.
|
|
151
|
+
res << "SystemT #{Low2C.obj_name(self)};\n\n"
|
|
152
|
+
|
|
153
|
+
# Generate the signals of the system.
|
|
154
|
+
self.each_signal { |signal| res << signal.to_c(level) }
|
|
155
|
+
|
|
156
|
+
# Generate the code for all the blocks included in the system.
|
|
157
|
+
self.scope.each_scope_deep do |scope|
|
|
158
|
+
scope.each_behavior do |behavior|
|
|
159
|
+
res << behavior.block.to_c_code(level)
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Generate the code for all the values included in the system.
|
|
164
|
+
self.each_signal do |signal|
|
|
165
|
+
# res << signal.value.to_c_make(level) if signal.value
|
|
166
|
+
signal.value.each_node_deep do |node|
|
|
167
|
+
res << node.to_c_make(level) if node.respond_to?(:to_c_make)
|
|
168
|
+
end if signal.value
|
|
169
|
+
end
|
|
170
|
+
self.scope.each_scope_deep do |scope|
|
|
171
|
+
scope.each_inner do |signal|
|
|
172
|
+
# res << signal.value.to_c_make(level) if signal.value
|
|
173
|
+
signal.value.each_node_deep do |node|
|
|
174
|
+
res << node.to_c_make(level) if node.respond_to?(:to_c_make)
|
|
175
|
+
end if signal.value
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
self.scope.each_block_deep do |block|
|
|
179
|
+
block.each_inner do |signal|
|
|
180
|
+
# res << signal.value.to_c_make(level) if signal.value
|
|
181
|
+
signal.value.each_node_deep do |node|
|
|
182
|
+
res << node.to_c_make(level) if node.respond_to?(:to_c_make)
|
|
183
|
+
end if signal.value
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
self.scope.each_node_deep do |node|
|
|
187
|
+
res << node.to_c_make(level) if node.is_a?(Value)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# Generate the scope.
|
|
191
|
+
res << self.scope.to_c(level)
|
|
192
|
+
|
|
193
|
+
# Generate the entity
|
|
194
|
+
res << "SystemT #{Low2C.make_name(self)}() {\n"
|
|
195
|
+
# Creates the structure.
|
|
196
|
+
res << " " * (level+1)*3
|
|
197
|
+
res << "SystemT systemT = malloc(sizeof(SystemTS));\n"
|
|
198
|
+
res << " " * (level+1)*3
|
|
199
|
+
res << "systemT->kind = SYSTEMT;\n";
|
|
200
|
+
|
|
201
|
+
# Sets the global variable of the system.
|
|
202
|
+
res << "\n"
|
|
203
|
+
res << " " * (level+1)*3
|
|
204
|
+
res << "#{Low2C.obj_name(self)} = systemT;\n"
|
|
205
|
+
|
|
206
|
+
# Set the owner if any.
|
|
207
|
+
if @owner then
|
|
208
|
+
res << " " * (level+1)*3
|
|
209
|
+
res << "systemT->owner = (Object)" +
|
|
210
|
+
"#{Low2C.obj_name(@owner)};\n"
|
|
211
|
+
else
|
|
212
|
+
res << "systemT->owner = NULL;\n"
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# The name
|
|
216
|
+
res << " " * (level+1)*3
|
|
217
|
+
res << "systemT->name = \"#{self.name}\";\n"
|
|
218
|
+
|
|
219
|
+
# The ports
|
|
220
|
+
# Inputs
|
|
221
|
+
res << " " * (level+1)*3
|
|
222
|
+
res << "systemT->num_inputs = #{self.each_input.to_a.size};\n"
|
|
223
|
+
res << " " * (level+1)*3
|
|
224
|
+
res << "systemT->inputs = calloc(sizeof(SignalI)," +
|
|
225
|
+
"systemT->num_inputs);\n"
|
|
226
|
+
self.each_input.with_index do |input,i|
|
|
227
|
+
res << " " * (level+1)*3
|
|
228
|
+
res << "systemT->inputs[#{i}] = " +
|
|
229
|
+
"#{Low2C.make_name(input)}();\n"
|
|
230
|
+
end
|
|
231
|
+
# Outputs
|
|
232
|
+
res << " " * (level+1)*3
|
|
233
|
+
res << "systemT->num_outputs = #{self.each_output.to_a.size};\n"
|
|
234
|
+
res << " " * (level+1)*3
|
|
235
|
+
res << "systemT->outputs = calloc(sizeof(SignalI)," +
|
|
236
|
+
"systemT->num_outputs);\n"
|
|
237
|
+
self.each_output.with_index do |output,i|
|
|
238
|
+
res << " " * (level+1)*3
|
|
239
|
+
res << "systemT->outputs[#{i}] = " +
|
|
240
|
+
"#{Low2C.make_name(output)}();\n"
|
|
241
|
+
end
|
|
242
|
+
# Inouts
|
|
243
|
+
res << " " * (level+1)*3
|
|
244
|
+
res << "systemT->num_inouts = #{self.each_inout.to_a.size};\n"
|
|
245
|
+
res << " " * (level+1)*3
|
|
246
|
+
res << "systemT->inouts = calloc(sizeof(SignalI)," +
|
|
247
|
+
"systemT->num_inouts);\n"
|
|
248
|
+
self.each_inout.with_index do |inout,i|
|
|
249
|
+
res << " " * (level+1)*3
|
|
250
|
+
res << "systemT->inouts[#{i}] = " +
|
|
251
|
+
"#{Low2C.make_name(inout)}();\n"
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
# Adds the scope.
|
|
255
|
+
res << "\n"
|
|
256
|
+
res << " " * (level+1)*3
|
|
257
|
+
res << "systemT->scope = #{Low2C.make_name(self.scope)}();\n"
|
|
258
|
+
|
|
259
|
+
# Generate the Returns of the result.
|
|
260
|
+
res << "\n"
|
|
261
|
+
res << " " * (level+1)*3
|
|
262
|
+
res << "return systemT;\n"
|
|
263
|
+
# End of the system.
|
|
264
|
+
res << " " * level*3
|
|
265
|
+
res << "}"
|
|
266
|
+
# Return the result.
|
|
267
|
+
return res
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
## Generates the code for an execution starting from the system.
|
|
272
|
+
# +level+ is the hierachical level of the object.
|
|
273
|
+
def to_c_code(level)
|
|
274
|
+
res << " " * (level*3)
|
|
275
|
+
res << "#{Low2C.code_name(self)}() {\n"
|
|
276
|
+
# res << "printf(\"Executing #{Low2C.code_name(self)}...\\n\");"
|
|
277
|
+
# Launch the execution of all the time behaviors of the
|
|
278
|
+
# system.
|
|
279
|
+
self.each_behavior_deep do |behavior|
|
|
280
|
+
if behavior.is_a?(HDLRuby::Low::TimeBehavior) then
|
|
281
|
+
res << " " * (level+1)*3
|
|
282
|
+
res << "#{Low2C.code_name(behavior.block)}();\n"
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
# Close the execution procedure.
|
|
286
|
+
res << " " * level*3
|
|
287
|
+
res << "}\n"
|
|
288
|
+
# Return the result.
|
|
289
|
+
return res
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
## Generates the content of the h file.
|
|
294
|
+
def to_ch
|
|
295
|
+
res = ""
|
|
296
|
+
# Declare the global variable holding the signal.
|
|
297
|
+
res << "extern SystemT #{Low2C.obj_name(self)};\n\n"
|
|
298
|
+
|
|
299
|
+
# Generate the access to the function making the systemT. */
|
|
300
|
+
res << "extern SystemT #{Low2C.make_name(self)}();\n\n"
|
|
301
|
+
|
|
302
|
+
# Generate the accesses to the values.
|
|
303
|
+
self.each_signal do |signal|
|
|
304
|
+
# res << signal.value.to_ch if signal.value
|
|
305
|
+
if signal.value then
|
|
306
|
+
signal.value.each_node_deep do |node|
|
|
307
|
+
res << node.to_ch if node.is_a?(Value)
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
self.scope.each_scope_deep do |scope|
|
|
312
|
+
scope.each_inner do |signal|
|
|
313
|
+
# res << signal.value.to_ch if signal.value
|
|
314
|
+
if signal.value then
|
|
315
|
+
signal.value.each_node_deep do |node|
|
|
316
|
+
res << node.to_ch if node.is_a?(Value)
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
self.scope.each_block_deep do |block|
|
|
322
|
+
block.each_inner do |signal|
|
|
323
|
+
res << signal.value.to_ch if signal.value
|
|
324
|
+
end
|
|
325
|
+
block.each_node_deep do |node|
|
|
326
|
+
res << node.to_ch if node.is_a?(Value)
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
# Generate the accesses to the ports.
|
|
331
|
+
self.each_input { |input| res << input.to_ch }
|
|
332
|
+
self.each_output { |output| res << output.to_ch }
|
|
333
|
+
self.each_inout { |inout| res << inout.to_ch }
|
|
334
|
+
|
|
335
|
+
# Generate the accesses to the scope.
|
|
336
|
+
res << self.scope.to_ch << "\n"
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
return res;
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
## Extends the Scope class with generation of HDLRuby::High C text.
|
|
346
|
+
class Scope
|
|
347
|
+
|
|
348
|
+
# Generates the text of the equivalent HDLRuby::High code.
|
|
349
|
+
# +level+ is the hierachical level of the object.
|
|
350
|
+
def to_c(level = 0)
|
|
351
|
+
# The resulting string.
|
|
352
|
+
res = ""
|
|
353
|
+
|
|
354
|
+
# Declare the global variable holding the scope.
|
|
355
|
+
res << "Scope #{Low2C.obj_name(self)};\n\n"
|
|
356
|
+
|
|
357
|
+
# Generate the code makeing the complex sub components.
|
|
358
|
+
|
|
359
|
+
# Generates the code for making signals if any.
|
|
360
|
+
self.each_signal { |signal| res << signal.to_c(level) }
|
|
361
|
+
# Generates the code for making signals if any.
|
|
362
|
+
self.each_systemI { |systemI| res << systemI.to_c(level) }
|
|
363
|
+
# Generates the code for making sub scopes if any.
|
|
364
|
+
self.each_scope { |scope| res << scope.to_c(level) }
|
|
365
|
+
# Generate the code for making the behaviors.
|
|
366
|
+
self.each_behavior { |behavior| res << behavior.to_c(level) }
|
|
367
|
+
# Generate the code for making the non-HDLRuby codes.
|
|
368
|
+
self.each_code { |code| res << code.to_c(level) }
|
|
369
|
+
|
|
370
|
+
# Generate the code of the scope.
|
|
371
|
+
|
|
372
|
+
# The header of the scope.
|
|
373
|
+
res << " " * level*3
|
|
374
|
+
res << "Scope #{Low2C.make_name(self)}() {\n"
|
|
375
|
+
res << " " * (level+1)*3
|
|
376
|
+
res << "Scope scope = malloc(sizeof(ScopeS));\n"
|
|
377
|
+
res << " " * (level+1)*3
|
|
378
|
+
res << "scope->kind = SCOPE;\n";
|
|
379
|
+
|
|
380
|
+
# Sets the global variable of the scope.
|
|
381
|
+
res << "\n"
|
|
382
|
+
res << " " * (level+1)*3
|
|
383
|
+
res << "#{Low2C.obj_name(self)} = scope;\n"
|
|
384
|
+
|
|
385
|
+
# Set the owner if any.
|
|
386
|
+
if self.parent then
|
|
387
|
+
res << " " * (level+1)*3
|
|
388
|
+
res << "scope->owner = (Object)" +
|
|
389
|
+
"#{Low2C.obj_name(self.parent)};\n"
|
|
390
|
+
else
|
|
391
|
+
res << "scope->owner = NULL;\n"
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
# The name
|
|
395
|
+
res << " " * (level+1)*3
|
|
396
|
+
res << "scope->name = \"#{self.name}\";\n"
|
|
397
|
+
|
|
398
|
+
# Add the system instances declaration.
|
|
399
|
+
res << " " * (level+1)*3
|
|
400
|
+
res << "scope->num_systemIs = #{self.each_systemI.to_a.size};\n"
|
|
401
|
+
res << " " * (level+1)*3
|
|
402
|
+
res << "scope->systemIs = calloc(sizeof(SystemI)," +
|
|
403
|
+
"scope->num_systemIs);\n"
|
|
404
|
+
self.each_systemI.with_index do |systemI,i|
|
|
405
|
+
res << " " * (level+1)*3
|
|
406
|
+
res << "scope->systemIs[#{i}] = " +
|
|
407
|
+
"#{Low2C.make_name(systemI)}();\n"
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
# Add the inner signals declaration.
|
|
411
|
+
res << " " * (level+1)*3
|
|
412
|
+
res << "scope->num_inners = #{self.each_inner.to_a.size};\n"
|
|
413
|
+
res << " " * (level+1)*3
|
|
414
|
+
res << "scope->inners = calloc(sizeof(SignalI)," +
|
|
415
|
+
"scope->num_inners);\n"
|
|
416
|
+
self.each_inner.with_index do |inner,i|
|
|
417
|
+
res << " " * (level+1)*3
|
|
418
|
+
res << "scope->inners[#{i}] = " +
|
|
419
|
+
"#{Low2C.make_name(inner)}();\n"
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
# Add the sub scopes.
|
|
423
|
+
res << " " * (level+1)*3
|
|
424
|
+
res << "scope->num_scopes = #{self.each_scope.to_a.size};\n"
|
|
425
|
+
res << " " * (level+1)*3
|
|
426
|
+
res << "scope->scopes = calloc(sizeof(Scope)," +
|
|
427
|
+
"scope->num_scopes);\n"
|
|
428
|
+
self.each_scope.with_index do |scope,i|
|
|
429
|
+
res << " " * (level+1)*3
|
|
430
|
+
res << "scope->scopes[#{i}] = " +
|
|
431
|
+
"#{Low2C.make_name(scope)}();\n"
|
|
432
|
+
end
|
|
433
|
+
|
|
434
|
+
# Add the behaviors.
|
|
435
|
+
res << " " * (level+1)*3
|
|
436
|
+
res << "scope->num_behaviors = #{self.each_behavior.to_a.size};\n"
|
|
437
|
+
res << " " * (level+1)*3
|
|
438
|
+
res << "scope->behaviors = calloc(sizeof(Behavior)," +
|
|
439
|
+
"scope->num_behaviors);\n"
|
|
440
|
+
self.each_behavior.with_index do |behavior,i|
|
|
441
|
+
res << " " * (level+1)*3
|
|
442
|
+
res << "scope->behaviors[#{i}] = " +
|
|
443
|
+
"#{Low2C.make_name(behavior)}();\n"
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
# Add the non-HDLRuby codes.
|
|
447
|
+
res << " " * (level+1)*3
|
|
448
|
+
res << "scope->num_codes = #{self.each_code.to_a.size};\n"
|
|
449
|
+
res << " " * (level+1)*3
|
|
450
|
+
res << "scope->codes = calloc(sizeof(Code)," +
|
|
451
|
+
"scope->num_codes);\n"
|
|
452
|
+
self.each_code.with_index do |code,i|
|
|
453
|
+
res << " " * (level+1)*3
|
|
454
|
+
res << "scope->codes[#{i}] = " +
|
|
455
|
+
"#{Low2C.make_name(code)}();\n"
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
# Generate the Returns of the result.
|
|
459
|
+
res << "\n"
|
|
460
|
+
res << " " * (level+1)*3
|
|
461
|
+
res << "return scope;\n"
|
|
462
|
+
|
|
463
|
+
# Close the scope.
|
|
464
|
+
res << " " * level*3
|
|
465
|
+
res << "}\n\n"
|
|
466
|
+
return res
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
## Generates the content of the h file.
|
|
470
|
+
def to_ch
|
|
471
|
+
res = ""
|
|
472
|
+
# Declare the global variable holding the signal.
|
|
473
|
+
res << "extern Scope #{Low2C.obj_name(self)};\n\n"
|
|
474
|
+
|
|
475
|
+
# Generate the access to the function making the scope.
|
|
476
|
+
res << "extern Scope #{Low2C.make_name(self)}();\n\n"
|
|
477
|
+
|
|
478
|
+
# Generate the accesses to the system instances.
|
|
479
|
+
self.each_systemI { |systemI| res << systemI.to_ch }
|
|
480
|
+
|
|
481
|
+
# Generate the accesses to the signals.
|
|
482
|
+
self.each_inner { |inner| res << inner.to_ch }
|
|
483
|
+
|
|
484
|
+
# Generate the access to the sub scopes.
|
|
485
|
+
self.each_scope { |scope| res << scope.to_ch }
|
|
486
|
+
|
|
487
|
+
# Generate the access to the behaviors.
|
|
488
|
+
self.each_behavior { |behavior| res << behavior.to_ch }
|
|
489
|
+
|
|
490
|
+
# Generate the access to the non-HDLRuby code.
|
|
491
|
+
self.each_behavior { |code| res << code.to_ch }
|
|
492
|
+
|
|
493
|
+
return res;
|
|
494
|
+
end
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
## Extends the Type class with generation of HDLRuby::High text.
|
|
499
|
+
class Type
|
|
500
|
+
|
|
501
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
502
|
+
# +level+ is the hierachical level of the object.
|
|
503
|
+
def to_c(level = 0)
|
|
504
|
+
# return Low2C.c_name(self.name)
|
|
505
|
+
# return Low2C.type_name(Bit) + "()"
|
|
506
|
+
if self.name == :bit || self.name == :unsigned then
|
|
507
|
+
return "get_type_bit()"
|
|
508
|
+
elsif self.name == :signed then
|
|
509
|
+
return "get_type_signed()"
|
|
510
|
+
else
|
|
511
|
+
raise "Unknown type: #{self.name}"
|
|
512
|
+
end
|
|
513
|
+
end
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
## Extends the TypeDef class with generation of HDLRuby::High text.
|
|
517
|
+
class TypeDef
|
|
518
|
+
|
|
519
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
520
|
+
# +level+ is the hierachical level of the object.
|
|
521
|
+
def to_c(level = 0)
|
|
522
|
+
# Simply use the name of the type.
|
|
523
|
+
return Low2C.type_name(self.name) + "()"
|
|
524
|
+
end
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
## Extends the TypeVector class with generation of HDLRuby::High text.
|
|
528
|
+
class TypeVector
|
|
529
|
+
|
|
530
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
531
|
+
# +level+ is the hierachical level of the object.
|
|
532
|
+
def to_c(level = 0)
|
|
533
|
+
# The resulting string.
|
|
534
|
+
return "get_type_vector(#{self.base.to_c(level+1)}," +
|
|
535
|
+
"#{self.size})"
|
|
536
|
+
end
|
|
537
|
+
end
|
|
538
|
+
|
|
539
|
+
## Extends the TypeTuple class with generation of HDLRuby::High text.
|
|
540
|
+
class TypeTuple
|
|
541
|
+
|
|
542
|
+
# Generates the text of the equivalent HDLRuby::High code.
|
|
543
|
+
# +level+ is the hierachical level of the object.
|
|
544
|
+
#
|
|
545
|
+
# NOTE: type tuples are converted to bit vector of their contents.
|
|
546
|
+
def to_c(level = 0)
|
|
547
|
+
return "get_type_tuple(#{self.each.join(",") do |type|
|
|
548
|
+
type.to_c(level+1)
|
|
549
|
+
end})"
|
|
550
|
+
end
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
## Extends the TypeStruct class with generation of HDLRuby::High text.
|
|
555
|
+
class TypeStruct
|
|
556
|
+
|
|
557
|
+
# Generates the text of the equivalent HDLRuby::High code.
|
|
558
|
+
# +level+ is the hierachical level of the object.
|
|
559
|
+
def to_c(level = 0)
|
|
560
|
+
return "get_type_struct(#{self.each.join(",") do |key,type|
|
|
561
|
+
"\"#{key.to_s}\",#{type.to_c(level+1)}"
|
|
562
|
+
end})"
|
|
563
|
+
end
|
|
564
|
+
end
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
## Extends the Behavior class with generation of HDLRuby::High text.
|
|
568
|
+
class Behavior
|
|
569
|
+
|
|
570
|
+
# Generates the text of the equivalent HDLRuby::High code.
|
|
571
|
+
# +level+ is the hierachical level of the object and
|
|
572
|
+
# +time+ is a flag telling if the behavior is timed or not.
|
|
573
|
+
def to_c(level = 0, time = false)
|
|
574
|
+
# puts "For behavior: #{self}"
|
|
575
|
+
# The resulting string.
|
|
576
|
+
res = ""
|
|
577
|
+
|
|
578
|
+
# Declare the global variable holding the behavior.
|
|
579
|
+
res << "Behavior #{Low2C.obj_name(self)};\n\n"
|
|
580
|
+
|
|
581
|
+
# Generate the code of the behavior.
|
|
582
|
+
|
|
583
|
+
# The header of the behavior.
|
|
584
|
+
res << " " * level*3
|
|
585
|
+
res << "Behavior #{Low2C.make_name(self)}() {\n"
|
|
586
|
+
res << " " * (level+1)*3
|
|
587
|
+
|
|
588
|
+
# Allocate the behavior.
|
|
589
|
+
res << "Behavior behavior = malloc(sizeof(BehaviorS));\n"
|
|
590
|
+
res << " " * (level+1)*3
|
|
591
|
+
res << "behavior->kind = BEHAVIOR;\n";
|
|
592
|
+
|
|
593
|
+
# Sets the global variable of the behavior.
|
|
594
|
+
res << "\n"
|
|
595
|
+
res << " " * (level+1)*3
|
|
596
|
+
res << "#{Low2C.obj_name(self)} = behavior;\n"
|
|
597
|
+
|
|
598
|
+
# Register it as a time behavior if it is one of them. */
|
|
599
|
+
if time then
|
|
600
|
+
res << " " * (level+1)*3
|
|
601
|
+
res << "register_timed_behavior(behavior);\n"
|
|
602
|
+
end
|
|
603
|
+
|
|
604
|
+
# Set the owner if any.
|
|
605
|
+
if self.parent then
|
|
606
|
+
res << " " * (level+1)*3
|
|
607
|
+
res << "behavior->owner = (Object)" +
|
|
608
|
+
"#{Low2C.obj_name(self.parent)};\n"
|
|
609
|
+
else
|
|
610
|
+
res << "behavior->owner = NULL;\n"
|
|
611
|
+
end
|
|
612
|
+
|
|
613
|
+
# Set the behavior as inactive. */
|
|
614
|
+
res << " " * (level+1)*3
|
|
615
|
+
res << "behavior->activated = 0;\n"
|
|
616
|
+
|
|
617
|
+
# Tells if the behavior is timed or not.
|
|
618
|
+
res << " " * (level+1)*3
|
|
619
|
+
res << "behavior->timed = #{time ? 1 : 0};\n"
|
|
620
|
+
|
|
621
|
+
# Is it a clocked behavior?
|
|
622
|
+
events = self.each_event.to_a
|
|
623
|
+
if events.empty? then
|
|
624
|
+
# No events, this is not a clock behavior.
|
|
625
|
+
# Generate the events list from the right values.
|
|
626
|
+
# First get the references.
|
|
627
|
+
refs = self.block.each_node_deep.select do |node|
|
|
628
|
+
node.is_a?(RefName) && !node.leftvalue? &&
|
|
629
|
+
!node.parent.is_a?(RefName)
|
|
630
|
+
end.to_a
|
|
631
|
+
# Keep only one ref per signal.
|
|
632
|
+
refs.uniq! { |node| node.full_name }
|
|
633
|
+
# Generate the event.
|
|
634
|
+
events = refs.map {|ref| Event.new(:anyedge,ref.clone) }
|
|
635
|
+
# Add them to the behavior for further processing.
|
|
636
|
+
events.each {|event| self.add_event(event) }
|
|
637
|
+
end
|
|
638
|
+
# Add the events and register the behavior as activable
|
|
639
|
+
# on them.
|
|
640
|
+
# First allocates the array containing the events.
|
|
641
|
+
res << " " * (level+1)*3
|
|
642
|
+
res << "behavior->num_events = #{events.size};\n"
|
|
643
|
+
res << " " * (level+1)*3
|
|
644
|
+
res << "behavior->events = calloc(sizeof(Event)," +
|
|
645
|
+
"behavior->num_events);\n"
|
|
646
|
+
# Then, create and add them.
|
|
647
|
+
events.each_with_index do |event,i|
|
|
648
|
+
# puts "for event=#{event}"
|
|
649
|
+
# Add the event.
|
|
650
|
+
res << " " * (level+1)*3
|
|
651
|
+
res << "behavior->events[#{i}] = #{event.to_c};\n"
|
|
652
|
+
|
|
653
|
+
# Register the behavior as activable on this event.
|
|
654
|
+
# Select the active field.
|
|
655
|
+
field = "any"
|
|
656
|
+
field = "pos" if event.type == :posedge
|
|
657
|
+
field = "neg" if event.type == :negedge
|
|
658
|
+
# puts "Adding #{field} event: #{event}\n"
|
|
659
|
+
# Get the target signal access
|
|
660
|
+
sigad = event.ref.resolve.to_c_signal
|
|
661
|
+
# Add the behavior to the relevant field.
|
|
662
|
+
res << " " * (level+1)*3
|
|
663
|
+
res << "#{sigad}->num_#{field} += 1;\n"
|
|
664
|
+
res << " " * (level+1)*3
|
|
665
|
+
res << "#{sigad}->#{field} = realloc(#{sigad}->#{field}," +
|
|
666
|
+
"#{sigad}->num_#{field}*sizeof(Object));\n"
|
|
667
|
+
res << "#{sigad}->#{field}[#{sigad}->num_#{field}-1] = " +
|
|
668
|
+
"(Object)behavior;\n"
|
|
669
|
+
end
|
|
670
|
+
|
|
671
|
+
# Adds the block.
|
|
672
|
+
res << " " * (level+1)*3
|
|
673
|
+
res << "behavior->block = #{Low2C.make_name(self.block)}();\n"
|
|
674
|
+
|
|
675
|
+
# Generate the Returns of the result.
|
|
676
|
+
res << "\n"
|
|
677
|
+
res << " " * (level+1)*3
|
|
678
|
+
res << "return behavior;\n"
|
|
679
|
+
|
|
680
|
+
# Close the behavior makeing.
|
|
681
|
+
res << " " * level*3
|
|
682
|
+
res << "}\n\n"
|
|
683
|
+
return res
|
|
684
|
+
end
|
|
685
|
+
|
|
686
|
+
## Generates the content of the h file.
|
|
687
|
+
def to_ch
|
|
688
|
+
res = ""
|
|
689
|
+
# Declare the global variable holding the signal.
|
|
690
|
+
res << "extern Behavior #{Low2C.obj_name(self)};\n\n"
|
|
691
|
+
|
|
692
|
+
# Generate the access to the function making the behavior.
|
|
693
|
+
res << "extern Behavior #{Low2C.make_name(self)}();\n\n"
|
|
694
|
+
|
|
695
|
+
# Generate the accesses to the block of the behavior.
|
|
696
|
+
res << self.block.to_ch
|
|
697
|
+
|
|
698
|
+
return res;
|
|
699
|
+
end
|
|
700
|
+
end
|
|
701
|
+
|
|
702
|
+
## Extends the TimeBehavior class with generation of HDLRuby::High text.
|
|
703
|
+
class TimeBehavior
|
|
704
|
+
|
|
705
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
706
|
+
# +level+ is the hierachical level of the object.
|
|
707
|
+
def to_c(level = 0)
|
|
708
|
+
super(level,true)
|
|
709
|
+
end
|
|
710
|
+
end
|
|
711
|
+
|
|
712
|
+
|
|
713
|
+
## Extends the Event class with generation of HDLRuby::High text.
|
|
714
|
+
class Event
|
|
715
|
+
|
|
716
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
717
|
+
# +level+ is the hierachical level of the object.
|
|
718
|
+
def to_c(level = 0)
|
|
719
|
+
edge = "ANYEDGE"
|
|
720
|
+
edge = "POSEDGE" if self.type == :posedge
|
|
721
|
+
edge = "NEGEDGE" if self.type == :negedge
|
|
722
|
+
return "make_event(#{edge}," +
|
|
723
|
+
"#{self.ref.resolve.to_c_signal(level+1)})"
|
|
724
|
+
end
|
|
725
|
+
end
|
|
726
|
+
|
|
727
|
+
|
|
728
|
+
## Extends the SignalI class with generation of HDLRuby::High text.
|
|
729
|
+
class SignalI
|
|
730
|
+
|
|
731
|
+
## Generates the C text for an access to the signal.
|
|
732
|
+
# +level+ is the hierachical level of the object.
|
|
733
|
+
def to_c_signal(level = 0)
|
|
734
|
+
res = Low2C.obj_name(self)
|
|
735
|
+
# Accumulate the names of each parent until there is no one left.
|
|
736
|
+
obj = self.parent
|
|
737
|
+
while(obj) do
|
|
738
|
+
res << "_" << Low2C.obj_name(obj)
|
|
739
|
+
obj = obj.parent
|
|
740
|
+
end
|
|
741
|
+
return res
|
|
742
|
+
end
|
|
743
|
+
|
|
744
|
+
## Generates the C text of the equivalent HDLRuby::High code.
|
|
745
|
+
# +level+ is the hierachical level of the object.
|
|
746
|
+
def to_c(level = 0)
|
|
747
|
+
# The resulting string.
|
|
748
|
+
res = ""
|
|
749
|
+
|
|
750
|
+
# Declare the global variable holding the signal.
|
|
751
|
+
res << "SignalI #{self.to_c_signal(level+1)};\n\n"
|
|
752
|
+
|
|
753
|
+
# The header of the signal generation.
|
|
754
|
+
res << " " * level*3
|
|
755
|
+
res << "SignalI #{Low2C.make_name(self)}() {\n"
|
|
756
|
+
res << " " * (level+1)*3
|
|
757
|
+
res << "SignalI signalI = malloc(sizeof(SignalIS));\n"
|
|
758
|
+
res << " " * (level+1)*3
|
|
759
|
+
res << "signalI->kind = SIGNALI;\n";
|
|
760
|
+
|
|
761
|
+
# Sets the global variable of the signal.
|
|
762
|
+
res << "\n"
|
|
763
|
+
res << " " * (level+1)*3
|
|
764
|
+
res << "#{self.to_c_signal(level+1)} = signalI;\n"
|
|
765
|
+
|
|
766
|
+
# Set the owner if any.
|
|
767
|
+
if self.parent then
|
|
768
|
+
res << " " * (level+1)*3
|
|
769
|
+
res << "signalI->owner = (Object)" +
|
|
770
|
+
"#{Low2C.obj_name(self.parent)};\n"
|
|
771
|
+
else
|
|
772
|
+
res << "signalI->owner = NULL;\n"
|
|
773
|
+
end
|
|
774
|
+
|
|
775
|
+
# Set the name
|
|
776
|
+
res << " " * (level+1)*3
|
|
777
|
+
res << "signalI->name = \"#{self.name}\";\n"
|
|
778
|
+
# Set the type.
|
|
779
|
+
res << " " * (level+1)*3
|
|
780
|
+
res << "signalI->type = #{self.type.to_c(level+2)};\n"
|
|
781
|
+
# Set the current and the next value.
|
|
782
|
+
res << " " * (level+1)*3
|
|
783
|
+
res << "signalI->c_value = make_value(signalI->type,0);\n"
|
|
784
|
+
res << " " * (level+1)*3
|
|
785
|
+
res << "signalI->c_value->signal = signalI;\n"
|
|
786
|
+
res << " " * (level+1)*3
|
|
787
|
+
res << "signalI->f_value = make_value(signalI->type,0);\n"
|
|
788
|
+
res << " " * (level+1)*3
|
|
789
|
+
res << "signalI->f_value->signal = signalI;\n"
|
|
790
|
+
if self.value then
|
|
791
|
+
# There is an initial value.
|
|
792
|
+
res << " " * (level+1)*3
|
|
793
|
+
res << "copy_value(#{self.value.to_c(level+2)}," +
|
|
794
|
+
"signalI->c_value);\n"
|
|
795
|
+
end
|
|
796
|
+
|
|
797
|
+
# Initially the signal can be overwritten by anything.
|
|
798
|
+
res << " " * (level+1)*3
|
|
799
|
+
res << "signalI->fading = 1;\n"
|
|
800
|
+
|
|
801
|
+
# Initialize the lists of behavior activated on this signal to 0.
|
|
802
|
+
res << " " * (level+1)*3
|
|
803
|
+
res << "signalI->num_any = 0;\n"
|
|
804
|
+
res << " " * (level+1)*3
|
|
805
|
+
res << "signalI->any = NULL;\n"
|
|
806
|
+
res << " " * (level+1)*3
|
|
807
|
+
res << "signalI->num_pos = 0;\n"
|
|
808
|
+
res << " " * (level+1)*3
|
|
809
|
+
res << "signalI->pos = NULL;\n"
|
|
810
|
+
res << " " * (level+1)*3
|
|
811
|
+
res << "signalI->num_neg = 0;\n"
|
|
812
|
+
res << " " * (level+1)*3
|
|
813
|
+
res << "signalI->neg = NULL;\n"
|
|
814
|
+
|
|
815
|
+
# Register the signal for global processing.
|
|
816
|
+
res << " " * (level+1)*3
|
|
817
|
+
res << "register_signal(signalI);\n"
|
|
818
|
+
|
|
819
|
+
|
|
820
|
+
# Generate the return of the signal.
|
|
821
|
+
res << "\n"
|
|
822
|
+
res << " " * (level+1)*3
|
|
823
|
+
res << "return signalI;\n"
|
|
824
|
+
|
|
825
|
+
# Close the signal.
|
|
826
|
+
res << " " * level*3
|
|
827
|
+
res << "};\n\n"
|
|
828
|
+
return res
|
|
829
|
+
end
|
|
830
|
+
|
|
831
|
+
## Generates the content of the h file.
|
|
832
|
+
def to_ch
|
|
833
|
+
res = ""
|
|
834
|
+
# Declare the global variable holding the signal.
|
|
835
|
+
res << "extern SignalI #{self.to_c_signal()};\n\n"
|
|
836
|
+
|
|
837
|
+
# Generate the access to the function making the behavior.
|
|
838
|
+
res << "extern SignalI #{Low2C.make_name(self)}();\n\n"
|
|
839
|
+
|
|
840
|
+
return res;
|
|
841
|
+
end
|
|
842
|
+
end
|
|
843
|
+
|
|
844
|
+
|
|
845
|
+
## Extends the SystemI class with generation of HDLRuby::High text.
|
|
846
|
+
class SystemI
|
|
847
|
+
|
|
848
|
+
## Generates the C text of the equivalent HDLRuby::High code.
|
|
849
|
+
# +level+ is the hierachical level of the object.
|
|
850
|
+
def to_c(level = 0)
|
|
851
|
+
# The resulting string.
|
|
852
|
+
res = ""
|
|
853
|
+
|
|
854
|
+
# Declare the global variable holding the signal.
|
|
855
|
+
res << "SystemI #{Low2C.obj_name(self)};\n\n"
|
|
856
|
+
|
|
857
|
+
# The header of the signal generation.
|
|
858
|
+
res << " " * level*3
|
|
859
|
+
res << "SystemI #{Low2C.make_name(self)}() {\n"
|
|
860
|
+
res << " " * (level+1)*3
|
|
861
|
+
res << "SystemI systemI = malloc(sizeof(SystemIS));\n"
|
|
862
|
+
res << " " * (level+1)*3
|
|
863
|
+
res << "systemI->kind = SYSTEMI;\n";
|
|
864
|
+
|
|
865
|
+
# Sets the global variable of the system instance.
|
|
866
|
+
res << "\n"
|
|
867
|
+
res << " " * (level+1)*3
|
|
868
|
+
res << "#{Low2C.obj_name(self)} = systemI;\n"
|
|
869
|
+
|
|
870
|
+
# Set the owner if any.
|
|
871
|
+
if self.parent then
|
|
872
|
+
res << " " * (level+1)*3
|
|
873
|
+
res << "systemI->owner = (Object)" +
|
|
874
|
+
"#{Low2C.obj_name(self.parent)};\n"
|
|
875
|
+
else
|
|
876
|
+
res << "systemI->owner = NULL;\n"
|
|
877
|
+
end
|
|
878
|
+
|
|
879
|
+
# Set the name
|
|
880
|
+
res << " " * (level+1)*3
|
|
881
|
+
res << "systemI->name = \"#{self.name}\";\n"
|
|
882
|
+
# Set the type.
|
|
883
|
+
res << " " * (level+1)*3
|
|
884
|
+
res << "systemI->system = #{Low2C.obj_name(self.systemT)};\n"
|
|
885
|
+
|
|
886
|
+
# Generate the return of the signal.
|
|
887
|
+
res << "\n"
|
|
888
|
+
res << " " * (level+1)*3
|
|
889
|
+
res << "return systemI;\n"
|
|
890
|
+
|
|
891
|
+
# Close the signal.
|
|
892
|
+
res << " " * level*3
|
|
893
|
+
res << "};\n\n"
|
|
894
|
+
return res
|
|
895
|
+
end
|
|
896
|
+
|
|
897
|
+
## Generates the content of the h file.
|
|
898
|
+
def to_ch
|
|
899
|
+
res = ""
|
|
900
|
+
# Declare the global variable holding the signal.
|
|
901
|
+
res << "extern SystemI #{Low2C.obj_name(self)};\n\n"
|
|
902
|
+
|
|
903
|
+
# Generate the access to the function making the systemT. */
|
|
904
|
+
res << "extern SystemI #{Low2C.make_name(self)}();\n\n"
|
|
905
|
+
|
|
906
|
+
return res
|
|
907
|
+
end
|
|
908
|
+
end
|
|
909
|
+
|
|
910
|
+
|
|
911
|
+
# Extend the Chunk cass with generation of text code.
|
|
912
|
+
class HDLRuby::Low::Chunk
|
|
913
|
+
|
|
914
|
+
# Generates the text of the equivalent HDLRuby::High code.
|
|
915
|
+
# +level+ is the hierachical level of the object.
|
|
916
|
+
def to_c(level = 0)
|
|
917
|
+
res = " " * level
|
|
918
|
+
res << self.each_lump.map do |lump|
|
|
919
|
+
if !lump.is_a?(String) then
|
|
920
|
+
lump.respond_to?(:to_c) ? lump.to_c(level+1) : lump.to_s
|
|
921
|
+
else
|
|
922
|
+
lump
|
|
923
|
+
end
|
|
924
|
+
end.join
|
|
925
|
+
return res
|
|
926
|
+
end
|
|
927
|
+
end
|
|
928
|
+
|
|
929
|
+
|
|
930
|
+
## Extends the SystemI class with generation of HDLRuby::High text.
|
|
931
|
+
class Code
|
|
932
|
+
# Generates the text of the equivalent HDLRuby::High code.
|
|
933
|
+
# +level+ is the hierachical level of the object.
|
|
934
|
+
def to_c(level = 0)
|
|
935
|
+
# puts "For behavior: #{self}"
|
|
936
|
+
# The resulting string.
|
|
937
|
+
res = ""
|
|
938
|
+
|
|
939
|
+
# Declare the global variable holding the behavior.
|
|
940
|
+
res << "Code #{Low2C.obj_name(self)};\n\n"
|
|
941
|
+
|
|
942
|
+
# Generate the code of the behavior.
|
|
943
|
+
|
|
944
|
+
# The header of the behavior.
|
|
945
|
+
res << " " * level*3
|
|
946
|
+
res << "Code #{Low2C.make_name(self)}() {\n"
|
|
947
|
+
res << " " * (level+1)*3
|
|
948
|
+
|
|
949
|
+
# Allocate the code.
|
|
950
|
+
res << "Code code = malloc(sizeof(CodeS));\n"
|
|
951
|
+
res << " " * (level+1)*3
|
|
952
|
+
res << "code->kind = CODE;\n";
|
|
953
|
+
|
|
954
|
+
# Sets the global variable of the code.
|
|
955
|
+
res << "\n"
|
|
956
|
+
res << " " * (level+1)*3
|
|
957
|
+
res << "#{Low2C.obj_name(self)} = code;\n"
|
|
958
|
+
|
|
959
|
+
# Set the owner if any.
|
|
960
|
+
if self.parent then
|
|
961
|
+
res << " " * (level+1)*3
|
|
962
|
+
res << "code->owner = (Object)" +
|
|
963
|
+
"#{Low2C.obj_name(self.parent)};\n"
|
|
964
|
+
else
|
|
965
|
+
res << "code->owner = NULL;\n"
|
|
966
|
+
end
|
|
967
|
+
|
|
968
|
+
# Set the code as inactive. */
|
|
969
|
+
res << " " * (level+1)*3
|
|
970
|
+
res << "code->activated = 0;\n"
|
|
971
|
+
|
|
972
|
+
# Add the events and register the code as activable
|
|
973
|
+
# on them.
|
|
974
|
+
res << " " * (level+1)*3
|
|
975
|
+
res << "code->num_events = #{self.each_event.to_a.size};\n"
|
|
976
|
+
res << " " * (level+1)*3
|
|
977
|
+
res << "code->events = calloc(sizeof(Event)," +
|
|
978
|
+
"code->num_events);\n"
|
|
979
|
+
# Process the events.
|
|
980
|
+
events = self.each_event.to_a
|
|
981
|
+
events.each_with_index do |event,i|
|
|
982
|
+
# puts "for event=#{event}"
|
|
983
|
+
# Add the event.
|
|
984
|
+
res << " " * (level+1)*3
|
|
985
|
+
res << "code->events[#{i}] = #{event.to_c};\n"
|
|
986
|
+
|
|
987
|
+
# Register the behavior as activable on this event.
|
|
988
|
+
# Select the active field.
|
|
989
|
+
field = "any"
|
|
990
|
+
field = "pos" if event.type == :posedge
|
|
991
|
+
field = "neg" if event.type == :negedge
|
|
992
|
+
# Get the target signal access
|
|
993
|
+
sigad = event.ref.resolve.to_c_signal
|
|
994
|
+
# Add the code to the relevant field.
|
|
995
|
+
res << " " * (level+1)*3
|
|
996
|
+
res << "#{sigad}->num_#{field} += 1;\n"
|
|
997
|
+
res << " " * (level+1)*3
|
|
998
|
+
res << "#{sigad}->#{field} = realloc(#{sigad}->#{field}," +
|
|
999
|
+
"#{sigad}->num_#{field}*sizeof(Object));\n"
|
|
1000
|
+
res << "#{sigad}->#{field}[#{sigad}->num_#{field}-1] = " +
|
|
1001
|
+
"(Object)code;\n"
|
|
1002
|
+
end
|
|
1003
|
+
|
|
1004
|
+
# Adds the function to execute.
|
|
1005
|
+
function = self.each_chunk.find { |chunk| chunk.name == :sim }
|
|
1006
|
+
res << " " * (level+1)*3
|
|
1007
|
+
res << "code->function = &#{function.to_c};\n"
|
|
1008
|
+
|
|
1009
|
+
# Generate the Returns of the result.
|
|
1010
|
+
res << "\n"
|
|
1011
|
+
res << " " * (level+1)*3
|
|
1012
|
+
res << "return code;\n"
|
|
1013
|
+
|
|
1014
|
+
# Close the behavior makeing.
|
|
1015
|
+
res << " " * level*3
|
|
1016
|
+
res << "}\n\n"
|
|
1017
|
+
return res
|
|
1018
|
+
end
|
|
1019
|
+
|
|
1020
|
+
## Generates the content of the h file.
|
|
1021
|
+
def to_ch
|
|
1022
|
+
res = ""
|
|
1023
|
+
# Declare the global variable holding the signal.
|
|
1024
|
+
res << "extern Behavior #{Low2C.obj_name(self)};\n\n"
|
|
1025
|
+
|
|
1026
|
+
# Generate the access to the function making the behavior.
|
|
1027
|
+
res << "extern Behavior #{Low2C.make_name(self)}();\n\n"
|
|
1028
|
+
|
|
1029
|
+
# Generate the accesses to the block of the behavior.
|
|
1030
|
+
res << self.block.to_ch
|
|
1031
|
+
|
|
1032
|
+
return res;
|
|
1033
|
+
end
|
|
1034
|
+
end
|
|
1035
|
+
|
|
1036
|
+
|
|
1037
|
+
## Extends the Statement class with generation of HDLRuby::High text.
|
|
1038
|
+
class Statement
|
|
1039
|
+
|
|
1040
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
1041
|
+
# +level+ is the hierachical level of the object.
|
|
1042
|
+
def to_c(level = 0)
|
|
1043
|
+
# Should never be here.
|
|
1044
|
+
raise AnyError, "Internal error: to_c should be implemented in class :#{self.class}"
|
|
1045
|
+
end
|
|
1046
|
+
|
|
1047
|
+
# Adds the c code of the blocks to +res+ at +level+
|
|
1048
|
+
def add_blocks_code(res,level)
|
|
1049
|
+
if self.respond_to?(:each_node) then
|
|
1050
|
+
self.each_node do |node|
|
|
1051
|
+
if node.respond_to?(:add_blocks_code) then
|
|
1052
|
+
node.add_blocks_code(res,level)
|
|
1053
|
+
end
|
|
1054
|
+
end
|
|
1055
|
+
end
|
|
1056
|
+
end
|
|
1057
|
+
end
|
|
1058
|
+
|
|
1059
|
+
## Extends the Transmit class with generation of HDLRuby::High text.
|
|
1060
|
+
class Transmit
|
|
1061
|
+
|
|
1062
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
1063
|
+
# +level+ is the hierachical level of the object.
|
|
1064
|
+
def to_c(level = 0)
|
|
1065
|
+
# Save the state of the value pool.
|
|
1066
|
+
res = (" " * ((level)*3))
|
|
1067
|
+
res << "{\n"
|
|
1068
|
+
res << (" " * ((level+1)*3))
|
|
1069
|
+
res << "unsigned int pool_state = get_value_pos();\n"
|
|
1070
|
+
# Perform the copy and the touching only if the new content
|
|
1071
|
+
# is different.
|
|
1072
|
+
res << (" " * ((level+1)*3))
|
|
1073
|
+
# Is it a sequential execution model?
|
|
1074
|
+
seq = self.block.mode == :seq ? "_seq" : ""
|
|
1075
|
+
# Generate the assignment.
|
|
1076
|
+
if (self.left.is_a?(RefName)) then
|
|
1077
|
+
# Direct assignment to a signal, simple transmission.
|
|
1078
|
+
res << "transmit_to_signal#{seq}(#{self.right.to_c(level)},"+
|
|
1079
|
+
"#{self.left.to_c_signal(level)});\n"
|
|
1080
|
+
else
|
|
1081
|
+
# Assignment inside a signal (RefIndex or RefRange).
|
|
1082
|
+
res << "transmit_to_signal_range#{seq}(#{self.right.to_c(level)},"+
|
|
1083
|
+
"#{self.left.to_c_signal(level)});\n"
|
|
1084
|
+
end
|
|
1085
|
+
# Restore the value pool state.
|
|
1086
|
+
res << (" " * ((level+1)*3))
|
|
1087
|
+
res << "set_value_pos(pool_state);\n"
|
|
1088
|
+
res << (" " * ((level)*3))
|
|
1089
|
+
res << "}\n"
|
|
1090
|
+
return res
|
|
1091
|
+
end
|
|
1092
|
+
end
|
|
1093
|
+
|
|
1094
|
+
|
|
1095
|
+
## Extends the If class with generation of HDLRuby::High text.
|
|
1096
|
+
class If
|
|
1097
|
+
|
|
1098
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
1099
|
+
# +level+ is the hierachical level of the object.
|
|
1100
|
+
def to_c(level = 0)
|
|
1101
|
+
# The result string.
|
|
1102
|
+
res = " " * level*3
|
|
1103
|
+
# Compute the condition.
|
|
1104
|
+
res << "{\n"
|
|
1105
|
+
res << " " * (level+1)*3
|
|
1106
|
+
res << "Value cond = " << self.condition.to_c(level+1) << ";\n"
|
|
1107
|
+
# Ensure the condition is testable.
|
|
1108
|
+
res << " " * (level+1)*3
|
|
1109
|
+
res << "if (is_defined_value(cond)) {\n"
|
|
1110
|
+
# The condition is testable.
|
|
1111
|
+
res << " " * (level+2)*3
|
|
1112
|
+
res << "if (value2integer(cond)) {\n"
|
|
1113
|
+
# Generate the yes part.
|
|
1114
|
+
res << self.yes.to_c(level+3)
|
|
1115
|
+
res << " " * level*3
|
|
1116
|
+
res << "}\n"
|
|
1117
|
+
# Generate the alternate if parts.
|
|
1118
|
+
self.each_noif do |cond,stmnt|
|
|
1119
|
+
res << " " * level*3
|
|
1120
|
+
res << "else if (value2integer(" << cond.to_c(level+1) << ")) {\n"
|
|
1121
|
+
res << stmnt.to_c(level+1)
|
|
1122
|
+
res << " " * level*3
|
|
1123
|
+
res << "}\n"
|
|
1124
|
+
end
|
|
1125
|
+
# Generate the no part if any.
|
|
1126
|
+
if self.no then
|
|
1127
|
+
res << " " * level*3
|
|
1128
|
+
res << "else {\n" << self.no.to_c(level+1)
|
|
1129
|
+
res << " " * level*3
|
|
1130
|
+
res << "}\n"
|
|
1131
|
+
end
|
|
1132
|
+
# Close the if.
|
|
1133
|
+
res << " " * (level+1)*3
|
|
1134
|
+
res << "}\n"
|
|
1135
|
+
res << " " * (level)*3
|
|
1136
|
+
res << "}\n"
|
|
1137
|
+
# Return the result.
|
|
1138
|
+
return res
|
|
1139
|
+
end
|
|
1140
|
+
end
|
|
1141
|
+
|
|
1142
|
+
## Extends the When class with generation of HDLRuby::High text.
|
|
1143
|
+
class When
|
|
1144
|
+
|
|
1145
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
1146
|
+
# +level+ is the hierachical level of the object.
|
|
1147
|
+
def to_c(level = 0)
|
|
1148
|
+
# The result string.
|
|
1149
|
+
res = " " * level*3
|
|
1150
|
+
# Generate the match.
|
|
1151
|
+
res << "case " << self.match.to_c(level+1) << ": {\n"
|
|
1152
|
+
# Generate the statement.
|
|
1153
|
+
res << self.statement.to_c(level+1)
|
|
1154
|
+
# Adds a break
|
|
1155
|
+
res << " " * (level+1)*3 << "break;\n"
|
|
1156
|
+
res << " " * level*3 << "}\n"
|
|
1157
|
+
# Returns the result.
|
|
1158
|
+
return res
|
|
1159
|
+
end
|
|
1160
|
+
|
|
1161
|
+
# Adds the c code of the blocks to +res+ at +level+
|
|
1162
|
+
def add_blocks_code(res,level)
|
|
1163
|
+
self.statement.add_blocks_code(res,level)
|
|
1164
|
+
end
|
|
1165
|
+
end
|
|
1166
|
+
|
|
1167
|
+
## Extends the Case class with generation of HDLRuby::High text.
|
|
1168
|
+
class Case
|
|
1169
|
+
|
|
1170
|
+
# Generates the text of the equivalent HDLRuby::High code.
|
|
1171
|
+
# +level+ is the hierachical level of the object.
|
|
1172
|
+
def to_c(level = 0)
|
|
1173
|
+
res = ""
|
|
1174
|
+
# Compute the selection value.
|
|
1175
|
+
res << "{\n"
|
|
1176
|
+
res << " " * (level+1)*3
|
|
1177
|
+
res << "Value value = " << self.value.to_c(level+1) << ";\n"
|
|
1178
|
+
# Ensure the selection value is testable.
|
|
1179
|
+
res << " " * (level+1)*3
|
|
1180
|
+
res << "if (is_defined_value(value)) {\n"
|
|
1181
|
+
# The condition is testable.
|
|
1182
|
+
# Generate the case as a succession of if statements.
|
|
1183
|
+
first = true
|
|
1184
|
+
self.each_when do |w|
|
|
1185
|
+
res << " " * (level+2)*3
|
|
1186
|
+
if first then
|
|
1187
|
+
first = false
|
|
1188
|
+
else
|
|
1189
|
+
res << "else "
|
|
1190
|
+
end
|
|
1191
|
+
res << "if (value2integer(value) == "
|
|
1192
|
+
res << "value2integer(" << w.match.to_c(level+2) << ")) {\n"
|
|
1193
|
+
res << w.statement.to_c(level+3)
|
|
1194
|
+
res << " " * (level+2)*3
|
|
1195
|
+
res << "}\n"
|
|
1196
|
+
end
|
|
1197
|
+
if self.default then
|
|
1198
|
+
res << " " * (level+2)*3
|
|
1199
|
+
res << "else {\n"
|
|
1200
|
+
res << self.default.to_c(level+3)
|
|
1201
|
+
res << " " * (level+2)*3
|
|
1202
|
+
res << "}\n"
|
|
1203
|
+
end
|
|
1204
|
+
# Close the case.
|
|
1205
|
+
res << " " * (level+1)*3
|
|
1206
|
+
res << "}\n"
|
|
1207
|
+
res << " " * (level)*3
|
|
1208
|
+
res << "}\n"
|
|
1209
|
+
# Return the resulting string.
|
|
1210
|
+
return res
|
|
1211
|
+
end
|
|
1212
|
+
end
|
|
1213
|
+
|
|
1214
|
+
|
|
1215
|
+
## Extends the Delay class with generation of HDLRuby::High text.
|
|
1216
|
+
class Delay
|
|
1217
|
+
|
|
1218
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
1219
|
+
# +level+ is the hierachical level of the object.
|
|
1220
|
+
def to_c(level = 0)
|
|
1221
|
+
return "make_delay(#{self.value.to_s}," +
|
|
1222
|
+
"#{Low2C.unit_name(self.unit)})"
|
|
1223
|
+
end
|
|
1224
|
+
end
|
|
1225
|
+
|
|
1226
|
+
|
|
1227
|
+
## Extends the TimeWait class with generation of HDLRuby::High text.
|
|
1228
|
+
class TimeWait
|
|
1229
|
+
|
|
1230
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
1231
|
+
# +level+ is the hierachical level of the object.
|
|
1232
|
+
def to_c(level = 0)
|
|
1233
|
+
# The resulting string.
|
|
1234
|
+
res = " " * level*3
|
|
1235
|
+
# Generate the wait.
|
|
1236
|
+
res << "hw_wait(#{self.delay.to_c(level+1)}," +
|
|
1237
|
+
"#{Low2C.behavior_access(self)});\n"
|
|
1238
|
+
# Return the resulting string.
|
|
1239
|
+
return res
|
|
1240
|
+
end
|
|
1241
|
+
end
|
|
1242
|
+
|
|
1243
|
+
## Extends the TimeRepeat class with generation of HDLRuby::High text.
|
|
1244
|
+
class TimeRepeat
|
|
1245
|
+
|
|
1246
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
1247
|
+
# +level+ is the hierachical level of the object.
|
|
1248
|
+
def to_c(level = 0)
|
|
1249
|
+
# The resulting string.
|
|
1250
|
+
res = " " * level*3
|
|
1251
|
+
# Generate an infinite loop executing the block and waiting.
|
|
1252
|
+
res << "for(;;) {\n"
|
|
1253
|
+
res << "#{self.to_c(level+1)}\n"
|
|
1254
|
+
res = " " * (level+1)*3
|
|
1255
|
+
res << Low2C.wait_code(self,level)
|
|
1256
|
+
# Return the resulting string.
|
|
1257
|
+
return res
|
|
1258
|
+
end
|
|
1259
|
+
end
|
|
1260
|
+
|
|
1261
|
+
## Extends the Block class with generation of HDLRuby::High text.
|
|
1262
|
+
class Block
|
|
1263
|
+
|
|
1264
|
+
# Adds the c code of the blocks to +res+ at +level+
|
|
1265
|
+
def add_blocks_code(res,level)
|
|
1266
|
+
res << self.to_c_code(level)
|
|
1267
|
+
end
|
|
1268
|
+
|
|
1269
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
1270
|
+
# +level+ is the hierachical level of the object.
|
|
1271
|
+
def to_c_code(level = 0)
|
|
1272
|
+
# The resulting string.
|
|
1273
|
+
res = ""
|
|
1274
|
+
# puts "generating self=#{self.object_id}"
|
|
1275
|
+
|
|
1276
|
+
# Declare the global variable holding the block.
|
|
1277
|
+
res << "Block #{Low2C.obj_name(self)};\n\n"
|
|
1278
|
+
|
|
1279
|
+
# Generate the c code of the sub blocks if any.
|
|
1280
|
+
self.each_statement do |stmnt|
|
|
1281
|
+
stmnt.add_blocks_code(res,level)
|
|
1282
|
+
end
|
|
1283
|
+
|
|
1284
|
+
# Generate the execution function.
|
|
1285
|
+
res << " " * level*3
|
|
1286
|
+
res << "void #{Low2C.code_name(self)}() {\n"
|
|
1287
|
+
# res << "printf(\"Executing #{Low2C.code_name(self)}...\\n\");"
|
|
1288
|
+
# Generate the statements.
|
|
1289
|
+
self.each_statement do |stmnt|
|
|
1290
|
+
res << stmnt.to_c(level+1)
|
|
1291
|
+
end
|
|
1292
|
+
# Close the execution function.
|
|
1293
|
+
res << " " * level*3
|
|
1294
|
+
res << "}\n\n"
|
|
1295
|
+
|
|
1296
|
+
|
|
1297
|
+
# Generate the signals.
|
|
1298
|
+
self.each_signal { |signal| res << signal.to_c(level) }
|
|
1299
|
+
|
|
1300
|
+
# The header of the block.
|
|
1301
|
+
res << " " * level*3
|
|
1302
|
+
res << "Block #{Low2C.make_name(self)}() {\n"
|
|
1303
|
+
res << " " * (level+1)*3
|
|
1304
|
+
res << "Block block = malloc(sizeof(BlockS));\n"
|
|
1305
|
+
res << " " * (level+1)*3
|
|
1306
|
+
res << "block->kind = BLOCK;\n";
|
|
1307
|
+
|
|
1308
|
+
# Sets the global variable of the block.
|
|
1309
|
+
res << "\n"
|
|
1310
|
+
res << " " * (level+1)*3
|
|
1311
|
+
res << "#{Low2C.obj_name(self)} = block;\n"
|
|
1312
|
+
|
|
1313
|
+
# Set the owner if any.
|
|
1314
|
+
if self.parent then
|
|
1315
|
+
# Look for a block or behavior parent.
|
|
1316
|
+
true_parent = self.parent
|
|
1317
|
+
until true_parent.is_a?(Block) || true_parent.is_a?(Behavior)
|
|
1318
|
+
true_parent = true_parent.parent
|
|
1319
|
+
end
|
|
1320
|
+
# Set it as the real parent.
|
|
1321
|
+
res << " " * (level+1)*3
|
|
1322
|
+
res << "block->owner = (Object)" +
|
|
1323
|
+
"#{Low2C.obj_name(true_parent)};\n"
|
|
1324
|
+
else
|
|
1325
|
+
res << "block->owner = NULL;\n"
|
|
1326
|
+
end
|
|
1327
|
+
|
|
1328
|
+
# Add the inner signals declaration.
|
|
1329
|
+
res << " " * (level+1)*3
|
|
1330
|
+
res << "block->num_inners = #{self.each_inner.to_a.size};\n"
|
|
1331
|
+
res << " " * (level+1)*3
|
|
1332
|
+
res << "block->inners = calloc(sizeof(SignalI)," +
|
|
1333
|
+
"block->num_inners);\n"
|
|
1334
|
+
self.each_inner.with_index do |inner,i|
|
|
1335
|
+
res << " " * (level+1)*3
|
|
1336
|
+
res << "block->inners[#{i}] = " +
|
|
1337
|
+
"#{Low2C.make_name(inner)}();\n"
|
|
1338
|
+
end
|
|
1339
|
+
|
|
1340
|
+
# Sets the execution function.
|
|
1341
|
+
res << " " * (level+1)*3
|
|
1342
|
+
res << "block->function = &#{Low2C.code_name(self)};\n"
|
|
1343
|
+
|
|
1344
|
+
# Generate the Returns of the result.
|
|
1345
|
+
res << "\n"
|
|
1346
|
+
res << " " * (level+1)*3
|
|
1347
|
+
res << "return block;\n"
|
|
1348
|
+
|
|
1349
|
+
# Close the block.
|
|
1350
|
+
res << " " * level*3
|
|
1351
|
+
res << "};\n\n"
|
|
1352
|
+
return res
|
|
1353
|
+
end
|
|
1354
|
+
|
|
1355
|
+
# Generates the execution of the block C text of the equivalent
|
|
1356
|
+
# HDLRuby::High code.
|
|
1357
|
+
# +level+ is the hierachical level of the object.
|
|
1358
|
+
def to_c(level = 0)
|
|
1359
|
+
res = " " * (level)
|
|
1360
|
+
res << "#{Low2C.code_name(self)}();\n"
|
|
1361
|
+
return res
|
|
1362
|
+
end
|
|
1363
|
+
|
|
1364
|
+
## Generates the content of the h file.
|
|
1365
|
+
def to_ch
|
|
1366
|
+
res = ""
|
|
1367
|
+
# Declare the global variable holding the block.
|
|
1368
|
+
res << "extern Block #{Low2C.obj_name(self)};\n\n"
|
|
1369
|
+
|
|
1370
|
+
# Generate the access to the function making the block. */
|
|
1371
|
+
res << "extern Block #{Low2C.make_name(self)}();\n\n"
|
|
1372
|
+
|
|
1373
|
+
# Generate the accesses to the ports.
|
|
1374
|
+
self.each_inner { |inner| res << inner.to_ch }
|
|
1375
|
+
|
|
1376
|
+
return res
|
|
1377
|
+
end
|
|
1378
|
+
end
|
|
1379
|
+
|
|
1380
|
+
|
|
1381
|
+
## Extends the Block class with generation of HDLRuby::High text.
|
|
1382
|
+
class TimeBlock
|
|
1383
|
+
# TimeBlock is identical to Block in C
|
|
1384
|
+
end
|
|
1385
|
+
|
|
1386
|
+
|
|
1387
|
+
## Extends the Connection class with generation of HDLRuby::High text.
|
|
1388
|
+
class Connection
|
|
1389
|
+
# Nothing required, Transmit is generated identically.
|
|
1390
|
+
end
|
|
1391
|
+
|
|
1392
|
+
|
|
1393
|
+
## Extends the Expression class with generation of HDLRuby::High text.
|
|
1394
|
+
class Expression
|
|
1395
|
+
|
|
1396
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
1397
|
+
# +level+ is the hierachical level of the object.
|
|
1398
|
+
def to_c(level = 0)
|
|
1399
|
+
# Should never be here.
|
|
1400
|
+
raise AnyError, "Internal error: to_c should be implemented in class :#{self.class}"
|
|
1401
|
+
end
|
|
1402
|
+
end
|
|
1403
|
+
|
|
1404
|
+
|
|
1405
|
+
## Extends the Value class with generation of HDLRuby::High text.
|
|
1406
|
+
class Value
|
|
1407
|
+
|
|
1408
|
+
## Generates the C text for an access to the value.
|
|
1409
|
+
# +level+ is the hierachical level of the object.
|
|
1410
|
+
def to_c(level = 0)
|
|
1411
|
+
return "#{Low2C.make_name(self)}()"
|
|
1412
|
+
end
|
|
1413
|
+
|
|
1414
|
+
## Generates the content of the h file.
|
|
1415
|
+
def to_ch
|
|
1416
|
+
res = ""
|
|
1417
|
+
return "extern Value #{Low2C.make_name(self)}();"
|
|
1418
|
+
end
|
|
1419
|
+
|
|
1420
|
+
# Generates the text of the equivalent c.
|
|
1421
|
+
# +level+ is the hierachical level of the object.
|
|
1422
|
+
def to_c_make(level = 0)
|
|
1423
|
+
# The resulting string.
|
|
1424
|
+
res = ""
|
|
1425
|
+
|
|
1426
|
+
# The header of the value generation.
|
|
1427
|
+
res << " " * level*3
|
|
1428
|
+
res << "Value #{Low2C.make_name(self)}() {\n"
|
|
1429
|
+
|
|
1430
|
+
# Declares the data.
|
|
1431
|
+
# Create the bit string.
|
|
1432
|
+
str = self.content.is_a?(BitString) ?
|
|
1433
|
+
self.content.to_s : self.content.to_s(2).rjust(32,"0")
|
|
1434
|
+
# Sign extend.
|
|
1435
|
+
str = str.rjust(self.type.width, self.type.signed ? str[-1] : "0")
|
|
1436
|
+
# Is it a fully defined number?
|
|
1437
|
+
if str =~ /^[01]+$/ then
|
|
1438
|
+
# Yes, generate a numeral value.
|
|
1439
|
+
res << " " * (level+1)*3
|
|
1440
|
+
res << "static unsigned long long data[] = { "
|
|
1441
|
+
res << str.scan(/.{1,#{Low2C.int_width}}/m).map do |sub|
|
|
1442
|
+
sub.to_i(2).to_s + "ULL"
|
|
1443
|
+
end.join(",")
|
|
1444
|
+
res << " };\n"
|
|
1445
|
+
# Create the value.
|
|
1446
|
+
res << " " * (level+1)*3
|
|
1447
|
+
# puts "str=#{str} type width=#{self.type.width}"
|
|
1448
|
+
res << "return make_set_value(#{self.type.to_c(level+1)},1," +
|
|
1449
|
+
"data);\n"
|
|
1450
|
+
else
|
|
1451
|
+
# No, generate a bit string value.
|
|
1452
|
+
res << " " * (level+1)*3
|
|
1453
|
+
res << "static unsigned char data[] = \"#{str}\";\n"
|
|
1454
|
+
# Create the value.
|
|
1455
|
+
res << " " * (level+1)*3
|
|
1456
|
+
res << "return make_set_value(#{self.type.to_c(level+1)},0," +
|
|
1457
|
+
"data);\n"
|
|
1458
|
+
end
|
|
1459
|
+
|
|
1460
|
+
# Close the value.
|
|
1461
|
+
res << " " * level*3
|
|
1462
|
+
res << "}\n\n"
|
|
1463
|
+
# Return the result.
|
|
1464
|
+
return res
|
|
1465
|
+
end
|
|
1466
|
+
end
|
|
1467
|
+
|
|
1468
|
+
## Extends the Cast class with generation of HDLRuby::High text.
|
|
1469
|
+
class Cast
|
|
1470
|
+
|
|
1471
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
1472
|
+
# +level+ is the hierachical level of the object.
|
|
1473
|
+
def to_c(level = 0)
|
|
1474
|
+
res = "({\n"
|
|
1475
|
+
# Overrides the upper src0 and dst...
|
|
1476
|
+
res << (" " * ((level+1)*3))
|
|
1477
|
+
res << "Value src0, dst = get_value();\n"
|
|
1478
|
+
# Save the state of the value pool.
|
|
1479
|
+
res << (" " * ((level+1)*3))
|
|
1480
|
+
res << "unsigned int pool_state = get_value_pos();\n"
|
|
1481
|
+
# Compute the child.
|
|
1482
|
+
res << (" " * ((level+1)*3))
|
|
1483
|
+
res << "src0 = #{self.child.to_c(level+2)};\n"
|
|
1484
|
+
res << (" " * ((level+1)*3))
|
|
1485
|
+
res += "dst = cast_value(src0," +
|
|
1486
|
+
"#{self.type.to_c(level+1)},dst);\n"
|
|
1487
|
+
# Restore the value pool state.
|
|
1488
|
+
res << (" " * ((level+1)*3))
|
|
1489
|
+
res << "set_value_pos(pool_state);\n"
|
|
1490
|
+
# Close the computation
|
|
1491
|
+
res << (" " * (level*3))
|
|
1492
|
+
res << "dst; })"
|
|
1493
|
+
|
|
1494
|
+
return res
|
|
1495
|
+
end
|
|
1496
|
+
end
|
|
1497
|
+
|
|
1498
|
+
|
|
1499
|
+
## Extends the Operation class with generation of HDLRuby::High text.
|
|
1500
|
+
class Operation
|
|
1501
|
+
|
|
1502
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
1503
|
+
# +level+ is the hierachical level of the object.
|
|
1504
|
+
def to_c(level = 0)
|
|
1505
|
+
# Should never be here.
|
|
1506
|
+
raise AnyError, "Internal error: to_c should be implemented in class :#{self.class}"
|
|
1507
|
+
end
|
|
1508
|
+
end
|
|
1509
|
+
|
|
1510
|
+
## Extends the Unary class with generation of HDLRuby::High text.
|
|
1511
|
+
class Unary
|
|
1512
|
+
|
|
1513
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
1514
|
+
# +level+ is the hierachical level of the object.
|
|
1515
|
+
def to_c(level = 0)
|
|
1516
|
+
res = "({\n"
|
|
1517
|
+
# Overrides the upper src0 and dst...
|
|
1518
|
+
res << (" " * ((level+1)*3))
|
|
1519
|
+
res << "Value src0, dst;\n"
|
|
1520
|
+
if (self.operator != :+@) then
|
|
1521
|
+
# And allocates a new value for dst unless the operator
|
|
1522
|
+
# is +@ that does not compute anything.
|
|
1523
|
+
res << (" " * ((level+1)*3))
|
|
1524
|
+
res << "dst = get_value();\n"
|
|
1525
|
+
end
|
|
1526
|
+
# Save the state of the value pool.
|
|
1527
|
+
res << (" " * ((level+1)*3))
|
|
1528
|
+
res << "unsigned int pool_state = get_value_pos();\n"
|
|
1529
|
+
# Compute the child.
|
|
1530
|
+
res << (" " * ((level+1)*3))
|
|
1531
|
+
res << "src0 = #{self.child.to_c(level+2)};\n"
|
|
1532
|
+
res << (" " * ((level+1)*3))
|
|
1533
|
+
case self.operator
|
|
1534
|
+
when :~ then
|
|
1535
|
+
res += "dst = not_value(src0,dst);\n"
|
|
1536
|
+
when :-@ then
|
|
1537
|
+
res += "dst = neg_value(src0,dst);\n"
|
|
1538
|
+
when :+@ then
|
|
1539
|
+
res += "dst = #{self.child.to_c(level)};\n"
|
|
1540
|
+
else
|
|
1541
|
+
raise "Invalid unary operator: #{self.operator}."
|
|
1542
|
+
end
|
|
1543
|
+
# Restore the value pool state.
|
|
1544
|
+
res << (" " * ((level+1)*3))
|
|
1545
|
+
res << "set_value_pos(pool_state);\n"
|
|
1546
|
+
# Close the computation
|
|
1547
|
+
res << (" " * (level*3))
|
|
1548
|
+
res << "dst; })"
|
|
1549
|
+
|
|
1550
|
+
return res
|
|
1551
|
+
end
|
|
1552
|
+
end
|
|
1553
|
+
|
|
1554
|
+
|
|
1555
|
+
## Extends the Binary class with generation of HDLRuby::High text.
|
|
1556
|
+
class Binary
|
|
1557
|
+
|
|
1558
|
+
# # Generates the C text of the equivalent HDLRuby::High code.
|
|
1559
|
+
# # +level+ is the hierachical level of the object.
|
|
1560
|
+
# def to_c(level = 0)
|
|
1561
|
+
# res = ""
|
|
1562
|
+
# case self.operator
|
|
1563
|
+
# when :+ then
|
|
1564
|
+
# return "add_value(#{self.left.to_c(level)}," +
|
|
1565
|
+
# "#{self.right.to_c(level)})"
|
|
1566
|
+
# when :- then
|
|
1567
|
+
# return "sub_value(#{self.left.to_c(level)}," +
|
|
1568
|
+
# "#{self.right.to_c(level)})"
|
|
1569
|
+
# when :* then
|
|
1570
|
+
# return "mul_value(#{self.left.to_c(level)}," +
|
|
1571
|
+
# "#{self.right.to_c(level)})"
|
|
1572
|
+
# when :/ then
|
|
1573
|
+
# return "div_value(#{self.left.to_c(level)}," +
|
|
1574
|
+
# "#{self.right.to_c(level)})"
|
|
1575
|
+
# when :% then
|
|
1576
|
+
# return "mod_value(#{self.left.to_c(level)}," +
|
|
1577
|
+
# "#{self.right.to_c(level)})"
|
|
1578
|
+
# when :** then
|
|
1579
|
+
# return "pow_value(#{self.left.to_c(level)}," +
|
|
1580
|
+
# "#{self.right.to_c(level)})"
|
|
1581
|
+
# when :& then
|
|
1582
|
+
# return "and_value(#{self.left.to_c(level)}," +
|
|
1583
|
+
# "#{self.right.to_c(level)})"
|
|
1584
|
+
# when :| then
|
|
1585
|
+
# return "or_value(#{self.left.to_c(level)}," +
|
|
1586
|
+
# "#{self.right.to_c(level)})"
|
|
1587
|
+
# when :^ then
|
|
1588
|
+
# return "xor_value(#{self.left.to_c(level)}," +
|
|
1589
|
+
# "#{self.right.to_c(level)})"
|
|
1590
|
+
# when :<<,:ls then
|
|
1591
|
+
# return "shift_left_value(#{self.left.to_c(level)}," +
|
|
1592
|
+
# "#{self.right.to_c(level)})"
|
|
1593
|
+
# when :>>,:rs then
|
|
1594
|
+
# return "shift_right_value(#{self.left.to_c(level)}," +
|
|
1595
|
+
# "#{self.right.to_c(level)})"
|
|
1596
|
+
# when :lr then
|
|
1597
|
+
# return "rotate_left_value(#{self.left.to_c(level)}," +
|
|
1598
|
+
# "#{self.right.to_c(level)})"
|
|
1599
|
+
# when :rr then
|
|
1600
|
+
# return "rotate_right_value(#{self.left.to_c(level)}," +
|
|
1601
|
+
# "#{self.right.to_c(level)})"
|
|
1602
|
+
# when :== then
|
|
1603
|
+
# return "equal_value(#{self.left.to_c(level)}," +
|
|
1604
|
+
# "#{self.right.to_c(level)})"
|
|
1605
|
+
# when :!= then
|
|
1606
|
+
# return "not_equal_value(#{self.left.to_c(level)}," +
|
|
1607
|
+
# "#{self.right.to_c(level)})"
|
|
1608
|
+
# when :> then
|
|
1609
|
+
# return "greater_value(#{self.left.to_c(level)}," +
|
|
1610
|
+
# "#{self.right.to_c(level)})"
|
|
1611
|
+
# when :< then
|
|
1612
|
+
# return "lesser_value(#{self.left.to_c(level)}," +
|
|
1613
|
+
# "#{self.right.to_c(level)})"
|
|
1614
|
+
# when :>= then
|
|
1615
|
+
# return "greater_equal_value(#{self.left.to_c(level)}," +
|
|
1616
|
+
# "#{self.right.to_c(level)})"
|
|
1617
|
+
# when :<= then
|
|
1618
|
+
# return "lesser_equal_value(#{self.left.to_c(level)}," +
|
|
1619
|
+
# "#{self.right.to_c(level)})"
|
|
1620
|
+
# else
|
|
1621
|
+
# raise "Invalid binary operator: #{self.operator}."
|
|
1622
|
+
# end
|
|
1623
|
+
# return res
|
|
1624
|
+
# end
|
|
1625
|
+
|
|
1626
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
1627
|
+
# +level+ is the hierachical level of the object.
|
|
1628
|
+
def to_c(level = 0)
|
|
1629
|
+
# res = " " * (level*3)
|
|
1630
|
+
res = "({\n"
|
|
1631
|
+
# Overrides the upper src0, src1 and dst...
|
|
1632
|
+
# And allocates a new value for dst.
|
|
1633
|
+
res << (" " * ((level+1)*3))
|
|
1634
|
+
res << "Value src0,src1,dst = get_value();\n"
|
|
1635
|
+
# Save the state of the value pool.
|
|
1636
|
+
res << (" " * ((level+1)*3))
|
|
1637
|
+
res << "unsigned int pool_state = get_value_pos();\n"
|
|
1638
|
+
# Compute the left.
|
|
1639
|
+
res << (" " * ((level+1)*3))
|
|
1640
|
+
res << "src0 = #{self.left.to_c(level+2)};\n"
|
|
1641
|
+
# Compute the right.
|
|
1642
|
+
res << (" " * ((level+1)*3))
|
|
1643
|
+
res << "src1 = #{self.right.to_c(level+2)};\n"
|
|
1644
|
+
res << (" " * ((level+1)*3))
|
|
1645
|
+
|
|
1646
|
+
# Compute the current binary operation.
|
|
1647
|
+
case self.operator
|
|
1648
|
+
when :+ then
|
|
1649
|
+
res += "dst = add_value(src0,src1,dst);\n"
|
|
1650
|
+
when :- then
|
|
1651
|
+
res += "dst = sub_value(src0,src1,dst);\n"
|
|
1652
|
+
when :* then
|
|
1653
|
+
res += "dst = mul_value(src0,src1,dst);\n"
|
|
1654
|
+
when :/ then
|
|
1655
|
+
res += "dst = div_value(src0,src1,dst);\n"
|
|
1656
|
+
when :% then
|
|
1657
|
+
res += "dst = mod_value(src0,src1,dst);\n"
|
|
1658
|
+
when :** then
|
|
1659
|
+
res += "dst = pow_value(src0,src1,dst);\n"
|
|
1660
|
+
when :& then
|
|
1661
|
+
res += "dst = and_value(src0,src1,dst);\n"
|
|
1662
|
+
when :| then
|
|
1663
|
+
res += "dst = or_value(src0,src1,dst);\n"
|
|
1664
|
+
when :^ then
|
|
1665
|
+
res += "dst = xor_value(src0,src1,dst);\n"
|
|
1666
|
+
when :<<,:ls then
|
|
1667
|
+
res += "dst = shift_left_value(src0,src1,dst);\n"
|
|
1668
|
+
when :>>,:rs then
|
|
1669
|
+
res += "dst = shift_right_value(src0,src1,dst);\n"
|
|
1670
|
+
when :lr then
|
|
1671
|
+
res += "dst = rotate_left_value(src0,src1,dst);\n"
|
|
1672
|
+
when :rr then
|
|
1673
|
+
res += "dst = rotate_right_value(src0,src1,dst);\n"
|
|
1674
|
+
when :== then
|
|
1675
|
+
res += "dst = equal_value(src0,src1,dst);\n"
|
|
1676
|
+
when :!= then
|
|
1677
|
+
res += "dst = not_equal_value(src0,src1,dst);\n"
|
|
1678
|
+
when :> then
|
|
1679
|
+
res += "dst = greater_value(src0,src1,dst);\n"
|
|
1680
|
+
when :< then
|
|
1681
|
+
res += "dst = lesser_value(src0,src1,dst);\n"
|
|
1682
|
+
when :>= then
|
|
1683
|
+
res += "dst = greater_equal_value(src0,src1,dst);\n"
|
|
1684
|
+
when :<= then
|
|
1685
|
+
res += "dst = lesser_equal_value(src0,src1,dst);\n"
|
|
1686
|
+
else
|
|
1687
|
+
raise "Invalid binary operator: #{self.operator}."
|
|
1688
|
+
end
|
|
1689
|
+
# Restore the state of the value pool.
|
|
1690
|
+
res << (" " * ((level+1)*3))
|
|
1691
|
+
res << "set_value_pos(pool_state);\n"
|
|
1692
|
+
# Close the computation.
|
|
1693
|
+
res << (" " * (level*3))
|
|
1694
|
+
res << "dst; })"
|
|
1695
|
+
|
|
1696
|
+
return res
|
|
1697
|
+
end
|
|
1698
|
+
end
|
|
1699
|
+
|
|
1700
|
+
## Extends the Select class with generation of HDLRuby::High text.
|
|
1701
|
+
class Select
|
|
1702
|
+
|
|
1703
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
1704
|
+
# +level+ is the hierachical level of the object.
|
|
1705
|
+
def to_c(level = 0)
|
|
1706
|
+
# res = "select_value(#{self.select.to_c(level)}," +
|
|
1707
|
+
# "#{self.each_choice.to_a.size}"
|
|
1708
|
+
# self.each_choice { |choice| res << ",#{choice.to_c(level)}" }
|
|
1709
|
+
# res << ")"
|
|
1710
|
+
# return res
|
|
1711
|
+
# Gather the possible selection choices.
|
|
1712
|
+
expressions = self.each_choice.to_a
|
|
1713
|
+
# Create the resulting string.
|
|
1714
|
+
# res = " " * (level*3)
|
|
1715
|
+
res = "({\n"
|
|
1716
|
+
# Overrides the upper sel, src0, src1, ..., and dst...
|
|
1717
|
+
# And allocates a new value for dst.
|
|
1718
|
+
res << (" " * ((level+1)*3))
|
|
1719
|
+
res << "Value sel;\n"
|
|
1720
|
+
res << (" " * ((level+1)*3))
|
|
1721
|
+
res << "Value #{expressions.size.times.map do |i|
|
|
1722
|
+
"src#{i}"
|
|
1723
|
+
end.join(",")};\n"
|
|
1724
|
+
res << (" " * ((level+1)*3))
|
|
1725
|
+
res << "Value dst = get_value();\n"
|
|
1726
|
+
# Save the state of the value pool.
|
|
1727
|
+
res << (" " * ((level+1)*3))
|
|
1728
|
+
res << "unsigned int pool_state = get_value_pos();\n"
|
|
1729
|
+
# Compute the selection.
|
|
1730
|
+
res << (" " * ((level+1)*3))
|
|
1731
|
+
res << "sel = #{self.select.to_c(level+2)};\n"
|
|
1732
|
+
# Compute each choice expression.
|
|
1733
|
+
expressions.each_with_index do |expr,i|
|
|
1734
|
+
res << (" " * ((level+1)*3))
|
|
1735
|
+
res << "src#{i} = #{expr.to_c(level+2)};\n"
|
|
1736
|
+
end
|
|
1737
|
+
# Compute the resulting selection.
|
|
1738
|
+
res << (" " * ((level+1)*3))
|
|
1739
|
+
res << "select_value(sel,dst,#{expressions.size},"
|
|
1740
|
+
res << "#{expressions.size.times.map { |i| "src#{i}" }.join(",")}"
|
|
1741
|
+
res << ");\n"
|
|
1742
|
+
# Restore the state of the value pool.
|
|
1743
|
+
res << (" " * ((level+1)*3))
|
|
1744
|
+
res << "set_value_pos(pool_state);\n"
|
|
1745
|
+
# Close the computation.
|
|
1746
|
+
res << (" " * (level*3))
|
|
1747
|
+
res << "dst; })"
|
|
1748
|
+
end
|
|
1749
|
+
end
|
|
1750
|
+
|
|
1751
|
+
## Extends the Concat class with generation of HDLRuby::High text.
|
|
1752
|
+
class Concat
|
|
1753
|
+
|
|
1754
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
1755
|
+
# +level+ is the hierachical level of the object.
|
|
1756
|
+
def to_c(level = 0)
|
|
1757
|
+
# Gather the content to concat.
|
|
1758
|
+
expressions = self.each_expression.to_a
|
|
1759
|
+
# Create the resulting string.
|
|
1760
|
+
# res = " " * (level*3)
|
|
1761
|
+
res = "({\n"
|
|
1762
|
+
# Overrides the upper src0, src1, ..., and dst...
|
|
1763
|
+
# And allocates a new value for dst.
|
|
1764
|
+
res << (" " * ((level+1)*3))
|
|
1765
|
+
res << "Value #{expressions.size.times.map do |i|
|
|
1766
|
+
"src#{i}"
|
|
1767
|
+
end.join(",")};\n"
|
|
1768
|
+
res << (" " * ((level+1)*3))
|
|
1769
|
+
res << "Value dst = get_value();\n"
|
|
1770
|
+
# Save the state of the value pool.
|
|
1771
|
+
res << (" " * ((level+1)*3))
|
|
1772
|
+
res << "unsigned int pool_state = get_value_pos();\n"
|
|
1773
|
+
# Compute each sub expression.
|
|
1774
|
+
expressions.each_with_index do |expr,i|
|
|
1775
|
+
res << (" " * ((level+1)*3))
|
|
1776
|
+
res << "src#{i} = #{expr.to_c(level+2)};\n"
|
|
1777
|
+
end
|
|
1778
|
+
# Compute the direction.
|
|
1779
|
+
# Compute the resulting concatenation.
|
|
1780
|
+
res << (" " * ((level+1)*3))
|
|
1781
|
+
res << "concat_value(#{expressions.size},"
|
|
1782
|
+
res << "#{self.type.direction == :little ? 1 : 0},dst,"
|
|
1783
|
+
res << "#{expressions.size.times.map { |i| "src#{i}" }.join(",")}"
|
|
1784
|
+
res << ");\n"
|
|
1785
|
+
# Restore the state of the value pool.
|
|
1786
|
+
res << (" " * ((level+1)*3))
|
|
1787
|
+
res << "set_value_pos(pool_state);\n"
|
|
1788
|
+
# Close the computation.
|
|
1789
|
+
res << (" " * (level*3))
|
|
1790
|
+
res << "dst; })"
|
|
1791
|
+
|
|
1792
|
+
return res
|
|
1793
|
+
|
|
1794
|
+
end
|
|
1795
|
+
end
|
|
1796
|
+
|
|
1797
|
+
|
|
1798
|
+
## Extends the Ref class with generation of HDLRuby::High text.
|
|
1799
|
+
class Ref
|
|
1800
|
+
|
|
1801
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
1802
|
+
# +level+ is the hierachical level of the object and
|
|
1803
|
+
# +left+ tells if it is a left value or not.
|
|
1804
|
+
def to_c(level = 0, left = false)
|
|
1805
|
+
# Should never be here.
|
|
1806
|
+
raise AnyError, "Internal error: to_c should be implemented in class :#{self.class}"
|
|
1807
|
+
end
|
|
1808
|
+
end
|
|
1809
|
+
|
|
1810
|
+
## Extends the RefConcat class with generation of HDLRuby::High text.
|
|
1811
|
+
class RefConcat
|
|
1812
|
+
|
|
1813
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
1814
|
+
# +level+ is the hierachical level of the object and
|
|
1815
|
+
# +left+ tells if it is a left value or not.
|
|
1816
|
+
def to_c(level = 0, left = false)
|
|
1817
|
+
raise "RefConcat cannot be converted to C directly, please use break_concat_assign!."
|
|
1818
|
+
# # The resulting string.
|
|
1819
|
+
# res = "ref_concat(#{self.each_ref.to_a.size}"
|
|
1820
|
+
# self.each_ref do |ref|
|
|
1821
|
+
# res << ",#{ref.to_c(level,left)}"
|
|
1822
|
+
# end
|
|
1823
|
+
# res << ")"
|
|
1824
|
+
# return res
|
|
1825
|
+
end
|
|
1826
|
+
|
|
1827
|
+
# Generates the C text for reference as left value to a signal.
|
|
1828
|
+
# +level+ is the hierarchical level of the object.
|
|
1829
|
+
def to_c_signal(level = 0)
|
|
1830
|
+
raise "RefConcat cannot be converted to C directly, please use break_concat_assign!."
|
|
1831
|
+
# # The resulting string.
|
|
1832
|
+
# res = "sig_concat(#{self.each_ref.to_a.size}"
|
|
1833
|
+
# self.each_ref do |ref|
|
|
1834
|
+
# res << ",#{ref.to_c_signal(level)}"
|
|
1835
|
+
# end
|
|
1836
|
+
# res << ")"
|
|
1837
|
+
# return res
|
|
1838
|
+
end
|
|
1839
|
+
end
|
|
1840
|
+
|
|
1841
|
+
|
|
1842
|
+
## Extends the RefIndex class with generation of HDLRuby::High text.
|
|
1843
|
+
class RefIndex
|
|
1844
|
+
|
|
1845
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
1846
|
+
# +level+ is thehierachical level of the object and
|
|
1847
|
+
# +left+ tells if it is a left value or not.
|
|
1848
|
+
def to_c(level = 0, left = false)
|
|
1849
|
+
res = "({\n"
|
|
1850
|
+
# And allocates a new value for dst.
|
|
1851
|
+
res << (" " * ((level+1)*3))
|
|
1852
|
+
res << "Value ref,dst = get_value();\n"
|
|
1853
|
+
res << (" " * ((level+1)*3))
|
|
1854
|
+
res << "unsigned long long idx;\n"
|
|
1855
|
+
# Save the state of the value pool.
|
|
1856
|
+
res << (" " * ((level+1)*3))
|
|
1857
|
+
res << "unsigned int pool_state = get_value_pos();\n"
|
|
1858
|
+
# Compute the reference.
|
|
1859
|
+
res << (" " * ((level+1)*3))
|
|
1860
|
+
res << "ref = #{self.ref.to_c(level+2)};\n"
|
|
1861
|
+
# Compute the index.
|
|
1862
|
+
res << (" " * ((level+1)*3))
|
|
1863
|
+
# res << "idx = read64(#{self.index.to_c(level+2)});\n"
|
|
1864
|
+
res << "idx = value2integer(#{self.index.to_c(level+2)});\n"
|
|
1865
|
+
# Make the access.
|
|
1866
|
+
res << (" " * ((level+1)*3))
|
|
1867
|
+
res << "dst = read_range(ref,idx,idx,#{self.ref.type.base.to_c(level)},dst);\n"
|
|
1868
|
+
# Restore the state of the value pool.
|
|
1869
|
+
res << (" " * ((level+1)*3))
|
|
1870
|
+
res << "set_value_pos(pool_state);\n"
|
|
1871
|
+
# Close the computation.
|
|
1872
|
+
res << (" " * (level*3))
|
|
1873
|
+
res << "dst; })"
|
|
1874
|
+
end
|
|
1875
|
+
|
|
1876
|
+
# Generates the C text for reference as left value to a signal.
|
|
1877
|
+
# +level+ is the hierarchical level of the object.
|
|
1878
|
+
def to_c_signal(level = 0)
|
|
1879
|
+
return "make_ref_rangeS(#{self.ref.to_c_signal(level)}," +
|
|
1880
|
+
"value2integer(#{self.index.to_c(level)}),value2integer(#{self.index.to_c(level)}))"
|
|
1881
|
+
end
|
|
1882
|
+
end
|
|
1883
|
+
|
|
1884
|
+
|
|
1885
|
+
## Extends the RefRange class with generation of HDLRuby::High text.
|
|
1886
|
+
class RefRange
|
|
1887
|
+
|
|
1888
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
1889
|
+
# +level+ is the hierachical level of the object and
|
|
1890
|
+
# +left+ tells if it is a left value or not.
|
|
1891
|
+
def to_c(level = 0, left = false)
|
|
1892
|
+
# if left then
|
|
1893
|
+
# res = "write_range(#{self.ref.to_c(level,left)},"
|
|
1894
|
+
# else
|
|
1895
|
+
# res = "read_range(#{self.ref.to_c(level,left)},"
|
|
1896
|
+
# end
|
|
1897
|
+
# res << "read64(#{self.range.first.to_c(level)})," +
|
|
1898
|
+
# "read64(#{self.range.last.to_c(level)})," +
|
|
1899
|
+
# "#{self.type.base.to_c(level)})"
|
|
1900
|
+
# return res
|
|
1901
|
+
# Decide if it is a read or a write
|
|
1902
|
+
command = left ? "write" : "read"
|
|
1903
|
+
res = "({\n"
|
|
1904
|
+
# Overrides the upper ref and dst...
|
|
1905
|
+
# And allocates a new value for dst.
|
|
1906
|
+
res << (" " * ((level+1)*3))
|
|
1907
|
+
res << "Value ref,dst = get_value();\n"
|
|
1908
|
+
res << (" " * ((level+1)*3))
|
|
1909
|
+
res << "unsigned long long first,last;\n"
|
|
1910
|
+
# Save the state of the value pool.
|
|
1911
|
+
res << (" " * ((level+1)*3))
|
|
1912
|
+
res << "unsigned int pool_state = get_value_pos();\n"
|
|
1913
|
+
# Compute the reference.
|
|
1914
|
+
res << (" " * ((level+1)*3))
|
|
1915
|
+
res << "ref = #{self.ref.to_c(level+2)};\n"
|
|
1916
|
+
# Compute the range.
|
|
1917
|
+
res << (" " * ((level+1)*3))
|
|
1918
|
+
# res << "first = read64(#{self.range.first.to_c(level+2)});\n"
|
|
1919
|
+
res << "first = value2integer(#{self.range.first.to_c(level+2)});\n"
|
|
1920
|
+
res << (" " * ((level+1)*3))
|
|
1921
|
+
# res << "last = read64(#{self.range.last.to_c(level+2)});\n"
|
|
1922
|
+
res << "last = value2integer(#{self.range.last.to_c(level+2)});\n"
|
|
1923
|
+
# Make the access.
|
|
1924
|
+
res << (" " * ((level+1)*3))
|
|
1925
|
+
res << "dst = #{command}_range(ref,first,last,#{self.ref.type.base.to_c(level)},dst);\n"
|
|
1926
|
+
# Restore the state of the value pool.
|
|
1927
|
+
res << (" " * ((level+1)*3))
|
|
1928
|
+
res << "set_value_pos(pool_state);\n"
|
|
1929
|
+
# Close the computation.
|
|
1930
|
+
res << (" " * (level*3))
|
|
1931
|
+
res << "dst; })"
|
|
1932
|
+
end
|
|
1933
|
+
|
|
1934
|
+
# Generates the C text for reference as left value to a signal.
|
|
1935
|
+
# +level+ is the hierarchical level of the object.
|
|
1936
|
+
def to_c_signal(level = 0)
|
|
1937
|
+
return to_c(level,true)
|
|
1938
|
+
end
|
|
1939
|
+
end
|
|
1940
|
+
|
|
1941
|
+
## Extends the RefName class with generation of HDLRuby::High text.
|
|
1942
|
+
class RefName
|
|
1943
|
+
|
|
1944
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
1945
|
+
# +level+ is the hierachical level of the object and
|
|
1946
|
+
# +left+ tells if it is a left value or not.
|
|
1947
|
+
def to_c(level = 0, left = false)
|
|
1948
|
+
# puts "RefName to_c for #{self.name}"
|
|
1949
|
+
return "#{self.resolve.to_c_signal(level+1)}->" +
|
|
1950
|
+
(left ? "f_value" : "c_value")
|
|
1951
|
+
end
|
|
1952
|
+
|
|
1953
|
+
# Generates the C text for reference as left value to a signal.
|
|
1954
|
+
# +level+ is the hierarchical level of the object.
|
|
1955
|
+
def to_c_signal(level = 0)
|
|
1956
|
+
return "#{self.resolve.to_c_signal(level+1)}"
|
|
1957
|
+
end
|
|
1958
|
+
end
|
|
1959
|
+
|
|
1960
|
+
## Extends the RefThis class with generation of HDLRuby::High text.
|
|
1961
|
+
class RefThis
|
|
1962
|
+
# Generates the C text of the equivalent HDLRuby::High code.
|
|
1963
|
+
# +level+ is the hierachical level of the object and
|
|
1964
|
+
# +left+ tells if it is a left value or not.
|
|
1965
|
+
def to_c(level = 0, left = false)
|
|
1966
|
+
return "this()"
|
|
1967
|
+
end
|
|
1968
|
+
|
|
1969
|
+
# Generates the C text for reference as left value to a signal.
|
|
1970
|
+
# +level+ is the hierarchical level of the object.
|
|
1971
|
+
def to_c_signal(level = 0)
|
|
1972
|
+
return "this()"
|
|
1973
|
+
end
|
|
1974
|
+
end
|
|
1975
|
+
|
|
1976
|
+
# ## Extends the Numeric class with generation of HDLRuby::High text.
|
|
1977
|
+
# class ::Numeric
|
|
1978
|
+
|
|
1979
|
+
# # Generates the text of the equivalent HDLRuby::High code.
|
|
1980
|
+
# # +level+ is the hierachical level of the object.
|
|
1981
|
+
# def to_c(level = 0)
|
|
1982
|
+
# return self.to_s
|
|
1983
|
+
# end
|
|
1984
|
+
# end
|
|
1985
|
+
|
|
1986
|
+
end
|