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.
Files changed (224) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +5 -0
  4. data/.yardopts +1 -0
  5. data/Gemfile +4 -0
  6. data/HDLRuby.gemspec +36 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +2774 -0
  9. data/README.pdf +0 -0
  10. data/Rakefile +10 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/exe/hdrcc +3 -0
  14. data/lib/HDLRuby/alcc.rb +137 -0
  15. data/lib/HDLRuby/backend/hruby_allocator.rb +69 -0
  16. data/lib/HDLRuby/backend/hruby_c_allocator.rb +76 -0
  17. data/lib/HDLRuby/hdr_samples/adder.rb +7 -0
  18. data/lib/HDLRuby/hdr_samples/adder_assign_error.rb +11 -0
  19. data/lib/HDLRuby/hdr_samples/adder_bench.rb +27 -0
  20. data/lib/HDLRuby/hdr_samples/adder_gen.rb +7 -0
  21. data/lib/HDLRuby/hdr_samples/adder_nodef_error.rb +7 -0
  22. data/lib/HDLRuby/hdr_samples/addsub.rb +19 -0
  23. data/lib/HDLRuby/hdr_samples/addsubz.rb +22 -0
  24. data/lib/HDLRuby/hdr_samples/alu.rb +47 -0
  25. data/lib/HDLRuby/hdr_samples/calculator.rb +48 -0
  26. data/lib/HDLRuby/hdr_samples/counter_bench.rb +83 -0
  27. data/lib/HDLRuby/hdr_samples/dff.rb +9 -0
  28. data/lib/HDLRuby/hdr_samples/dff_bench.rb +66 -0
  29. data/lib/HDLRuby/hdr_samples/dff_counter.rb +20 -0
  30. data/lib/HDLRuby/hdr_samples/include.rb +14 -0
  31. data/lib/HDLRuby/hdr_samples/instance_open.rb +23 -0
  32. data/lib/HDLRuby/hdr_samples/mei8.rb +256 -0
  33. data/lib/HDLRuby/hdr_samples/mei8_bench.rb +309 -0
  34. data/lib/HDLRuby/hdr_samples/multer_gen.rb +8 -0
  35. data/lib/HDLRuby/hdr_samples/multer_seq.rb +29 -0
  36. data/lib/HDLRuby/hdr_samples/neural/a.rb +9 -0
  37. data/lib/HDLRuby/hdr_samples/neural/a_sub.rb +5 -0
  38. data/lib/HDLRuby/hdr_samples/neural/bw.rb +23 -0
  39. data/lib/HDLRuby/hdr_samples/neural/counter.rb +16 -0
  40. data/lib/HDLRuby/hdr_samples/neural/dadz.rb +9 -0
  41. data/lib/HDLRuby/hdr_samples/neural/dadz_sub.rb +4 -0
  42. data/lib/HDLRuby/hdr_samples/neural/forward.rb +153 -0
  43. data/lib/HDLRuby/hdr_samples/neural/forward_sub.rb +62 -0
  44. data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand.rb +41 -0
  45. data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand_typedef.rb +47 -0
  46. data/lib/HDLRuby/hdr_samples/neural/mem.rb +30 -0
  47. data/lib/HDLRuby/hdr_samples/neural/random.rb +23 -0
  48. data/lib/HDLRuby/hdr_samples/neural/selector.rb +29 -0
  49. data/lib/HDLRuby/hdr_samples/neural/sigmoid.rb +20 -0
  50. data/lib/HDLRuby/hdr_samples/neural/z.rb +33 -0
  51. data/lib/HDLRuby/hdr_samples/prog.obj +256 -0
  52. data/lib/HDLRuby/hdr_samples/ram.rb +18 -0
  53. data/lib/HDLRuby/hdr_samples/register_with_code_bench.rb +98 -0
  54. data/lib/HDLRuby/hdr_samples/rom.rb +10 -0
  55. data/lib/HDLRuby/hdr_samples/struct.rb +14 -0
  56. data/lib/HDLRuby/hdr_samples/sumprod.rb +29 -0
  57. data/lib/HDLRuby/hdr_samples/sw_encrypt_bench.rb +103 -0
  58. data/lib/HDLRuby/hdr_samples/sw_encrypt_cpu_bench.rb +261 -0
  59. data/lib/HDLRuby/hdr_samples/sw_encrypt_cpusim_bench.rb +302 -0
  60. data/lib/HDLRuby/hdr_samples/system_open.rb +11 -0
  61. data/lib/HDLRuby/hdr_samples/tuple.rb +16 -0
  62. data/lib/HDLRuby/hdr_samples/with_channel.rb +118 -0
  63. data/lib/HDLRuby/hdr_samples/with_class.rb +199 -0
  64. data/lib/HDLRuby/hdr_samples/with_decoder.rb +17 -0
  65. data/lib/HDLRuby/hdr_samples/with_fsm.rb +34 -0
  66. data/lib/HDLRuby/hdr_samples/with_reconf.rb +103 -0
  67. data/lib/HDLRuby/hdrcc.rb +623 -0
  68. data/lib/HDLRuby/high_samples/_adder_fault.rb +23 -0
  69. data/lib/HDLRuby/high_samples/_generic_transmission2.rb +146 -0
  70. data/lib/HDLRuby/high_samples/adder.rb +21 -0
  71. data/lib/HDLRuby/high_samples/adder_common_errors.rb +25 -0
  72. data/lib/HDLRuby/high_samples/addsub.rb +33 -0
  73. data/lib/HDLRuby/high_samples/addsubz.rb +37 -0
  74. data/lib/HDLRuby/high_samples/after.rb +28 -0
  75. data/lib/HDLRuby/high_samples/all_signals.rb +29 -0
  76. data/lib/HDLRuby/high_samples/alu.rb +61 -0
  77. data/lib/HDLRuby/high_samples/anonymous.rb +41 -0
  78. data/lib/HDLRuby/high_samples/before.rb +28 -0
  79. data/lib/HDLRuby/high_samples/blockblock.rb +26 -0
  80. data/lib/HDLRuby/high_samples/bugs/dadz.rb +22 -0
  81. data/lib/HDLRuby/high_samples/bugs/misample_instan.rb +20 -0
  82. data/lib/HDLRuby/high_samples/bugs/misample_updown.rb +22 -0
  83. data/lib/HDLRuby/high_samples/bugs/sample_add.rb +16 -0
  84. data/lib/HDLRuby/high_samples/bugs/sample_barrel.rb +13 -0
  85. data/lib/HDLRuby/high_samples/bugs/sample_daice.rb +57 -0
  86. data/lib/HDLRuby/high_samples/bugs/sample_kumiawase.rb +52 -0
  87. data/lib/HDLRuby/high_samples/bugs/sample_multi.rb +18 -0
  88. data/lib/HDLRuby/high_samples/bugs/sample_sub.rb +14 -0
  89. data/lib/HDLRuby/high_samples/bugs/z2.rb +32 -0
  90. data/lib/HDLRuby/high_samples/case.rb +32 -0
  91. data/lib/HDLRuby/high_samples/case2.rb +30 -0
  92. data/lib/HDLRuby/high_samples/change.rb +23 -0
  93. data/lib/HDLRuby/high_samples/clocks.rb +35 -0
  94. data/lib/HDLRuby/high_samples/comparer.rb +21 -0
  95. data/lib/HDLRuby/high_samples/conditionals.rb +29 -0
  96. data/lib/HDLRuby/high_samples/dff.rb +23 -0
  97. data/lib/HDLRuby/high_samples/each.rb +28 -0
  98. data/lib/HDLRuby/high_samples/exporter.rb +42 -0
  99. data/lib/HDLRuby/high_samples/functions.rb +60 -0
  100. data/lib/HDLRuby/high_samples/if_seq.rb +26 -0
  101. data/lib/HDLRuby/high_samples/inherit_as_dff.rb +32 -0
  102. data/lib/HDLRuby/high_samples/inherit_dff.rb +36 -0
  103. data/lib/HDLRuby/high_samples/instance.rb +37 -0
  104. data/lib/HDLRuby/high_samples/memory.rb +64 -0
  105. data/lib/HDLRuby/high_samples/multi_file.rb +27 -0
  106. data/lib/HDLRuby/high_samples/overload.rb +32 -0
  107. data/lib/HDLRuby/high_samples/paper_after.rb +49 -0
  108. data/lib/HDLRuby/high_samples/ram.rb +27 -0
  109. data/lib/HDLRuby/high_samples/registers.rb +139 -0
  110. data/lib/HDLRuby/high_samples/rom.rb +23 -0
  111. data/lib/HDLRuby/high_samples/scopeblockname.rb +37 -0
  112. data/lib/HDLRuby/high_samples/scopescope.rb +26 -0
  113. data/lib/HDLRuby/high_samples/shift.rb +31 -0
  114. data/lib/HDLRuby/high_samples/shift2.rb +40 -0
  115. data/lib/HDLRuby/high_samples/simple_instance.rb +31 -0
  116. data/lib/HDLRuby/high_samples/test_all.sh +10 -0
  117. data/lib/HDLRuby/high_samples/typedef.rb +24 -0
  118. data/lib/HDLRuby/high_samples/values.rb +70 -0
  119. data/lib/HDLRuby/high_samples/vector.rb +22 -0
  120. data/lib/HDLRuby/high_samples/with_decoder.rb +30 -0
  121. data/lib/HDLRuby/high_samples/with_fsm.rb +46 -0
  122. data/lib/HDLRuby/high_samples/with_pipe.rb +43 -0
  123. data/lib/HDLRuby/high_samples/with_seq.rb +25 -0
  124. data/lib/HDLRuby/hruby_bstr.rb +1085 -0
  125. data/lib/HDLRuby/hruby_check.rb +317 -0
  126. data/lib/HDLRuby/hruby_db.rb +432 -0
  127. data/lib/HDLRuby/hruby_error.rb +44 -0
  128. data/lib/HDLRuby/hruby_high.rb +4103 -0
  129. data/lib/HDLRuby/hruby_low.rb +4735 -0
  130. data/lib/HDLRuby/hruby_low2c.rb +1986 -0
  131. data/lib/HDLRuby/hruby_low2high.rb +738 -0
  132. data/lib/HDLRuby/hruby_low2seq.rb +248 -0
  133. data/lib/HDLRuby/hruby_low2sym.rb +126 -0
  134. data/lib/HDLRuby/hruby_low2vhd.rb +1437 -0
  135. data/lib/HDLRuby/hruby_low_bool2select.rb +295 -0
  136. data/lib/HDLRuby/hruby_low_cleanup.rb +193 -0
  137. data/lib/HDLRuby/hruby_low_fix_types.rb +437 -0
  138. data/lib/HDLRuby/hruby_low_mutable.rb +1803 -0
  139. data/lib/HDLRuby/hruby_low_resolve.rb +165 -0
  140. data/lib/HDLRuby/hruby_low_skeleton.rb +129 -0
  141. data/lib/HDLRuby/hruby_low_with_bool.rb +141 -0
  142. data/lib/HDLRuby/hruby_low_with_port.rb +167 -0
  143. data/lib/HDLRuby/hruby_low_with_var.rb +302 -0
  144. data/lib/HDLRuby/hruby_low_without_bit2vector.rb +88 -0
  145. data/lib/HDLRuby/hruby_low_without_concat.rb +162 -0
  146. data/lib/HDLRuby/hruby_low_without_connection.rb +113 -0
  147. data/lib/HDLRuby/hruby_low_without_namespace.rb +718 -0
  148. data/lib/HDLRuby/hruby_low_without_outread.rb +107 -0
  149. data/lib/HDLRuby/hruby_low_without_select.rb +206 -0
  150. data/lib/HDLRuby/hruby_serializer.rb +398 -0
  151. data/lib/HDLRuby/hruby_tools.rb +37 -0
  152. data/lib/HDLRuby/hruby_types.rb +239 -0
  153. data/lib/HDLRuby/hruby_values.rb +64 -0
  154. data/lib/HDLRuby/hruby_verilog.rb +1888 -0
  155. data/lib/HDLRuby/hruby_verilog_name.rb +52 -0
  156. data/lib/HDLRuby/low_samples/adder.yaml +97 -0
  157. data/lib/HDLRuby/low_samples/after.yaml +228 -0
  158. data/lib/HDLRuby/low_samples/before.yaml +223 -0
  159. data/lib/HDLRuby/low_samples/blockblock.yaml +48 -0
  160. data/lib/HDLRuby/low_samples/bugs/sample_add.yaml +97 -0
  161. data/lib/HDLRuby/low_samples/bugs/sample_daice.yaml +444 -0
  162. data/lib/HDLRuby/low_samples/bugs/sample_kumiawase.yaml +332 -0
  163. data/lib/HDLRuby/low_samples/bugs/sample_sub.yaml +97 -0
  164. data/lib/HDLRuby/low_samples/bugs/seqpar.yaml +184 -0
  165. data/lib/HDLRuby/low_samples/case.yaml +327 -0
  166. data/lib/HDLRuby/low_samples/change.yaml +135 -0
  167. data/lib/HDLRuby/low_samples/clocks.yaml +674 -0
  168. data/lib/HDLRuby/low_samples/cloner.rb +22 -0
  169. data/lib/HDLRuby/low_samples/comparer.yaml +85 -0
  170. data/lib/HDLRuby/low_samples/conditionals.yaml +133 -0
  171. data/lib/HDLRuby/low_samples/dff.yaml +107 -0
  172. data/lib/HDLRuby/low_samples/each.yaml +1328 -0
  173. data/lib/HDLRuby/low_samples/exporter.yaml +226 -0
  174. data/lib/HDLRuby/low_samples/functions.yaml +298 -0
  175. data/lib/HDLRuby/low_samples/generic_transmission.yaml +597 -0
  176. data/lib/HDLRuby/low_samples/inherit_as_dff.yaml +125 -0
  177. data/lib/HDLRuby/low_samples/inherit_dff.yaml +107 -0
  178. data/lib/HDLRuby/low_samples/load_yaml.rb +11 -0
  179. data/lib/HDLRuby/low_samples/memory.yaml +678 -0
  180. data/lib/HDLRuby/low_samples/namespace_extractor.rb +23 -0
  181. data/lib/HDLRuby/low_samples/overload.yaml +226 -0
  182. data/lib/HDLRuby/low_samples/paper_after.yaml +431 -0
  183. data/lib/HDLRuby/low_samples/port_maker.rb +14 -0
  184. data/lib/HDLRuby/low_samples/ram.yaml +207 -0
  185. data/lib/HDLRuby/low_samples/registers.yaml +228 -0
  186. data/lib/HDLRuby/low_samples/rom.yaml +2950 -0
  187. data/lib/HDLRuby/low_samples/shift.yaml +230 -0
  188. data/lib/HDLRuby/low_samples/shift2.yaml +2095 -0
  189. data/lib/HDLRuby/low_samples/simple_instance.yaml +102 -0
  190. data/lib/HDLRuby/low_samples/test_all.sh +43 -0
  191. data/lib/HDLRuby/low_samples/typedef.yaml +115 -0
  192. data/lib/HDLRuby/low_samples/values.yaml +577 -0
  193. data/lib/HDLRuby/low_samples/variable_maker.rb +14 -0
  194. data/lib/HDLRuby/low_samples/vector.yaml +56 -0
  195. data/lib/HDLRuby/low_samples/with_seq.yaml +188 -0
  196. data/lib/HDLRuby/low_samples/yaml2hdr.rb +10 -0
  197. data/lib/HDLRuby/low_samples/yaml2vhd.rb +19 -0
  198. data/lib/HDLRuby/sim/Makefile +19 -0
  199. data/lib/HDLRuby/sim/hruby_sim.h +590 -0
  200. data/lib/HDLRuby/sim/hruby_sim_calc.c +2362 -0
  201. data/lib/HDLRuby/sim/hruby_sim_core.c +589 -0
  202. data/lib/HDLRuby/sim/hruby_sim_list.c +93 -0
  203. data/lib/HDLRuby/sim/hruby_sim_vizualize.c +91 -0
  204. data/lib/HDLRuby/sim/hruby_value_pool.c +64 -0
  205. data/lib/HDLRuby/std/channel.rb +354 -0
  206. data/lib/HDLRuby/std/clocks.rb +165 -0
  207. data/lib/HDLRuby/std/counters.rb +82 -0
  208. data/lib/HDLRuby/std/decoder.rb +214 -0
  209. data/lib/HDLRuby/std/fsm.rb +516 -0
  210. data/lib/HDLRuby/std/pipeline.rb +220 -0
  211. data/lib/HDLRuby/std/reconf.rb +309 -0
  212. data/lib/HDLRuby/test_hruby_bstr.rb +2259 -0
  213. data/lib/HDLRuby/test_hruby_high.rb +594 -0
  214. data/lib/HDLRuby/test_hruby_high_low.rb +99 -0
  215. data/lib/HDLRuby/test_hruby_low.rb +934 -0
  216. data/lib/HDLRuby/v_samples/adder.v +10 -0
  217. data/lib/HDLRuby/v_samples/dff.v +12 -0
  218. data/lib/HDLRuby/v_samples/ram.v +20 -0
  219. data/lib/HDLRuby/v_samples/rom.v +270 -0
  220. data/lib/HDLRuby/version.rb +3 -0
  221. data/lib/HDLRuby.rb +11 -0
  222. data/makedoc +1 -0
  223. data/metadata.yaml +4 -0
  224. metadata +299 -0
