HDLRuby 2.0.8

Sign up to get free protection for your applications and to get access to all the features.
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