HDLRuby 2.0.8
Sign up to get free protection for your applications and to get access to all the features.
- 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,398 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
require "HDLRuby/hruby_bstr"
|
4
|
+
|
5
|
+
|
6
|
+
module HDLRuby
|
7
|
+
|
8
|
+
# Reduce a constant +name+ to +num+ number of namespace levels.
|
9
|
+
def self.const_reduce(name, num = 1)
|
10
|
+
levels = name.split("::")
|
11
|
+
return levels[-([num,levels.size].min)..-1].join("::")
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
# The classes meant to support to_basic.
|
16
|
+
TO_BASICS = [
|
17
|
+
# Low::SystemT, Low::SignalT, Low::Behavior, Low::TimeBehavior,
|
18
|
+
Low::SystemT,
|
19
|
+
Low::Scope,
|
20
|
+
Low::Type, # Low::TypeNumeric,
|
21
|
+
Low::TypeDef,
|
22
|
+
Low::TypeVector,
|
23
|
+
Low::TypeSigned, Low::TypeUnsigned, Low::TypeFloat,
|
24
|
+
Low::TypeTuple, Low::TypeStruct,
|
25
|
+
Low::Behavior, Low::TimeBehavior,
|
26
|
+
Low::Event, Low::Block, Low::TimeBlock, Low::Code,
|
27
|
+
Low::SignalI, Low::SignalC,
|
28
|
+
Low::SystemI, Low::Connection,
|
29
|
+
Low::Transmit, Low::If, Low::Case, Low::When, Low::Cast,
|
30
|
+
Low::TimeWait, Low::TimeRepeat,
|
31
|
+
Low::Delay,
|
32
|
+
# Low::Value, Low::Unary, Low::Binary, Low::Ternary, Low::Concat,
|
33
|
+
Low::Value, Low::Unary, Low::Binary, Low::Select, Low::Concat,
|
34
|
+
Low::RefConcat, Low::RefIndex, Low::RefRange,
|
35
|
+
Low::RefName, Low::RefThis,
|
36
|
+
|
37
|
+
BitString
|
38
|
+
]
|
39
|
+
# The names of the classes of HDLRuby supporting to_basic
|
40
|
+
TO_BASIC_NAMES = TO_BASICS.map { |klass| const_reduce(klass.to_s) }
|
41
|
+
# The classes describing types (must be described only once)
|
42
|
+
TO_BASICS_TYPES = [Low::SystemT,
|
43
|
+
Low::Type, Low::TypeDef,
|
44
|
+
Low::TypeVector, Low::TypeTuple, Low::TypeStruct]
|
45
|
+
|
46
|
+
# The list of fields to exclude from serialization.
|
47
|
+
FIELDS_TO_EXCLUDE = { Low::SystemT => [:@interface,:@parent ] }
|
48
|
+
FIELDS_TO_EXCLUDE.default = [ :@parent ]
|
49
|
+
|
50
|
+
# The list of fields that correspond to reference.
|
51
|
+
FIELDS_OF_REF = { Low::SystemI => [ :@systemT,:@systemTs ] }
|
52
|
+
FIELDS_OF_REF.default = [ :@type ]
|
53
|
+
|
54
|
+
# The name of the reference argument if any.
|
55
|
+
REF_ARG_NAMES = { Low::SystemI => ["systemT","systemTs"],
|
56
|
+
Low::SignalI => ["type"],
|
57
|
+
Low::TypeVector => ["base"],
|
58
|
+
Low::TypeTuple => ["types"],
|
59
|
+
Low::RefThis => ["type"],
|
60
|
+
Low::RefName => ["type"],
|
61
|
+
Low::RefIndex => ["type"],
|
62
|
+
Low::Unary => ["type"],
|
63
|
+
Low::Binary => ["type"],
|
64
|
+
Low::Select => ["type"],
|
65
|
+
Low::Value => ["type"]
|
66
|
+
}
|
67
|
+
|
68
|
+
# The table of the object that can be refered to, used when deserializing.
|
69
|
+
FROM_BASICS_REFS = { }
|
70
|
+
|
71
|
+
# Tells if a +basic+ structure is a representation of an HDLRuby object.
|
72
|
+
def self.is_basic_HDLRuby?(basic)
|
73
|
+
return ( basic.is_a?(Hash) and basic.size == 1 and
|
74
|
+
TO_BASIC_NAMES.include?(HDLRuby.const_reduce(basic.keys[0])) )
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
# Converts a +value+ to a basic structure easy-to-write YAML string.
|
79
|
+
#
|
80
|
+
# Other parameters:
|
81
|
+
# +top+:: indicates if the object is the top of the
|
82
|
+
# description or not. If it is the top, the namespace it comes
|
83
|
+
# from is kept.
|
84
|
+
# +types+:: contains the type objects which will have to be converted
|
85
|
+
# separately.
|
86
|
+
# def self.value_to_basic(value, types = {})
|
87
|
+
# Converts a +value+ to a basic structure easy-to-write YAML string.
|
88
|
+
#
|
89
|
+
# Other parameters:
|
90
|
+
# +ref+:: indicates if the object is a reference or not.
|
91
|
+
# +types+:: contains the type objects which will have to be converted
|
92
|
+
# separately.
|
93
|
+
# +generated+:: is the stack of the generated named objects in the current
|
94
|
+
# context.
|
95
|
+
def self.value_to_basic(ref, value, types = {}, generated = [[]])
|
96
|
+
# Depending on the class.
|
97
|
+
if value.is_a?(Symbol) then
|
98
|
+
# Symbol objects are converted to strings.
|
99
|
+
return value.to_s
|
100
|
+
elsif value.is_a?(String) then
|
101
|
+
# String objects are cloned for avoid side effects.
|
102
|
+
return value.clone
|
103
|
+
elsif value.is_a?(Numeric) or value.is_a?(NilClass) then
|
104
|
+
# Nil and Numeric objects are kept as they are.
|
105
|
+
return value
|
106
|
+
elsif value.is_a?(Range)
|
107
|
+
# Convert to an array made of the converted first and last.
|
108
|
+
return [value_to_basic(ref,value.first,types,generated),
|
109
|
+
value_to_basic(ref,value.last,types,generated)]
|
110
|
+
elsif value.is_a?(Array) then
|
111
|
+
# Arrays are kept as they are, but their content is converted
|
112
|
+
# to basic.
|
113
|
+
return value.map { |elem| value_to_basic(ref,elem,types,generated) }
|
114
|
+
# elsif value.is_a?(Base::HashName) then
|
115
|
+
elsif value.is_a?(Low::HashName) then
|
116
|
+
# Hash name, convert it to an array.
|
117
|
+
return value.map { |v| value_to_basic(ref,v,types,generated) }
|
118
|
+
elsif value.is_a?(Hash) then
|
119
|
+
# Maybe the hash is empty.
|
120
|
+
if value.empty? then
|
121
|
+
return { }
|
122
|
+
end
|
123
|
+
# Convert its content to basic.
|
124
|
+
return value.map do |k,v|
|
125
|
+
[value_to_basic(ref,k,types,generated),
|
126
|
+
value_to_basic(ref,v,types,generated)]
|
127
|
+
end.to_h
|
128
|
+
else
|
129
|
+
# For the other cases, only HDLRuby classes supporting to_basic
|
130
|
+
# are supported.
|
131
|
+
unless TO_BASICS.include?(value.class) then
|
132
|
+
raise AnyError, "Invalid class for converting to basic structure: #{value.class}"
|
133
|
+
end
|
134
|
+
# return value.to_basic(false,types)
|
135
|
+
return value.to_basic(false,ref,types,generated)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
# Convert a +basic+ structure to a ruby object.
|
141
|
+
def self.basic_to_value(basic)
|
142
|
+
# print "For basic=#{basic} (#{basic.class})\n"
|
143
|
+
# Detect which kind of basic struture it is.
|
144
|
+
if basic.is_a?(NilClass) or basic.is_a?(Numeric) or
|
145
|
+
basic.is_a?(Low::Value) then
|
146
|
+
# Nil, Numeric or Value objects are kept as they are.
|
147
|
+
return basic
|
148
|
+
elsif basic.is_a?(Range) then
|
149
|
+
# First and last of range are converted.
|
150
|
+
return basic_to_value(basic.first)..basic_to_value(basic.last)
|
151
|
+
elsif basic.is_a?(String) then
|
152
|
+
# String objects are cloned for avoiding side effects.
|
153
|
+
return basic.clone
|
154
|
+
elsif basic.is_a?(Array) then
|
155
|
+
# Array objects are kept as they are, but their content is converted
|
156
|
+
# to basic.
|
157
|
+
return basic.map { |elem| basic_to_value(elem) }
|
158
|
+
elsif basic.is_a?(Hash) then
|
159
|
+
# Is the hash representing a class?
|
160
|
+
# print "basic.size = #{basic.size}\n"
|
161
|
+
# if basic.size == 1 then
|
162
|
+
# print "name = #{HDLRuby.const_reduce(basic.keys[0])}\n"
|
163
|
+
# end
|
164
|
+
if is_basic_HDLRuby?(basic) then
|
165
|
+
# Yes, rebuild the object.
|
166
|
+
# First get the class.
|
167
|
+
klass = HDLRuby.const_get(basic.keys[0])
|
168
|
+
# print "klass=#{klass}\n"
|
169
|
+
# The the content.
|
170
|
+
content = basic.values[0]
|
171
|
+
# Handle the case of the ranges
|
172
|
+
content.each do |k,v|
|
173
|
+
if k.to_sym == :range and v.is_a?(Array) then
|
174
|
+
content[k] = basic_to_value(v[0])..basic_to_value(v[1])
|
175
|
+
end
|
176
|
+
end
|
177
|
+
# Single instance variables are set with the structure,
|
178
|
+
# separate them from the multiple instances.
|
179
|
+
multiples,singles = content.partition do |k,v|
|
180
|
+
(v.is_a?(Hash) or v.is_a?(Array)) and !is_basic_HDLRuby?(v)
|
181
|
+
end
|
182
|
+
# Create the object.
|
183
|
+
# Get the name of the reference used in the constructor if any
|
184
|
+
ref = REF_ARG_NAMES[klass]
|
185
|
+
# Process the arguments of the object constructor.
|
186
|
+
singles.map! do |k,v|
|
187
|
+
# puts "ref=#{ref} k=#{k} v=#{v}"
|
188
|
+
elem = basic_to_value(v)
|
189
|
+
# puts "elem=#{elem}"
|
190
|
+
# if ref == k and elem.is_a?(String) then
|
191
|
+
if ref and ref.include?(k) and elem.is_a?(String) then
|
192
|
+
# The argument is actually a reference, get the
|
193
|
+
# corresponding object.
|
194
|
+
elem = FROM_BASICS_REFS[elem.to_sym]
|
195
|
+
end
|
196
|
+
# puts "now elem=#{elem}"
|
197
|
+
elem
|
198
|
+
end
|
199
|
+
# Build the object with the processed arguments.
|
200
|
+
# object = klass.new(*singles.map{|k,v| basic_to_value(v) })
|
201
|
+
# puts "klass=#{klass}, singles=#{singles.join("\n")}, multiples=#{multiples.join("\n")}"
|
202
|
+
object = klass.new(*singles)
|
203
|
+
# Adds the multiple instances.
|
204
|
+
multiples.each do |k,v|
|
205
|
+
# puts "k=#{k} v=#{v}"
|
206
|
+
# Construct the add method: add_<key name without ending s>
|
207
|
+
add_meth = ("add_" + k)[0..-2].to_sym
|
208
|
+
# Treat the values a an array.
|
209
|
+
v = v.values if v.is_a?(Hash)
|
210
|
+
# puts "v=#{v}"
|
211
|
+
v.each do |elem|
|
212
|
+
# object.send(add_meth, *basic_to_value(elem) )
|
213
|
+
elem = basic_to_value(elem)
|
214
|
+
# puts "ref=#{ref}, k=#{k}"
|
215
|
+
# puts "to add elem=#{elem}"
|
216
|
+
# if ref == k and elem.is_a?(String) then
|
217
|
+
if ref and ref.include?(k) and elem.is_a?(String) then
|
218
|
+
# The argument is actually a reference, get the
|
219
|
+
# corresponding object.
|
220
|
+
elem = FROM_BASICS_REFS[elem.to_sym]
|
221
|
+
end
|
222
|
+
# puts "adding elem=#{elem} to object=#{object}" if elem.is_a?(SystemT)
|
223
|
+
# In general it is enough to add the element to
|
224
|
+
# the object. However, in the case of a systemI,
|
225
|
+
# the main systemT is added to the list at
|
226
|
+
# the creation of the SystemI and is therefore
|
227
|
+
# not to be added.
|
228
|
+
if !object.is_a?(SystemI) || object.systemT != elem
|
229
|
+
object.send(add_meth, *elem )
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
# Store the objects if it is named.
|
234
|
+
if object.respond_to?(:name) then
|
235
|
+
# puts "Registering name=#{object.name} with #{object}"
|
236
|
+
FROM_BASICS_REFS[object.name] = object
|
237
|
+
end
|
238
|
+
# Returns the resulting object.
|
239
|
+
return object
|
240
|
+
else
|
241
|
+
# No, this a standard hash, keep it as is but convert its
|
242
|
+
# contents.
|
243
|
+
return basic.map do |k,v|
|
244
|
+
[ basic_to_value(k), basic_to_value(v) ]
|
245
|
+
end.to_h
|
246
|
+
end
|
247
|
+
else
|
248
|
+
# Other cases should happen.
|
249
|
+
raise AnyError, "Invalid class for a basic object: #{basic.class}."
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
|
254
|
+
# Convert a stream to a HDLRuby list of objects.
|
255
|
+
def self.from_yaml(stream)
|
256
|
+
# Get the basic structure from the stream.
|
257
|
+
basic = YAML.load_stream(stream)
|
258
|
+
# Convert the basic structure to HDLRuby objects.
|
259
|
+
return basic_to_value(basic)
|
260
|
+
end
|
261
|
+
|
262
|
+
#
|
263
|
+
# Module adding serialization capability to HDLRuby classes
|
264
|
+
###########################################################
|
265
|
+
module Serializer
|
266
|
+
|
267
|
+
# Converts the object to a basic structure which can be dumped into an
|
268
|
+
# easy-to-write YAML string.
|
269
|
+
#
|
270
|
+
# Other parameters:
|
271
|
+
# +top+:: indicates if the object is the top of the
|
272
|
+
# description or not. If it is the top, the namespace it comes
|
273
|
+
# from is kept.
|
274
|
+
# +types+:: contains the type objects which will have to be converted
|
275
|
+
# separately.
|
276
|
+
# def to_basic(top = true, types = {})
|
277
|
+
# Converts the object to a basic structure which can be dumped into an
|
278
|
+
# easy-to-write YAML string.
|
279
|
+
#
|
280
|
+
# Other parameters:
|
281
|
+
# +top+:: indicates if the object is the top of the
|
282
|
+
# description or not. If it is the top, the namespace it comes
|
283
|
+
# from is kept.
|
284
|
+
# +ref+:: indicates if the object is a reference or not.
|
285
|
+
# If it is a reference, its generation is to be skipped
|
286
|
+
# for later.
|
287
|
+
# +types+:: contains the type objects which will have to be converted
|
288
|
+
# separately.
|
289
|
+
# +generated+:: is the stack of the generated named objects in the
|
290
|
+
# current context.
|
291
|
+
def to_basic(top = true, ref = false, types = {}, generated = [[]])
|
292
|
+
# if !top and TO_BASICS_TYPES.include?(self.class) and
|
293
|
+
# Ensure it is a initial ref: if the object has no name
|
294
|
+
# it is the case.
|
295
|
+
if ref then
|
296
|
+
ref = self.respond_to?(:name) && !self.name.empty?
|
297
|
+
end
|
298
|
+
# Process the object
|
299
|
+
if !top and ref then
|
300
|
+
# Refered object, but not the top, add it to the types list
|
301
|
+
# without converting it if not already generated.
|
302
|
+
unless generated.flatten.include?(self.name)
|
303
|
+
# puts "Adding type with name=#{self.name}\n"
|
304
|
+
types[self.name] = self
|
305
|
+
end
|
306
|
+
# puts "types=#{types}"
|
307
|
+
# And return the name.
|
308
|
+
return self.name.to_s
|
309
|
+
end
|
310
|
+
# puts "generating #{self.class} with name=#{self.name}\n" if self.respond_to?(:name)
|
311
|
+
# Self is generated, remove it from the types to generate.
|
312
|
+
generated[-1] << self.name if self.respond_to?(:name)
|
313
|
+
# Add a level to the stack of generated named objects.
|
314
|
+
generated << []
|
315
|
+
# print "to_basic for class=#{self.class}\n"
|
316
|
+
# Create the hash which will contains the content of the object.
|
317
|
+
content = { }
|
318
|
+
# Create the resulting hash with a single entry whose key
|
319
|
+
# is the class name and whose value is the content of the
|
320
|
+
# object.
|
321
|
+
class_name = self.class.to_s
|
322
|
+
# Keep only the class name
|
323
|
+
class_name = HDLRuby.const_reduce(class_name)
|
324
|
+
|
325
|
+
result = { class_name => content }
|
326
|
+
# Fills the contents with the instance variables value.
|
327
|
+
self.instance_variables.each do |var_sym|
|
328
|
+
# Skip the fields that should not be serialized
|
329
|
+
# next if var_sym == :@parent # Now added to FIELDS_TO_EXCLUDE
|
330
|
+
next if (FIELDS_TO_EXCLUDE[self.class] and
|
331
|
+
FIELDS_TO_EXCLUDE[self.class].include?(var_sym) )
|
332
|
+
# print "for instance variable #{var_sym}...\n"
|
333
|
+
# Skip the parent.
|
334
|
+
# Get the value of the variable.
|
335
|
+
var_val = self.instance_variable_get(var_sym)
|
336
|
+
# Sets the content.
|
337
|
+
# content[var_sym] = HDLRuby.value_to_basic(var_val,types)
|
338
|
+
value = HDLRuby.value_to_basic(
|
339
|
+
# FIELDS_OF_REF[self.class].include?(var_sym) &&
|
340
|
+
# var_val.respond_to?(:name) && !var_val.name.empty?,
|
341
|
+
FIELDS_OF_REF[self.class].include?(var_sym),
|
342
|
+
var_val, types,generated)
|
343
|
+
# Remove the @ from the symbol.
|
344
|
+
var_sym = var_sym.to_s[1..-1]
|
345
|
+
# EMPTY VALUES ARE NOT SKIPPED
|
346
|
+
# # Empty values are skipped
|
347
|
+
# unless value.respond_to?(:empty?) and value.empty? then
|
348
|
+
# content[var_sym] = value
|
349
|
+
# end
|
350
|
+
content[var_sym] = value
|
351
|
+
end
|
352
|
+
|
353
|
+
if top and !types.empty? then
|
354
|
+
# It is a top and there where types.
|
355
|
+
# The result is a sequence including each type and the
|
356
|
+
# current object.
|
357
|
+
result = [ result ]
|
358
|
+
# Sort the type so that data types comes first.
|
359
|
+
to_treat = types.each.partition {|name,type| !type.is_a?(Type) }
|
360
|
+
to_treat.flatten!(1)
|
361
|
+
while !to_treat.empty?
|
362
|
+
others = {}
|
363
|
+
to_treat.each do |name,type|
|
364
|
+
# print "Dumping type with name=#{name}\n"
|
365
|
+
# type_basic = type.to_basic(true)
|
366
|
+
type_basic = type.to_basic(true,others)
|
367
|
+
type_basic = type_basic.last if type_basic.is_a?(Array)
|
368
|
+
result.unshift(type_basic)
|
369
|
+
end
|
370
|
+
to_treat = others
|
371
|
+
end
|
372
|
+
|
373
|
+
end
|
374
|
+
|
375
|
+
# Restore the stack of generated named objets.
|
376
|
+
generated.pop
|
377
|
+
|
378
|
+
# Return the resulting hash.
|
379
|
+
return result
|
380
|
+
end
|
381
|
+
|
382
|
+
# Converts the object to YAML string.
|
383
|
+
def to_yaml
|
384
|
+
# Convert the object to basic representations
|
385
|
+
basics = to_basic
|
386
|
+
# puts "basics=#{basics}"
|
387
|
+
basics = [ basics ] unless basics.is_a?(Array)
|
388
|
+
# Remove duplicate descriptions
|
389
|
+
basics.uniq! { |elem| elem.first[1]["name"] }
|
390
|
+
# Convert the basic representations to YAML
|
391
|
+
return YAML.dump_stream(*basics)
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
|
396
|
+
# Adds the serializing features to the HDLRuby classes supporting to_basic.
|
397
|
+
TO_BASICS.each { |klass| klass.include(Serializer) }
|
398
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
|
2
|
+
module HDLRuby
|
3
|
+
|
4
|
+
##
|
5
|
+
# General tools for handling HDLRuby objects
|
6
|
+
#######################################################
|
7
|
+
|
8
|
+
|
9
|
+
# Method and attribute for generating an absolute uniq name.
|
10
|
+
# Such names cannot be used in HDLRuby::High code, but can be used
|
11
|
+
# to generate such code.
|
12
|
+
|
13
|
+
@@absoluteCounter = -1 # The absolute name counter.
|
14
|
+
|
15
|
+
# Generates an absolute uniq name.
|
16
|
+
def self.uniq_name
|
17
|
+
@@absoluteCounter += 1
|
18
|
+
name = ":#{@@absoluteCounter}"
|
19
|
+
if Symbol.all_symbols.find {|symbol| symbol.to_s == name } then
|
20
|
+
# The symbol exists, try again.
|
21
|
+
return self.uniq_name
|
22
|
+
else
|
23
|
+
return name.to_sym
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
# Extends the Integer class for computing the bit width.
|
29
|
+
class ::Integer
|
30
|
+
|
31
|
+
# Gets the bit width
|
32
|
+
def width
|
33
|
+
return Math.log2(self+1).ceil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,239 @@
|
|
1
|
+
module HDLRuby
|
2
|
+
|
3
|
+
##
|
4
|
+
# Library for imnplementing the type processing
|
5
|
+
#
|
6
|
+
########################################################################
|
7
|
+
|
8
|
+
|
9
|
+
# To include to classes for type processing support.
|
10
|
+
module Tprocess
|
11
|
+
|
12
|
+
# Creates a new generic vector type named +name+ from +base+ type and
|
13
|
+
# with +range+.
|
14
|
+
# NOTE: used for type processing.
|
15
|
+
def make(name,base,range)
|
16
|
+
# Generate a vector or a scalar type depending on the range.
|
17
|
+
# First for checking the rangem ensures the bounds are Ruby
|
18
|
+
# values.
|
19
|
+
first = range.first
|
20
|
+
last = range.last
|
21
|
+
first = first.content if first.is_a?(Value)
|
22
|
+
last = last.content if last.is_a?(Value)
|
23
|
+
# Necessarily a TypeVector, since [0..0] has actually a
|
24
|
+
# different meaning from [0]!
|
25
|
+
# # Now can compare at Ruby level (and not HDLRuby level).
|
26
|
+
# if first == last then
|
27
|
+
# # Single-element, return the base.
|
28
|
+
# return base
|
29
|
+
# else
|
30
|
+
# # Multiple elements, create a new type vector.
|
31
|
+
# return TypeVector.new(name,base,range)
|
32
|
+
# end
|
33
|
+
return TypeVector.new(name,base,range)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Type resolution: decide which class to use for representing
|
37
|
+
# a computating result with +type+.
|
38
|
+
def resolve(type)
|
39
|
+
# puts "self=#{self} type=#{type}"
|
40
|
+
if self.float? then
|
41
|
+
return self
|
42
|
+
elsif type.float? then
|
43
|
+
return type
|
44
|
+
elsif self.signed? then
|
45
|
+
return self
|
46
|
+
elsif type.signed? then
|
47
|
+
return type
|
48
|
+
elsif self.unsigned? then
|
49
|
+
return self
|
50
|
+
elsif type.unsigned? then
|
51
|
+
return type
|
52
|
+
elsif self.width >= type.width then
|
53
|
+
return self
|
54
|
+
else
|
55
|
+
return type
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Range access with +idx+
|
60
|
+
# NOTE:
|
61
|
+
# - +idx+ may be a range.
|
62
|
+
# - Do not use the [] operator for this since it is used for
|
63
|
+
# defining vector types!
|
64
|
+
def slice(idx)
|
65
|
+
if idx.is_a?(Range) then
|
66
|
+
# Make a resized vector.
|
67
|
+
return make(:"",self.base,idx)
|
68
|
+
else
|
69
|
+
# Return the base type.
|
70
|
+
return self.base
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
# Arithmetic operations
|
76
|
+
|
77
|
+
# Addition.
|
78
|
+
def +(type)
|
79
|
+
# Resolve the type class.
|
80
|
+
resolved = self.resolve(type)
|
81
|
+
# New type range: largest range + 1
|
82
|
+
bounds = [ self.range.first.to_i, type.range.first.to_i,
|
83
|
+
self.range.last.to_i, type.range.last.to_i ]
|
84
|
+
res_lsb = bounds.min
|
85
|
+
res_msb = bounds.max + 1
|
86
|
+
# Create and return the new type: its endianess is the one of self
|
87
|
+
if self.range.first.to_i > self.range.last.to_i then
|
88
|
+
return resolved.make(:"",resolved.base,res_msb..res_lsb)
|
89
|
+
else
|
90
|
+
return resolved.make(:"",resolved.base,res_lsb..res_msb)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Subtraction
|
95
|
+
alias_method :-, :+
|
96
|
+
|
97
|
+
# Multiplication
|
98
|
+
def *(type)
|
99
|
+
# Resolve the type class.
|
100
|
+
resolved = self.resolve(type)
|
101
|
+
# New type range: largest range * 2
|
102
|
+
bounds = [ self.range.first.to_i, type.range.first.to_i,
|
103
|
+
self.range.last.to_i, type.range.last.to_i ]
|
104
|
+
res_lsb = bounds.min
|
105
|
+
res_msb = bounds.max * 2
|
106
|
+
# Create and return the new type: its endianess is the one of self
|
107
|
+
if self.range.first.to_i > self.range.last.to_i then
|
108
|
+
return resolved.make(:"",resolved.base,res_msb..res_lsb)
|
109
|
+
else
|
110
|
+
return resolved.make(:"",resolved.base,res_lsb..res_msb)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Division
|
115
|
+
def /(type)
|
116
|
+
# Resolve the type class.
|
117
|
+
resolved = self.resolve(type)
|
118
|
+
# New type range: largest range
|
119
|
+
bounds = [ self.range.first.to_i, type.range.first.to_i,
|
120
|
+
self.range.last.to_i, type.range.last.to_i ]
|
121
|
+
res_lsb = bounds.min
|
122
|
+
res_msb = bounds.max
|
123
|
+
# Create and return the new type: its endianess is the one of self
|
124
|
+
if self.range.first.to_i > self.range.last.to_i then
|
125
|
+
return resolved.make(:"",resolved.base,res_msb..res_lsb)
|
126
|
+
else
|
127
|
+
return resolved.make(:"",resolved.base,res_lsb..res_msb)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# Modulo
|
132
|
+
alias_method :%, :/
|
133
|
+
|
134
|
+
# Positive
|
135
|
+
def +@()
|
136
|
+
return self
|
137
|
+
end
|
138
|
+
|
139
|
+
# Negative
|
140
|
+
def -@()
|
141
|
+
return self
|
142
|
+
end
|
143
|
+
|
144
|
+
# Absolute value
|
145
|
+
def abs()
|
146
|
+
return self
|
147
|
+
end
|
148
|
+
|
149
|
+
# Logical operations and comparisons
|
150
|
+
|
151
|
+
|
152
|
+
# And
|
153
|
+
def &(type)
|
154
|
+
# puts "compute types with=#{self} and #{type}"
|
155
|
+
# Resolve the type class.
|
156
|
+
resolved = self.resolve(type)
|
157
|
+
|
158
|
+
# Logical operation on non-vector types are kept as is.
|
159
|
+
return resolved unless resolved.is_a?(TypeVector)
|
160
|
+
|
161
|
+
# Otherwise the range is computed.
|
162
|
+
# New type range: largest range
|
163
|
+
bounds = [ self.range.first.to_i, type.range.first.to_i,
|
164
|
+
self.range.last.to_i, type.range.last.to_i ]
|
165
|
+
# puts "bounds=#{bounds}"
|
166
|
+
res_lsb = bounds.min
|
167
|
+
res_msb = bounds.max
|
168
|
+
# Create and return the new type: its endianess is the one of self
|
169
|
+
if self.range.first.to_i > self.range.last.to_i then
|
170
|
+
return resolved.make(:"",resolved.base,res_msb..res_lsb)
|
171
|
+
else
|
172
|
+
return resolved.make(:"",resolved.base,res_lsb..res_msb)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# Or
|
177
|
+
alias_method :|, :&
|
178
|
+
|
179
|
+
# Xor
|
180
|
+
alias_method :^, :&
|
181
|
+
|
182
|
+
# Not
|
183
|
+
def ~()
|
184
|
+
return self
|
185
|
+
end
|
186
|
+
|
187
|
+
# Equals
|
188
|
+
# alias_method :==, :&
|
189
|
+
def ==(type)
|
190
|
+
return Bit
|
191
|
+
end
|
192
|
+
alias_method :!=, :==
|
193
|
+
|
194
|
+
# Inferior
|
195
|
+
alias_method :<, :&
|
196
|
+
|
197
|
+
# Superior
|
198
|
+
alias_method :>, :&
|
199
|
+
|
200
|
+
# Inferior or equal
|
201
|
+
alias_method :<=, :&
|
202
|
+
|
203
|
+
# Superior or equal
|
204
|
+
alias_method :>=, :&
|
205
|
+
|
206
|
+
# Comparison
|
207
|
+
alias_method :<=>, :&
|
208
|
+
|
209
|
+
|
210
|
+
# Shifts
|
211
|
+
|
212
|
+
# Shift left
|
213
|
+
def <<(type)
|
214
|
+
# The result type is the type of left.
|
215
|
+
resolved = self
|
216
|
+
# New type range: 2**(type width) times self range
|
217
|
+
bounds = [ self.range.first.to_i, self.range.last.to_i ]
|
218
|
+
res_lsb = bounds.min
|
219
|
+
res_msb = bounds.max +
|
220
|
+
(2 ** ((type.range.last-type.range.first).abs))
|
221
|
+
# Create and return the new type: its endianess is the one of self
|
222
|
+
if self.range.first.to_i > self.range.last.to_i then
|
223
|
+
return resolved.make(:"",resolved.base,res_msb..res_lsb)
|
224
|
+
else
|
225
|
+
return resolved.make(:"",resolved.base,res_lsb..res_msb)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
# Shift right
|
230
|
+
alias_method :>>, :<<
|
231
|
+
|
232
|
+
|
233
|
+
end
|
234
|
+
|
235
|
+
|
236
|
+
|
237
|
+
|
238
|
+
|
239
|
+
end
|