HDLRuby 2.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (224) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +5 -0
  4. data/.yardopts +1 -0
  5. data/Gemfile +4 -0
  6. data/HDLRuby.gemspec +36 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +2774 -0
  9. data/README.pdf +0 -0
  10. data/Rakefile +10 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/exe/hdrcc +3 -0
  14. data/lib/HDLRuby/alcc.rb +137 -0
  15. data/lib/HDLRuby/backend/hruby_allocator.rb +69 -0
  16. data/lib/HDLRuby/backend/hruby_c_allocator.rb +76 -0
  17. data/lib/HDLRuby/hdr_samples/adder.rb +7 -0
  18. data/lib/HDLRuby/hdr_samples/adder_assign_error.rb +11 -0
  19. data/lib/HDLRuby/hdr_samples/adder_bench.rb +27 -0
  20. data/lib/HDLRuby/hdr_samples/adder_gen.rb +7 -0
  21. data/lib/HDLRuby/hdr_samples/adder_nodef_error.rb +7 -0
  22. data/lib/HDLRuby/hdr_samples/addsub.rb +19 -0
  23. data/lib/HDLRuby/hdr_samples/addsubz.rb +22 -0
  24. data/lib/HDLRuby/hdr_samples/alu.rb +47 -0
  25. data/lib/HDLRuby/hdr_samples/calculator.rb +48 -0
  26. data/lib/HDLRuby/hdr_samples/counter_bench.rb +83 -0
  27. data/lib/HDLRuby/hdr_samples/dff.rb +9 -0
  28. data/lib/HDLRuby/hdr_samples/dff_bench.rb +66 -0
  29. data/lib/HDLRuby/hdr_samples/dff_counter.rb +20 -0
  30. data/lib/HDLRuby/hdr_samples/include.rb +14 -0
  31. data/lib/HDLRuby/hdr_samples/instance_open.rb +23 -0
  32. data/lib/HDLRuby/hdr_samples/mei8.rb +256 -0
  33. data/lib/HDLRuby/hdr_samples/mei8_bench.rb +309 -0
  34. data/lib/HDLRuby/hdr_samples/multer_gen.rb +8 -0
  35. data/lib/HDLRuby/hdr_samples/multer_seq.rb +29 -0
  36. data/lib/HDLRuby/hdr_samples/neural/a.rb +9 -0
  37. data/lib/HDLRuby/hdr_samples/neural/a_sub.rb +5 -0
  38. data/lib/HDLRuby/hdr_samples/neural/bw.rb +23 -0
  39. data/lib/HDLRuby/hdr_samples/neural/counter.rb +16 -0
  40. data/lib/HDLRuby/hdr_samples/neural/dadz.rb +9 -0
  41. data/lib/HDLRuby/hdr_samples/neural/dadz_sub.rb +4 -0
  42. data/lib/HDLRuby/hdr_samples/neural/forward.rb +153 -0
  43. data/lib/HDLRuby/hdr_samples/neural/forward_sub.rb +62 -0
  44. data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand.rb +41 -0
  45. data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand_typedef.rb +47 -0
  46. data/lib/HDLRuby/hdr_samples/neural/mem.rb +30 -0
  47. data/lib/HDLRuby/hdr_samples/neural/random.rb +23 -0
  48. data/lib/HDLRuby/hdr_samples/neural/selector.rb +29 -0
  49. data/lib/HDLRuby/hdr_samples/neural/sigmoid.rb +20 -0
  50. data/lib/HDLRuby/hdr_samples/neural/z.rb +33 -0
  51. data/lib/HDLRuby/hdr_samples/prog.obj +256 -0
  52. data/lib/HDLRuby/hdr_samples/ram.rb +18 -0
  53. data/lib/HDLRuby/hdr_samples/register_with_code_bench.rb +98 -0
  54. data/lib/HDLRuby/hdr_samples/rom.rb +10 -0
  55. data/lib/HDLRuby/hdr_samples/struct.rb +14 -0
  56. data/lib/HDLRuby/hdr_samples/sumprod.rb +29 -0
  57. data/lib/HDLRuby/hdr_samples/sw_encrypt_bench.rb +103 -0
  58. data/lib/HDLRuby/hdr_samples/sw_encrypt_cpu_bench.rb +261 -0
  59. data/lib/HDLRuby/hdr_samples/sw_encrypt_cpusim_bench.rb +302 -0
  60. data/lib/HDLRuby/hdr_samples/system_open.rb +11 -0
  61. data/lib/HDLRuby/hdr_samples/tuple.rb +16 -0
  62. data/lib/HDLRuby/hdr_samples/with_channel.rb +118 -0
  63. data/lib/HDLRuby/hdr_samples/with_class.rb +199 -0
  64. data/lib/HDLRuby/hdr_samples/with_decoder.rb +17 -0
  65. data/lib/HDLRuby/hdr_samples/with_fsm.rb +34 -0
  66. data/lib/HDLRuby/hdr_samples/with_reconf.rb +103 -0
  67. data/lib/HDLRuby/hdrcc.rb +623 -0
  68. data/lib/HDLRuby/high_samples/_adder_fault.rb +23 -0
  69. data/lib/HDLRuby/high_samples/_generic_transmission2.rb +146 -0
  70. data/lib/HDLRuby/high_samples/adder.rb +21 -0
  71. data/lib/HDLRuby/high_samples/adder_common_errors.rb +25 -0
  72. data/lib/HDLRuby/high_samples/addsub.rb +33 -0
  73. data/lib/HDLRuby/high_samples/addsubz.rb +37 -0
  74. data/lib/HDLRuby/high_samples/after.rb +28 -0
  75. data/lib/HDLRuby/high_samples/all_signals.rb +29 -0
  76. data/lib/HDLRuby/high_samples/alu.rb +61 -0
  77. data/lib/HDLRuby/high_samples/anonymous.rb +41 -0
  78. data/lib/HDLRuby/high_samples/before.rb +28 -0
  79. data/lib/HDLRuby/high_samples/blockblock.rb +26 -0
  80. data/lib/HDLRuby/high_samples/bugs/dadz.rb +22 -0
  81. data/lib/HDLRuby/high_samples/bugs/misample_instan.rb +20 -0
  82. data/lib/HDLRuby/high_samples/bugs/misample_updown.rb +22 -0
  83. data/lib/HDLRuby/high_samples/bugs/sample_add.rb +16 -0
  84. data/lib/HDLRuby/high_samples/bugs/sample_barrel.rb +13 -0
  85. data/lib/HDLRuby/high_samples/bugs/sample_daice.rb +57 -0
  86. data/lib/HDLRuby/high_samples/bugs/sample_kumiawase.rb +52 -0
  87. data/lib/HDLRuby/high_samples/bugs/sample_multi.rb +18 -0
  88. data/lib/HDLRuby/high_samples/bugs/sample_sub.rb +14 -0
  89. data/lib/HDLRuby/high_samples/bugs/z2.rb +32 -0
  90. data/lib/HDLRuby/high_samples/case.rb +32 -0
  91. data/lib/HDLRuby/high_samples/case2.rb +30 -0
  92. data/lib/HDLRuby/high_samples/change.rb +23 -0
  93. data/lib/HDLRuby/high_samples/clocks.rb +35 -0
  94. data/lib/HDLRuby/high_samples/comparer.rb +21 -0
  95. data/lib/HDLRuby/high_samples/conditionals.rb +29 -0
  96. data/lib/HDLRuby/high_samples/dff.rb +23 -0
  97. data/lib/HDLRuby/high_samples/each.rb +28 -0
  98. data/lib/HDLRuby/high_samples/exporter.rb +42 -0
  99. data/lib/HDLRuby/high_samples/functions.rb +60 -0
  100. data/lib/HDLRuby/high_samples/if_seq.rb +26 -0
  101. data/lib/HDLRuby/high_samples/inherit_as_dff.rb +32 -0
  102. data/lib/HDLRuby/high_samples/inherit_dff.rb +36 -0
  103. data/lib/HDLRuby/high_samples/instance.rb +37 -0
  104. data/lib/HDLRuby/high_samples/memory.rb +64 -0
  105. data/lib/HDLRuby/high_samples/multi_file.rb +27 -0
  106. data/lib/HDLRuby/high_samples/overload.rb +32 -0
  107. data/lib/HDLRuby/high_samples/paper_after.rb +49 -0
  108. data/lib/HDLRuby/high_samples/ram.rb +27 -0
  109. data/lib/HDLRuby/high_samples/registers.rb +139 -0
  110. data/lib/HDLRuby/high_samples/rom.rb +23 -0
  111. data/lib/HDLRuby/high_samples/scopeblockname.rb +37 -0
  112. data/lib/HDLRuby/high_samples/scopescope.rb +26 -0
  113. data/lib/HDLRuby/high_samples/shift.rb +31 -0
  114. data/lib/HDLRuby/high_samples/shift2.rb +40 -0
  115. data/lib/HDLRuby/high_samples/simple_instance.rb +31 -0
  116. data/lib/HDLRuby/high_samples/test_all.sh +10 -0
  117. data/lib/HDLRuby/high_samples/typedef.rb +24 -0
  118. data/lib/HDLRuby/high_samples/values.rb +70 -0
  119. data/lib/HDLRuby/high_samples/vector.rb +22 -0
  120. data/lib/HDLRuby/high_samples/with_decoder.rb +30 -0
  121. data/lib/HDLRuby/high_samples/with_fsm.rb +46 -0
  122. data/lib/HDLRuby/high_samples/with_pipe.rb +43 -0
  123. data/lib/HDLRuby/high_samples/with_seq.rb +25 -0
  124. data/lib/HDLRuby/hruby_bstr.rb +1085 -0
  125. data/lib/HDLRuby/hruby_check.rb +317 -0
  126. data/lib/HDLRuby/hruby_db.rb +432 -0
  127. data/lib/HDLRuby/hruby_error.rb +44 -0
  128. data/lib/HDLRuby/hruby_high.rb +4103 -0
  129. data/lib/HDLRuby/hruby_low.rb +4735 -0
  130. data/lib/HDLRuby/hruby_low2c.rb +1986 -0
  131. data/lib/HDLRuby/hruby_low2high.rb +738 -0
  132. data/lib/HDLRuby/hruby_low2seq.rb +248 -0
  133. data/lib/HDLRuby/hruby_low2sym.rb +126 -0
  134. data/lib/HDLRuby/hruby_low2vhd.rb +1437 -0
  135. data/lib/HDLRuby/hruby_low_bool2select.rb +295 -0
  136. data/lib/HDLRuby/hruby_low_cleanup.rb +193 -0
  137. data/lib/HDLRuby/hruby_low_fix_types.rb +437 -0
  138. data/lib/HDLRuby/hruby_low_mutable.rb +1803 -0
  139. data/lib/HDLRuby/hruby_low_resolve.rb +165 -0
  140. data/lib/HDLRuby/hruby_low_skeleton.rb +129 -0
  141. data/lib/HDLRuby/hruby_low_with_bool.rb +141 -0
  142. data/lib/HDLRuby/hruby_low_with_port.rb +167 -0
  143. data/lib/HDLRuby/hruby_low_with_var.rb +302 -0
  144. data/lib/HDLRuby/hruby_low_without_bit2vector.rb +88 -0
  145. data/lib/HDLRuby/hruby_low_without_concat.rb +162 -0
  146. data/lib/HDLRuby/hruby_low_without_connection.rb +113 -0
  147. data/lib/HDLRuby/hruby_low_without_namespace.rb +718 -0
  148. data/lib/HDLRuby/hruby_low_without_outread.rb +107 -0
  149. data/lib/HDLRuby/hruby_low_without_select.rb +206 -0
  150. data/lib/HDLRuby/hruby_serializer.rb +398 -0
  151. data/lib/HDLRuby/hruby_tools.rb +37 -0
  152. data/lib/HDLRuby/hruby_types.rb +239 -0
  153. data/lib/HDLRuby/hruby_values.rb +64 -0
  154. data/lib/HDLRuby/hruby_verilog.rb +1888 -0
  155. data/lib/HDLRuby/hruby_verilog_name.rb +52 -0
  156. data/lib/HDLRuby/low_samples/adder.yaml +97 -0
  157. data/lib/HDLRuby/low_samples/after.yaml +228 -0
  158. data/lib/HDLRuby/low_samples/before.yaml +223 -0
  159. data/lib/HDLRuby/low_samples/blockblock.yaml +48 -0
  160. data/lib/HDLRuby/low_samples/bugs/sample_add.yaml +97 -0
  161. data/lib/HDLRuby/low_samples/bugs/sample_daice.yaml +444 -0
  162. data/lib/HDLRuby/low_samples/bugs/sample_kumiawase.yaml +332 -0
  163. data/lib/HDLRuby/low_samples/bugs/sample_sub.yaml +97 -0
  164. data/lib/HDLRuby/low_samples/bugs/seqpar.yaml +184 -0
  165. data/lib/HDLRuby/low_samples/case.yaml +327 -0
  166. data/lib/HDLRuby/low_samples/change.yaml +135 -0
  167. data/lib/HDLRuby/low_samples/clocks.yaml +674 -0
  168. data/lib/HDLRuby/low_samples/cloner.rb +22 -0
  169. data/lib/HDLRuby/low_samples/comparer.yaml +85 -0
  170. data/lib/HDLRuby/low_samples/conditionals.yaml +133 -0
  171. data/lib/HDLRuby/low_samples/dff.yaml +107 -0
  172. data/lib/HDLRuby/low_samples/each.yaml +1328 -0
  173. data/lib/HDLRuby/low_samples/exporter.yaml +226 -0
  174. data/lib/HDLRuby/low_samples/functions.yaml +298 -0
  175. data/lib/HDLRuby/low_samples/generic_transmission.yaml +597 -0
  176. data/lib/HDLRuby/low_samples/inherit_as_dff.yaml +125 -0
  177. data/lib/HDLRuby/low_samples/inherit_dff.yaml +107 -0
  178. data/lib/HDLRuby/low_samples/load_yaml.rb +11 -0
  179. data/lib/HDLRuby/low_samples/memory.yaml +678 -0
  180. data/lib/HDLRuby/low_samples/namespace_extractor.rb +23 -0
  181. data/lib/HDLRuby/low_samples/overload.yaml +226 -0
  182. data/lib/HDLRuby/low_samples/paper_after.yaml +431 -0
  183. data/lib/HDLRuby/low_samples/port_maker.rb +14 -0
  184. data/lib/HDLRuby/low_samples/ram.yaml +207 -0
  185. data/lib/HDLRuby/low_samples/registers.yaml +228 -0
  186. data/lib/HDLRuby/low_samples/rom.yaml +2950 -0
  187. data/lib/HDLRuby/low_samples/shift.yaml +230 -0
  188. data/lib/HDLRuby/low_samples/shift2.yaml +2095 -0
  189. data/lib/HDLRuby/low_samples/simple_instance.yaml +102 -0
  190. data/lib/HDLRuby/low_samples/test_all.sh +43 -0
  191. data/lib/HDLRuby/low_samples/typedef.yaml +115 -0
  192. data/lib/HDLRuby/low_samples/values.yaml +577 -0
  193. data/lib/HDLRuby/low_samples/variable_maker.rb +14 -0
  194. data/lib/HDLRuby/low_samples/vector.yaml +56 -0
  195. data/lib/HDLRuby/low_samples/with_seq.yaml +188 -0
  196. data/lib/HDLRuby/low_samples/yaml2hdr.rb +10 -0
  197. data/lib/HDLRuby/low_samples/yaml2vhd.rb +19 -0
  198. data/lib/HDLRuby/sim/Makefile +19 -0
  199. data/lib/HDLRuby/sim/hruby_sim.h +590 -0
  200. data/lib/HDLRuby/sim/hruby_sim_calc.c +2362 -0
  201. data/lib/HDLRuby/sim/hruby_sim_core.c +589 -0
  202. data/lib/HDLRuby/sim/hruby_sim_list.c +93 -0
  203. data/lib/HDLRuby/sim/hruby_sim_vizualize.c +91 -0
  204. data/lib/HDLRuby/sim/hruby_value_pool.c +64 -0
  205. data/lib/HDLRuby/std/channel.rb +354 -0
  206. data/lib/HDLRuby/std/clocks.rb +165 -0
  207. data/lib/HDLRuby/std/counters.rb +82 -0
  208. data/lib/HDLRuby/std/decoder.rb +214 -0
  209. data/lib/HDLRuby/std/fsm.rb +516 -0
  210. data/lib/HDLRuby/std/pipeline.rb +220 -0
  211. data/lib/HDLRuby/std/reconf.rb +309 -0
  212. data/lib/HDLRuby/test_hruby_bstr.rb +2259 -0
  213. data/lib/HDLRuby/test_hruby_high.rb +594 -0
  214. data/lib/HDLRuby/test_hruby_high_low.rb +99 -0
  215. data/lib/HDLRuby/test_hruby_low.rb +934 -0
  216. data/lib/HDLRuby/v_samples/adder.v +10 -0
  217. data/lib/HDLRuby/v_samples/dff.v +12 -0
  218. data/lib/HDLRuby/v_samples/ram.v +20 -0
  219. data/lib/HDLRuby/v_samples/rom.v +270 -0
  220. data/lib/HDLRuby/version.rb +3 -0
  221. data/lib/HDLRuby.rb +11 -0
  222. data/makedoc +1 -0
  223. data/metadata.yaml +4 -0
  224. metadata +299 -0
@@ -0,0 +1,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