@@ -0,0 +1,1803 @@
1
+ require "HDLRuby/hruby_error"
2
+
3
+
4
+
5
+ ##
6
+ # Make HDLRuby::Low objects mutable trough "!" methods.
7
+ #
8
+ # NOTE: * should be used with care, since it can comprimize the internal
9
+ # structures.
10
+ # * this is a work in progress.
11
+ #
12
+ ########################################################################
13
+ module HDLRuby::Low
14
+
15
+ ##
16
+ # Describes a system type.
17
+ #
18
+ # NOTE: delegates its content-related methods to its Scope object.
19
+ class SystemT
20
+
21
+ # Sets the +name+.
22
+ def set_name!(name)
23
+ @name = name.to_sym
24
+ end
25
+
26
+ # Sets the +scope+.
27
+ def set_scope!(scope)
28
+ unless scope.is_a?(Scope) then
29
+ raise AnyError, "Invalid class for a scope: #{scope.class}"
30
+ end
31
+ scope.parent = self
32
+ @scope = scope
33
+ end
34
+
35
+ # Maps on the inputs.
36
+ def map_inputs!(&ruby_block)
37
+ @inputs.map! do |input|
38
+ input = ruby_block.call(input)
39
+ input.parent = self unless input.parent
40
+ input
41
+ end
42
+ end
43
+
44
+ # Maps on the outputs.
45
+ def map_outputs!(&ruby_block)
46
+ @outputs.map! do |output|
47
+ output = ruby_block.call(output)
48
+ output.parent = self unless output.parent
49
+ output
50
+ end
51
+ end
52
+
53
+ # Maps on the inouts.
54
+ def map_inouts!(&ruby_block)
55
+ @inouts.map! do |inout|
56
+ inout = ruby_block.call(inout)
57
+ inout.parent = self unless inout.parent
58
+ inout
59
+ end
60
+ end
61
+
62
+ # Deletes an input.
63
+ def delete_input!(signal)
64
+ if @inputs.key?(signal.name) then
65
+ # The signal is present, delete it.
66
+ @inputs.delete(signal.name)
67
+ @interface.delete(signal)
68
+ # And remove its parent.
69
+ signal.parent = nil
70
+ end
71
+ signal
72
+ end
73
+
74
+ # Deletes an output.
75
+ def delete_output!(signal)
76
+ if @outputs.key?(signal.name) then
77
+ # The signal is present, delete it.
78
+ @outputs.delete(signal.name)
79
+ @interface.delete(signal)
80
+ # And remove its parent.
81
+ signal.parent = nil
82
+ end
83
+ signal
84
+ end
85
+
86
+ # Deletes an inout.
87
+ def delete_inout!(signal)
88
+ if @inouts.key?(signal.name) then
89
+ # The signal is present, delete it.
90
+ @inouts.delete(signal.name)
91
+ @interface.delete(signal)
92
+ # And remove its parent.
93
+ signal.parent = nil
94
+ end
95
+ signal
96
+ end
97
+ end
98
+
99
+
100
+ ##
101
+ # Describes scopes of system types.
102
+ class Scope
103
+
104
+ # Maps on the local types.
105
+ def map_types!(&ruby_block)
106
+ @types.map(&ruby_block)
107
+ end
108
+
109
+ # Maps on the local systemTs.
110
+ def map_systemTs!(&ruby_block)
111
+ @systemTs.map(&ruby_block)
112
+ end
113
+
114
+ # Maps on the scopes.
115
+ def map_scopes!(&ruby_block)
116
+ @scopes.map! do |scope|
117
+ scope = ruby_block.call(scope)
118
+ scope.parent = self unless scope.parent
119
+ scope
120
+ end
121
+ end
122
+
123
+ # Maps on the inners.
124
+ def map_inners!(&ruby_block)
125
+ @inners.map! do |inner|
126
+ inner = ruby_block.call(inner)
127
+ inner.parent = self unless inner.parent
128
+ inner
129
+ end
130
+ end
131
+
132
+ # Maps on the systemIs.
133
+ def map_systemIs!(&ruby_block)
134
+ @systemIs.map! do |systemI|
135
+ systemI = ruby_block.call(systemI)
136
+ systemI.parent = self unless systemI.parent
137
+ systemI
138
+ end
139
+ end
140
+
141
+ # Maps on the connections.
142
+ def map_connections!(&ruby_block)
143
+ @connections.map! do |connection|
144
+ connection = ruby_block.call(connection)
145
+ connection.parent = self unless connection.parent
146
+ connection
147
+ end
148
+ end
149
+
150
+ # Maps on the behaviors.
151
+ def map_behaviors!(&ruby_block)
152
+ @behaviors.map! do |behavior|
153
+ behavior = ruby_block.call(behavior)
154
+ behavior.parent = self unless behavior.parent
155
+ behavior
156
+ end
157
+ end
158
+
159
+ # Deletes an type.
160
+ def delete_type!(type)
161
+ if @types.key?(type.name) then
162
+ # The type is present, delete it.
163
+ @types.delete(type.name)
164
+ # And remove its parent.
165
+ type.parent = nil
166
+ end
167
+ type
168
+ end
169
+
170
+ # Deletes an systemT.
171
+ def delete_systemT!(systemT)
172
+ if @systemTs.key?(systemT.name) then
173
+ # The systemT is present, delete it.
174
+ @systemTs.delete(systemT.name)
175
+ # And remove its parent.
176
+ systemT.parent = nil
177
+ end
178
+ systemT
179
+ end
180
+
181
+ # Deletes a scope.
182
+ def delete_scope!(scope)
183
+ # Remove the scope from the list
184
+ @scopes.delete(scope)
185
+ # And remove its parent.
186
+ scope.parent = nil
187
+ # Return the deleted scope
188
+ scope
189
+ end
190
+
191
+ # Deletes an inner.
192
+ def delete_inner!(signal)
193
+ if @inners.key?(signal.name) then
194
+ # The signal is present, delete it.
195
+ @inners.delete(signal.name)
196
+ # And remove its parent.
197
+ signal.parent = nil
198
+ end
199
+ signal
200
+ end
201
+
202
+ # Deletes a systemI.
203
+ def delete_systemI!(systemI)
204
+ if @systemIs.key?(systemI.name) then
205
+ # The instance is present, do remove it.
206
+ @systemIs.delete(systemI.name)
207
+ # And remove its parent.
208
+ systemI.parent = nil
209
+ end
210
+ systemI
211
+ end
212
+
213
+ # Deletes a connection.
214
+ def delete_connection!(connection)
215
+ if @connections.include?(connection) then
216
+ # The connection is present, delete it.
217
+ @connections.delete(connection)
218
+ # And remove its parent.
219
+ connection.parent = nil
220
+ end
221
+ connection
222
+ end
223
+
224
+ # Deletes a behavior.
225
+ def delete_behavior!(behavior)
226
+ if @behaviors.include?(behavior) then
227
+ # The behavior is present, delete it.
228
+ @behaviors.delete(behavior)
229
+ # And remove its parent.
230
+ behavior.parent = nil
231
+ end
232
+ end
233
+ end
234
+
235
+
236
+ ##
237
+ # Describes a data type.
238
+ class Type
239
+
240
+ # Sets the +name+.
241
+ def set_name!(name)
242
+ @name = name.to_sym
243
+ end
244
+ end
245
+
246
+
247
+ ##
248
+ # Describes a high-level type definition.
249
+ #
250
+ # NOTE: type definition are actually type with a name refering to another
251
+ # type (and equivalent to it).
252
+ class TypeDef
253
+
254
+ # Sets the type definition to +type+.
255
+ def set_def!(type)
256
+ # Checks the referered type.
257
+ unless type.is_a?(Type) then
258
+ raise AnyError, "Invalid class for a type: #{type.class}"
259
+ end
260
+ # Set the referened type.
261
+ @def = type
262
+ end
263
+ end
264
+
265
+
266
+
267
+ ##
268
+ # Describes a vector type.
269
+ class TypeVector
270
+
271
+ # Sets the +base+ type.
272
+ def set_base!(type)
273
+ # Check and set the base
274
+ unless type.is_a?(Type)
275
+ raise AnyError,
276
+ "Invalid class for VectorType base: #{base.class}."
277
+ end
278
+ @base = type
279
+ end
280
+
281
+ # Sets the +range+.
282
+ def set_range!(ranage)
283
+ # Check and set the range.
284
+ if range.respond_to?(:to_i) then
285
+ # Integer case: convert to 0..(range-1).
286
+ range = (range-1)..0
287
+ elsif
288
+ # Other cases: assume there is a first and a last to create
289
+ # the range.
290
+ range = range.first..range.last
291
+ end
292
+ @range = range
293
+ end
294
+ end
295
+
296
+
297
+ ##
298
+ # Describes a tuple type.
299
+ class TypeTuple
300
+
301
+ # Maps on the sub types.
302
+ def map_types!(&ruby_block)
303
+ @types.map(&ruby_block)
304
+ end
305
+
306
+ # Deletes a type.
307
+ def delete_type!(type)
308
+ if @types.include?(type) then
309
+ # The type is present, delete it.
310
+ @types.delete(type)
311
+ # And remove its parent.
312
+ type.parent = nil
313
+ end
314
+ type
315
+ end
316
+ end
317
+
318
+
319
+ ##
320
+ # Describes a structure type.
321
+ class TypeStruct
322
+
323
+ # Maps on the sub types.
324
+ def map_types!(&ruby_block)
325
+ @types.map(&ruby_block)
326
+ end
327
+
328
+ # Deletes a sub type by +key+.
329
+ def delete_type!(key)
330
+ if @types.include?(key) then
331
+ # The type is present, delete it.
332
+ type = @types.delete(key)
333
+ # And remove its parent.
334
+ type.parent = nil
335
+ end
336
+ type
337
+ end
338
+ end
339
+
340
+
341
+
342
+ ##
343
+ # Describes a behavior.
344
+ class Behavior
345
+
346
+ # Sets the block.
347
+ def set_block!(block)
348
+ self.block = block
349
+ end
350
+
351
+ # Maps on the events.
352
+ def map_events!(&ruby_block)
353
+ @events.map! do |event|
354
+ event = ruby_block.call(event)
355
+ event.parent = self unless event.parent
356
+ event
357
+ end
358
+ end
359
+
360
+ # Deletes a event.
361
+ def delete_event!(event)
362
+ if @events.include?(event) then
363
+ # The event is present, delete it.
364
+ @events.delete(event)
365
+ # And remove its parent.
366
+ event.parent = nil
367
+ end
368
+ event
369
+ end
370
+ end
371
+
372
+
373
+ ##
374
+ # Describes a timed behavior.
375
+ #
376
+ # NOTE:
377
+ # * this is the only kind of behavior that can include time statements.
378
+ # * this kind of behavior is not synthesizable!
379
+ class TimeBehavior
380
+
381
+ # Sets the block.
382
+ def set_block!(block)
383
+ # Check and set the block.
384
+ unless block.is_a?(Block)
385
+ raise AnyError, "Invalid class for a block: #{block.class}."
386
+ end
387
+ # Time blocks are supported here.
388
+ @block = block
389
+ block.parent = self
390
+ end
391
+ end
392
+
393
+
394
+ ##
395
+ # Describes an event.
396
+ class Event
397
+ # Sets the type.
398
+ def set_type!(type)
399
+ # Check and set the type.
400
+ @type = type.to_sym
401
+ end
402
+
403
+ # Sets the reference to +ref+.
404
+ def set_ref!(ref)
405
+ # Check and set the reference.
406
+ unless ref.is_a?(Ref)
407
+ raise AnyError, "Invalid class for a reference: #{ref.class}"
408
+ end
409
+ @ref = ref
410
+ end
411
+
412
+ # Replace node by corresponding replacement from +node2reassign+ that
413
+ # is a table whose entries are:
414
+ # +node+ the node to replace
415
+ # +rep+ the replacement of the node
416
+ # +ref+ the reference where to reassign the node.
417
+ def reassign_expressions!(node2reassign)
418
+ # Build the replacement table.
419
+ node2rep = node2reassign.map {|n,r| [n,r[0]] }.to_h
420
+
421
+ # Performs the replacement.
422
+ node2rep_done = {} # The performed replacements.
423
+ # Replace on the sons of the reference.
424
+ node2rep_done.merge!(self.ref.replace_expressions!(node2rep))
425
+ # Shall we replace the ref?
426
+ rep = node2rep[self.ref]
427
+ if rep then
428
+ # Yes, do it.
429
+ rep = rep.clone
430
+ node = self.ref
431
+ # node.set_parent!(nil)
432
+ self.set_ref!(rep)
433
+ node2rep_done[node] = rep
434
+ end
435
+
436
+ # Assign the replaced nodes.
437
+ node2rep_done.each do |node,rep|
438
+ reassign = node2reassign[node][1].clone
439
+ self.parent.
440
+ add_connection(Connection.new(reassign,node.clone))
441
+ end
442
+ end
443
+ end
444
+
445
+
446
+ ##
447
+ # Describes a signal.
448
+ class SignalI
449
+
450
+ # Sets the name.
451
+ def set_name!(name)
452
+ # Check and set the name.
453
+ @name = name.to_sym
454
+ end
455
+
456
+ # Sets the type.
457
+ def set_type!(type)
458
+ # Check and set the type.
459
+ if type.is_a?(Type) then
460
+ @type = type
461
+ else
462
+ raise AnyError, "Invalid class for a type: #{type.class}."
463
+ end
464
+ end
465
+
466
+ # Sets the value.
467
+ def set_value!(value)
468
+ # Check and set teh value.
469
+ unless value.is_a?(Expression) then
470
+ raise AnyError, "Invalid class for a constant: #{val.class}"
471
+ end
472
+ @value = value
473
+ value.parent = self
474
+ end
475
+
476
+ end
477
+
478
+
479
+ ##
480
+ # Describes a system instance.
481
+ class SystemI
482
+
483
+ # Sets the name.
484
+ def set_name!(name)
485
+ # Set the name as a symbol.
486
+ @name = name.to_sym
487
+ end
488
+
489
+ # Sets the systemT.
490
+ def set_systemT(systemT)
491
+ # Check and set the systemT.
492
+ if !systemT.is_a?(SystemT) then
493
+ raise AnyError, "Invalid class for a system type: #{systemT.class}"
494
+ end
495
+ @systemT = systemT
496
+ end
497
+
498
+ end
499
+
500
+
501
+
502
+ ##
503
+ # Describes a statement.
504
+ #
505
+ # NOTE: this is an abstract class which is not to be used directly.
506
+ class Statement
507
+ # Replaces sub expressions using +node2rep+ table indicating the
508
+ # node to replace and the corresponding replacement.
509
+ # Returns the actually replaced nodes and their corresponding
510
+ # replacement.
511
+ #
512
+ # NOTE: the replacement is duplicated.
513
+ def replace_expressions!(node2rep)
514
+ # By default: nothing to do.
515
+ return {}
516
+ end
517
+ end
518
+
519
+
520
+
521
+
522
+ ##
523
+ # Decribes a transmission statement.
524
+ class Transmit
525
+ # Sets the left.
526
+ def set_left!(left)
527
+ # Check and set the left reference.
528
+ unless left.is_a?(Ref)
529
+ raise AnyError,
530
+ "Invalid class for a reference (left value): #{left.class}"
531
+ end
532
+ @left = left
533
+ # and set its parent.
534
+ left.parent = self
535
+ end
536
+
537
+ # Sets the right.
538
+ def set_right!(right)
539
+ # Check and set the right expression.
540
+ unless right.is_a?(Expression)
541
+ raise AnyError, "Invalid class for an expression (right value): #{right.class}"
542
+ end
543
+ @right = right
544
+ # and set its parent.
545
+ right.parent = self
546
+ end
547
+
548
+ # Maps on the children.
549
+ def map_nodes!(&ruby_block)
550
+ @left = ruby_block.call(@left)
551
+ left.parent = self unless left.parent
552
+ @right = ruby_block.call(@right)
553
+ right.parent = self unless right.parent
554
+ end
555
+
556
+ # Replaces sub expressions using +node2rep+ table indicating the
557
+ # node to replace and the corresponding replacement.
558
+ # Returns the actually replaced nodes and their corresponding
559
+ # replacement.
560
+ #
561
+ # NOTE: the replacement is duplicated.
562
+ def replace_expressions!(node2rep)
563
+ # First recurse on the children.
564
+ res = self.left.replace_expressions!(node2rep)
565
+ res.merge!(self.right.replace_expressions!(node2rep))
566
+ # Is there a replacement to do on the left?
567
+ rep = node2rep[self.left]
568
+ if rep then
569
+ # Yes, do it.
570
+ rep = rep.clone
571
+ node = self.left
572
+ # node.set_parent!(nil)
573
+ self.set_left!(rep)
574
+ # And register the replacement.
575
+ res[node] = rep
576
+ end
577
+ # Is there a replacement to do on the right?
578
+ rep = node2rep[self.right]
579
+ if rep then
580
+ # Yes, do it.
581
+ rep = rep.clone
582
+ node = self.right
583
+ # node.set_parent!(nil)
584
+ self.set_right!(rep)
585
+ # And register the replacement.
586
+ res[node] = rep
587
+ end
588
+
589
+ return res
590
+ end
591
+ end
592
+
593
+
594
+ ##
595
+ # Describes an if statement.
596
+ class If
597
+
598
+ # Sets the condition.
599
+ def set_condition!(condition)
600
+ # Check and set the condition.
601
+ unless condition.is_a?(Expression)
602
+ raise AnyError,
603
+ "Invalid class for a condition: #{condition.class}"
604
+ end
605
+ @condition = condition
606
+ # And set its parent.
607
+ condition.parent = self
608
+ end
609
+
610
+ # Sets the yes block.
611
+ def set_yes!(yes)
612
+ # Check and set the yes statement.
613
+ unless yes.is_a?(Statement)
614
+ raise AnyError, "Invalid class for a statement: #{yes.class}"
615
+ end
616
+ @yes = yes
617
+ # And set its parent.
618
+ yes.parent = self
619
+ end
620
+
621
+ # Sets the no block.
622
+ def set_no!(no)
623
+ # Check and set the yes statement.
624
+ if no and !no.is_a?(Statement)
625
+ raise AnyError, "Invalid class for a statement: #{no.class}"
626
+ end
627
+ @no = no
628
+ # And set its parent.
629
+ no.parent = self if no
630
+ end
631
+
632
+ # Deletes an alternate if.
633
+ def delete_noif!(noif)
634
+ if @noifs.include?(noif) then
635
+ # The noif is present, delete it.
636
+ @noifs.delete(noif)
637
+ # And remove its parent.
638
+ noif.parent = nil
639
+ end
640
+ noif
641
+ end
642
+
643
+ # Maps on the noifs.
644
+ def map_noifs!(&ruby_block)
645
+ @noifs.map! do |cond,stmnt|
646
+ cond,stmnt = ruby_block.call(cond,stmnt)
647
+ # cond, stmnt = ruby_block.call(cond), ruby_block.call(stmnt)
648
+ cond.parent = self unless cond.parent
649
+ stmnt.parent = self unless stmnt.parent
650
+ [cond,stmnt]
651
+ end
652
+ end
653
+
654
+ # Maps on the children (including the condition).
655
+ def map_nodes!(&ruby_block)
656
+ @condition = ruby_block.call(@condition)
657
+ @yes = ruby_block.call(@yes)
658
+ self.map_noifs! do |cond,stmnt|
659
+ [ruby_block.call(cond), ruby_block.call(stmnt)]
660
+ end
661
+ # @noifs.map! do |cond,stmnt|
662
+ # cond = ruby_block.call(cond)
663
+ # stmnt = ruby_block.call(stmnt)
664
+ # cond.parent = self unless cond.parent
665
+ # stmnt.parent = self unless stmnt.parent
666
+ # [cond,stmnt]
667
+ # end
668
+ @no = ruby_block.call(@no) if @no
669
+ end
670
+
671
+ # Replaces sub expressions using +node2rep+ table indicating the
672
+ # node to replace and the corresponding replacement.
673
+ # Returns the actually replaced nodes and their corresponding
674
+ # replacement.
675
+ #
676
+ # NOTE: the replacement is duplicated.
677
+ def replace_expressions!(node2rep)
678
+ # First recurse on the children.
679
+ res = {}
680
+ self.each_node do |node|
681
+ res.merge!(node.replace_expressions!(node2rep))
682
+ end
683
+ # Is there a replacement to do on the condition?
684
+ rep = node2rep[self.condition]
685
+ if rep then
686
+ # Yes, do it.
687
+ rep = rep.clone
688
+ node = self.condition
689
+ # node.set_parent!(nil)
690
+ self.set_condition!(rep)
691
+ # And register the replacement.
692
+ res[node] = rep
693
+ end
694
+
695
+ return res
696
+ end
697
+ end
698
+
699
+ ##
700
+ # Describes a when for a case statement.
701
+ class When
702
+ # Sets the match.
703
+ def set_match!(match)
704
+ # Checks the match.
705
+ unless match.is_a?(Expression)
706
+ raise AnyError, "Invalid class for a case match: #{match.class}"
707
+ end
708
+ # Set the match.
709
+ @match = match
710
+ # And set their parents.
711
+ match.parent = self
712
+ end
713
+
714
+ # Sets the statement.
715
+ def set_statement!(statement)
716
+ # Checks statement.
717
+ unless statement.is_a?(Statement)
718
+ raise AnyError,
719
+ "Invalid class for a statement: #{statement.class}"
720
+ end
721
+ # Set the statement.
722
+ @statement = statement
723
+ # And set their parents.
724
+ statement.parent = self
725
+ end
726
+
727
+ # Maps on the children (including the match).
728
+ def map_nodes!(&ruby_block)
729
+ @match = ruby_block.call(@match)
730
+ @match.parent = self unless @match.parent
731
+ @statement = ruby_block.call(@statement)
732
+ @statement.parent = self unless @statement.parent
733
+ end
734
+
735
+ # Replaces sub expressions using +node2rep+ table indicating the
736
+ # node to replace and the corresponding replacement.
737
+ # Returns the actually replaced nodes and their corresponding
738
+ # replacement.
739
+ #
740
+ # NOTE: the replacement is duplicated.
741
+ def replace_expressions!(node2rep)
742
+ # First recurse on the children.
743
+ res = {}
744
+ self.each_node do |node|
745
+ res.merge!(node.replace_expressions!(node2rep))
746
+ end
747
+ # Is there a replacement to do on the value?
748
+ rep = node2rep[self.match]
749
+ if rep then
750
+ # Yes, do it.
751
+ rep = rep.clone
752
+ node = self.match
753
+ # node.set_parent!(nil)
754
+ self.set_match!(rep)
755
+ # And register the replacement.
756
+ res[node] = rep
757
+ end
758
+
759
+ return res
760
+ end
761
+ end
762
+
763
+
764
+ ##
765
+ # Describes a case statement.
766
+ class Case
767
+
768
+ # Sets the value.
769
+ def set_value!(value)
770
+ # Check and set the value.
771
+ unless value.is_a?(Expression)
772
+ raise AnyError, "Invalid class for a value: #{value.class}"
773
+ end
774
+ @value = value
775
+ # And set its parent.
776
+ value.parent = self
777
+ end
778
+
779
+ # Sets the default.
780
+ def set_default!(default)
781
+ # Checks and set the default case if any.
782
+ self.default = default
783
+ end
784
+
785
+ # Maps on the whens.
786
+ def map_whens!(&ruby_block)
787
+ @whens.map! do |w|
788
+ w = ruby_block.call(w)
789
+ w.parent = self unless w.parent
790
+ w
791
+ end
792
+ end
793
+
794
+ # Delete a when.
795
+ def delete_when!(w)
796
+ @whens.delete(w)
797
+ end
798
+
799
+ # Maps on the children (including the value).
800
+ def map_nodes!(&ruby_block)
801
+ # A block? Apply it on each child.
802
+ @value = ruby_block.call(@value)
803
+ map_whens!(&ruby_block)
804
+ if @default then
805
+ @default = ruby_block.call(@default)
806
+ @default.parent = self unless @default.parent
807
+ end
808
+ end
809
+
810
+ # Replaces sub expressions using +node2rep+ table indicating the
811
+ # node to replace and the corresponding replacement.
812
+ # Returns the actually replaced nodes and their corresponding
813
+ # replacement.
814
+ #
815
+ # NOTE: the replacement is duplicated.
816
+ def replace_expressions!(node2rep)
817
+ # First recurse on the children.
818
+ res = {}
819
+ self.each_node do |node|
820
+ res.merge!(node.replace_expressions!(node2rep))
821
+ end
822
+ # Is there a replacement to do on the value?
823
+ rep = node2rep[self.value]
824
+ if rep then
825
+ # Yes, do it.
826
+ rep = rep.clone
827
+ node = self.value
828
+ # node.set_parent!(nil)
829
+ self.set_value!(rep)
830
+ # And register the replacement.
831
+ res[node] = rep
832
+ end
833
+
834
+ return res
835
+ end
836
+ end
837
+
838
+
839
+ ##
840
+ # Describes a delay: not synthesizable.
841
+ class Delay
842
+
843
+ # Sets the value.
844
+ def set_value!(value)
845
+ # Check and set the value.
846
+ unless value.is_a?(Numeric)
847
+ raise AnyError,
848
+ "Invalid class for a delay value: #{value.class}."
849
+ end
850
+ @value = value
851
+ end
852
+
853
+ # Sets the unit.
854
+ def set_unit!(unit)
855
+ # Check and set the unit.
856
+ @unit = unit.to_sym
857
+ end
858
+
859
+ # Replaces sub expressions using +node2rep+ table indicating the
860
+ # node to replace and the corresponding replacement.
861
+ # Returns the actually replaced nodes and their corresponding
862
+ # replacement.
863
+ #
864
+ # NOTE: the replacement is duplicated.
865
+ def replace_expressions!(node2rep)
866
+ # First recurse on the children.
867
+ res = self.value.replace_expressions!
868
+ # Is there a replacement to do on the value?
869
+ rep = node2rep[self.value]
870
+ if rep then
871
+ # Yes, do it.
872
+ rep = rep.clone
873
+ node = self.value
874
+ # node.set_parent!(nil)
875
+ self.set_value!(rep)
876
+ # And register the replacement.
877
+ res[node] = rep
878
+ end
879
+
880
+ return res
881
+ end
882
+ end
883
+
884
+
885
+ ##
886
+ # Describes a wait statement: not synthesizable!
887
+ class TimeWait
888
+
889
+ # Sets the delay.
890
+ def set_delay!(delay)
891
+ # Check and set the delay.
892
+ unless delay.is_a?(Delay)
893
+ raise AnyError, "Invalid class for a delay: #{delay.class}."
894
+ end
895
+ @delay = delay
896
+ # And set its parent.
897
+ delay.parent = self
898
+ end
899
+
900
+ # Maps on the children (including the condition).
901
+ def map_nodes!(&ruby_block)
902
+ # Nothing to do.
903
+ end
904
+ end
905
+
906
+
907
+ ##
908
+ # Describes a timed loop statement: not synthesizable!
909
+ class TimeRepeat
910
+
911
+ # Sets the statement.
912
+ def set_statement!(statement)
913
+ # Check and set the statement.
914
+ unless statement.is_a?(Statement)
915
+ raise AnyError,
916
+ "Invalid class for a statement: #{statement.class}."
917
+ end
918
+ @statement = statement
919
+ # And set its parent.
920
+ statement.parent = self
921
+ end
922
+
923
+ # Sets the delay.
924
+ def set_delay!(delay)
925
+ # Check and set the delay.
926
+ unless delay.is_a?(Delay)
927
+ raise AnyError, "Invalid class for a delay: #{delay.class}."
928
+ end
929
+ @delay = delay
930
+ # And set its parent.
931
+ delay.parent = self
932
+ end
933
+
934
+ # Maps on the child.
935
+ def map_nodes!(&ruby_block)
936
+ @statement = ruby_block.call(@statement)
937
+ @statement.parent = self unless @statement.parent
938
+ end
939
+
940
+ # Replaces sub expressions using +node2rep+ table indicating the
941
+ # node to replace and the corresponding replacement.
942
+ # Returns the actually replaced nodes and their corresponding
943
+ # replacement.
944
+ #
945
+ # NOTE: the replacement is duplicated.
946
+ def replace_expressions!(node2rep)
947
+ res = {}
948
+ # Recurse on the children.
949
+ self.each_node do |node|
950
+ res.merge!(node.replace_expressions!(node2rep))
951
+ end
952
+ return res
953
+ end
954
+ end
955
+
956
+
957
+ ##
958
+ # Describes a block.
959
+ class Block
960
+
961
+ # Sets the mode.
962
+ def set_mode!(mode)
963
+ # Check and set the type.
964
+ @mode = mode.to_sym
965
+ end
966
+
967
+ # Sets the name.
968
+ def set_name!(name)
969
+ # Check and set the name.
970
+ @name = name.to_sym
971
+ end
972
+
973
+ # Maps on the inners.
974
+ def map_inners!(&ruby_block)
975
+ @inners.map! do |inner|
976
+ inner = ruby_block.call(inner)
977
+ inner.parent = self unless inner.parent
978
+ inner
979
+ end
980
+ end
981
+
982
+ # Deletes an inner.
983
+ def delete_inner!(signal)
984
+ if @inners.key?(signal.name) then
985
+ # The signal is present, delete it.
986
+ @inners.delete(signal.name)
987
+ # And remove its parent.
988
+ signal.parent = nil
989
+ end
990
+ signal
991
+ end
992
+
993
+ # Inserts statement *stmnt+ at index +idx+.
994
+ def insert_statement!(idx,stmnt)
995
+ # Checks the index.
996
+ if idx > @statements.size then
997
+ raise AryError, "Index out of range: #{idx}"
998
+ end
999
+ # Checks the statement.
1000
+ unless stmnt.is_a?(Statement)
1001
+ raise AnyError, "Invalid type for a statement: #{stmnt.class}"
1002
+ end
1003
+ # Inserts the statement.
1004
+ @statements.insert(idx,stmnt)
1005
+ stmnt.parent = self
1006
+ end
1007
+
1008
+ # Sets statement +stmnt+ at index +idx+.
1009
+ def set_statement!(idx,stmnt)
1010
+ # Checks the index.
1011
+ if idx > @statements.size then
1012
+ raise AryError, "Index out of range: #{idx}"
1013
+ end
1014
+ # Checks the statement.
1015
+ unless stmnt.is_a?(Statement)
1016
+ raise AnyError, "Invalid type for a statement: #{stmnt.class}"
1017
+ end
1018
+ # Detach the previous statement if any.
1019
+ @statements[idx].parent = nil if @statements[idx]
1020
+ # Set the new statement.
1021
+ @statements[idx] = stmnt
1022
+ stmnt.parent = self
1023
+ end
1024
+
1025
+ # Maps on the statements.
1026
+ def map_statements!(&ruby_block)
1027
+ @statements.map! do |stmnt|
1028
+ stmnt = ruby_block.call(stmnt)
1029
+ stmnt.parent = self unless stmnt.parent
1030
+ stmnt
1031
+ end
1032
+ end
1033
+
1034
+ alias_method :map_nodes!, :map_statements!
1035
+
1036
+ # Deletes a statement.
1037
+ def delete_statement!(statement)
1038
+ if @statements.include?(statement) then
1039
+ # Statement is present, delete it.
1040
+ @statements.delete(statement)
1041
+ # And remove its parent.
1042
+ statement.parent = nil
1043
+ end
1044
+ statement
1045
+ end
1046
+
1047
+ # Replaces sub expressions using +node2rep+ table indicating the
1048
+ # node to replace and the corresponding replacement.
1049
+ # Returns the actually replaced nodes and their corresponding
1050
+ # replacement.
1051
+ #
1052
+ # NOTE: the replacement is duplicated.
1053
+ def replace_expressions!(node2rep)
1054
+ res = {}
1055
+ # Recurse on the children.
1056
+ self.each_node do |node|
1057
+ res.merge!(node.replace_expressions!(node2rep))
1058
+ end
1059
+ return res
1060
+ end
1061
+
1062
+ # Replace node by corresponding replacement from +node2reassign+ that
1063
+ # is a table whose entries are:
1064
+ # +node+ the node to replace
1065
+ # +rep+ the replacement of the node
1066
+ # +ref+ the reference where to reassign the node.
1067
+ def reassign_expressions!(node2reassign)
1068
+ # Build the replacement table.
1069
+ node2rep = node2reassign.map {|n,r| [n,r[0]] }.to_h
1070
+
1071
+ # First recurse on the sub blocks.
1072
+ self.each_block { |block| block.reassign_expressions!(node2rep) }
1073
+
1074
+ # Now work on the block.
1075
+ # Replace on the statements.
1076
+ self.map_statements! do |statement|
1077
+ # Do the replacement
1078
+ node2rep_done = statement.replace_expressions!(node2rep)
1079
+ # Assign the replaced nodes in a new block.
1080
+ unless node2rep_done.empty?
1081
+ blk = Block.new(:seq)
1082
+ node2rep_done.each do |node,rep|
1083
+ reassign = node2reassign[node][1].clone
1084
+ blk.add_statement(Transmit.new(reassign,node.clone))
1085
+ end
1086
+ blk.add_statement(statement.clone)
1087
+ blk
1088
+ else
1089
+ statement
1090
+ end
1091
+ end
1092
+ end
1093
+ end
1094
+
1095
+ # Describes a timed block.
1096
+ #
1097
+ # NOTE:
1098
+ # * this is the only kind of block that can include time statements.
1099
+ # * this kind of block is not synthesizable!
1100
+ class TimeBlock
1101
+ end
1102
+
1103
+
1104
+ ##
1105
+ # Decribes a piece of software code.
1106
+ class Code
1107
+ # Sets the type.
1108
+ def set_type!(type)
1109
+ # Check and set type.
1110
+ @type = type.to_sym
1111
+ end
1112
+
1113
+ # Sets the content.
1114
+ def set_content!(content)
1115
+ @content = content
1116
+ # Freeze it to avoid dynamic tempering of the hardware.
1117
+ content.freeze
1118
+ end
1119
+ end
1120
+
1121
+
1122
+ ##
1123
+ # Describes a connection.
1124
+ #
1125
+ # NOTE: eventhough a connection is semantically different from a
1126
+ # transmission, it has a common structure. Therefore, it is described
1127
+ # as a subclass of a transmit.
1128
+ class Connection
1129
+
1130
+ # Replace node by corresponding replacement from +node2reassign+ that
1131
+ # is a table whose entries are:
1132
+ # +node+ the node to replace
1133
+ # +rep+ the replacement of the node
1134
+ # +ref+ the reference where to reassign the node.
1135
+ def reassign_expressions!(node2reassign)
1136
+ # Build the replacement table.
1137
+ node2rep = node2reassign.map {|n,r| [n,r[0]] }.to_h
1138
+
1139
+ # Performs the replacements.
1140
+ node2rep_done = {} # The performed replacements.
1141
+ # Replace on the sons of the left.
1142
+ node2rep_done.merge!(self.left.replace_expressions!(node2rep))
1143
+ # Replace on the sons of the left.
1144
+ node2rep_done.merge!(self.right.replace_expressions!(node2rep))
1145
+ # Shall we replace the right?
1146
+ rep = node2rep[self.right]
1147
+ if rep then
1148
+ # Yes, do it.
1149
+ rep = rep.clone
1150
+ node = self.right
1151
+ # node.set_parent!(nil)
1152
+ self.set_right!(rep)
1153
+ node2rep_done[node] = rep
1154
+ end
1155
+
1156
+ # Assign the replaced nodes.
1157
+ node2rep_done.each do |node,rep|
1158
+ reassign = node2reassign[node][1].clone
1159
+ self.parent.add_connection(
1160
+ Connection.new(reassign,node.clone))
1161
+ end
1162
+ end
1163
+ end
1164
+
1165
+
1166
+
1167
+ ##
1168
+ # Describes an expression.
1169
+ #
1170
+ # NOTE: this is an abstract class which is not to be used directly.
1171
+ class Expression
1172
+
1173
+ # Sets the type.
1174
+ def set_type!(type)
1175
+ # Check and set the type.
1176
+ if type.is_a?(Type) then
1177
+ @type = type
1178
+ else
1179
+ raise AnyError, "Invalid class for a type: #{type.class}."
1180
+ end
1181
+ end
1182
+
1183
+ # Maps on the children.
1184
+ def map_nodes!(&ruby_block)
1185
+ # By default, nothing to do.
1186
+ end
1187
+
1188
+ alias_method :map_expressions!, :map_nodes!
1189
+
1190
+ # Replaces sub expressions using +node2rep+ table indicating the
1191
+ # node to replace and the corresponding replacement.
1192
+ # Returns the actually replaced nodes and their corresponding
1193
+ # replacement.
1194
+ #
1195
+ # NOTE: the replacement is duplicated.
1196
+ def replace_expressions!(node2rep)
1197
+ # By default, nothing to do.
1198
+ return {}
1199
+ end
1200
+ end
1201
+
1202
+
1203
+ ##
1204
+ # Describes a value.
1205
+ class Value
1206
+
1207
+ # Sets the content.
1208
+ def set_content!(content)
1209
+ unless content.is_a?(Numeric) or content.is_a?(HDLRuby::BitString)
1210
+ content = HDLRuby::BitString.new(content.to_s)
1211
+ end
1212
+ @content = content
1213
+ end
1214
+ end
1215
+
1216
+ # Module for mutable expressions with one child.
1217
+ module OneChildMutable
1218
+ # Sets the child.
1219
+ def set_child!(child)
1220
+ # Check and set the child.
1221
+ unless child.is_a?(Expression)
1222
+ raise AnyError,"Invalid class for an expression: #{child.class}"
1223
+ end
1224
+ @child = child
1225
+ # And set its parent.
1226
+ child.parent = self
1227
+ end
1228
+
1229
+ # Maps on the child.
1230
+ def map_nodes!(&ruby_block)
1231
+ @child = ruby_block.call(@child)
1232
+ @child.parent = self unless @child.parent
1233
+ end
1234
+
1235
+ # Replaces sub expressions using +node2rep+ table indicating the
1236
+ # node to replace and the corresponding replacement.
1237
+ # Returns the actually replaced nodes and their corresponding
1238
+ # replacement.
1239
+ #
1240
+ # NOTE: the replacement is duplicated.
1241
+ def replace_expressions!(node2rep)
1242
+ # First recurse on the child.
1243
+ res = self.child.replace_expressions!(node2rep)
1244
+ # Is there a replacement to do?
1245
+ rep = node2rep[self.child]
1246
+ if rep then
1247
+ # Yes, do it.
1248
+ rep = rep.clone
1249
+ node = self.child
1250
+ # node.set_parent!(nil)
1251
+ self.set_child!(rep)
1252
+ # And register the replacement.
1253
+ res[node] = rep
1254
+ end
1255
+ return res
1256
+ end
1257
+ end
1258
+
1259
+ ##
1260
+ # Describes a cast.
1261
+ class Cast
1262
+ include OneChildMutable
1263
+ end
1264
+
1265
+
1266
+ ##
1267
+ # Describes an operation.
1268
+ #
1269
+ # NOTE: this is an abstract class which is not to be used directly.
1270
+ class Operation
1271
+
1272
+ # Sets the operator.
1273
+ def set_operator!(operator)
1274
+ # Check and set the operator.
1275
+ @operator = operator.to_sym
1276
+ end
1277
+ end
1278
+
1279
+
1280
+ ##
1281
+ # Describes an unary operation.
1282
+ class Unary
1283
+ include OneChildMutable
1284
+
1285
+ # Moved to OneChildMutable
1286
+ # # Sets the child.
1287
+ # def set_child!(child)
1288
+ # # Check and set the child.
1289
+ # unless child.is_a?(Expression)
1290
+ # raise AnyError,"Invalid class for an expression: #{child.class}"
1291
+ # end
1292
+ # @child = child
1293
+ # # And set its parent.
1294
+ # child.parent = self
1295
+ # end
1296
+
1297
+ # # Maps on the child.
1298
+ # def map_nodes!(&ruby_block)
1299
+ # @child = ruby_block.call(@child)
1300
+ # @child.parent = self unless @child.parent
1301
+ # end
1302
+ end
1303
+
1304
+
1305
+ ##
1306
+ # Describes an binary operation.
1307
+ class Binary
1308
+
1309
+ # Sets the left.
1310
+ def set_left!(left)
1311
+ # Check and set the left.
1312
+ unless left.is_a?(Expression)
1313
+ raise AnyError,"Invalid class for an expression: #{left.class}"
1314
+ end
1315
+ @left = left
1316
+ # And set its parent.
1317
+ left.parent = self
1318
+ end
1319
+
1320
+ # Sets the right.
1321
+ def set_right!(right)
1322
+ # Check and set the right.
1323
+ unless right.is_a?(Expression)
1324
+ raise AnyError,"Invalid class for an expression: #{right.class}"
1325
+ end
1326
+ @right = right
1327
+ # And set its parent.
1328
+ right.parent = self
1329
+ end
1330
+
1331
+ # Maps on the child.
1332
+ def map_nodes!(&ruby_block)
1333
+ @left = ruby_block.call(@left)
1334
+ @left.parent = self unless @left.parent
1335
+ @right = ruby_block.call(@right)
1336
+ @right.parent = self unless @right.parent
1337
+ end
1338
+
1339
+ # Replaces sub expressions using +node2rep+ table indicating the
1340
+ # node to replace and the corresponding replacement.
1341
+ # Returns the actually replaced nodes and their corresponding
1342
+ # replacement.
1343
+ #
1344
+ # NOTE: the replacement is duplicated.
1345
+ def replace_expressions!(node2rep)
1346
+ # First recurse on the children.
1347
+ res = self.left.replace_expressions!(node2rep)
1348
+ res.merge!(self.right.replace_expressions!(node2rep))
1349
+ # Is there a replacement to do on the left?
1350
+ rep = node2rep[self.left]
1351
+ if rep then
1352
+ # Yes, do it.
1353
+ rep = rep.clone
1354
+ node = self.left
1355
+ # node.set_parent!(nil)
1356
+ self.set_left!(rep)
1357
+ # And register the replacement.
1358
+ res[node] = rep
1359
+ end
1360
+ # Is there a replacement to do on the right?
1361
+ rep = node2rep[self.right]
1362
+ if rep then
1363
+ # Yes, do it.
1364
+ rep = rep.clone
1365
+ node = self.right
1366
+ # node.set_parent!(nil)
1367
+ self.set_right!(rep)
1368
+ # And register the replacement.
1369
+ res[node] = rep
1370
+ end
1371
+
1372
+ return res
1373
+ end
1374
+ end
1375
+
1376
+
1377
+ ##
1378
+ # Describes a section operation (generalization of the ternary operator).
1379
+ #
1380
+ # NOTE: choice is using the value of +select+ as an index.
1381
+ class Select
1382
+
1383
+ # Sets the select.
1384
+ def set_select!(select)
1385
+ # Check and set the selection.
1386
+ unless select.is_a?(Expression)
1387
+ raise AnyError,
1388
+ "Invalid class for an expression: #{select.class}"
1389
+ end
1390
+ @select = select
1391
+ # And set its parent.
1392
+ select.parent = self
1393
+ end
1394
+
1395
+ # Maps on the choices.
1396
+ def map_choices!(&ruby_block)
1397
+ @choices.map! do |choice|
1398
+ choice = ruby_block.call(choice)
1399
+ choice.parent = self unless choice.parent
1400
+ choice
1401
+ end
1402
+ end
1403
+
1404
+ # Deletes a choice.
1405
+ def delete_choice!(choice)
1406
+ if @choices.include?(choice) then
1407
+ # The choice is present, delete it.
1408
+ @choices.delete(choice)
1409
+ # And remove its parent.
1410
+ choice.parent = nil
1411
+ end
1412
+ choice
1413
+ end
1414
+
1415
+ # Maps on the children.
1416
+ def map_nodes!(&ruby_block)
1417
+ @select = ruby_block.call(@select)
1418
+ @select.parent = self unless @select.parent
1419
+ map_choices!(&ruby_block)
1420
+ end
1421
+
1422
+ # Replaces sub expressions using +node2rep+ table indicating the
1423
+ # node to replace and the corresponding replacement.
1424
+ # Returns the actually replaced nodes and their corresponding
1425
+ # replacement.
1426
+ #
1427
+ # NOTE: the replacement is duplicated.
1428
+ def replace_expressions!(node2rep)
1429
+ # First recurse on the children.
1430
+ res = {}
1431
+ self.each_node do |node|
1432
+ res.merge!(node.replace_expressions!(node2rep))
1433
+ end
1434
+ # Is there a replacement to do on the select?
1435
+ rep = node2rep[self.select]
1436
+ if rep then
1437
+ # Yes, do it.
1438
+ rep = rep.clone
1439
+ node = self.select
1440
+ # node.set_parent!(nil)
1441
+ self.set_select!(rep)
1442
+ # And register the replacement.
1443
+ res[node] = rep
1444
+ end
1445
+ # Is there a replacement of on a choice.
1446
+ self.map_choices! do |choice|
1447
+ rep = node2rep[choice]
1448
+ if rep then
1449
+ # Yes, do it.
1450
+ rep = rep.clone
1451
+ node = choice
1452
+ # node.set_parent!(nil)
1453
+ # And register the replacement.
1454
+ res[node] = rep
1455
+ rep
1456
+ else
1457
+ choice
1458
+ end
1459
+ end
1460
+ return res
1461
+ end
1462
+ end
1463
+
1464
+ # Module adding some (but not all) mutable methods to Concat and
1465
+ # RefConcat.
1466
+ module MutableConcat
1467
+
1468
+ # Replaces sub expressions using +node2rep+ table indicating the
1469
+ # node to replace and the corresponding replacement.
1470
+ # Returns the actually replaced nodes and their corresponding
1471
+ # replacement.
1472
+ #
1473
+ # NOTE: the replacement is duplicated.
1474
+ def replace_expressions!(node2rep)
1475
+ # First recurse on the children.
1476
+ res = {}
1477
+ self.each_node do |node|
1478
+ res.merge!(node.replace_expressions!(node2rep))
1479
+ end
1480
+ # Is there a replacement of on a sub node?
1481
+ self.map_nodes! do |sub|
1482
+ rep = node2rep[sub]
1483
+ if rep then
1484
+ # Yes, do it.
1485
+ rep = rep.clone
1486
+ node = sub
1487
+ # node.set_parent!(nil)
1488
+ # And register the replacement.
1489
+ res[node] = rep
1490
+ rep
1491
+ else
1492
+ sub
1493
+ end
1494
+ end
1495
+ return res
1496
+ end
1497
+ end
1498
+
1499
+
1500
+ ##
1501
+ # Describes a concatenation expression.
1502
+ class Concat
1503
+ include MutableConcat
1504
+
1505
+ # Maps on the expression.
1506
+ def map_expressions!(&ruby_block)
1507
+ @expressions.map! do |expression|
1508
+ expression = ruby_block.call(expression)
1509
+ expression.parent = self unless expression.parent
1510
+ expression
1511
+ end
1512
+ end
1513
+
1514
+ alias_method :map_nodes!, :map_expressions!
1515
+
1516
+ # Delete an expression.
1517
+ def delete_expression!(expression)
1518
+ if @expressions.include?(expression) then
1519
+ # The expression is present, delete it.
1520
+ @expressions.delete(expression)
1521
+ # And remove its parent.
1522
+ expression.parent = nil
1523
+ end
1524
+ expression
1525
+ end
1526
+
1527
+ end
1528
+
1529
+
1530
+ ##
1531
+ # Describes a reference expression.
1532
+ #
1533
+ # NOTE: this is an abstract class which is not to be used directly.
1534
+ class Ref
1535
+ # Maps on the children.
1536
+ def map_nodes!(&ruby_block)
1537
+ # Nothing to do.
1538
+ end
1539
+ end
1540
+
1541
+
1542
+ ##
1543
+ # Describes concatenation reference.
1544
+ class RefConcat
1545
+ include MutableConcat
1546
+
1547
+ # Maps on the references.
1548
+ def map_refs!(&ruby_block)
1549
+ @refs.map! do |ref|
1550
+ ref = ruby_block.call(ref)
1551
+ ref.parent = self unless ref.parent
1552
+ ref
1553
+ end
1554
+ end
1555
+
1556
+ alias_method :map_nodes!, :map_refs!
1557
+
1558
+ # Delete a reference.
1559
+ def delete_ref!(ref)
1560
+ if @refs.include?(ref) then
1561
+ # The ref is present, delete it.
1562
+ @refs.delete(ref)
1563
+ # And remove its parent.
1564
+ ref.parent = nil
1565
+ end
1566
+ ref
1567
+ end
1568
+
1569
+ end
1570
+
1571
+
1572
+ ##
1573
+ # Describes a index reference.
1574
+ class RefIndex
1575
+
1576
+ # Sets the base reference.
1577
+ def set_ref!(ref)
1578
+ # Check and set the accessed reference.
1579
+ unless ref.is_a?(Ref) then
1580
+ raise AnyError, "Invalid class for a reference: #{ref.class}."
1581
+ end
1582
+ @ref = ref
1583
+ # And set its parent.
1584
+ ref.parent = self
1585
+ end
1586
+
1587
+ # Sets the index.
1588
+ def set_index!(ref)
1589
+ # Check and set the index.
1590
+ unless index.is_a?(Expression) then
1591
+ raise AnyError,
1592
+ "Invalid class for an index reference: #{index.class}."
1593
+ end
1594
+ @index = index
1595
+ # And set its parent.
1596
+ index.parent = self
1597
+ end
1598
+
1599
+ # Maps on the children.
1600
+ def map_nodes!(&ruby_block)
1601
+ @index = ruby_block.call(@index)
1602
+ @index.parent = self unless @index.parent
1603
+ @ref = ruby_block.call(@ref)
1604
+ @ref.parent = self unless @ref.parent
1605
+ end
1606
+
1607
+ # Replaces sub expressions using +node2rep+ table indicating the
1608
+ # node to replace and the corresponding replacement.
1609
+ # Returns the actually replaced nodes and their corresponding
1610
+ # replacement.
1611
+ #
1612
+ # NOTE: the replacement is duplicated.
1613
+ def replace_expressions!(node2rep)
1614
+ # First recurse on the ref.
1615
+ res = self.ref.replace_expressions!(node2rep)
1616
+ # And and the index.
1617
+ res = self.index.replace_expressions!(node2rep)
1618
+
1619
+ # Is there a replacement to on the ref?
1620
+ rep = node2rep[self.ref]
1621
+ if rep then
1622
+ # Yes, do it.
1623
+ rep = rep.clone
1624
+ node = self.ref
1625
+ # node.set_parent!(nil)
1626
+ self.set_ref!(rep)
1627
+ # And register the replacement.
1628
+ res[node] = rep
1629
+ end
1630
+ # Is there a replacement to on the index?
1631
+ rep = node2rep[self.index]
1632
+ if rep then
1633
+ # Yes, do it.
1634
+ rep = rep.clone
1635
+ node = self.index
1636
+ # node.set_parent!(nil)
1637
+ self.set_index!(rep)
1638
+ # And register the replacement.
1639
+ res[node] = rep
1640
+ end
1641
+ return res
1642
+ end
1643
+ end
1644
+
1645
+
1646
+ ##
1647
+ # Describes a range reference.
1648
+ class RefRange
1649
+
1650
+ # Sets the base reference.
1651
+ def set_ref!(ref)
1652
+ # Check and set the refered object.
1653
+ # unless ref.is_a?(Ref) then
1654
+ unless ref.is_a?(Expression) then
1655
+ raise AnyError, "Invalid class for a reference: #{ref.class}."
1656
+ end
1657
+ @ref = ref
1658
+ # And set its parent.
1659
+ ref.parent = self
1660
+ end
1661
+
1662
+ # Sets the range.
1663
+ def set_range!(range)
1664
+ # Check and set the range.
1665
+ first = range.first
1666
+ unless first.is_a?(Expression) then
1667
+ raise AnyError,
1668
+ "Invalid class for a range first: #{first.class}."
1669
+ end
1670
+ last = range.last
1671
+ unless last.is_a?(Expression) then
1672
+ raise AnyError, "Invalid class for a range last: #{last.class}."
1673
+ end
1674
+ @range = first..last
1675
+ # And set their parents.
1676
+ first.parent = last.parent = self
1677
+ end
1678
+
1679
+ # Maps on the children.
1680
+ def map_nodes!(&ruby_block)
1681
+ @range = ruby_block.call(@range.first)..ruby_block.call(@range.last)
1682
+ @range.first.parent = self unless @range.first.parent
1683
+ @range.last.parent = self unless @range.last.parent
1684
+ @ref = ruby_block.call(@ref)
1685
+ @ref.parent = self unless @ref.parent
1686
+ end
1687
+
1688
+ # Replaces sub expressions using +node2rep+ table indicating the
1689
+ # node to replace and the corresponding replacement.
1690
+ # Returns the actually replaced nodes and their corresponding
1691
+ # replacement.
1692
+ #
1693
+ # NOTE: the replacement is duplicated.
1694
+ def replace_expressions!(node2rep)
1695
+ # First recurse on the ref.
1696
+ res = self.ref.replace_expressions!(node2rep)
1697
+ # And and the range.
1698
+ res = self.range.first.replace_expressions!(node2rep)
1699
+ res = self.range.last.replace_expressions!(node2rep)
1700
+
1701
+ # Is there a replacement to on the ref?
1702
+ rep = node2rep[self.ref]
1703
+ if rep then
1704
+ # Yes, do it.
1705
+ rep = rep.clone
1706
+ node = self.ref
1707
+ # node.set_parent!(nil)
1708
+ self.set_ref!(rep)
1709
+ # And register the replacement.
1710
+ res[node] = rep
1711
+ end
1712
+ # Is there a replacement to on the range first?
1713
+ range = self.range
1714
+ rep = node2rep[range.first]
1715
+ if rep then
1716
+ # Yes, do it.
1717
+ rep = rep.clone
1718
+ node = range.first
1719
+ # node.set_parent!(nil)
1720
+ range.first = rep
1721
+ # And register the replacement.
1722
+ res[node] = rep
1723
+ end
1724
+ rep = node2rep[range.last]
1725
+ if rep then
1726
+ # Yes, do it.
1727
+ rep = rep.clone
1728
+ node = range.last
1729
+ # node.set_parent!(nil)
1730
+ range.last = rep
1731
+ # And register the replacement.
1732
+ res[node] = rep
1733
+ end
1734
+ self.set_range!(range)
1735
+ return res
1736
+ end
1737
+ end
1738
+
1739
+
1740
+ ##
1741
+ # Describes a name reference.
1742
+ class RefName
1743
+ # Sets the base reference.
1744
+ def set_ref!(ref)
1745
+ # Check and set the accessed reference.
1746
+ unless ref.is_a?(Ref) then
1747
+ raise AnyError, "Invalid class for a reference: #{ref.class}."
1748
+ end
1749
+ @ref = ref
1750
+ # And set its parent.
1751
+ ref.parent = self
1752
+ end
1753
+
1754
+ # Sets the name.
1755
+ def set_name!(name)
1756
+ # Check and set the symbol.
1757
+ @name = name.to_sym
1758
+ end
1759
+
1760
+ # Maps on the children.
1761
+ def map_nodes!(&ruby_block)
1762
+ @ref = ruby_block.call(@ref)
1763
+ @ref.parent = self unless @ref.parent
1764
+ end
1765
+
1766
+ # Replaces sub expressions using +node2rep+ table indicating the
1767
+ # node to replace and the corresponding replacement.
1768
+ # Returns the actually replaced nodes and their corresponding
1769
+ # replacement.
1770
+ #
1771
+ # NOTE: the replacement is duplicated.
1772
+ def replace_expressions!(node2rep)
1773
+ # First recurse on the ref.
1774
+ res = self.ref.replace_expressions!(node2rep)
1775
+
1776
+ # Is there a replacement to on the ref?
1777
+ rep = node2rep[self.ref]
1778
+ if rep then
1779
+ # Yes, do it.
1780
+ rep = rep.clone
1781
+ node = self.ref
1782
+ # node.set_parent!(nil)
1783
+ self.set_ref!(rep)
1784
+ # And register the replacement.
1785
+ res[node] = rep
1786
+ end
1787
+ return res
1788
+ end
1789
+ end
1790
+
1791
+
1792
+ ##
1793
+ # Describe a this reference.
1794
+ #
1795
+ # This is the current system.
1796
+ class RefThis
1797
+
1798
+ # Maps on the children.
1799
+ def map_nodes!(&ruby_block)
1800
+ # Nothing to do.
1801
+ end
1802
+ end
1803
+ end