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,1437 @@
1
+ require 'HDLRuby'
2
+ require 'HDLRuby/hruby_low_with_bool'
3
+ require 'HDLRuby/hruby_low_without_namespace'
4
+ require 'HDLRuby/hruby_low_with_var'
5
+
6
+
7
+ module HDLRuby::Low
8
+
9
+
10
+ ##
11
+ # Converts a HDLRuby::Low description to a VHDL text
12
+ # description
13
+ #
14
+ ########################################################################
15
+
16
+ ## Provides tools for converting HDLRuby::Low objects to VHDL.
17
+ module Low2VHDL
18
+
19
+ # Indicates if VHDL'08 can be generated.
20
+ # Default: true
21
+ #
22
+ # NOTE: when possible, it is better to be left true since the
23
+ # identifier does not require any mangling in VHDL'08
24
+ @@vhdl08 = true
25
+
26
+ ## Tells if VHDL'08 is supported or not.
27
+ def self.vhdl08
28
+ return @@vhdl08
29
+ end
30
+
31
+ ## Sets/unsets the support of VHDL'08.
32
+ def self.vhdl08=(mode)
33
+ @@vhdl08 = mode ? true : false
34
+ end
35
+
36
+ # Indicates if target toolchain is Alliance: requires a slightly
37
+ # different VHDL syntax.
38
+ #
39
+ # NOTE: this syntax is not lint-compatible and should be avoided
40
+ # unless using specifically Alliance.
41
+ @@alliance = false
42
+
43
+ ## Tells if Allicance toolchain is targeted.
44
+ def self.alliance
45
+ return @@alliance
46
+ end
47
+
48
+ ## Sets/unsets the Allicance toolchain targeting.
49
+ def self.alliance=(mode)
50
+ @@alliance = mode ? true : false
51
+ end
52
+
53
+ ## Generates the pakage requirement for an entity.
54
+ # +spaces+ are the spaces to put before each line.
55
+ def self.packages(spaces)
56
+ return "#{spaces}library ieee;\n" +
57
+ "#{spaces}use ieee.std_logic_1164.all;\n" +
58
+ "#{spaces}use ieee.numeric_std.all;\n\n"
59
+ end
60
+
61
+ ## Tells if a +name+ is VHDL-compatible.
62
+ # To ensure compatibile, assume all the character must have the
63
+ # same case.
64
+ def self.vhdl_name?(name)
65
+ name = name.to_s
66
+ # First: character check.
67
+ return false unless name =~ /^[a-zA-Z]|([a-zA-Z][a-zA-Z_0-9]*[a-zA-Z0-9])$/
68
+ # Then character sequence check.
69
+ return false if name.include?("__")
70
+ # Then case check.
71
+ return (name == name.upcase || name == name.downcase)
72
+ end
73
+
74
+ ## Converts a +name+ to a VHDL-compatible name.
75
+ def self.vhdl_name(name)
76
+ if vhdl08 then
77
+ # VHDL'08, nothing to do if the name is VHDL-compatible.
78
+ return name.to_s if self.vhdl_name?(name)
79
+ # Otherwise put the name between //
80
+ return "\\#{name}\\".to_s
81
+ else
82
+ # Not VHDL'08, need to mangle the name.
83
+ # For safety also force downcase.
84
+ name = name.to_s
85
+ # Other letters: convert special characters.
86
+ name = name.each_char.map do |c|
87
+ if c=~ /[a-uw-z0-9]/ then
88
+ c
89
+ elsif c == "v" then
90
+ "vv"
91
+ else
92
+ "v" + c.ord.to_s
93
+ end
94
+ end.join
95
+ # First character: only letter is possible.
96
+ unless name[0] =~ /[a-z]/ then
97
+ name = "v" + name
98
+ end
99
+ return name
100
+ end
101
+ end
102
+
103
+ ## Converts a +name+ to a VHDL entity name.
104
+ #
105
+ # NOTE: assume names have been converted to VHDL-compatible ones.
106
+ def self.entity_name(name)
107
+ return self.vhdl_name(name.to_s + "_e")
108
+ end
109
+
110
+ ## Converts a +name+ to a VHDL architecture name.
111
+ #
112
+ # NOTE: assume names have been converted to VHDL-compatible ones.
113
+ def self.architecture_name(name)
114
+ return self.vhdl_name(name.to_s + "_a")
115
+ end
116
+
117
+ ## Tells if a +type+ is arithmetic-compatible.
118
+ def self.arith?(type)
119
+ return type.is_a?(TypeVector) &&
120
+ [:signed,:unsigned,:float].include?(type.base.name)
121
+ end
122
+
123
+ ## Generates expression +expr+ while casting it to
124
+ # arithmetic-compatible type if required.
125
+ def self.to_arith(expr)
126
+ if arith?(expr.type) then
127
+ # The expression is arithmetic-compatible, just generate it.
128
+ if expr.is_a?(Value) then
129
+ return expr.to_arith
130
+ else
131
+ return expr.to_vhdl
132
+ end
133
+ else
134
+ # The expression is to convert, by default convert to unsigned
135
+ # (this is the standard interpretation of HDLRuby).
136
+ if expr.type.to_vhdl == "std_logic" then
137
+ # std_logic case: must convert to vector first.
138
+ if alliance then
139
+ # Alliance toolchain case.
140
+ return "unsigned('0' & " + expr.to_vhdl + ")"
141
+ else
142
+ # General case.
143
+ return "unsigned(\"\" & " + expr.to_vhdl + ")"
144
+ end
145
+ else
146
+ # Other case, ue the expression direction.
147
+ return "unsigned(" + expr.to_vhdl + ")"
148
+ end
149
+ end
150
+ end
151
+
152
+ # Moved to hruby_low_with_bool.rb
153
+ #
154
+ # ## Tells if an expression is a boolean.
155
+ # def self.boolean?(expr)
156
+ # if expr.is_a?(Unary) && expr.operator == :~ then
157
+ # # NOT, boolean is the sub expr is boolean.
158
+ # return Low2VHDL.boolean?(expr.child)
159
+ # elsif expr.is_a?(Binary) then
160
+ # # Binary case.
161
+ # case(expr.operator)
162
+ # when :==,:!=,:>,:<,:>=,:<= then
163
+ # # Comparison, it is a boolean.
164
+ # return true
165
+ # when :&,:|,:^ then
166
+ # # AND, OR or XOR, boolean if both subs are boolean.
167
+ # return Low2VHDL.boolean?(expr.left) &&
168
+ # Low2VHDL.boolean?(expr.right)
169
+ # else
170
+ # # Other cases: not boolean.
171
+ # return false
172
+ # end
173
+ # elsif expr.is_a?(Select) then
174
+ # # Select, binary if the choices are boolean.
175
+ # return !expr.each_choice.any? {|c| !Low2VHDL.boolean?(c) }
176
+ # else
177
+ # # Other cases are not considered as boolean.
178
+ # return false
179
+ # end
180
+ # end
181
+
182
+ ## Generates a expression converted to the boolean type.
183
+ def self.to_boolean(expr)
184
+ # if boolean?(expr) then
185
+ if expr.boolean? then
186
+ # Comparison, no conversion required.
187
+ return expr.to_vhdl
188
+ else
189
+ # Conversion to boolean required.
190
+ return "(" + expr.to_vhdl + " = '1')"
191
+ end
192
+ end
193
+
194
+ ## Generates epression +expr+ while casting it to match +type+ if
195
+ # required.
196
+ def self.to_type(type,expr)
197
+ # puts "expr=#{expr.to_vhdl}" unless expr.is_a?(Concat)
198
+ # puts "type.width=#{type.width}, expr.type.width=#{expr.type.width}"
199
+ if type.to_vhdl == "std_logic" then
200
+ # Conversion to std_logic required.
201
+ if expr.is_a?(Value) then
202
+ # Values can simply be rewritten.
203
+ if expr.content.to_s.to_i(2) == 0 then
204
+ return "'0'"
205
+ else
206
+ return "'1'"
207
+ end
208
+ elsif expr.type.to_vhdl != "std_logic"
209
+ # Otherwise a cast is required.
210
+ # if expr.type.base.name == :signed then
211
+ # return "unsigned(#{expr.to_vhdl})(0)"
212
+ # else
213
+ # # return "unsigned(#{expr.to_vhdl}(0))"
214
+ # return "unsigned(#{expr.to_vhdl})(0)"
215
+ # end
216
+ if alliance then
217
+ # Specific syntax for casting to std_logic with Alliance
218
+ if expr.type.width == 1 then
219
+ # No cast required with alliance if bitwidth is 1.
220
+ return expr.to_vhdl
221
+ else
222
+ # Multi-bit, need to select a bit and possibly
223
+ # cast to unsigned.
224
+ if expr.type.signed? then
225
+ return "unsigned(#{expr.to_vhdl}(0))"
226
+ # elsif expr.is_a?(RefRange) then
227
+ # # Range reference case.
228
+ # return "#{expr.ref.to_vhdl}(#{expr.range.first.to_vhdl})"
229
+ else
230
+ # Other cases.
231
+ return "#{expr.to_vhdl}(0)"
232
+ end
233
+ end
234
+ else
235
+ # Lint-compatible casting to std_logic
236
+ if expr.type.signed? then
237
+ # Signed, cast to unsigned.
238
+ return "unsigned(#{expr.to_vhdl})(0)"
239
+ # elsif expr.is_a?(RefRange) then
240
+ # # Range reference case.
241
+ # return "#{expr.ref.to_vhdl}(#{expr.range.first.to_vhdl})"
242
+ else
243
+ # Other cases: for std_logic generation.
244
+ return expr.to_vhdl(0,true)
245
+ end
246
+ end
247
+ else
248
+ # Both are std_logic, nothing to to.
249
+ return expr.to_vhdl
250
+ end
251
+ elsif expr.is_a?(Value) then
252
+ # puts "type=#{type}, type.range=#{type.range}"
253
+ # Value width must be adjusted.
254
+ return expr.to_vhdl(0,false,type.width)
255
+ elsif expr.is_a?(Concat) then
256
+ return expr.to_vhdl(type)
257
+ elsif expr.type.width < type.width then
258
+ # Need to extend the type.
259
+ return '"' + "0" * (type.width - expr.type.width) + '" & ' +
260
+ expr.to_vhdl
261
+ else
262
+ # No conversion required.
263
+ return expr.to_vhdl
264
+ end
265
+ end
266
+
267
+ ## Cast a +type+ to undo arithmetic conversion if necessary.
268
+ def self.unarith_cast(type)
269
+ # Is the type arithmetic?
270
+ if arith?(type) then
271
+ # Yes, no undo required.
272
+ return ""
273
+ else
274
+ # No, undo required.
275
+ return "std_logic_vector"
276
+ end
277
+ end
278
+
279
+ ## Generates the name of a mux function by type string +tstr+ and
280
+ # number of arguments +num+.
281
+ def self.mux_name(tstr,num)
282
+ return "mux#{tstr.gsub(/[^a-zA-Z0-9_]/,"_")}#{num}"
283
+ end
284
+
285
+ ## Generates the VHDL code for the mux function for type string +tstr+
286
+ # with +num+ choices.
287
+ # +spaces+ is the ident for the resulting code.
288
+ def self.mux_function(type,num,spaces)
289
+ # Create the strin of the type.
290
+ tstr = type.to_vhdl
291
+ # Create the name of the function from the type.
292
+ name = mux_name(tstr,num)
293
+ # Create the condition.
294
+ if num == 2 then
295
+ cond = "cond : boolean"
296
+ else
297
+ # First compute the width of the condition.
298
+ width = (num-1).width
299
+ # Now generate the condition.
300
+ cond = "val : std_logic_vector(#{width-1} downto 0)"
301
+ end
302
+ # Generate the arguments.
303
+ args = num.times.map {|i| "arg#{i} : #{tstr}" }.join("; ")
304
+ # Generate the body.
305
+ if num == 2 then
306
+ body = "#{spaces} if(cond) then\n" +
307
+ "#{spaces} return arg0;\n" +
308
+ "#{spaces} else\n" +
309
+ "#{spaces} return arg1;\n" +
310
+ "#{spaces} end if;\n"
311
+ else
312
+ # First compute the type of the choices.
313
+ vtype = TypeVector.new(:"",Bit,width-1..0)
314
+ # Now generate the body.
315
+ body = "#{spaces} case(val) is\n" +
316
+ num.times.map do |i|
317
+ pos = Value.new(vtype,i).to_vhdl
318
+ "#{spaces} when #{pos} => return arg#{i};\n"
319
+ end.join +
320
+ "#{spaces} end case;\n"
321
+ end
322
+ # Generate the choices.
323
+ # Generates the function
324
+ return "#{spaces}function #{name}" +
325
+ "(#{cond}; #{args})\n" +
326
+ "#{spaces}return #{tstr} is\n" +
327
+ "#{spaces}begin\n" + body +
328
+ "#{spaces}end #{mux_name(tstr,num)};\n\n"
329
+ end
330
+
331
+ end
332
+
333
+
334
+ ## Extends the SystemT class with generation of HDLRuby::High text.
335
+ class SystemT
336
+
337
+ # Generates the text of the equivalent HDLRuby::High code.
338
+ # +level+ is the hierachical level of the object.
339
+ def to_vhdl(level = 0)
340
+ # The resulting string.
341
+ res = ""
342
+ # Generate the entity
343
+ # The header
344
+ res << Low2VHDL.packages(" " * (level*3))
345
+ res << " " * (level*3)
346
+ res << "entity #{Low2VHDL.entity_name(self.name)} is\n"
347
+ # The ports
348
+ res << " " * ((level+1)*3)
349
+ res << "port (\n"
350
+ # Inputs
351
+ self.each_input do |input|
352
+ res << " " * ((level+2)*3)
353
+ res << Low2VHDL.vhdl_name(input.name) << ": in "
354
+ res << input.type.to_vhdl << ";\n"
355
+ end
356
+ # Outputs
357
+ self.each_output do |output|
358
+ res << " " * ((level+2)*3)
359
+ res << Low2VHDL.vhdl_name(output.name) << ": out "
360
+ res << output.type.to_vhdl << ";\n"
361
+ end
362
+ # Inouts
363
+ self.each_inout do |inout|
364
+ res << " " * ((level+2)*3)
365
+ res << Low2VHDL.vhdl_name(inout.name) << ": inout "
366
+ res << inout.type.to_vhdl << ";\n"
367
+ end
368
+ # Remove the last ";" for conforming with VHDL syntax.
369
+ res[-2..-1] = "\n" if res[-2] == ";"
370
+ res << " " * ((level+1)*3)
371
+ # Close the port declaration.
372
+ res << ");\n"
373
+ # Close the entity
374
+ res << " " * (level*3)
375
+ res << "end #{Low2VHDL.entity_name(self.name)};\n\n"
376
+
377
+
378
+ # Generate the architecture.
379
+ res << " " * (level*3)
380
+ res << "architecture #{Low2VHDL.architecture_name(self.name)} "
381
+ res << "of #{Low2VHDL.entity_name(self.name)} is\n"
382
+ # Generate the scope.
383
+ res << "\n"
384
+ res << self.scope.to_vhdl(level+1)
385
+ # End of the system.
386
+ res << " " * (level*3)
387
+ res << "end #{Low2VHDL.architecture_name(self.name)};\n\n"
388
+ # Return the result.
389
+ return res
390
+ end
391
+ end
392
+
393
+
394
+ ## Extends the Scope class with generation of HDLRuby::High text.
395
+ class Scope
396
+
397
+ ## Tells if an expression is a reference to port +systemI.signal+.
398
+ def port_assign?(expr, systemI, signal)
399
+ return expr.is_a?(RefName) && expr.name == signal.name &&
400
+ expr.ref.is_a?(RefName) && expr.ref.name == systemI.name
401
+ end
402
+
403
+ ## Extracts the assignments to port +systemI.signal+ and returns
404
+ # the resulting reference to a port wire.
405
+ #
406
+ # NOTE: assumes to_upper_space! and with_port! has been called.
407
+ def extract_port_assign!(systemI,signal)
408
+ # Extract the assignment.
409
+ assign = nil
410
+ self.each_connection.to_a.each do |connection|
411
+ if self.port_assign?(connection.left,systemI,signal) then
412
+ # The left is the port.
413
+ # Delete the connection.
414
+ self.delete_connection!(connection)
415
+ # And return a copy of the right.
416
+ return connection.right.clone
417
+ elsif self.port_assign?(connection.right,systemI,signal) then
418
+ # The right is the port.
419
+ # Delete the connection.
420
+ self.delete_connection!(connection)
421
+ # And return a copy of the left.
422
+ return connection.left.clone
423
+ end
424
+ end
425
+ # No port found, nothing to do
426
+ return nil
427
+ end
428
+
429
+ # Generates the text of the equivalent HDLRuby::High code.
430
+ # +level+ is the hierachical level of the object and
431
+ def to_vhdl(level = 0)
432
+ # The resulting string.
433
+ res = ""
434
+
435
+ # Generate the architecture's header
436
+ # The instances' headers
437
+ self.each_systemI do |systemI|
438
+ systemT = systemI.systemT
439
+ # Its entity
440
+ res << (" " * level*3)
441
+ res << "component #{Low2VHDL.entity_name(systemT.name)}\n"
442
+ res << (" " * (level+1)*3)
443
+ # Its ports
444
+ res << "port(\n"
445
+ # Inputs
446
+ systemT.each_input do |input|
447
+ res << " " * ((level+2)*3)
448
+ res << Low2VHDL.vhdl_name(input.name) << ": in "
449
+ res << input.type.to_vhdl << ";\n"
450
+ end
451
+ # Outputs
452
+ systemT.each_output do |output|
453
+ res << " " * ((level+2)*3)
454
+ res << Low2VHDL.vhdl_name(output.name) << ": out "
455
+ res << output.type.to_vhdl << ";\n"
456
+ end
457
+ # Inouts
458
+ systemT.each_inout do |inout|
459
+ res << " " * ((level+2)*3)
460
+ res << Low2VHDL.vhdl_name(inout.name) << ": inout "
461
+ res << inout.type.to_vhdl << ";\n"
462
+ end
463
+ # Remove the last ";" for conforming with VHDL syntax.
464
+ res[-2..-1] = "\n" if res[-2] == ";"
465
+ res << " " * ((level+1)*3)
466
+ # Close the port declaration.
467
+ res << ");\n"
468
+ # Close the component.
469
+ res << " " * (level*3)
470
+ res << "end component;\n\n"
471
+ end
472
+
473
+ # Generate the architecture's type definition.
474
+ # It is assumed that these types are all TypeDef.
475
+ self.each_type do |type|
476
+ res << (" " * level*3)
477
+ res << "type #{Low2VHDL.vhdl_name(type.name)} is "
478
+ res << type.def.to_vhdl(level+1)
479
+ res << ";\n"
480
+ end
481
+
482
+ ## Generates the required mux functions.
483
+ mtps = [] # The mux functions to generate by type.
484
+ # Gather the mux functions to generate.
485
+ self.each_scope_deep do |scope|
486
+ # Checks the connections.
487
+ scope.each_connection do |connection|
488
+ connection.right.each_node_deep do |node|
489
+ if node.is_a?(Select) then
490
+ mtps << [node.type,node.each_choice.to_a.size]
491
+ end
492
+ end
493
+ end
494
+ # Checks the statements.
495
+ scope.each_behavior do |behavior|
496
+ behavior.block.each_node_deep do |node|
497
+ if node.is_a?(Select) then
498
+ mtps << [node.type,node.each_choice.to_a.size]
499
+ end
500
+ end
501
+ end
502
+ end
503
+ # Generate the gathered functions (only one per type).
504
+ mtps.uniq!
505
+ mtps.each do |type,num|
506
+ res << Low2VHDL.mux_function(type,num," " * level*3)
507
+ end
508
+
509
+ # Generate the inner signals declaration.
510
+ self.each_inner do |inner|
511
+ res << " " * (level * 3)
512
+ # General signal or constant signal?
513
+ res << (inner.is_a?(SignalC) ? "constant " : "signal ")
514
+ # Signal name.
515
+ res << Low2VHDL.vhdl_name(inner.name) << ": "
516
+ # Signal type.
517
+ res << inner.type.to_vhdl(level)
518
+ # Signal value.
519
+ if inner.value then
520
+ if inner.value.is_a?(Concat) then
521
+ # Concat are to be given the expected type of the
522
+ # elements for casting them equally.
523
+ res << " := " << inner.value.to_vhdl(inner.type.base,level)
524
+ else
525
+ res << " := " << inner.value.to_vhdl(level)
526
+ end
527
+ end
528
+ res << ";\n"
529
+ end
530
+
531
+ # Generate the architecture's content.
532
+ res << " " * ((level-1)*3) << "begin\n"
533
+
534
+ # Generate the instances connections.
535
+ self.each_systemI do |systemI|
536
+ # Its Declaration.
537
+ res << " " * (level*3)
538
+ res << Low2VHDL.vhdl_name(systemI.name) << ": "
539
+ systemT = systemI.systemT
540
+ res << Low2VHDL.entity_name(systemT.name).to_s << "\n"
541
+ res << " " * ((level+1)*3)
542
+ # Its ports
543
+ res << "port map(\n"
544
+ # Inputs
545
+ systemT.each_input do |input|
546
+ ref = self.extract_port_assign!(systemI,input)
547
+ if ref then
548
+ res << " " * ((level+2)*3)
549
+ res << Low2VHDL.vhdl_name(input.name) << " => "
550
+ res << ref.to_vhdl(level)
551
+ res << ",\n"
552
+ end
553
+ end
554
+ # Outputs
555
+ systemT.each_output do |output|
556
+ ref = self.extract_port_assign!(systemI,output)
557
+ if ref then
558
+ res << " " * ((level+2)*3)
559
+ res << Low2VHDL.vhdl_name(output.name) << " => "
560
+ res << ref.to_vhdl(level)
561
+ res << ",\n"
562
+ end
563
+ end
564
+ # Inouts
565
+ systemT.each_inout do |inout|
566
+ ref = self.extract_port_assign!(systemI,inout)
567
+ if ref then
568
+ res << " " * ((level+2)*3)
569
+ res << Low2VHDL.vhdl_name(inout.name) << " => "
570
+ res << ref.to_vhdl(level)
571
+ res << ",\n"
572
+ end
573
+ end
574
+ # Remove the last ";" for conforming with VHDL syntax.
575
+ res[-2..-1] = "\n" if res[-2] == ","
576
+ # Close the port map declaration.
577
+ res << " " * ((level+1)*3)
578
+ res << ");\n"
579
+ end
580
+ # Generate the connections.
581
+ res << "\n" if self.each_scope.any?
582
+ self.each_scope_deep do |scope|
583
+ scope.each_connection do |connection|
584
+ res << connection.to_vhdl([],level)
585
+ end
586
+ end
587
+
588
+ # Generate the behaviors.
589
+ # Current scope's
590
+ res << "\n" if self.each_connection.any?
591
+ self.each_scope_deep do |scope|
592
+ scope.each_behavior do |behavior|
593
+ res << behavior.to_vhdl(level)
594
+ end
595
+ end
596
+ return res
597
+ end
598
+ end
599
+
600
+
601
+ ## Extends the Type class with generation of HDLRuby::High text.
602
+ class Type
603
+
604
+ # Generates the text of the equivalent HDLRuby::High code.
605
+ # +level+ is the hierachical level of the object.
606
+ def to_vhdl(level = 0)
607
+ return self.boolean? ? "boolean" : "std_logic"
608
+ end
609
+ end
610
+
611
+ ## Extends the TypeDef class with generation of HDLRuby::High text.
612
+ class TypeDef
613
+
614
+ # Generates the text of the equivalent HDLRuby::High code.
615
+ # +level+ is the hierachical level of the object.
616
+ def to_vhdl(level = 0)
617
+ # # Simply generates the redefined type.
618
+ # return self.def.to_vhdl(level)
619
+ # Simply use the name of the type.
620
+ return Low2VHDL.vhdl_name(self.name)
621
+ end
622
+ end
623
+
624
+ ## Extends the TypeVector class with generation of HDLRuby::High text.
625
+ class TypeVector
626
+
627
+ # Generates the text of the equivalent HDLRuby::High code.
628
+ # +level+ is the hierachical level of the object.
629
+ def to_vhdl(level = 0)
630
+ # The resulting string.
631
+ res = ""
632
+ # Depending on the base.
633
+ if self.base.class < Type then
634
+ # The base is not a leaf, therefore the type is a VHDL array.
635
+ # NOTE: array are always valid if used in type definition,
636
+ # it is assumed that break_types! from
637
+ # hruby_low_without_namespace.rb is used.
638
+ res << "array ("
639
+ res << self.range.first.to_vhdl(level)
640
+ if self.range.first >= self.range.last then
641
+ res << " downto "
642
+ else
643
+ res << " to "
644
+ end
645
+ res << self.range.last.to_vhdl(level)
646
+ res << ") of "
647
+ # Now generate the base.
648
+ res << base.to_vhdl(level+1)
649
+ else
650
+ # The base is a leaf, therefore the type is VHDL vector.
651
+ # Depending on the base name.
652
+ case(base.name)
653
+ when :bit
654
+ # std_logic_vector.
655
+ res << "std_logic_vector"
656
+ when :signed
657
+ res << "signed"
658
+ when :unsigned
659
+ res << "unsigned"
660
+ else
661
+ res << Low2VHDL.vhdl_name(self.base.name)
662
+ end
663
+ # Now the range
664
+ res << "("
665
+ res << self.range.first.to_vhdl(level)
666
+ left = self.range.first
667
+ right = self.range.last
668
+ left = left.content if left.is_a?(Value)
669
+ right = right.content if right.is_a?(Value)
670
+ if left >= right then
671
+ res << " downto "
672
+ else
673
+ res << " to "
674
+ end
675
+ res << self.range.last.to_vhdl(level)
676
+ res << ")"
677
+ end
678
+ # Return the result.
679
+ return res
680
+ end
681
+ end
682
+
683
+ ## Extends the TypeTuple class with generation of HDLRuby::High text.
684
+ class TypeTuple
685
+
686
+ # Generates the text of the equivalent HDLRuby::High code.
687
+ # +level+ is the hierachical level of the object.
688
+ #
689
+ # NOTE: type tuples are converted to bit vector of their contents.
690
+ def to_vhdl(level = 0)
691
+ # raise AnyError, "Tuple types are not supported in VHDL, please convert them to Struct types using Low::tuple2struct from HDLRuby/hruby_low_witout_tuple."
692
+ return self.to_vector.to_vhdl(level)
693
+ end
694
+ end
695
+
696
+ ## Extends the TypeStruct class with generation of HDLRuby::High text.
697
+ class TypeStruct
698
+
699
+ # Generates the text of the equivalent HDLRuby::High code.
700
+ # +level+ is the hierachical level of the object.
701
+ def to_vhdl(level = 0)
702
+ # The resulting string.
703
+ res = "record \n"
704
+ # Generate each sub type.
705
+ self.each do |key,type|
706
+ res << " " * ((level+1)*3)
707
+ res << Low2VHDL.vhdl_name(key)
708
+ res << ": " << type.to_vhdl(level+1)
709
+ res << ";\n"
710
+ end
711
+ res << " " * (level*3)
712
+ # Close the record.
713
+ res << "end record"
714
+ # Return the result.
715
+ return res
716
+ end
717
+ end
718
+
719
+
720
+ ## Extends the Behavior class with generation of HDLRuby::High text.
721
+ class Behavior
722
+
723
+ # Generates the text of the equivalent HDLRuby::High code.
724
+ # +level+ is the hierachical level of the object.
725
+ def to_vhdl(level = 0)
726
+ # Gather the variables.
727
+ # It is assumed that the inners are all in declared in the
728
+ # direct sub block and that they represent variables, i.e.,
729
+ # Low::to_upper_space! and Low::with_var! has been called.
730
+ vars = self.block.each_inner.to_a
731
+
732
+ # The resulting string.
733
+ res = " " * (level*3)
734
+ # Generate the header.
735
+ unless self.block.name.empty? then
736
+ res << Low2VHDL.vhdl_name(self.block.name) << ": "
737
+ end
738
+ res << "process "
739
+ # Generate the senitivity list.
740
+ if self.each_event.any? then
741
+ # If there is a clock.
742
+ res << "("
743
+ res << self.each_event.map do |event|
744
+ event.ref.to_vhdl(level)
745
+ end.join(", ")
746
+ res << ")"
747
+ else
748
+ # If no clock, generate the sensitivity list from the right
749
+ # values.
750
+ list = self.block.each_node_deep.select do |node|
751
+ node.is_a?(RefName) && !node.leftvalue? &&
752
+ !node.parent.is_a?(RefName) &&
753
+ # Also skip the variables
754
+ !vars.find {|var| var.name == node.name }
755
+ end.to_a
756
+ # Keep only one ref per signal.
757
+ list.uniq! { |node| node.name }
758
+ # Generate the sensitivity list from it.
759
+ res << "("
760
+ res << list.map {|node| node.to_vhdl(level) }.join(", ")
761
+ res << ")"
762
+ end
763
+ res << "\n"
764
+ # Generate the variables.
765
+ vars.each do |var|
766
+ res << " " * ((level+1)*3)
767
+ res << "variable "
768
+ res << Low2VHDL.vhdl_name(var.name) << ": "
769
+ res << var.type.to_vhdl << ";\n"
770
+ end
771
+
772
+ # Generate the content.
773
+ res << " " * (level*3)
774
+ res << "begin\n"
775
+ # Generate the edges if any.
776
+ if self.each_event.find {|event| event.type != :change} then
777
+ # Generate the edge test.
778
+ level = level + 1
779
+ res << " " * (level*3)
780
+ res << "if ("
781
+ res << self.each_event.map do |event|
782
+ if event.type == :posedge then
783
+ "rising_edge(" << event.ref.to_vhdl(level) << ")"
784
+ else
785
+ "falling_edge(" << event.ref.to_vhdl(level)<< ")"
786
+ end
787
+ # The change mode is not an edge!
788
+ end.join(" and ")
789
+ res << ") then\n"
790
+ # Generate the body.
791
+ res << self.block.to_vhdl(vars,level+2)
792
+ # Close the edge test.
793
+ res << " " * (level*3)
794
+ res << "end if;\n"
795
+ level = level - 1
796
+ else
797
+ # Generate the body directly.
798
+ res << self.block.to_vhdl(vars,level+1)
799
+ end
800
+ # Close the process.
801
+ res << " " * (level*3)
802
+ res << "end process;\n\n"
803
+ # Return the result.
804
+ return res
805
+ end
806
+ end
807
+
808
+ ## Extends the TimeBehavior class with generation of HDLRuby::High text.
809
+ class TimeBehavior
810
+ # TimeBehavior is identical to Behavior in VHDL
811
+ end
812
+
813
+
814
+ ## Extends the Event class with generation of HDLRuby::High text.
815
+ class Event
816
+ # Events are not directly generated.
817
+ end
818
+
819
+
820
+ ## Extends the SignalI class with generation of HDLRuby::High text.
821
+ class SignalI
822
+ # Signals are not directly generated.
823
+
824
+ # Generates the text of the equivalent HDLRuby::High code.
825
+ # +level+ is the hierachical level of the object.
826
+ def to_vhdl(level = 0)
827
+ # Should never be here.
828
+ raise AnyError, "Internal error: to_vhdl should be implemented in class :#{self.class}"
829
+ end
830
+ end
831
+
832
+
833
+ ## Extends the SystemI class with generation of HDLRuby::High text.
834
+ class SystemI
835
+ # Instances are not directly generated.
836
+
837
+ # Generates the text of the equivalent HDLRuby::High code.
838
+ # +level+ is the hierachical level of the object.
839
+ def to_vhdl(level = 0)
840
+ # Should never be here.
841
+ raise AnyError, "Internal error: to_vhdl should be implemented in class :#{self.class}"
842
+ end
843
+ end
844
+
845
+
846
+ ## Extends the Statement class with generation of HDLRuby::High text.
847
+ class Statement
848
+
849
+ # Generates the text of the equivalent HDLRuby::High code.
850
+ # +vars+ is the list of the variables and
851
+ # +level+ is the hierachical level of the object.
852
+ def to_vhdl(vars, level = 0)
853
+ # Should never be here.
854
+ raise AnyError, "Internal error: to_vhdl should be implemented in class :#{self.class}"
855
+ end
856
+ end
857
+
858
+ ## Extends the Transmit class with generation of HDLRuby::High text.
859
+ class Transmit
860
+
861
+ # Generates the text of the equivalent HDLRuby::High code.
862
+ # +vars+ is the list of the variables and
863
+ # +level+ is the hierachical level of the object.
864
+ def to_vhdl(vars,level = 0)
865
+ # Generate the assign operator.
866
+ assign = vars.any? do |var|
867
+ self.left.respond_to?(:name) && var.name == self.left.name
868
+ end ? " := " : " <= "
869
+ # Generate the assignment.
870
+ return " " * (level*3) +
871
+ self.left.to_vhdl(level) + assign +
872
+ Low2VHDL.to_type(self.left.type,self.right) + ";\n"
873
+ end
874
+ end
875
+
876
+ ## Extends the If class with generation of HDLRuby::High text.
877
+ class If
878
+
879
+ # Generates the text of the equivalent HDLRuby::High code.
880
+ # +vars+ is the list of the variables and
881
+ # +level+ is the hierachical level of the object.
882
+ def to_vhdl(vars,level = 0)
883
+ # The result string.
884
+ res = " " * (level*3)
885
+ # Generate the test.
886
+ res << "if (" << Low2VHDL.to_boolean(self.condition) << ") then\n"
887
+ # Generate the yes part.
888
+ res << self.yes.to_vhdl(vars,level+1)
889
+ # Generate the alternate if parts.
890
+ self.each_noif do |cond,stmnt|
891
+ res << " " * (level*3)
892
+ # res << "elsif (" << cond.to_vhdl(level) << ") then\n"
893
+ res << "elsif (" << Low2VHDL.to_boolean(cond) << ") then\n"
894
+ res << stmnt.to_vhdl(vars,level+1)
895
+ end
896
+ # Generate the no part if any.
897
+ if self.no then
898
+ res << " " * (level*3)
899
+ res << "else\n" << self.no.to_vhdl(vars,level+1)
900
+ end
901
+ # Close the if.
902
+ res << " " * (level*3)
903
+ res << "end if;\n"
904
+ # Return the result.
905
+ return res
906
+ end
907
+ end
908
+
909
+ ## Extends the When class with generation of HDLRuby::High text.
910
+ class When
911
+
912
+ # Generates the text of the equivalent HDLRuby::High code ensuring
913
+ # the match is of +type+.
914
+ # +vars+ is the list of the variables and
915
+ # +level+ is the hierachical level of the object.
916
+ def to_vhdl(vars,type,level = 0)
917
+ # The result string.
918
+ res = " " * (level*3)
919
+ # Generate the match.
920
+ res << "when " << Low2VHDL.to_type(type,self.match) << " =>\n"
921
+ # Generate the statement.
922
+ res << self.statement.to_vhdl(vars,level+1)
923
+ # Returns the result.
924
+ return res
925
+ end
926
+ end
927
+
928
+ ## Extends the Case class with generation of HDLRuby::High text.
929
+ class Case
930
+
931
+ # Generates the text of the equivalent HDLRuby::High code.
932
+ # +vars+ is the list of the variables and
933
+ # +level+ is the hierachical level of the object.
934
+ def to_vhdl(vars,level = 0)
935
+ # The result string.
936
+ res = " " * (level*3)
937
+ # Generate the test.
938
+ res << "case " << self.value.to_vhdl(level) << " is\n"
939
+ # Generate the whens.
940
+ self.each_when do |w|
941
+ res << w.to_vhdl(vars,self.value.type,level)
942
+ end
943
+ # Generate teh default if any.
944
+ if self.default then
945
+ res << " " * (level*3)
946
+ res << "when others =>\n"
947
+ res << self.default.to_vhdl(vars,level+1)
948
+ else
949
+ # NOTE: some VHDL parsers are very picky about others,
950
+ # even though all the cases have been treated through
951
+ # "when" statements.
952
+ res << " " * (level*3)
953
+ res << "when others =>\n"
954
+ end
955
+ # Close the case.
956
+ res << " " * (level*3)
957
+ res << "end case;\n"
958
+ # Return the resulting string.
959
+ return res
960
+ end
961
+ end
962
+
963
+
964
+ ## Extends the Delay class with generation of HDLRuby::High text.
965
+ class Delay
966
+
967
+ # Generates the text of the equivalent HDLRuby::High code.
968
+ # +level+ is the hierachical level of the object.
969
+ def to_vhdl(level = 0)
970
+ return self.value.to_vhdl(level) + " #{self.unit}"
971
+ end
972
+ end
973
+
974
+
975
+ ## Extends the TimeWait class with generation of HDLRuby::High text.
976
+ class TimeWait
977
+
978
+ # Generates the text of the equivalent HDLRuby::High code.
979
+ # +vars+ is the list of the variables and
980
+ # +level+ is the hierachical level of the object.
981
+ def to_vhdl(vars,level = 0)
982
+ # The resulting string.
983
+ res = " " * (level*3)
984
+ # Generate the wait.
985
+ res << "wait for " << self.delay.to_vhdl(level) << ";\n"
986
+ # Return the resulting string.
987
+ return res
988
+ end
989
+ end
990
+
991
+ ## Extends the TimeRepeat class with generation of HDLRuby::High text.
992
+ class TimeRepeat
993
+
994
+ # Generates the text of the equivalent HDLRuby::High code.
995
+ # +vars+ is the list of the variables and
996
+ # +level+ is the hierachical level of the object.
997
+ def to_vhdl(vars,level = 0)
998
+ raise AnyError, "Internal error: TimeRepeat not supported yet for conversion to VHDL."
999
+ end
1000
+ end
1001
+
1002
+ ## Extends the Block class with generation of HDLRuby::High text.
1003
+ class Block
1004
+
1005
+ # Generates the text of the equivalent HDLRuby::High code.
1006
+ # +vars+ is the list of variables and
1007
+ # +level+ is the hierachical level of the object.
1008
+ #
1009
+ # NOTE: only the statements are generated, the remaining is assumed
1010
+ # to be handled by the upper scope.
1011
+ def to_vhdl(vars, level = 0)
1012
+ # The resulting string.
1013
+ res = ""
1014
+ # Generate the statements.
1015
+ self.each_statement do |stmnt|
1016
+ res << stmnt.to_vhdl(vars,level)
1017
+ end
1018
+ # Return the result.
1019
+ return res
1020
+ end
1021
+ end
1022
+
1023
+ ## Extends the TimeBlock class with generation of HDLRuby::High text.
1024
+ class TimeBlock
1025
+ # TimeBlock is identical to Block in VHDL
1026
+ end
1027
+
1028
+
1029
+ ## Extends the Code class with generation of HDLRuby::High text.
1030
+ class Code
1031
+
1032
+ # Generates the text of the equivalent HDLRuby::High code.
1033
+ # +level+ is the hierachical level of the object.
1034
+ def to_vhdl(level = 0)
1035
+ raise "Code constructs cannot be converted into VHDL."
1036
+ end
1037
+ end
1038
+
1039
+ ## Extends the Connection class with generation of HDLRuby::High text.
1040
+ class Connection
1041
+ # Nothing required, Transmit is generated identically.
1042
+ end
1043
+
1044
+
1045
+ ## Extends the Expression class with generation of HDLRuby::High text.
1046
+ class Expression
1047
+
1048
+ # Generates the text of the equivalent HDLRuby::High code.
1049
+ # +level+ is the hierachical level of the object.
1050
+ def to_vhdl(level = 0)
1051
+ # Should never be here.
1052
+ raise AnyError, "Internal error: to_vhdl should be implemented in class :#{self.class}"
1053
+ end
1054
+ end
1055
+
1056
+ ## Extends the Value class with generation of HDLRuby::High text.
1057
+ class Value
1058
+
1059
+ # Generate the text of the equivalent VHDL is case of arithmetic
1060
+ # expression.
1061
+ def to_arith
1062
+ case self.content
1063
+ when HDLRuby::BitString
1064
+ if self.content.specified? then
1065
+ sign = self.type.signed? && self.content.to_s[-1] == "0" ?
1066
+ -1 : 1
1067
+ return (sign * self.content.to_s.to_i(2)).to_s
1068
+ else
1069
+ return self.content.to_s.upcase
1070
+ end
1071
+ else
1072
+ # NOTE: in VHDL, "z" and "x" must be upcase.
1073
+ return self.content.to_s.upcase
1074
+ end
1075
+ end
1076
+
1077
+ # Generates the text of the equivalent VHDL with
1078
+ # +width+ bits.
1079
+ # +level+ is the hierachical level of the object.
1080
+ def to_vhdl(level = 0, std_logic = false, width = nil)
1081
+ raise "Invalid std_logic argument: #{std_logic}." unless std_logic == true || std_logic == false
1082
+ if self.type.boolean? then
1083
+ # Boolean case
1084
+ if self.content.is_a?(HDLRuby::BitString)
1085
+ return self.zero? ? "false" : "true"
1086
+ else
1087
+ return self.to_i == 0 ? "false" : "true"
1088
+ end
1089
+ end
1090
+ # Other cases
1091
+ # Maybe the value is used as a range or an index.
1092
+ if self.parent.is_a?(RefIndex) or self.parent.is_a?(RefRange) then
1093
+ # Yes, convert to a simple integer.
1094
+ return self.to_i.to_s.upcase
1095
+ end
1096
+ # No, generates as a bit string.
1097
+ width = self.type.width unless width
1098
+ # puts "self.type=#{self.type} width=#{width}"
1099
+ case self.content
1100
+ # when Numeric
1101
+ # return self.content.to_s
1102
+ when HDLRuby::BitString
1103
+ sign = self.type.signed? ? self.content.to_s[-1] : "0"
1104
+ return '"' + self.content.to_s.rjust(width,sign).upcase + '"'
1105
+ else
1106
+ sign = self.type.signed? ? (self.content>=0 ? "0" : "1") : "0"
1107
+ return '"' + self.content.to_s(2).rjust(width,sign).upcase + '"'
1108
+ end
1109
+ end
1110
+ end
1111
+
1112
+ ## Extends the Cast class with generation of HDLRuby::High text.
1113
+ class Cast
1114
+
1115
+ # Generates the text of the equivalent HDLRuby::High code.
1116
+ # +level+ is the hierachical level of the object.
1117
+ def to_vhdl(level = 0)
1118
+ if type.class == TypeVector then
1119
+ case type.base.name
1120
+ when :bit
1121
+ return "std_logic_vector(resize(unsigned(" +
1122
+ self.child.to_vhdl(level) + ")," +
1123
+ (type.range.first-type.range.last+1).abs.to_s + "))"
1124
+ when :signed
1125
+ return "resize(signed(" +
1126
+ self.child.to_vhdl(level) + ")," +
1127
+ (type.range.first-type.range.last+1).abs.to_s + ")"
1128
+ when :unsigned
1129
+ return "resize(unsigned(" +
1130
+ self.child.to_vhdl(level) + ")," +
1131
+ (type.range.first-type.range.last+1).abs.to_s + ")"
1132
+ else
1133
+ raise "Intenal error: convertion to #{type.class} not supported yet for VHDL conversion."
1134
+ end
1135
+ elsif [:bit,:signed,:unsigned].include?(type.name) then
1136
+ # No conversion required.
1137
+ return self.child.to_vhdl(level)
1138
+ else
1139
+ raise "Intenal error: convertion to #{type.class} not supported yet for VHDL conversion."
1140
+ end
1141
+ end
1142
+ end
1143
+
1144
+ ## Extends the Operation class with generation of HDLRuby::High text.
1145
+ class Operation
1146
+
1147
+ # Generates the text of the equivalent HDLRuby::High code.
1148
+ # +level+ is the hierachical level of the object.
1149
+ def to_vhdl(level = 0)
1150
+ # Should never be here.
1151
+ raise AnyError, "Internal error: to_vhdl should be implemented in class :#{self.class}"
1152
+ end
1153
+ end
1154
+
1155
+ ## Extends the Unary class with generation of HDLRuby::High text.
1156
+ class Unary
1157
+
1158
+ # Generates the text of the equivalent HDLRuby::High code.
1159
+ # +level+ is the hierachical level of the object.
1160
+ # +std_logic+ tells if std_logic computation is to be done.
1161
+ def to_vhdl(level = 0, std_logic = false)
1162
+ # Generate the operator string.
1163
+ operator = self.operator == :~ ? "not " : self.operator.to_s[0]
1164
+ # Is the operator arithmetic?
1165
+ if [:+@, :-@].include?(self.operator) then
1166
+ # Yes, type conversion my be required by VHDL standard.
1167
+ res = "#{Low2VHDL.unarith_cast(self)}(#{operator}" +
1168
+ Low2VHDL.to_arith(self.child) + ")"
1169
+ res += "(0)" if std_logic
1170
+ return res
1171
+ else
1172
+ # No, generate simply the unary operation.
1173
+ # (The other unary operator is logic, no need to force
1174
+ # std_logic.)
1175
+ return "(#{operator}" + self.child.to_vhdl(level,std_logic) + ")"
1176
+ end
1177
+ end
1178
+ end
1179
+
1180
+ ## Extends the Binary class with generation of HDLRuby::High text.
1181
+ class Binary
1182
+
1183
+ # Generates the text of the equivalent HDLRuby::High code.
1184
+ # +level+ is the hierachical level of the object.
1185
+ # +std_logic+ tells if std_logic computation is to be done.
1186
+ def to_vhdl(level = 0, std_logic = false)
1187
+ # Shifts/rotate require function call.
1188
+ if [:<<, :>>, :ls, :rs, :lr, :rr].include?(self.operator) then
1189
+ # Generate the function name.
1190
+ case self.operator
1191
+ when :<<, :ls
1192
+ func = "shift_left"
1193
+ when :>>, :rs
1194
+ func = "shift_right"
1195
+ when :lr
1196
+ func = "rotate_left"
1197
+ when :rr
1198
+ function = "rotate_right"
1199
+ else
1200
+ raise AnyError, "Internal unexpected error."
1201
+ end
1202
+ res = Low2VHDL.unarith_cast(self) + "(#{func}(" +
1203
+ Low2VHDL.to_arith(self.left) + "," +
1204
+ Low2VHDL.to_arith(self.right) + "))"
1205
+ res += "(0)" if std_logic # Force std_logic if required.
1206
+ return res
1207
+ end
1208
+ # Usual operators.
1209
+ # Generate the operator string.
1210
+ case self.operator
1211
+ when :&
1212
+ # puts "self.left.to_vhdl=#{self.left.to_vhdl}"
1213
+ # puts "self.right.to_vhdl=#{self.right.to_vhdl}"
1214
+ # puts "self.left.type=#{self.left.type.to_vhdl}"
1215
+ # puts "self.right.type=#{self.right.type.to_vhdl}"
1216
+ # puts "self.type=#{self.type.to_vhdl}"
1217
+ opr = " and "
1218
+ when :|
1219
+ opr = " or "
1220
+ when :^
1221
+ opr = " xor "
1222
+ when :==
1223
+ opr = " = "
1224
+ when :!=
1225
+ opr = " /= "
1226
+ else
1227
+ opr = self.operator.to_s
1228
+ end
1229
+ # Is the operator arithmetic?
1230
+ if [:+, :-, :*, :/, :%].include?(self.operator) then
1231
+ # Yes, type conversion my be required by VHDL standard.
1232
+ res = "#{Low2VHDL.unarith_cast(self)}(" +
1233
+ Low2VHDL.to_arith(self.left) + opr +
1234
+ Low2VHDL.to_arith(self.right) + ")"
1235
+ res += "(0)" if std_logic # Force std_logic if required.
1236
+ return res
1237
+ # Is it a comparison ?
1238
+ elsif [:>, :<, :>=, :<=, :==, :!=].include?(self.operator) then
1239
+ # Generate comparison operation
1240
+ return "(" + self.left.to_vhdl(level) + opr +
1241
+ Low2VHDL.to_type(self.left.type,self.right) + ")"
1242
+ else
1243
+ # No, simply generate the binary operation
1244
+ if std_logic then
1245
+ return "(" + self.left.to_vhdl(level,std_logic) + opr +
1246
+ self.right.to_vhdl(level,std_logic) + ")"
1247
+ else
1248
+ return "(" + self.left.to_vhdl(level) + opr +
1249
+ Low2VHDL.to_type(self.left.type,self.right) + ")"
1250
+ end
1251
+ end
1252
+ end
1253
+ end
1254
+
1255
+ ## Extends the Select class with generation of HDLRuby::High text.
1256
+ class Select
1257
+
1258
+ # Generates the text of the equivalent HDLRuby::High code.
1259
+ # +level+ is the hierachical level of the object.
1260
+ #
1261
+ # NOTE: assumes the existance of the mux function.
1262
+ def to_vhdl(level = 0, std_logic = false)
1263
+ # The resulting string.
1264
+ res = ""
1265
+ # The number of arguments.
1266
+ num = @choices.size
1267
+ # Generate the header.
1268
+ res << "#{Low2VHDL.mux_name(self.type.to_vhdl(level),num)}(" +
1269
+ self.select.to_vhdl(level) << ", "
1270
+ # Generate the choices
1271
+ res << self.each_choice.map do |choice|
1272
+ choice.to_vhdl(level+1)
1273
+ end.join(", ")
1274
+ # Close the select.
1275
+ res << ")"
1276
+ # Return the resulting string.
1277
+ return res
1278
+ end
1279
+ end
1280
+
1281
+ ## Extends the Concat class with generation of HDLRuby::High text.
1282
+ class Concat
1283
+
1284
+ # Generates the text of the equivalent HDLRuby::High code.
1285
+ # +type+ is the expected type of the content.
1286
+ # +level+ is the hierachical level of the object.
1287
+ def to_vhdl(type,level = 0)
1288
+ raise "Invalid class for a type: #{type.class}" unless type.is_a?(Type)
1289
+ # The resulting string.
1290
+ res = ""
1291
+ # Generate the header.
1292
+ # Generate the expressions.
1293
+ # Depends if it is an initialization or not.
1294
+ # if self.type.is_a?(TypeTuple) then
1295
+ if self.parent.is_a?(SignalC) then
1296
+ res << "( " << self.each_expression.map do |expression|
1297
+ Low2VHDL.to_type(type,expression)
1298
+ end.join(",\n#{" "*((level+1)*3)}") << " )"
1299
+ else
1300
+ # Compute the width of the concatenation.
1301
+ width = self.each_expression.reduce(0) do |sum,expr|
1302
+ sum += expr.type.width
1303
+ end
1304
+ # Generate the missing bits if any.
1305
+ width = type.width - width
1306
+ res << '"' + "0" * width + '" & ' if width > 0
1307
+ # Generate the concatenation.
1308
+ res << self.each_expression.map do |expression|
1309
+ # "(" + Low2VHDL.to_type(type,expression) + ")"
1310
+ "(" + expression.to_vhdl(level+1) + ")"
1311
+ end.join(" & ")
1312
+ end
1313
+ # Return the resulting string.
1314
+ return res
1315
+ end
1316
+ end
1317
+
1318
+
1319
+ ## Extends the Ref class with generation of HDLRuby::High text.
1320
+ class Ref
1321
+
1322
+ # Generates the text of the equivalent HDLRuby::High code.
1323
+ # +level+ is the hierachical level of the object.
1324
+ def to_vhdl(level = 0)
1325
+ # Should never be here.
1326
+ raise AnyError, "Internal error: to_vhdl should be implemented in class :#{self.class}"
1327
+ end
1328
+ end
1329
+
1330
+ ## Extends the RefConcat class with generation of HDLRuby::High text.
1331
+ class RefConcat
1332
+
1333
+ # Generates the text of the equivalent HDLRuby::High code.
1334
+ # +level+ is the hierachical level of the object.
1335
+ def to_vhdl(level = 0)
1336
+ # The resulting string.
1337
+ res = ""
1338
+ # Generate the header.
1339
+ res << "( "
1340
+ # Generate the references.
1341
+ res << self.each_ref.map do |ref|
1342
+ ref.to_vhdl(level+1)
1343
+ end.join(", ")
1344
+ # Close the select.
1345
+ res << " )"
1346
+ # Return the resulting string.
1347
+ return res
1348
+ end
1349
+ end
1350
+
1351
+ ## Extends the RefIndex class with generation of HDLRuby::High text.
1352
+ class RefIndex
1353
+
1354
+ # Generates the text of the equivalent HDLRuby::High code.
1355
+ # +level+ is the hierachical level of the object.
1356
+ # +std_logic+ tells if std_logic computation is to be done.
1357
+ def to_vhdl(level = 0, std_logic = false)
1358
+ if self.index.is_a?(Value) then
1359
+ return self.ref.to_vhdl(level,std_logic) +
1360
+ "(#{self.index.to_vhdl(level)})"
1361
+ else
1362
+ return self.ref.to_vhdl(level,std_logic) +
1363
+ "(to_integer(unsigned(#{self.index.to_vhdl(level)})))"
1364
+ end
1365
+ end
1366
+ end
1367
+
1368
+ ## Extends the RefRange class with generation of HDLRuby::High text.
1369
+ class RefRange
1370
+
1371
+ # Generates the text of the equivalent HDLRuby::High code.
1372
+ # +level+ is the hierachical level of the object.
1373
+ # +std_logic+ tells if std_logic computation is to be done.
1374
+ def to_vhdl(level = 0, std_logic = false)
1375
+ # Generates the direction.
1376
+ first = self.range.first
1377
+ first = first.content if first.is_a?(Value)
1378
+ last = self.range.last
1379
+ last = last.content if last.is_a?(Value)
1380
+ direction = first >= last ? "downto " : " to "
1381
+ # Generate the reference.
1382
+ # Forced std_logic case.
1383
+ if std_logic then
1384
+ if first == last then
1385
+ # No range, single bit access for forcing std_logic.
1386
+ return self.ref.to_vhdl(level) +
1387
+ "(#{self.range.first.to_vhdl(level)})"
1388
+ else
1389
+ return self.ref.to_vhdl(level) +
1390
+ "((#{self.range.first.to_vhdl(level)}) " +
1391
+ direction + "(#{self.range.last.to_vhdl(level)}))(0)"
1392
+ end
1393
+ else
1394
+ return self.ref.to_vhdl(level) +
1395
+ "((#{self.range.first.to_vhdl(level)}) " +
1396
+ direction + "(#{self.range.last.to_vhdl(level)}))"
1397
+ end
1398
+ end
1399
+ end
1400
+
1401
+ ## Extends the RefName class with generation of HDLRuby::High text.
1402
+ class RefName
1403
+
1404
+ # Generates the text of the equivalent HDLRuby::High code.
1405
+ # +level+ is the hierachical level of the object.
1406
+ # +std_logic+ tells if std_logic computation is to be done.
1407
+ def to_vhdl(level = 0, std_logic = false)
1408
+ # The resulting string.
1409
+ res = ""
1410
+ # Generate the sub refs if any (case of struct).
1411
+ unless self.ref.is_a?(RefThis) then
1412
+ res << self.ref.to_vhdl(level) << "."
1413
+ end
1414
+ # Generates the current reference.
1415
+ res << Low2VHDL.vhdl_name(self.name)
1416
+ res << "(0)" if std_logic # Force to std_logic if required
1417
+ # Returns the resulting string.
1418
+ return res
1419
+ end
1420
+ end
1421
+
1422
+ ## Extends the RefThis class with generation of HDLRuby::High text.
1423
+ class RefThis
1424
+ # Nothing to generate.
1425
+ end
1426
+
1427
+ ## Extends the Numeric class with generation of HDLRuby::High text.
1428
+ class ::Numeric
1429
+
1430
+ # Generates the text of the equivalent HDLRuby::High code.
1431
+ # +level+ is the hierachical level of the object.
1432
+ def to_vhdl(level = 0)
1433
+ return self.to_s
1434
+ end
1435
+ end
1436
+
1437
+ end