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,1888 @@
1
+ require "HDLRuby.rb"
2
+ require "HDLRuby/hruby_verilog_name.rb"
3
+
4
+ require 'HDLRuby/hruby_low_mutable'
5
+
6
+
7
+ # module HDLRuby::Verilog
8
+ include HDLRuby::Verilog
9
+
10
+ #include HDLRuby::Low
11
+ module HDLRuby::Low
12
+
13
+
14
+ # Sample of very handy for programming.
15
+ # puts "class=#{self.yes.class}" # Confirm class of self.yes.
16
+ # puts "methods=#{self.right.methods}" # Confirm method of self.right.
17
+ # puts "outputs=#{outputs}" # Confirm outputs
18
+
19
+ # each. do |*arg| # I forgot this.
20
+ # puts args
21
+ # end
22
+
23
+ # Global variable used for indentation and structure (temporary).
24
+ $space_count = 0 # Count used for increasing indent by if statement. (temporary)
25
+ $vector_reg = "" # For storing signal type at structure declaration. (temporary)
26
+ $vector_cnt = 0 # For allocating numbers at structure declaration. (temporary)
27
+
28
+ class Fixnum
29
+ def to_verilog
30
+ to_s
31
+ end
32
+ end
33
+
34
+ # Class summarizing "hash" used for "par" or "seq" conversion.
35
+ class Fm
36
+ attr_reader :fm_seq, :fm_par, :rep, :rep_sharp
37
+ def initialize
38
+ @fm_seq = {} # Used to seq -> par.
39
+ @fm_par = {} # Used to par -> seq.
40
+ @rep = {} # Used to give ' to variables
41
+ @rep_sharp = {} # Used to give # to variables
42
+ end
43
+ end
44
+
45
+ # Declaration of fm to manage each hash.
46
+ $fm = Fm.new
47
+
48
+ # A class that translates the left-hand side, operator, and right-hand side into form of expression.
49
+ class Binary
50
+ # Converts the system to Verilog code.
51
+ def to_verilog
52
+ return "(#{self.left.to_verilog} #{self.operator} #{self.right.to_verilog})"
53
+ end
54
+
55
+ # Method called when two or more expression terms are present.
56
+ # When translating par into seq mode = seq, when translating seq to par mode = par.
57
+ # Search recursively and replace if hash matches identifier.
58
+ def to_change(mode)
59
+ # Recursively search the left side and the right side, check the identifier and replace it.
60
+ if self.left.is_a? (Binary) then
61
+ # If there is an expression on the left side of the right side, to_chang is executed again.
62
+ left = self.left.to_change(mode)
63
+ else
64
+ # If you need to replace the variable, replace it. Otherwise we will get a clone.
65
+ if $fm.fm_par.has_key?(self.left.to_verilog) && mode == :par then
66
+ left = $fm.fm_par["#{self.left.to_verilog}"]
67
+ elsif $fm.fm_seq.has_key?(self.left.to_verilog) && mode == :seq then
68
+ left = $fm.fm_seq["#{self.left.to_verilog}"]
69
+ else
70
+ left = self.left.clone
71
+ end
72
+ end
73
+ if self.right.is_a? (Binary) then
74
+ # Recursively search the right side and the right side, check the identifier and replace it.
75
+ right = self.right.to_change(mode)
76
+ else
77
+ # If you need to replace the variable, replace it. Otherwise we will get a clone.
78
+ if $fm.fm_par.has_key?(self.right.to_verilog) && mode == :par then
79
+ right = $fm.fm_par["#{self.right.to_verilog}"]
80
+ elsif $fm.fm_seq.has_key?(self.right.to_verilog) && mode == :seq then
81
+ right = $fm.fm_seq["#{self.right.to_verilog}"]
82
+ else
83
+ right = self.right.clone
84
+ end
85
+ end
86
+ # After confirmation, we create and return an expression.
87
+ return Binary.new(self.type,self.operator,left.clone,right.clone)
88
+ end
89
+ end
90
+
91
+ # class of Represent blocking substitution or nonblocking assignment.
92
+ # Enhance Transmit with generation of verilog code.
93
+ class Transmit
94
+ # Converts the system to Verilog code.
95
+ def to_verilog(mode = nil)
96
+ # Determine blocking assignment or nonblocking substitution from mode and return it.
97
+ code = "#{self.left.to_verilog} #{mode == "seq" ? "=" : "<="} #{self.right.to_verilog};\n"
98
+ return code
99
+ end
100
+ end
101
+
102
+ # To scheduling to the Block.
103
+ # Enhance Block with generation of verilog code.
104
+ class Block
105
+ # Converts the system to Verilog code.
106
+ def to_verilog(mode = nil)
107
+ # No translation is done in this class.
108
+ puts "Block to_verilog not found" # For debugging
109
+ end
110
+
111
+ # Process top layer of Block.
112
+ # Determine whether there is a block under block and convert it.
113
+ def flatten(mode = nil)
114
+ new_block = Block.new(self.mode,"") # A new block to store the converted statement.
115
+ list = [] # A list for confirming that variable declarations do not overlap.
116
+
117
+ # Is block in the statement?
118
+ if (self.each_statement.find {|stmnt| stmnt.is_a?(Block)}) then
119
+ # Process for each type of statement in block.
120
+ self.each_statement do |statement|
121
+
122
+
123
+ # If statement is case, there is a block for each default and when, so translate each.
124
+ if statement.is_a?(Case) then
125
+ if statement.default.is_a?(Block)
126
+ default = statement.default.flatten
127
+ new_default = Block.new(default.mode,"")
128
+
129
+ default.each_inner do |inner|
130
+ # I read inner, but when I am par, I delete all '.
131
+ unless (list.include?(inner.name.to_s)) then
132
+ if (self.mode == :seq) || (inner.name.to_s.include? "#") then
133
+ list << inner.name.to_s
134
+ new_block.add_inner(inner.clone)
135
+ end
136
+ end
137
+ end
138
+
139
+ default.each_statement do |statement|
140
+ # If statement is Transmit, it is an expression and should be processed.
141
+ if statement.is_a?(Transmit) then
142
+ # If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
143
+ unless (res_name(statement.left).name.to_s.include? "'") || default.mode == :par then
144
+ # Prepare a new signal with the # on the variable on the left side using the att_signal method.
145
+ new_signal = att_signal(statement.left, "#")
146
+ # Check list and add new variables to inner if they do not duplicate.
147
+ unless (list.include?(new_signal.name.to_s)) then
148
+ list << new_signal.name.to_s
149
+ new_block.add_inner(new_signal)
150
+ end
151
+
152
+ new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
153
+
154
+ $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
155
+
156
+ $fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
157
+ new_default.add_statement(new_statement.clone)
158
+ else
159
+ new_default.add_statement(statement.clone)
160
+ end
161
+ else
162
+ new_default.add_statement(statement.clone)
163
+ end
164
+ end
165
+ end
166
+
167
+ new_statement = Case.new(statement.value.clone,statement.default ? new_default.clone : nil,[])
168
+
169
+ statement.each_when do |whens|
170
+ when_smt = whens.statement.flatten
171
+ new_when_smt = Block.new(when_smt.mode,"")
172
+
173
+ when_smt.each_statement do |statement|
174
+ # If statement is Transmit, it is an expression and should be processed.
175
+ if statement.is_a?(Transmit) then
176
+ # # If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
177
+ unless (res_name(statement.left).name.to_s.include? "'") || when_smt.mode == :par then
178
+ # # Prepare a new signal with the # on the variable on the left side using the att_signal method.
179
+ new_signal = att_signal(statement.left, "#")
180
+ # Check list and add new variables to inner if they do not duplicate.
181
+ unless (list.include?(new_signal.name.to_s)) then
182
+ list << new_signal.name.to_s
183
+ new_block.add_inner(new_signal)
184
+ end
185
+
186
+ new_smt = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
187
+
188
+ $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
189
+
190
+ $fm.fm_par["#{statement.left.to_verilog}"] = new_smt.left
191
+ new_when_smt.add_statement(new_smt.clone)
192
+ else
193
+ new_when_smt.add_statement(statement.clone)
194
+ end
195
+ else
196
+ new_when_smt.add_statement(statement.clone)
197
+ end
198
+ end
199
+
200
+ new_when = When.new(whens.match.clone,new_when_smt.clone)
201
+ new_statement.add_when(new_when.clone)
202
+ end
203
+
204
+ new_block.add_statement(new_statement)
205
+
206
+ $fm.rep_sharp.each_key do |key|
207
+ new_smt = Transmit.new(key.clone,$fm.rep_sharp[key].clone)
208
+ new_block.add_statement(new_smt.clone)
209
+ end
210
+ $fm.rep_sharp.clear() # Deactivate rep that has become obsolete.
211
+
212
+ # If the statement is if, there is a block for each of yes, no, noifs, so translate each.
213
+ elsif statement.is_a?(If) then
214
+ yes = statement.yes.flatten # Smooth yes of if statement.
215
+ new_yes = Block.new(yes.mode,"") # New yes storage block
216
+
217
+ yes.each_inner do |inner|
218
+ # I read inner, but when I am par, I delete all '.
219
+ unless (list.include?(inner.name.to_s)) then
220
+ if (self.mode == :seq) || (inner.name.to_s.include? "#") then
221
+ list << inner.name.to_s
222
+ new_block.add_inner(inner.clone)
223
+ end
224
+ end
225
+ end
226
+
227
+ # Check the statements in "yes" in order.
228
+ yes.each_statement do |statement|
229
+ # If statement is Transmit, it is an expression and should be processed.
230
+ if statement.is_a?(Transmit) then
231
+ # If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
232
+ unless (res_name(statement.left).name.to_s.include? "'") || yes.mode == :par then
233
+ # Prepare a new signal with the # on the variable on the left side using the att_signal method.
234
+ new_signal = att_signal(statement.left, "#")
235
+ # Check list and add new variables to inner if they do not duplicate.
236
+ unless (list.include?(new_signal.name.to_s)) then
237
+ list << new_signal.name.to_s
238
+ new_block.add_inner(new_signal)
239
+ end
240
+
241
+ new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
242
+
243
+ $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
244
+
245
+ new_yes.add_statement(new_statement.clone)
246
+
247
+
248
+ $fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
249
+
250
+ else
251
+ new_yes.add_statement(statement.clone)
252
+ end
253
+ else
254
+ new_yes.add_statement(statement.clone)
255
+ end
256
+ end
257
+
258
+ # Confirm that "else" exists and convert it if it exists.
259
+ # Because error occurs when trying to convert when "else" does not exist.
260
+ if statement.no.is_a? (Block) then
261
+ no = statement.no.flatten
262
+ new_no = Block.new(no.mode,"")
263
+
264
+ no.each_inner do |inner|
265
+ # I read inner, but when I am par, I delete all '.
266
+ unless (list.include?(inner.name.to_s)) then
267
+ if (self.mode == :seq) || (inner.name.to_s.include? "#") then
268
+ list << inner.name.to_s
269
+ new_block.add_inner(inner.clone)
270
+ end
271
+ end
272
+ end
273
+
274
+ no.each_statement do |statement|
275
+ # If statement is Transmit, it is an expression and should be processed.
276
+ if statement.is_a?(Transmit) then
277
+ # If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
278
+ unless (res_name(statement.left).name.to_s.include? "'") || yes.mode == :par then
279
+
280
+ new_signal = att_signal(statement.left, "#")
281
+
282
+ # Double declaration of existing variable can not be done, so it is excluded.
283
+ unless (list.include?(new_signal.name.to_s)) then
284
+ list << new_signal.name.to_s
285
+ new_block.add_inner(new_signal)
286
+ end
287
+
288
+ new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
289
+
290
+ $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
291
+
292
+ $fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
293
+ new_no.add_statement(new_statement.clone)
294
+ else
295
+ new_no.add_statement(statement.clone)
296
+ end
297
+ else
298
+ new_no.add_statement(statement.clone)
299
+ end
300
+ end
301
+ end
302
+
303
+ # Rebuild the converted "if" as a new" statement (If)".
304
+ new_statement = If.new(statement.condition.clone,new_yes.clone,statement.no ? new_no.clone : nil)
305
+
306
+ # Just like "no", check if "noifs (elsif)" exists and if there is, take one by one and convert.
307
+ # After that, add the converted "noif" to "If".
308
+ statement.each_noif do |condition, block|
309
+ noif = block.flatten
310
+ new_noif = Block.new(noif.mode,"")
311
+
312
+ noif.each_inner do |inner|
313
+ # I read inner, but when I am par, I delete all '.
314
+ unless (list.include?(inner.name.to_s)) then
315
+ if (self.mode == :seq) || (inner.name.to_s.include? "#") then
316
+ list << inner.name.to_s
317
+ new_block.add_inner(inner.clone)
318
+ end
319
+ end
320
+ end
321
+
322
+
323
+ noif.each_statement do |statement|
324
+ # If statement is Transmit, it is an expression and should be processed.
325
+ if statement.is_a?(Transmit) then
326
+ # If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
327
+ unless (res_name(statement.left).name.to_s.include? "'") || yes.mode == :par then
328
+
329
+ new_signal = att_signal(statement.left, "#")
330
+
331
+ # Double declaration of existing variable can not be done, so it is excluded.
332
+ unless (list.include?(new_signal.name.to_s)) then
333
+ list << new_signal.name.to_s
334
+ new_block.add_inner(new_signal)
335
+ end
336
+
337
+ new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
338
+
339
+ $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
340
+
341
+ $fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
342
+ new_noif.add_statement(new_statement.clone)
343
+ else
344
+ new_noif.add_statement(statement.clone)
345
+ end
346
+ else
347
+ new_noif.add_statement(statement.clone)
348
+ end
349
+ end
350
+
351
+ new_statement.add_noif(condition.clone,new_noif.clone)
352
+ end
353
+
354
+ new_block.add_statement(new_statement.clone)
355
+
356
+ $fm.rep_sharp.each_key do |key|
357
+ new_smt = Transmit.new(key.clone,$fm.rep_sharp[key].clone)
358
+ new_block.add_statement(new_smt.clone)
359
+ end
360
+ $fm.rep_sharp.clear() # Deactivate rep that has become obsolete.
361
+
362
+ # Process when "statement" is "Transmit" (just expression).
363
+ # Record the expression in fm_par used for par-> seq and add the expression to new_block which is the "new block".
364
+ elsif statement.is_a?(Transmit) then
365
+ if self.mode == :seq then
366
+ $fm.fm_par["#{statement.left.to_verilog}"] = statement.right
367
+ end
368
+ new_block.add_statement(statement.clone)
369
+
370
+ # When statement is Block (lower layer exists).
371
+ # Smooth the lower layer with do_flat.
372
+ # Add the added variables (inner) and expressions (statement) to new_block, respectively.
373
+ elsif statement.is_a?(Block) then
374
+ smt = statement.do_flat(self.mode)
375
+
376
+ smt.each_inner do |inner|
377
+ # I read inner, but when I am par, I delete all '.
378
+ unless (list.include?(inner.name.to_s)) then
379
+ if (self.mode == :seq) || (inner.name.to_s.include? "#") then
380
+ list << inner.name.to_s
381
+ new_block.add_inner(inner.clone)
382
+ end
383
+ end
384
+ end
385
+ smt.each_statement do |tmt|
386
+ # Retrieve the RefName of the variable on the left side and store it in this_name.
387
+ if ((tmt.is_a? (Transmit)) && (self.mode == :seq)) then
388
+ $fm.fm_par["#{tmt.left.to_verilog}"] = tmt.right
389
+ end
390
+ new_block.add_statement(tmt.clone)
391
+ end
392
+ end
393
+ end
394
+
395
+ return new_block # Return the new_block that completed the smoothing.
396
+
397
+ # Processing when there is no block beneath.
398
+ # Unlike ordinary "if" and "case" blocks come down, we check individually block under block.
399
+ else
400
+ self.each_statement do |statement|
401
+ # If the if statement, convert it, otherwise add it as is
402
+ if statement.is_a?(If) then
403
+ # Since yes always exists, it is no problem even if it is converted as it is.
404
+ yes = statement.yes.flatten
405
+ new_yes = Block.new(yes.mode,"")
406
+
407
+ yes.each_inner do |inner|
408
+ # I read inner, but when I am par, I delete all '.
409
+ unless (list.include?(inner.name.to_s)) then
410
+ if (yes.mode == :seq) || (inner.name.to_s.include? "#") then
411
+ list << inner.name.to_s
412
+ new_block.add_inner(inner.clone)
413
+ end
414
+ end
415
+ end
416
+
417
+ # Check the statements in "yes" in order.
418
+ yes.each_statement do |statement|
419
+ # If statement is Transmit, it is an expression and should be processed.
420
+ if statement.is_a?(Transmit) then
421
+ # If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
422
+ unless (res_name(statement.left).name.to_s.include? "'") || yes.mode == :par then
423
+ # Generate a new signal to return #.
424
+ new_signal = att_signal(statement.left, "#")
425
+
426
+ # Double declaration of existing variable can not be done, so it is excluded.
427
+ unless (list.include?(new_signal.name.to_s)) then
428
+ list << new_signal.name.to_s
429
+ new_block.add_inner(new_signal)
430
+ end
431
+
432
+ new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
433
+
434
+ $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
435
+
436
+ $fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
437
+ new_yes.add_statement(new_statement.clone)
438
+ else
439
+ new_yes.add_statement(statement.clone)
440
+ end
441
+ else
442
+ new_yes.add_statement(statement.clone)
443
+ end
444
+ end
445
+
446
+ # Confirm that "else" exists and convert it if it exists.
447
+ # Because error occurs when trying to convert when "else" does not exist.
448
+ if statement.no.is_a? (Block) then
449
+ no = statement.no.flatten
450
+ new_no = Block.new(no.mode,"")
451
+
452
+ no.each_inner do |inner|
453
+ # I read inner, but when I am par, I delete all '.
454
+ unless (list.include?(inner.name.to_s)) then
455
+ if (no.mode == :seq) || (inner.name.to_s.include? "#") then
456
+ list << inner.name.to_s
457
+ new_block.add_inner(inner.clone)
458
+ end
459
+ end
460
+ end
461
+
462
+ no.each_statement do |statement|
463
+ # If statement is Transmit, it is an expression and should be processed.
464
+ if statement.is_a?(Transmit) then
465
+ # If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
466
+ unless (res_name(statement.left).name.to_s.include? "'") || no.mode == :par then
467
+
468
+ new_signal = att_signal(statement.left, "#")
469
+
470
+ # Double declaration of existing variable can not be done, so it is excluded.
471
+ unless (list.include?(new_signal.name.to_s)) then
472
+ list << new_signal.name.to_s
473
+ new_block.add_inner(new_signal)
474
+ end
475
+
476
+ new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
477
+
478
+ $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
479
+
480
+ $fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
481
+ new_no.add_statement(new_statement.clone)
482
+ else
483
+ new_no.add_statement(statement.clone)
484
+ end
485
+ else
486
+ new_no.add_statement(statement.clone)
487
+ end
488
+ end
489
+ end
490
+ # Rebuild the converted "if" as a new" statement (If)".
491
+ new_statement = If.new(statement.condition.clone,new_yes.clone,statement.no ? new_no.clone : nil)
492
+ # Just like "no", check if "noifs (elsif)" exists and if there is, take one by one and convert.
493
+ # After that, add the converted "noif" to "If".
494
+ statement.each_noif do |condition, block|
495
+
496
+ noif = block.flatten
497
+ new_noif = Block.new(noif.mode,"")
498
+
499
+ noif.each_inner do |inner|
500
+ # I read inner, but when I am par, I delete all '.
501
+ unless (list.include?(inner.name.to_s)) then
502
+ if (noif.mode == :seq) || (inner.name.to_s.include? "#") then
503
+ list << inner.name.to_s
504
+ new_block.add_inner(inner.clone)
505
+ end
506
+ end
507
+ end
508
+
509
+
510
+ noif.each_statement do |statement|
511
+ # If statement is Transmit, it is an expression and should be processed.
512
+ if statement.is_a?(Transmit) then
513
+ # If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
514
+ unless (res_name(statement.left).name.to_s.include? "'") || noif.mode == :par then
515
+
516
+ new_signal = att_signal(statement.left, "#")
517
+
518
+ # Double declaration of existing variable can not be done, so it is excluded.
519
+ unless (list.include?(new_signal.name.to_s)) then
520
+ list << new_signal.name.to_s
521
+ new_block.add_inner(new_signal)
522
+ end
523
+
524
+ new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
525
+
526
+ $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
527
+
528
+ $fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
529
+ new_noif.add_statement(new_statement.clone)
530
+ else
531
+ new_noif.add_statement(statement.clone)
532
+ end
533
+ else
534
+ new_noif.add_statement(statement.clone)
535
+ end
536
+ end
537
+
538
+ new_statement.add_noif(condition.clone,new_noif.clone)
539
+ end
540
+
541
+ new_block.add_statement(new_statement.clone)
542
+
543
+ $fm.rep_sharp.each_key do |key|
544
+ new_smt = Transmit.new(key.clone,$fm.rep_sharp[key].clone)
545
+ new_block.add_statement(new_smt.clone)
546
+ end
547
+ $fm.rep_sharp.clear() # Deactivate rep that has become obsolete.
548
+
549
+ elsif statement.is_a?(Case) then
550
+ if statement.default.is_a?(Block)
551
+ new_default = statement.default.flatten
552
+ end
553
+
554
+ new_statement = Case.new(statement.value.clone,statement.default ? new_default.clone : nil,[])
555
+ statement.each_when do |whens|
556
+ new_when_statement = whens.statement.flatten
557
+ new_when = When.new(whens.match.clone,new_when_statement.clone)
558
+
559
+ new_statement.add_when(new_when.clone)
560
+ end
561
+
562
+ new_block.add_statement(new_statement)
563
+ else
564
+ new_block.add_statement(statement.clone)
565
+ end
566
+ end
567
+ return new_block
568
+ end
569
+ end
570
+
571
+ def do_flat(mode = nil)
572
+ flat = Block.new(self.mode,"") # Block between lower layers when converting.
573
+ trans = Block.new(self.mode,"") # The block used for converting itself.
574
+ replase = Block.new(self.mode,"") # block to be used for further conversion in case of if statement.
575
+ list = []
576
+ rep_list = []
577
+
578
+ # If there is a block inside the statement it is not the lowest layer. If there is, it is the lowest layer.
579
+ if (self.each_statement.find {|stmnt| stmnt.is_a?(Block)} || (self.each_statement.find {|stmnt| stmnt.is_a?(If)}) || (self.each_statement.find {|stmnt| stmnt.is_a?(Case)}))then
580
+ # In the case of seq, the lower layer is par. Isolate fm_par so that it is not crosstalked.
581
+ if(self.mode == :seq) then
582
+ fm_buckup = $fm.fm_par.clone
583
+ $fm.fm_par.clear()
584
+
585
+ new_block = change_branch(self)
586
+ else
587
+ new_block = self.clone
588
+ end
589
+
590
+ # Process for each statement.
591
+ new_block.each_statement do |statement|
592
+ # If statement is If, convert yes, no, noif and add them to flat.
593
+ if statement.is_a?(Case) then
594
+ if(self.mode == :seq) then
595
+ fm_buckup_if = $fm.fm_par.clone
596
+ end
597
+
598
+ if statement.default.is_a?(Block)
599
+ default = statement.default.flatten
600
+ new_default = Block.new(default.mode,"")
601
+
602
+ default.each_statement do |statement|
603
+ new_default.add_statement(statement.clone)
604
+ end
605
+ end
606
+
607
+
608
+ new_statement = Case.new(statement.value.clone,statement.default ? new_default.clone : nil,[])
609
+
610
+ statement.each_when do |whens|
611
+ if(self.mode == :seq) then
612
+ fm_buckup_if.each_key do |key|
613
+ $fm.fm_par[key] = fm_buckup_if[key]
614
+ end
615
+ end
616
+
617
+ when_smt = whens.statement.flatten
618
+ new_when = When.new(whens.match.clone,when_smt.clone)
619
+ new_statement.add_when(new_when.clone)
620
+ end
621
+ flat.add_statement(new_statement)
622
+
623
+ elsif statement.is_a?(If) then
624
+ if(self.mode == :seq) then
625
+ fm_buckup_if = $fm.fm_par.clone
626
+ end
627
+
628
+ # Since yes always exist, convert without confirming.
629
+ new_yes = statement.yes.flatten
630
+
631
+ # I do not know whether no (else) exists, so convert it if it is confirmed.
632
+ if statement.no.is_a? (Block) then
633
+
634
+ if(self.mode == :seq) then
635
+ fm_buckup_if.each_key do |key|
636
+ $fm.fm_par[key] = fm_buckup_if[key]
637
+ end
638
+ end
639
+
640
+ new_no = statement.no.flatten
641
+ end
642
+ # Create a new if statement with converted yes and no.
643
+ new_statement = If.new(statement.condition.clone,new_yes.clone,statement.no ? new_no.clone : nil)
644
+
645
+ # Since I do not know whether there is noifs (elsif), I convert it and add it if it is confirmed.
646
+ statement.each_noif do |condition, block|
647
+ if(self.mode == :seq) then
648
+ fm_buckup_if.each_key do |key|
649
+ $fm.fm_par[key] = fm_buckup_if[key]
650
+ end
651
+ end
652
+
653
+ new_noif = block.flatten
654
+ new_statement.add_noif(condition.clone,new_noif.clone)
655
+ end
656
+ # Add the new statement (if statement) created to flat.
657
+ flat.add_statement(new_statement.clone)
658
+
659
+ # If statement is Transmit, record the expression in fm_par and add the expression to flat as it is.
660
+ elsif statement.is_a?(Transmit) then
661
+ if(self.mode == :seq) then
662
+ $fm.fm_par["#{statement.left.to_verilog}"] = statement.right.clone
663
+ end
664
+
665
+ flat.add_statement(statement.clone)
666
+ # If statement is Block, convert it with do_flat and add the returned expression and variable to flat respectively.
667
+
668
+ elsif statement.is_a?(Block) then
669
+ smt = statement.do_flat(self.mode)
670
+ # If smt has inner, check it separately and add it if it's convenient.
671
+ smt.each_inner do |inner|
672
+ if self.mode == :seq then
673
+ unless (list.include?(inner.name.to_s)) then
674
+ list << inner.name.to_s
675
+ flat.add_inner(inner.clone)
676
+ end
677
+ else
678
+ unless (list.include?(inner.name.to_s)) then
679
+ if(inner.name.to_s.include? "#") then
680
+ list << inner.name.to_s
681
+ flat.add_inner(inner.clone) # It was new_block. why?
682
+ end
683
+ end
684
+ end
685
+ end
686
+ # If it is seq, the expression after conversion is also likely to be used, so record the expression.
687
+ smt.each_statement do |tmt|
688
+ if self.mode == :seq then
689
+ $fm.fm_par["#{tmt.left.to_verilog}"] = tmt.right.clone
690
+ end
691
+ flat.add_statement(tmt.clone)
692
+ end
693
+ end
694
+ end
695
+
696
+ # Overwrite to restore fm_par which was quarantined.
697
+ if(self.mode == :seq) then
698
+ $fm.fm_par.clear()
699
+ fm_buckup.each_key do |key|
700
+ $fm.fm_par[key] = fm_buckup[key]
701
+ end
702
+ end
703
+
704
+
705
+
706
+ # Since it is a middle tier itself, it performs flat transformation, shifts inner, and returns the result.
707
+ trans = flat.to_conversion(mode)
708
+
709
+
710
+ # Write an expression that assigns an identifier that added # to an identifier that has not added.
711
+ trans.each_statement do |statement|
712
+ replase.add_statement(statement.clone)
713
+ if statement.is_a?(If)
714
+ $fm.rep_sharp.each_key do |key|
715
+ new_statement = Transmit.new(key.clone,$fm.rep_sharp[key].clone)
716
+ replase.add_statement(new_statement.clone)
717
+ end
718
+ $fm.rep_sharp.clear() # Deactivate rep that has become obsolete.
719
+ end
720
+ end
721
+
722
+ # Extract the inner left in flat and add it to replase.
723
+ flat.each_inner do |inner|
724
+ replase.add_inner(inner.clone)
725
+ end
726
+
727
+ # Extract the inner left in trans and add it to replase.
728
+ trans.each_inner do |inner|
729
+ replase.add_inner(inner.clone)
730
+ end
731
+
732
+ return replase
733
+
734
+ # Processing when there is no block (reaching the bottom layer).
735
+ else
736
+ # Since it is the lowest layer, it does not smooth but converts itself and returns it.
737
+ flat = self.to_conversion(mode)
738
+ return flat
739
+ end
740
+ end
741
+
742
+ def to_conversion(mode = nil, rst = true, rep = true)
743
+ flat = Block.new(mode,"") # Block that stores results.
744
+ new_yes = Block.new(mode,"") # Block containing the new yes.
745
+ new_no = Block.new(mode,"") # Block containing the new no.
746
+ new_noif = Block.new(mode,"") # Block containing the new noif.
747
+ list = []
748
+
749
+ if rst == false then
750
+ fm_seq_backup = $fm.fm_seq.dup
751
+ end
752
+
753
+ # The statement is divided (since it is the lowest layer, there is only Transmit).
754
+ self.each_statement do |statement|
755
+ # Various processing is performed depending on the type of Transmit.
756
+ # If the mode of the upper layer = its own mode, it compresses as it is.
757
+
758
+ if(mode == self.mode) then
759
+ new_statement = statement.clone
760
+ # In the case of an If statement, processing of if, else, elsif is performed.
761
+ elsif statement.is_a?(Case) then
762
+
763
+ if statement.default.is_a?(Block)
764
+ rep_buckup = $fm.rep.dup
765
+ $fm.rep.clear()
766
+ default = statement.default.to_conversion(mode,false,false)
767
+ $fm.rep.clear()
768
+ rep_buckup.each_key do |key|
769
+ $fm.rep[key] = rep_buckup[key]
770
+ end
771
+
772
+ new_default = Block.new(default.mode,"")
773
+
774
+ default.each_inner do |inner|
775
+ # I read inner, but when I am par, I delete all '.
776
+ unless (list.include?(inner.name.to_s)) then
777
+ if (self.mode == :seq) || (inner.name.to_s.include? "#") then
778
+ list << inner.name.to_s
779
+ flat.add_inner(inner.clone)
780
+ end
781
+ end
782
+ end
783
+
784
+ default.each_statement do |statement|
785
+ # If statement is Transmit, it is an expression and should be processed.
786
+ if statement.is_a?(Transmit) then
787
+ # If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
788
+ unless (res_name(statement.left).name.to_s.include? "'") || default.mode == :par then
789
+ # Prepare a new signal with the # on the variable on the left side using the att_signal method.
790
+ new_signal = att_signal(statement.left, "#")
791
+ # Check list and add new variables to inner if they do not duplicate.
792
+ unless (list.include?(new_signal.name.to_s)) then
793
+ list << new_signal.name.to_s
794
+ flat.add_inner(new_signal)
795
+ end
796
+
797
+ new_smt = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
798
+
799
+ $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
800
+
801
+ $fm.fm_par["#{statement.left.to_verilog}"] = new_smt.left
802
+ new_default.add_statement(new_smt.clone)
803
+ else
804
+ new_default.add_statement(statement.clone)
805
+ end
806
+ else
807
+ new_default.add_statement(statement.clone)
808
+ end
809
+ end
810
+ end
811
+
812
+
813
+ new_statement = Case.new(statement.value.clone,statement.default ? new_default.clone : nil,[])
814
+
815
+ statement.each_when do |whens|
816
+
817
+ rep_buckup = $fm.rep.dup
818
+ $fm.rep.clear()
819
+ when_smt = whens.statement.to_conversion(mode,false,false)
820
+ $fm.rep.clear()
821
+ rep_buckup.each_key do |key|
822
+ $fm.rep[key] = rep_buckup[key]
823
+ end
824
+
825
+ new_when_smt = Block.new(when_smt.mode,"")
826
+
827
+ when_smt.each_statement do |statement|
828
+ # If statement is Transmit, it is an expression and should be processed.
829
+ if statement.is_a?(Transmit) then
830
+ # If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
831
+ unless (res_name(statement.left).name.to_s.include? "'") || when_smt.mode == :par then
832
+ # Prepare a new signal with the # on the variable on the left side using the att_signal method.
833
+ new_signal = att_signal(statement.left, "#")
834
+ # Check list and add new variables to inner if they do not duplicate.
835
+ unless (list.include?(new_signal.name.to_s)) then
836
+ list << new_signal.name.to_s
837
+ flat.add_inner(new_signal)
838
+ end
839
+
840
+ new_smt = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
841
+
842
+ $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
843
+
844
+ $fm.fm_par["#{statement.left.to_verilog}"] = new_smt.left
845
+ new_when_smt.add_statement(new_smt.clone)
846
+ else
847
+ new_when_smt.add_statement(statement.clone)
848
+ end
849
+ else
850
+ new_when_smt.add_statement(statement.clone)
851
+ end
852
+ end
853
+
854
+ new_when = When.new(whens.match.clone,new_when_smt.clone)
855
+ new_statement.add_when(new_when.clone)
856
+ end
857
+
858
+ elsif statement.is_a?(If) then
859
+
860
+ rep_buckup = $fm.rep.dup
861
+ $fm.rep.clear()
862
+ yes = statement.yes.to_conversion(mode, false,false)
863
+ $fm.rep.clear()
864
+ rep_buckup.each_key do |key|
865
+ $fm.rep[key] = rep_buckup[key]
866
+ end
867
+
868
+ yes.each_inner do |inner|
869
+ unless (list.include?(inner.name.to_s)) then
870
+ if (yes.mode == :seq) || (inner.name.to_s.include? "#") then
871
+ list << inner.name.to_s
872
+ flat.add_inner(inner.clone) # It was new_block. why?
873
+ end
874
+ end
875
+ end
876
+
877
+ yes.each_statement do |smt|
878
+ if(yes.mode == :seq) then
879
+ new_signal = att_signal(smt.left, "#")
880
+
881
+ unless (list.include?(new_signal.name.to_s)) then
882
+ list << new_signal.name.to_s
883
+ flat.add_inner(new_signal)
884
+ end
885
+
886
+ yes_statement = Transmit.new(search_refname(smt.left,"#"),smt.right.clone)
887
+
888
+ $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
889
+
890
+ $fm.fm_par["#{smt.left.to_verilog}"] = yes_statement.left
891
+ new_yes.add_statement(yes_statement)
892
+ else
893
+ new_yes.add_statement(smt.clone)
894
+ end
895
+ end
896
+
897
+ if statement.no.is_a? (Block) then
898
+ rep_buckup = $fm.rep.dup
899
+ $fm.rep.clear()
900
+ no = statement.no.to_conversion(mode,false,false)
901
+ $fm.rep.clear()
902
+ rep_buckup.each_key do |key|
903
+ $fm.rep[key] = rep_buckup[key]
904
+ end
905
+
906
+ no.each_inner do |inner|
907
+ unless (list.include?(inner.name.to_s)) then
908
+ if (no.mode == :seq) || (inner.name.to_s.include? "#") then
909
+ list << inner.name.to_s
910
+ flat.add_inner(inner.clone) # It was new_block. why?
911
+ end
912
+ end
913
+ end
914
+
915
+ no.each_statement do |smt|
916
+ if(no.mode == :seq) then
917
+ new_signal = att_signal(smt.left, "#")
918
+
919
+ unless (list.include?(new_signal.name.to_s)) then
920
+ list << new_signal.name.to_s
921
+ flat.add_inner(new_signal)
922
+ end
923
+
924
+ no_statement = Transmit.new(search_refname(smt.left,"#"),smt.right.clone)
925
+
926
+ $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
927
+
928
+ $fm.fm_par["#{smt.left.to_verilog}"] = no_statement.left
929
+ new_no.add_statement(no_statement)
930
+ else
931
+ new_no.add_statement(smt.clone)
932
+ end
933
+ end
934
+ end
935
+
936
+ new_statement = If.new(statement.condition.clone,new_yes.clone,statement.no ? new_no.clone : nil)
937
+
938
+ statement.each_noif do |condition, block|
939
+ rep_buckup = $fm.rep.dup
940
+ $fm.rep.clear()
941
+ noif = block.to_conversion(mode,false,false)
942
+ $fm.rep.clear()
943
+ rep_buckup.each_key do |key|
944
+ $fm.rep[key] = rep_buckup[key]
945
+ end
946
+
947
+ noif.each_inner do |inner|
948
+ unless (list.include?(inner.name.to_s)) then
949
+ if (noif.mode == :seq) || (inner.name.to_s.include? "#") then
950
+ list << inner.name.to_s
951
+ flat.add_inner(inner.clone) # It was new_block. why?
952
+ end
953
+ end
954
+ end
955
+
956
+ noif.each_statement do |smt|
957
+ if(noif.mode == :seq) then
958
+ new_signal = att_signal(smt.left, "#")
959
+
960
+ unless (list.include?(new_signal.name.to_s)) then
961
+ list << new_signal.name.to_s
962
+ flat.add_inner(new_signal)
963
+ end
964
+
965
+ noif_statement = Transmit.new(search_refname(smt.left,"#"),smt.right.clone)
966
+
967
+ $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
968
+
969
+ $fm.fm_par["#{smt.left.to_verilog}"] = noif_statement.left
970
+ new_noif.add_statement(no_statement)
971
+ else
972
+ new_noif.add_statement(smt.clone)
973
+ end
974
+ end
975
+
976
+ new_statement.add_noif(condition.clone,new_noif.clone)
977
+ end
978
+
979
+ # Otherwise, it is necessary to process par-> seq or seq-> par.
980
+ else
981
+ # Make sure the right side is a formula (Binary).
982
+ if statement.right.is_a?(Binary) then
983
+ # Check the right side and the left side, and if they are variables, check the corresponding expressions and replace them.
984
+ # If it is not a variable, it calls the method to be searched.
985
+ if statement.right.left.is_a? (Ref) then
986
+ if (mode == :par && self.mode == :seq) && $fm.fm_seq.has_key?(statement.right.left.to_verilog) then
987
+ statement_left = $fm.fm_seq["#{statement.right.left.to_verilog}"]
988
+ elsif (mode == :seq && self.mode == :par) && $fm.fm_par.has_key?(statement.right.left.to_verilog) then
989
+ statement_left = $fm.fm_par["#{statement.right.left.to_verilog}"]
990
+ else
991
+ statement_left = statement.right.left.clone
992
+ end
993
+ elsif statement.right.left.is_a? (Binary) then
994
+ statement_left = statement.right.left.to_change(self.mode)
995
+ else
996
+ statement_left = statement.right.left.clone
997
+ end
998
+
999
+ if statement.right.right.is_a? (Ref) then
1000
+ if (mode == :par && self.mode == :seq) && $fm.fm_seq.has_key?(statement.right.right.to_verilog) then
1001
+ statement_right = $fm.fm_seq["#{statement.right.right.to_verilog}"]
1002
+ elsif (mode == :seq && self.mode == :par) && $fm.fm_par.has_key?(statement.right.right.to_verilog) then
1003
+ statement_right = $fm.fm_par["#{statement.right.right.to_verilog}"]
1004
+ else
1005
+ statement_right = statement.right.right.clone
1006
+ end
1007
+ elsif statement.right.right.is_a? (Binary) then
1008
+ statement_right = statement.right.right.to_change(self.mode)
1009
+ else
1010
+ statement_right = statement.right.right.clone
1011
+ end
1012
+ new_right = Binary.new(statement.right.type,statement.right.operator,statement_left.clone,statement_right.clone)
1013
+ # Confirm whether it is a variable.
1014
+ elsif statement.right.is_a?(Ref) then
1015
+ if (mode == :par && self.mode == :seq) && $fm.fm_seq.has_key?(statement.right.to_verilog) then
1016
+ new_right = $fm.fm_seq["#{statement.right.to_verilog}"].clone
1017
+ elsif (mode == :seq && self.mode == :par) && $fm.fm_par.has_key?(statement.right.to_verilog) then
1018
+ new_right = $fm.fm_par["#{statement.right.to_verilog}"].clone
1019
+ else
1020
+ new_right = statement.right.clone
1021
+ end
1022
+ # Because it is not a number. Put it in as it is.
1023
+ else
1024
+ new_right = statement.right.clone
1025
+ end
1026
+
1027
+ if (mode == :par && self.mode == :seq) then
1028
+ # Dock the existing left hand side and the replaced right hand side to create a new expression.
1029
+ # Record the expression after conversion to hash to continue seq-> par.
1030
+ new_statement = Transmit.new(statement.left.clone,new_right)
1031
+ $fm.fm_seq["#{statement.left.to_verilog}"] = new_right
1032
+ elsif (mode == :seq && self.mode == :par) && (rep) then
1033
+ unless (res_name(statement.left).name.to_s.include? "#")
1034
+ # Search the variable on the left side and give 'to the name.
1035
+ new_signal = att_signal(statement.left,"'")
1036
+
1037
+ unless (list.include?(new_signal.name.to_s)) then
1038
+ list << new_signal.name.to_s
1039
+ flat.add_inner(new_signal)
1040
+ end
1041
+
1042
+ new_statement = Transmit.new(search_refname(statement.left,"'"),new_right)
1043
+
1044
+ $fm.rep[statement.left] = new_statement
1045
+ end
1046
+ else
1047
+ new_statement = Transmit.new(statement.left.clone,new_right)
1048
+ end
1049
+ end
1050
+ # Add the converted statement to flat (because par -> par or seq -> seq will be added until then).
1051
+
1052
+ if new_statement.is_a?(Transmit) then
1053
+ unless (mode == :par && self.mode == :seq) && (res_name(new_statement.left).name.to_s.include? "'") then
1054
+ flat.add_statement(new_statement.clone)
1055
+ end
1056
+ else
1057
+ flat.add_statement(new_statement.clone)
1058
+ end
1059
+
1060
+ if (rep)
1061
+ $fm.rep_sharp.each_key do |key|
1062
+ new_smt = Transmit.new(key.clone,$fm.rep_sharp[key].clone)
1063
+ flat.add_statement(new_smt.clone)
1064
+ end
1065
+ $fm.rep_sharp.clear() # Deactivate rep that has become obsolete.
1066
+ end
1067
+ end
1068
+ # Add an expression after paragraph based on rep.
1069
+ # A complement expression like x = x '.
1070
+ $fm.rep.each_key do |key|
1071
+ new_statement = Transmit.new(key.clone,$fm.rep[key].left.clone)
1072
+ flat.add_statement(new_statement.clone)
1073
+ end
1074
+ $fm.rep.clear() # Deactivate rep that has become obsolete.
1075
+
1076
+
1077
+ # Since seq -> par is the end, fm_par is deleted.
1078
+ if (mode == :par && self.mode == :seq) then
1079
+ $fm.fm_seq.clear()
1080
+ end
1081
+
1082
+ # In case of if statement (when rst == false) you can not convert no or else if you delete the contents of fm_seq.
1083
+ # Therefore, in this case restore the backup to restore.
1084
+ # This means that it is necessary to erase fm_seq once obtained in the if statement once.
1085
+ if(rst == false) then
1086
+ $fm.fm_seq.clear()
1087
+ fm_seq_backup.each_key do |key|
1088
+ $fm.fm_seq[key] = fm_seq_backup[key]
1089
+ end
1090
+ end
1091
+
1092
+ return flat # Return flat finished checking.
1093
+ end
1094
+
1095
+
1096
+ def change_branch(block)
1097
+ flat = Block.new(self.mode,"") # Store the expression until if is found.
1098
+ trans = Block.new(self.mode,"") # A block that stores the expression after if is found.
1099
+ new_block = Block.new(self.mode,"") # Block storing each converted expression.
1100
+
1101
+ has_branch = false # It is true if there is an if in the block.
1102
+ more_has_branch = false # It is true if there are two or more if in the block.
1103
+
1104
+ # Search each expression for if.
1105
+ block.each_statement do |statement|
1106
+ if (has_branch)
1107
+ trans.add_statement(statement.clone)
1108
+ if statement.is_a?(If) || statement.is_a?(Case) then
1109
+ more_has_branch = true
1110
+ end
1111
+ else
1112
+ if statement.is_a?(If) || statement.is_a?(Case) then
1113
+ flat.add_statement(statement.clone)
1114
+ has_branch = true
1115
+ else
1116
+ flat.add_statement(statement.clone)
1117
+ end
1118
+ end
1119
+ end
1120
+
1121
+ # If there are two or more if, recursively process if.
1122
+ if(more_has_branch) then
1123
+ conversion_block = change_branch(trans)
1124
+ else
1125
+ conversion_block = trans.clone
1126
+ end
1127
+
1128
+ # Store "trans" contents for "if" and "case" in "flat".
1129
+ flat.each_statement do |statement|
1130
+ # Since case statements include defaulu and when, we store the expressions saved in each case.
1131
+ if statement.is_a?(Case) then
1132
+ if statement.default.is_a?(Block)
1133
+ new_default = statement.default.clone
1134
+ conversion_block.each_statement do |smt|
1135
+ new_default.add_statement(smt.clone)
1136
+ end
1137
+ end
1138
+
1139
+ new_statement = Case.new(statement.value.clone,statement.default ? new_default.clone : nil,[])
1140
+
1141
+ statement.each_when do |whens|
1142
+ new_when = whens.clone
1143
+
1144
+ conversion_block.each_statement do |smt|
1145
+ new_when.statement.add_statement(smt.clone)
1146
+ end
1147
+ new_statement.add_when(new_when.clone)
1148
+ end
1149
+
1150
+ new_block.add_statement(new_statement.clone)
1151
+ # Because there are yes, no and noifs in the if statement, store the expression saved in each.
1152
+ elsif statement.is_a?(If) then
1153
+ new_yes = statement.yes.clone
1154
+ conversion_block.each_statement do |smt|
1155
+ new_yes.add_statement(smt.clone)
1156
+ end
1157
+
1158
+ if statement.no.is_a? (Block) then
1159
+ new_no = statement.no.clone
1160
+ conversion_block.each_statement do |smt|
1161
+ new_no.add_statement(smt.clone)
1162
+ end
1163
+ end
1164
+
1165
+ # Make new if with converted yes and no.
1166
+ new_statement = If.new(statement.condition.clone,new_yes.clone,statement.no ? new_no.clone : nil)
1167
+
1168
+
1169
+ statement.each_noif do |condition, block|
1170
+ new_noif = block.clone
1171
+ conversion_block.each_statement do |smt|
1172
+ new_noif.add_statement(smt.clone)
1173
+ end
1174
+ new_statement.add_noif(condition.clone,new_noif.clone)
1175
+ end
1176
+ # Add the new statement (if) created to flat.
1177
+ new_block.add_statement(new_statement.clone)
1178
+ else
1179
+ new_block.add_statement(statement.clone)
1180
+ end
1181
+ end
1182
+
1183
+ return new_block # Return block after conversion.
1184
+ end
1185
+
1186
+ # Generate a signal for the variable to which "'" or "#" is added.
1187
+ def att_signal(left,att = "'")
1188
+ this_name = res_name(left)
1189
+ new_name = RefName.new(this_name.type, this_name.ref.clone, this_name.name.to_s + att)
1190
+ new_signal = SignalI.new(new_name.name,new_name.type)
1191
+
1192
+ return new_signal
1193
+ end
1194
+
1195
+ # A method that takes a variable from the sent left side and adds "att".
1196
+ def att_sharp(left,att = "'")
1197
+ #if left.is_a?(RefName) then
1198
+ new_left = search_refname(left, att)
1199
+ #elsif left.is_a?(RefIndex) then
1200
+ # new_ref = search_refname(left, att)
1201
+ # new_left = RefIndex.new(left.type, new_ref, left.index.clone)
1202
+ #elsif left.is_a?(RefRange) then
1203
+ # new_ref = search_refname(left, att)
1204
+ # my_range = left.range
1205
+ # new_left = RefRange.new(left.type, new_ref, my_range.first.clone..my_range.last.clone)
1206
+ #end
1207
+
1208
+ # Add new signal to hash.
1209
+ # if(att == "#") then
1210
+ # $fm.rep_sharp[left] = new_left
1211
+ # end
1212
+ return new_left
1213
+ end
1214
+
1215
+
1216
+ # Recursively search, add "att" to RefName and return.
1217
+ def search_refname(me,att = "'")
1218
+ if me.is_a? (RefName) then
1219
+ return RefName.new(me.type, me.ref.clone, me.name.to_s + att)
1220
+ elsif me.ref.is_a? (RefName) then
1221
+ return RefName.new(me.ref.type, me.ref.ref.clone, me.ref.name.to_s + att)
1222
+ elsif me.ref.is_a? (RefIndex) then
1223
+ return RefIndex.new(me.ref.type, search_refname(me.ref), me.ref.index.clone)
1224
+ elsif me.ref.is_a? (RefRange) then
1225
+ my_range = me.ref.range
1226
+ return RefRange.new(me.ref.type, search_refname(me.ref), my_range.first.clone..my_range.last.clone)
1227
+ end
1228
+ end
1229
+
1230
+ # Recursively search, return Refname.
1231
+ def res_name(me)
1232
+ if me.is_a? (RefName) then
1233
+ return me
1234
+ else
1235
+ if me.ref.is_a? (RefName) then
1236
+ return RefName.new(me.ref.type, me.ref.ref.clone, me.ref.name.to_s)
1237
+ elsif me.ref.is_a? (RefIndex) then
1238
+ return res_name(me.ref)
1239
+ elsif me.ref.is_a? (RefRange) then
1240
+ return res_name(me.ref)
1241
+ end
1242
+ end
1243
+ end
1244
+ end
1245
+
1246
+ # Used to display variable names.
1247
+ # Enhance RefName with generation of verilog code.
1248
+ class RefName
1249
+ # Converts the system to Verilog code using +renamer+ for producing Verilog-compatible names.
1250
+ def to_verilog
1251
+ # return "#{self.name.to_s}"
1252
+ return "#{name_to_verilog(self.name)}"
1253
+ end
1254
+
1255
+ # Used for instantiation (emergency procedure).
1256
+ def to_another_verilog
1257
+ return "_#{self.name.to_s}"
1258
+ end
1259
+
1260
+ def ancestor(my)
1261
+ if my.parent.parent.respond_to? (:mode) then
1262
+ return ancestor(my.parent)
1263
+ else
1264
+ return "#{my.parent.mode.to_s}#{my.mode.to_s}"
1265
+ end
1266
+ end
1267
+ end
1268
+
1269
+ # Used to convert an array.
1270
+ # Enhance RefIndex with generation of verilog code.
1271
+ class RefIndex
1272
+ # Converts the system to Verilog code.
1273
+ def to_verilog
1274
+ return "#{self.ref.to_verilog}[#{self.index.to_verilog}]"
1275
+ end
1276
+ end
1277
+
1278
+
1279
+ # Used to indicate the number of bits.
1280
+ # Enhance TypeVector with generation of verilog code.
1281
+ class TypeVector
1282
+ # Converts the system to Verilog code.
1283
+ def to_verilog
1284
+ if self.base.name.to_s != "bit"
1285
+ return " #{self.base.name.to_s}[#{self.range.first}:#{self.range.last}]"
1286
+ end
1287
+ return " [#{self.range.first}:#{self.range.last}]"
1288
+ end
1289
+ end
1290
+
1291
+ # Necessary for displaying bit width (eg, specify and assign).
1292
+ class RefRange
1293
+ # Converts the system to Verilog code.
1294
+ def to_verilog(unknown = false)
1295
+ return "#{self.ref.to_verilog}[#{self.range.first.to_getrange}:#{self.range.last.to_getrange}]"
1296
+ end
1297
+ end
1298
+
1299
+ # Used to output bitstring.
1300
+ # Enhance HDLRuby with generation of verilog code.
1301
+ class HDLRuby::BitString
1302
+ # Converts the system to Verilog code.
1303
+ def to_verilog
1304
+ return "#{self.to_s}"
1305
+ end
1306
+ end
1307
+
1308
+ # Used for connection using choice.
1309
+ # Enhance Select with generation of verilog code.
1310
+ class Select
1311
+ # Converts the system to Verilog code.
1312
+ def to_verilog
1313
+ # Outputs the first and second choices (choice (0) and choice (1)).
1314
+ return "#{self.select.to_verilog} == 1 #{self.operator} #{self.get_choice(0).to_verilog} : #{self.get_choice(1).to_verilog}"
1315
+ end
1316
+ end
1317
+
1318
+ # Used to output numbers.
1319
+ # Enhance Value with generation of verilog code.
1320
+ class Value
1321
+ # Converts the system to Verilog code.
1322
+ # If it is bit, it is b, and if it is int, it is represented by d. (Example: 4'b0000, 32'd1)
1323
+ def to_verilog(unknown = nil)
1324
+ if self.type.base.name.to_s == "bit"
1325
+ return "#{self.type.range.first + 1}'b#{self.content.to_verilog}"
1326
+ elsif self.type.name.to_s == "integer"
1327
+ return "#{self.type.range.first + 1}'d#{self.content.to_verilog}"
1328
+ end
1329
+ return "#{self.content.to_verilog}"
1330
+ end
1331
+ # How to use when simply obtaining the width
1332
+ def to_getrange
1333
+ return "#{self.content.to_verilog}"
1334
+ end
1335
+ end
1336
+
1337
+ # Used to transrate if.
1338
+ # Enhance If with generation of verilog code.
1339
+ class If
1340
+ # Converts the system to Verilog code.
1341
+ def to_verilog(mode = nil)
1342
+
1343
+ $blocking = false
1344
+
1345
+ if ($space_count == 0) then
1346
+ result = " " * ($space_count) # Indented based on space_count.
1347
+ else
1348
+ result = ""
1349
+ end
1350
+ $space_count += 1 # Add count to be used for indentation.
1351
+
1352
+ result << "if (#{self.condition.to_verilog}) begin\n"
1353
+
1354
+
1355
+ # Check if there is yes (if) and output yes or less.
1356
+ if self.respond_to? (:yes)
1357
+ self.yes.each_statement do |statement|
1358
+ result << "#{" " * $space_count} #{statement.to_verilog(mode)}"
1359
+ end
1360
+ result << "#{" " * $space_count} end\n"
1361
+ end
1362
+
1363
+ # If noif (else if) exists, it outputs it.
1364
+ # Since noif is directly under, respond_to is unnecessary.
1365
+ self.each_noif do |condition, block|
1366
+ result << "#{" " * $space_count} else if (#{condition.to_verilog})\n"
1367
+ block.each_statement do |statement|
1368
+ result << "#{" " * $space_count} #{statement.to_verilog(mode)}"
1369
+ end
1370
+ result << "#{" "* $space_count} end\n"
1371
+ end
1372
+
1373
+ # Check if there is no (else) and output no or less.
1374
+ if self.no.respond_to? (:mode)
1375
+ result << "#{" " * $space_count} else begin\n"
1376
+ self.no.each_statement do |statement|
1377
+ result << "#{" " * $space_count} #{statement.to_verilog(mode)}"
1378
+ end
1379
+ result << "#{" " * $space_count} end\n"
1380
+ end
1381
+
1382
+ $space_count -= 1 # Since the output ends, reduce the count.
1383
+ return result
1384
+ end
1385
+ end
1386
+
1387
+ # Used to translate case
1388
+ class Case
1389
+ def to_verilog(mode = nil)
1390
+
1391
+ if ($space_count == 0) then
1392
+ result = " " * ($space_count) # Indented based on space_count.
1393
+ else
1394
+ result = ""
1395
+ end
1396
+ $space_count += 1 # Add count to be used for indentation.
1397
+
1398
+ result = ""
1399
+ result << "case(#{self.value.to_verilog})\n"
1400
+
1401
+ # n the case statement, each branch is partitioned by when. Process each time when.
1402
+ self.each_when do |whens|
1403
+ # Reads and stores the numbers and expressions stored in when.
1404
+ result << " " + " " *$space_count + "#{whens.match.to_verilog}: "
1405
+ if whens.statement.each_statement.count > 1 then
1406
+ result << "begin\n"
1407
+ whens.statement.each_statement do |statement|
1408
+ result << " "+ " " *$space_count +"#{statement.to_verilog}"
1409
+ end
1410
+ result << " " + " " *$space_count + "end\n"
1411
+ elsif whens.statement.each_statement.count == 1 then
1412
+ whens.statement.each_statement do |statement|
1413
+ result << "#{statement.to_verilog}"
1414
+ end
1415
+ end
1416
+ end
1417
+ # The default part is stored in default instead of when. Reads and processes in the same way as when.
1418
+ if self.default.each_statement.count > 1 then
1419
+ result << " " + " " *$space_count + "default: begin\n"
1420
+ self.default.each_statement do |statement|
1421
+ result << " " + " " *$space_count + "#{statement.to_verilog}"
1422
+ end
1423
+ result << " end\n"
1424
+ elsif self.default.each_statement.count == 1 then
1425
+ result << " " + " " *$space_count + "default: "
1426
+ self.default.each_statement do |statement|
1427
+ result << "#{statement.to_verilog}"
1428
+ end
1429
+ end
1430
+ result << " " + " " *$space_count + "endcase\n" # Conclusion.
1431
+
1432
+ $space_count -= 1 # Since the output ends, reduce the count.
1433
+ return result # Return case after translation.
1434
+ end
1435
+ end
1436
+
1437
+ # Translate expression of combination circuit.
1438
+ # Enhance Connection with generation of verilog code.
1439
+ class Connection
1440
+ # Converts the system to Verilog code.
1441
+
1442
+ # Method used for array.
1443
+ def array_connection(left,right)
1444
+ expression = right.each_expression.to_a
1445
+ result = ""
1446
+ expression[0..-2].each do |expression|
1447
+ result << " assign #{left.to_verilog}[#{expression.content.to_s}] = #{expression.to_verilog};\n"
1448
+ end
1449
+ result << " assign #{left.to_verilog}[#{expression.last.content.to_s}] = #{expression.last.to_verilog};\n"
1450
+ return result
1451
+ end
1452
+
1453
+ def to_verilog
1454
+ # Decide whether to assign to array by if.
1455
+ # NOTICE: Now array assignment is done trough constant initialization, will be treated later.
1456
+ # if self.right.respond_to? (:each_expression)
1457
+ # array_connection(self.left,self.right);
1458
+ # else
1459
+ cnt = 0 # Use count.
1460
+ bit = -2 # Used to determine the bit width. Since there are 0 and default, -2.
1461
+
1462
+ # Measure the number of choices on the right side (case statement if it is 3 or more).
1463
+ if self.right.respond_to? (:each_choice)
1464
+ choice = self.right.each_choice.to_a
1465
+ choice.each do |choice|
1466
+ bit += 1
1467
+ end
1468
+ end
1469
+
1470
+ # Three or more choices.
1471
+ if (bit > 2)
1472
+ # The bit width is obtained by converting the bit into a binary number and obtaining the size.
1473
+ bit = bit.to_s(2).size
1474
+
1475
+ # Create a case statement.
1476
+ result = " begin\n"
1477
+ result << " case(#{self.right.select.to_verilog})\n"
1478
+ # Output other than the last one in order.
1479
+ choice[0..-2].each do |choice|
1480
+ result << " #{bit}'#{cnt}: #{self.left.to_verilog} = #{choice.to_verilog}\n"
1481
+ cnt += 1
1482
+ end
1483
+ # At the end, it becomes default because it needs default.
1484
+ result << " default: #{self.left.to_verilog} = #{choice.last.to_verilog}\n"
1485
+ result << " endcase\n"
1486
+ result << " end\n"
1487
+ return result
1488
+ end
1489
+
1490
+ # It is not a case so call it normally.
1491
+ return " assign #{self.left.to_verilog} = #{self.right.to_verilog};\n"
1492
+ # end
1493
+ end
1494
+ end
1495
+
1496
+ # It could be used for instantiation.
1497
+ class RefThis
1498
+ def to_another_verilog
1499
+ return ""
1500
+ end
1501
+ end
1502
+
1503
+ # Used when using "~" for expressions.
1504
+ class Unary
1505
+ # Converts the system to Verilog code.
1506
+ def to_verilog
1507
+ return "#{self.operator}#{self.child.to_verilog}"
1508
+ end
1509
+ end
1510
+
1511
+ # For declaring variables.
1512
+ # Enhance SignalI with generation of verilog code.
1513
+ class SignalI
1514
+ # Converts the system to Verilog code.
1515
+ def to_verilog
1516
+ # Convert unusable characters and return them.
1517
+ return "#{name_to_verilog(self.name)}"
1518
+ end
1519
+ end
1520
+
1521
+ # If it is signed, it outputs signed.
1522
+ # Enhance Type with generation of verilog code.
1523
+ class Type
1524
+ # Converts the system to Verilog code.
1525
+ def to_verilog
1526
+ return self.name == :signed ? "#{self.name.to_s} " : ""
1527
+ end
1528
+ end
1529
+
1530
+ # Use it when collecting.
1531
+ class Concat
1532
+ def to_verilog
1533
+ expression = self.each_expression.to_a
1534
+
1535
+ result = "{"
1536
+ expression[0..-2].each do |expression|
1537
+ result << "#{expression.to_verilog},"
1538
+ end
1539
+ result << "#{expression.last.to_verilog}}"
1540
+
1541
+ return result
1542
+ end
1543
+ end
1544
+
1545
+ # Look at the unit of time, convert the time to ps and output it.
1546
+ # One of two people, TimeWait and Delay.
1547
+ class TimeWait
1548
+ def to_verilog(mode=nil)
1549
+ return self.delay.to_verilog
1550
+ end
1551
+ end
1552
+ class Delay
1553
+ def to_verilog
1554
+ time = self.value.to_s
1555
+ if(self.unit.to_s == "ps") then
1556
+ return "##{time}\n"
1557
+ elsif(self.unit.to_s == "ns")
1558
+ return "##{time}000\n"
1559
+ elsif(self.unit.to_s == "us")
1560
+ return "##{time}000000\n"
1561
+ elsif(self.unit.to_s == "ms")
1562
+ return "##{time}000000000\n"
1563
+ end
1564
+ end
1565
+ end
1566
+
1567
+ # Those who disappeared.
1568
+ #class SystemI
1569
+ #class TypeTuple
1570
+ #class Event
1571
+
1572
+ # Enhance SystemT with generation of verilog code.
1573
+ class SystemT
1574
+
1575
+ ## Tells if an expression is a reference to port +systemI.signal+.
1576
+ def port_assign?(expr, systemI, signal)
1577
+ return expr.is_a?(RefName) && expr.name == signal.name &&
1578
+ expr.ref.is_a?(RefName) && expr.ref.name == systemI.name
1579
+ end
1580
+
1581
+ ## Extracts the assignments to port +systemI.signal+ and returns
1582
+ # the resulting reference to a port wire.
1583
+ #
1584
+ # NOTE: assumes to_upper_space! and with_port! has been called.
1585
+ def extract_port_assign!(systemI,signal)
1586
+ # Extract the assignment.
1587
+ assign = nil
1588
+ self.each_connection.to_a.each do |connection|
1589
+ if self.port_assign?(connection.left,systemI,signal) then
1590
+ # The left is the port.
1591
+ # Delete the connection.
1592
+ self.scope.delete_connection!(connection)
1593
+ # And return a copy of the right.
1594
+ return connection.right.clone
1595
+ elsif self.port_assign?(connection.right,systemI,signal) then
1596
+ # The right is the port.
1597
+ # Delete the connection.
1598
+ self.scope.delete_connection!(connection)
1599
+ # And return a copy of the left.
1600
+ return connection.left.clone
1601
+ end
1602
+ end
1603
+ # No port found, nothing to do
1604
+ return nil
1605
+ end
1606
+
1607
+
1608
+
1609
+ # Converts the system to Verilog code.
1610
+ def to_verilog
1611
+ # Preprocessing
1612
+ # Detect the registers
1613
+ regs = []
1614
+ self.each_behavior do |behavior|
1615
+ behavior.block.each_statement do |statement|
1616
+ regs << statement.left.to_verilog if statement.is_a?(Transmit)
1617
+ end
1618
+ end
1619
+
1620
+ # Code generation
1621
+ inputs = 0
1622
+ outputs = 0
1623
+ inout = 0
1624
+
1625
+ inputs = self.each_input.to_a
1626
+ outputs = self.each_output.to_a
1627
+ inout = self.each_inout.to_a
1628
+
1629
+ # Spelling necessary for simulation.
1630
+ code = "`timescale 1ps/1ps\n\n"
1631
+ # Output the module name.
1632
+ code << "module #{name_to_verilog(self.name)}("
1633
+
1634
+ # Output the last two to the input.
1635
+ inputs[0..-2].each do |input|
1636
+ code << " #{input.to_verilog},"
1637
+ end
1638
+ # When only input is used, it is necessary to close (), so it branches with if.
1639
+ if outputs.empty? && inout.empty? then
1640
+ code << " #{inputs.last.to_verilog} ); \n" unless inputs.empty?
1641
+ else
1642
+ code << " #{inputs.last.to_verilog}," unless inputs.empty?
1643
+ end
1644
+
1645
+ # Output the last two to the output.
1646
+ outputs[0..-2].each do |output|
1647
+ code << " #{output.to_verilog},"
1648
+ end
1649
+ # When only input and output are used, it is necessary to close (), so it branches with if.
1650
+ if inout.empty? then
1651
+ code << " #{outputs.last.to_verilog} ); \n" unless outputs.empty?
1652
+ else
1653
+ code << " #{outputs.last.to_verilog}," unless outputs.empty?
1654
+ end
1655
+
1656
+ # Output the last two to the inout.
1657
+ inout[0..-2].each do |inout|
1658
+ code << " #{inout.to_verilog},"
1659
+ end
1660
+ # There is no comma as it is the last one
1661
+ code << " #{inout.last.to_verilog} ); \n" unless inout.empty?
1662
+
1663
+ # Declare "input"
1664
+ self.each_input do |input|
1665
+ if input.type.respond_to? (:each_type) then
1666
+ $vector_reg = "#{input.to_verilog}"
1667
+ $vector_cnt = 0
1668
+ input.type.each_type do |type|
1669
+ code << "input #{type.to_verilog} #{$vector_reg}:#{$vector_cnt};\n"
1670
+ $vector_cnt += 1
1671
+ end
1672
+ else
1673
+ code << " input#{input.type.to_verilog} #{input.to_verilog};\n"
1674
+ end
1675
+ end
1676
+
1677
+ # Declare "output"
1678
+ self.each_output do |output|
1679
+ if output.type.respond_to? (:each_type) then
1680
+ $vector_reg = "#{output.to_verilog}"
1681
+ $vector_cnt = 0
1682
+ output.type.each_type do |type|
1683
+ if regs.include?(type.name) then
1684
+ code << " output reg"
1685
+ else
1686
+ code << " output"
1687
+ end
1688
+ code << "#{type.to_verilog} #{$vector_reg}:#{$vector_cnt};\n"
1689
+ $vector_cnt += 1
1690
+ end
1691
+ else
1692
+ if regs.include?(output.name) then
1693
+ code << " output reg"
1694
+ else
1695
+ code << " output"
1696
+ end
1697
+ code << "#{output.type.to_verilog} #{output.to_verilog};\n"
1698
+ end
1699
+ end
1700
+
1701
+ # Declare "inout"
1702
+ self.each_inout do |inout|
1703
+ if inout.type.respond_to? (:each_type) then
1704
+ $vector_reg = "#{inout.to_verilog}"
1705
+ $vector_cnt = 0
1706
+ inout.type.each_type do |type|
1707
+ code << "inout #{type.to_verilog} #{$vector_reg}:#{$vector_cnt};\n"
1708
+ $vector_cnt += 1
1709
+ end
1710
+ else
1711
+ code << " inout#{inout.type.to_verilog} #{inout.to_verilog};\n"
1712
+ end
1713
+ end
1714
+
1715
+ # Declare "inner".
1716
+ self.each_inner do |inner|
1717
+ if regs.include?(inner.name) then
1718
+ code << " reg"
1719
+ else
1720
+ code << " wire"
1721
+ end
1722
+
1723
+ if inner.type.base?
1724
+ if inner.type.base.base?
1725
+ code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog};\n"
1726
+ else
1727
+ code << "#{inner.type.to_verilog} #{inner.to_verilog};\n"
1728
+ end
1729
+ else
1730
+ code << " #{inner.type.to_verilog}#{inner.to_verilog};\n"
1731
+ end
1732
+ end
1733
+
1734
+ # If there is scope in scope, translate it.
1735
+ self.each_scope do |scope|
1736
+ scope.each_inner do |inner|
1737
+ if regs.include?(inner.name) then
1738
+ code << " reg "
1739
+ else
1740
+ code << " wire "
1741
+ end
1742
+
1743
+ if inner.type.respond_to? (:base)
1744
+ if inner.type.base.base?
1745
+ code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog};\n"
1746
+ else
1747
+ code << "#{inner.type.to_verilog} #{inner.to_verilog};\n"
1748
+ end
1749
+ else
1750
+ code << "inner #{inner.type.to_verilog} #{inner.to_verilog};\n"
1751
+ end
1752
+ end
1753
+
1754
+ scope.each_connection do |connection|
1755
+ code << "\n"
1756
+ code << "#{connection.to_verilog}"
1757
+ end
1758
+ end
1759
+
1760
+ code << "\n"
1761
+
1762
+ # transliation of the instantiation part.
1763
+ # Generate the instances connections.
1764
+ self.each_systemI do |systemI|
1765
+ # Its Declaration.
1766
+ code << " " * 3
1767
+ systemT = systemI.systemT
1768
+ code << name_to_verilog(systemT.name) << " "
1769
+ code << name_to_verilog(systemI.name) << "("
1770
+ # Its ports connections
1771
+ # Inputs
1772
+ systemT.each_input do |input|
1773
+ ref = self.extract_port_assign!(systemI,input)
1774
+ if ref then
1775
+ code << "." << name_to_verilog(input.name) << "("
1776
+ code << ref.to_verilog
1777
+ code << "),"
1778
+ end
1779
+ end
1780
+ # Outputs
1781
+ systemT.each_output do |output|
1782
+ ref = self.extract_port_assign!(systemI,output)
1783
+ if ref then
1784
+ code << "." << name_to_verilog(output.name) << "("
1785
+ code << ref.to_verilog
1786
+ code << "),"
1787
+ end
1788
+ end
1789
+ # Inouts
1790
+ systemT.each_inout do |inout|
1791
+ ref = self.extract_port_assign!(systemI,inout)
1792
+ if ref then
1793
+ code << "." << name_to_verilog(inout.name) << "("
1794
+ code << ref.to_vhdl(level)
1795
+ code << "),"
1796
+ end
1797
+ end
1798
+ # Remove the last "," for conforming with Verilog syntax.
1799
+ # and close the port connection.
1800
+ code[-1] = ");\n"
1801
+ end
1802
+
1803
+
1804
+
1805
+ # translation of the connection part (assigen).
1806
+ self.each_connection do |connection|
1807
+ code << "#{connection.to_verilog}\n"
1808
+ end
1809
+
1810
+ # Translation of behavior part (always).
1811
+ self.each_behavior do |behavior|
1812
+ code << " always @( "
1813
+ # If there is no "always" condition, it is always @("*").
1814
+ if behavior.each_event.to_a.empty? then
1815
+ code << "*"
1816
+ else
1817
+ event = behavior.each_event.to_a
1818
+ event[0..-2].each do |event|
1819
+ # If "posedge" or "negedge" does not exist, the variable is set to condition.
1820
+ if (event.type.to_s != "posedge" && event.type.to_s != "negedge") then
1821
+ code << "#{event.ref.to_verilog}, "
1822
+ else
1823
+ # Otherwise, it outputs "psoedge" or "negedge" as a condition.
1824
+ code << "#{event.type.to_s} #{event.ref.to_verilog}, "
1825
+ end
1826
+ end
1827
+ # Since no comma is necessary at the end, we try not to separate commas separately at the end.
1828
+ if (event.last.type.to_s != "posedge" && event.last.type.to_s != "negedge") then
1829
+ code << "#{event.last.ref.to_verilog}"
1830
+ else
1831
+ code << "#{event.last.type.to_s} #{event.last.ref.to_verilog}"
1832
+ end
1833
+ end
1834
+ code << " ) begin\n"
1835
+
1836
+ # Perform "scheduling" using the method "flatten".
1837
+ block = behavior.block.flatten(behavior.block.mode.to_s)
1838
+
1839
+ # Declaration of "inner" part within "always".
1840
+ block.each_inner do |inner|
1841
+ if regs.include?(inner.name) then
1842
+ code << " reg"
1843
+ else
1844
+ code << " wire"
1845
+ end
1846
+
1847
+ # Variable has "base", but if there is width etc, it is not in "base".
1848
+ # It is determined by an if.
1849
+ if inner.type.base?
1850
+ if inner.type.base.base?
1851
+ code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog};\n"
1852
+ else
1853
+ code << "#{inner.type.to_verilog} #{inner.to_verilog};\n"
1854
+ end
1855
+ else
1856
+ code << " #{inner.type.to_verilog}#{inner.to_verilog};\n"
1857
+ end
1858
+ end
1859
+
1860
+ # Translate the block that finished scheduling.
1861
+ block.each_statement do |statement|
1862
+ code << "\n #{statement.to_verilog(behavior.block.mode.to_s)}"
1863
+ end
1864
+
1865
+ $fm.fm_par.clear()
1866
+
1867
+ code << "\n end\n\n"
1868
+ end
1869
+
1870
+ # Conclusion.
1871
+ code << "endmodule"
1872
+ return code
1873
+ end
1874
+ end
1875
+
1876
+ end
1877
+
1878
+
1879
+
1880
+ ## Extends the Numeric class with generation of verilog text.
1881
+ class ::Numeric
1882
+
1883
+ # Generates the text of the equivalent verilog code.
1884
+ # +level+ is the hierachical level of the object.
1885
+ def to_verilog(level = 0)
1886
+ return self.to_s
1887
+ end
1888
+ end