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,4103 @@
1
+ require "HDLRuby/hruby_low"
2
+ require "HDLRuby/hruby_tools"
3
+ require "HDLRuby/hruby_types"
4
+ require "HDLRuby/hruby_values"
5
+ require "HDLRuby/hruby_bstr"
6
+ require "HDLRuby/hruby_low_mutable"
7
+
8
+ require 'set'
9
+ require 'forwardable'
10
+
11
+ ##
12
+ # High-level libraries for describing digital hardware.
13
+ #######################################################
14
+ module HDLRuby::High
15
+
16
+ # Tells HDLRuby is currently booting.
17
+ def self.booting?
18
+ true
19
+ end
20
+
21
+ # Base = HDLRuby::Base
22
+ Low = HDLRuby::Low
23
+
24
+ # Gets the infinity.
25
+ def infinity
26
+ return HDLRuby::Infinity
27
+ end
28
+
29
+
30
+
31
+ ##
32
+ # Module providing extension of class.
33
+ module SingletonExtend
34
+ # Adds the singleton contents of +obj+ to current eigen class.
35
+ #
36
+ # NOTE: conflicting existing singleton content will be overridden if
37
+ def eigen_extend(obj)
38
+ # puts "eigen_extend for #{self} class=#{self.class}"
39
+ obj.singleton_methods.each do |name|
40
+ next if name == :yaml_tag # Do not know why we need to skip
41
+ # puts "name=#{name}"
42
+ self.define_singleton_method(name, &obj.singleton_method(name))
43
+ end
44
+ end
45
+ end
46
+
47
+
48
+ ##
49
+ # Describes a namespace.
50
+ # Used for managing the access points to internals of hardware constructs.
51
+ class Namespace
52
+
53
+ include SingletonExtend
54
+
55
+ # The reserved names
56
+ RESERVED = [ :user, :initialize, :add_method, :concat_namespace,
57
+ :to_namespace, :user?, :user_deep? ]
58
+
59
+ # The construct using the namespace.
60
+ attr_reader :user
61
+
62
+ # Creates a new namespace attached to +user+.
63
+ def initialize(user)
64
+ # Sets the user.
65
+ @user = user
66
+ # Initialize the concat namespaces.
67
+ @concats = []
68
+ end
69
+
70
+ # Clones (safely) the namespace.
71
+ def clone
72
+ # Create the new namespace.
73
+ res = Namespace.new(@user)
74
+ # Adds the concats.
75
+ @concats.each do |concat|
76
+ res.concat_namespace(concat)
77
+ end
78
+ return res
79
+ end
80
+
81
+ # Adds method +name+ provided the name is not empty and the method
82
+ # is not already defined in the current namespace.
83
+ def add_method(name,&ruby_block)
84
+ # puts "add_method with name=#{name} and parameters=#{ruby_block.parameters}"
85
+ unless name.empty? then
86
+ if RESERVED.include?(name.to_sym) then
87
+ raise AnyError,
88
+ "Resevered name #{name} cannot be overridden."
89
+ end
90
+ if self.respond_to?(name) then
91
+ raise AnyError,
92
+ "Symbol #{name} is already defined."
93
+ end
94
+ define_singleton_method(name,&ruby_block)
95
+ end
96
+ end
97
+
98
+ # Concats another +namespace+ to current one.
99
+ def concat_namespace(namespace)
100
+ # Ensure namespace is really a namespace and concat it.
101
+ namespace = namespace.to_namespace
102
+ self.eigen_extend(namespace)
103
+ # Adds the concat the the list.
104
+ @concats << namespace
105
+ end
106
+
107
+ # Ensure it is a namespace
108
+ def to_namespace
109
+ return self
110
+ end
111
+
112
+ # Tell if an +object+ is the user of the namespace.
113
+ def user?(object)
114
+ return @user.equal?(object)
115
+ end
116
+
117
+ # Tell if an +object+ is the user of the namespace or of one of its
118
+ # concats.
119
+ def user_deep?(object)
120
+ # puts "@user=#{@user}, @concats=#{@concats.size}, object=#{object}"
121
+ # Convert the object to a user if appliable (for SystemT)
122
+ object = object.to_user if object.respond_to?(:to_user)
123
+ # Maybe object is the user of this namespace.
124
+ return true if user?(object)
125
+ # No, try in the concat namespaces.
126
+ @concats.any? { |concat| concat.user_deep?(object) }
127
+ end
128
+ end
129
+
130
+
131
+ ##
132
+ # Module providing handling of unknown methods for hardware constructs.
133
+ module Hmissing
134
+ High = HDLRuby::High
135
+
136
+ # Missing methods may be immediate values, if not, they are looked up
137
+ # in the upper level of the namespace if any.
138
+ def method_missing(m, *args, &ruby_block)
139
+ # puts "method_missing in class=#{self.class} with m=#{m}"
140
+ # Is the missing method an immediate value?
141
+ value = m.to_value
142
+ return value if value and args.empty?
143
+ # No, is there an upper namespace, i.e. is the current object
144
+ # present in the space?
145
+ if High.space_index(self) then
146
+ # Yes, self is in it, can try the methods in the space.
147
+ High.space_call(m,*args,&ruby_block)
148
+ elsif self.respond_to?(:namespace) and
149
+ High.space_index(self.namespace) then
150
+ # Yes, the private namespace is in it, can try the methods in
151
+ # the space.
152
+ begin
153
+ High.space_call(m,*args,&ruby_block)
154
+ end
155
+ elsif self.respond_to?(:public_namespace) and
156
+ High.space_index(self.public_namespace) then
157
+ # Yes, the private namespace is in it, can try the methods in
158
+ # the space.
159
+ High.space_call(m,*args,&ruby_block)
160
+ else
161
+ # No, this is a true error.
162
+ raise NotDefinedError, "undefined HDLRuby construct, local variable or method `#{m}'."
163
+ end
164
+ end
165
+ end
166
+
167
+ module HScope_missing
168
+
169
+ include Hmissing
170
+
171
+ alias_method :h_missing, :method_missing
172
+
173
+ # Missing methods are looked for in the private namespace.
174
+ #
175
+ # NOTE: it is ok to use the private namespace because the scope
176
+ # can only be accessed if it is available from its systemT.
177
+ def method_missing(m, *args, &ruby_block)
178
+ # puts "looking for #{m} in #{self}"
179
+ # Is the scope currently opened?
180
+ # if High.space_top.user_deep?(self) then
181
+ if High.space_index(self.namespace) then
182
+ # Yes, use the stack of namespaces.
183
+ h_missing(m,*args,&ruby_block)
184
+ else
185
+ # No, look into the current namespace and return a reference
186
+ # to the result if it is a referable hardware object.
187
+ res = self.namespace.send(m,*args,&ruby_block)
188
+ if res.respond_to?(:to_ref) then
189
+ # This is a referable object, build the reference from
190
+ # the namespace.
191
+ return RefObject.new(self.to_ref,res)
192
+ end
193
+ end
194
+ end
195
+ end
196
+
197
+
198
+ ##
199
+ # Module providing methods for declaring select expressions.
200
+ module Hmux
201
+ # Creates an operator selecting from +select+ one of the +choices+.
202
+ #
203
+ # NOTE: * +choices+ can either be a list of arguments or an array.
204
+ # If +choices+ has only two entries (and it is not a hash),
205
+ # +value+ will be converted to a boolean.
206
+ # * The type of the select is computed as the largest no
207
+ # integer-constant choice. If only constant integer choices,
208
+ # use the largest type of them.
209
+ def mux(select,*choices)
210
+ # Process the choices.
211
+ choices = choices.flatten(1) if choices.size == 1
212
+ choices.map! { |choice| choice.to_expr }
213
+ # Compute the type of the select as the largest no
214
+ # integer-constant type.
215
+ # If only such constants, use the largest type of them.
216
+ type = choices.reduce(Bit) do |type,choice|
217
+ unless choice.is_a?(Value) && choice.type == Integer then
218
+ type.width >= choice.type.width ? type : choice.type
219
+ else
220
+ type
221
+ end
222
+ end
223
+ unless type then
224
+ type = choices.reduce(Bit) do |type,choice|
225
+ type.width >= choice.type.width ? type : choice.type
226
+ end
227
+ end
228
+ # Generate the select expression.
229
+ return Select.new(type,"?",select.to_expr,*choices)
230
+ end
231
+ end
232
+
233
+
234
+ ##
235
+ # Module providing declaration of inner signal (assumes inner signals
236
+ # are present.
237
+ module Hinner
238
+
239
+ # Only adds the methods if not present.
240
+ def self.included(klass)
241
+ klass.class_eval do
242
+ unless instance_methods.include?(:make_inners) then
243
+ # Creates and adds a set of inners typed +type+ from a
244
+ # list of +names+.
245
+ #
246
+ # NOTE: * a name can also be a signal, is which case it is
247
+ # duplicated.
248
+ # * a name can also be a hash containing names
249
+ # associated with an initial value.
250
+ def make_inners(type, *names)
251
+ res = nil
252
+ names.each do |name|
253
+ if name.respond_to?(:to_sym) then
254
+ # Adds the inner signal
255
+ res = self.add_inner(
256
+ SignalI.new(name,type,:inner))
257
+ elsif name.is_a?(Hash) then
258
+ # Names associated with values.
259
+ names.each do |name,value|
260
+ res = self.add_inner(
261
+ SignalI.new(name,type,:inner,value))
262
+ end
263
+ else
264
+ raise AnyError,
265
+ "Invalid class for a name: #{name.class}"
266
+ end
267
+ end
268
+ return res
269
+ end
270
+ end
271
+
272
+ unless instance_methods.include?(:make_constants) then
273
+ # Creates and adds a set of contants typed +type+ from a
274
+ # hsh given names and corresponding values.
275
+ def make_constants(type, hsh)
276
+ res = nil
277
+ hsh.each do |name,value|
278
+ # Adds the Constant signal
279
+ res = self.add_inner(SignalC.new(name,type,value))
280
+ end
281
+ return res
282
+ end
283
+ end
284
+
285
+ unless instance_methods.include?(:inner) then
286
+ # Declares high-level bit inner signals named +names+.
287
+ def inner(*names)
288
+ self.make_inners(bit,*names)
289
+ end
290
+ end
291
+
292
+ unless instance_methods.include?(:constant) then
293
+ # Declares high-level untyped constant signals by name and
294
+ # value given by +hsh+ of the current type.
295
+ def constant(hsh)
296
+ self.make_constants(bit,hsh)
297
+ end
298
+ end
299
+ end
300
+ end
301
+ end
302
+
303
+
304
+ # Classes describing hardware types.
305
+
306
+ ##
307
+ # Describes a high-level system type.
308
+ class SystemT < Low::SystemT
309
+ High = HDLRuby::High
310
+
311
+ # include Hinner
312
+
313
+ include SingletonExtend
314
+
315
+ # The public namespace
316
+ #
317
+ # NOTE: the private namespace is the namespace of the scope object.
318
+ attr_reader :public_namespace
319
+
320
+ ##
321
+ # Creates a new high-level system type named +name+ and inheriting
322
+ # from +mixins+.
323
+ #
324
+ # # If name is hash, it is considered the system is unnamed and the
325
+ # # table is used to rename its signals or instances.
326
+ #
327
+ # The proc +ruby_block+ is executed when instantiating the system.
328
+ def initialize(name, *mixins, &ruby_block)
329
+ # Initialize the system type structure.
330
+ super(name,Scope.new(name,self))
331
+
332
+ # Initialize the set of extensions to transmit to the instances'
333
+ # eigen class
334
+ @singleton_instanceO = Namespace.new(self.scope)
335
+
336
+ # Create the public namespace.
337
+ @public_namespace = Namespace.new(self.scope)
338
+
339
+ # Check and set the mixins.
340
+ mixins.each do |mixin|
341
+ unless mixin.is_a?(SystemT) then
342
+ raise AnyError,
343
+ "Invalid class for inheriting: #{mixin.class}."
344
+ end
345
+ end
346
+ @to_includes = mixins
347
+ # Prepare the instantiation methods
348
+ make_instantiater(name,SystemI,&ruby_block)
349
+ end
350
+
351
+ # Converts to a namespace user.
352
+ def to_user
353
+ # Returns the scope.
354
+ return @scope
355
+ end
356
+
357
+ # Creates and adds a set of inputs typed +type+ from a list of +names+.
358
+ #
359
+ # NOTE: a name can also be a signal, is which case it is duplicated.
360
+ def make_inputs(type, *names)
361
+ # Check if called within the top scope of the block.
362
+ if High.top_user != @scope then
363
+ # No, cannot make an input from here.
364
+ raise AnyError,
365
+ "Input signals can only be declared in the top scope of a system."
366
+ end
367
+ res = nil
368
+ names.each do |name|
369
+ if name.respond_to?(:to_sym) then
370
+ res = self.add_input(SignalI.new(name,type,:input))
371
+ elsif name.is_a?(Hash) then
372
+ # Names associated with values.
373
+ names.each do |name,value|
374
+ res = self.add_inner(
375
+ SignalI.new(name,type,:inner,value))
376
+ end
377
+ else
378
+ raise AnyError, "Invalid class for a name: #{name.class}"
379
+ end
380
+ end
381
+ return res
382
+ end
383
+
384
+ # Creates and adds a set of outputs typed +type+ from a list of +names+.
385
+ #
386
+ # NOTE: a name can also be a signal, is which case it is duplicated.
387
+ def make_outputs(type, *names)
388
+ # puts "type=#{type.inspect}"
389
+ res = nil
390
+ names.each do |name|
391
+ # puts "name=#{name}"
392
+ if name.respond_to?(:to_sym) then
393
+ res = self.add_output(SignalI.new(name,type,:output))
394
+ elsif name.is_a?(Hash) then
395
+ # Names associated with values.
396
+ names.each do |name,value|
397
+ res = self.add_inner(
398
+ SignalI.new(name,type,:inner,value))
399
+ end
400
+ else
401
+ raise AnyError, "Invalid class for a name: #{name.class}"
402
+ end
403
+ end
404
+ return res
405
+ end
406
+
407
+ # Creates and adds a set of inouts typed +type+ from a list of +names+.
408
+ #
409
+ # NOTE: a name can also be a signal, is which case it is duplicated.
410
+ def make_inouts(type, *names)
411
+ res = nil
412
+ names.each do |name|
413
+ if name.respond_to?(:to_sym) then
414
+ res = self.add_inout(SignalI.new(name,type,:inout))
415
+ elsif name.is_a?(Hash) then
416
+ # Names associated with values.
417
+ names.each do |name,value|
418
+ res = self.add_inner(
419
+ SignalI.new(name,type,:inner,value))
420
+ end
421
+ else
422
+ raise AnyError, "Invalid class for a name: #{name.class}"
423
+ end
424
+ end
425
+ return res
426
+ end
427
+
428
+ # Iterates over the all interface signals, i.e, also the ones of
429
+ # the included systems.
430
+ #
431
+ # Returns an enumerator if no ruby block is given.
432
+ def each_signal_with_included(&ruby_block)
433
+ # No ruby block? Return an enumerator.
434
+ return to_enum(:each_signal_with_included) unless ruby_block
435
+ # Iterate on the signals of the current system.
436
+ self.each_signal(&ruby_block)
437
+ # Recurse on the included systems.
438
+ self.scope.each_included do |included|
439
+ included.each_signal_with_included(&ruby_block)
440
+ end
441
+ end
442
+
443
+ # Get one of all the interface signal by index, i.e., also the ones
444
+ # of the included systems.
445
+ def get_interface_with_included(i)
446
+ return each_signal_with_included.to_a[i]
447
+ end
448
+
449
+ # Iterates over the exported constructs
450
+ #
451
+ # NOTE: look into the scope.
452
+ def each_export(&ruby_block)
453
+ @scope.each_export(&ruby_block)
454
+ end
455
+
456
+ # Gets class containing the extension for the instances.
457
+ def singleton_instance
458
+ @singleton_instanceO.singleton_class
459
+ end
460
+
461
+ # Gets the private namespace of the system.
462
+ def namespace
463
+ return self.scope.namespace
464
+ end
465
+
466
+ # Execute +ruby_block+ in the context of the system.
467
+ def run(&ruby_block)
468
+ self.scope.open(&ruby_block)
469
+ end
470
+
471
+ # Opens for extension.
472
+ #
473
+ # NOTE: actually executes +ruby_block+ in the context of the scope
474
+ # of the system.
475
+ def open(&ruby_block)
476
+ # Are we instantiating current system?
477
+ if (High.space_include?(self.scope.namespace)) then
478
+ # Yes, execute the ruby block in the top context of the
479
+ # system.
480
+ # self.scope.open(&ruby_block)
481
+ self.run(&ruby_block)
482
+ else
483
+ # No, add the ruby block to the list of block to execute
484
+ # when instantiating.
485
+ @instance_procs << ruby_block
486
+ end
487
+ end
488
+
489
+ # The instantiation target class.
490
+ attr_reader :instance_class
491
+
492
+ # Iterates over the instance procedures.
493
+ #
494
+ # Returns an enumerator if no ruby block is given.
495
+ def each_instance_proc(&ruby_block)
496
+ # No ruby block? Return an enumerator.
497
+ return to_enum(:each_instance_proc) unless ruby_block
498
+ # A block? Apply it on each input signal instance.
499
+ @instance_procs.each(&ruby_block)
500
+ end
501
+
502
+ # Expands the system with possible arugments +args+ to a new system
503
+ # named +name+.
504
+ def expand(name, *args)
505
+ # puts "expand #{self.name} to #{name}"
506
+ # Create the new system.
507
+ expanded = self.class.new(name.to_s) {}
508
+ # Include the mixin systems given when declaring the system.
509
+ @to_includes.each { |system| expanded.scope.include(system) }
510
+
511
+ # Fills the scope of the expanded class.
512
+ # puts "Build top with #{self.name} for #{name}"
513
+ expanded.scope.build_top(self.scope,*args)
514
+ # puts "Top built with #{self.name} for #{name}"
515
+ return expanded
516
+ end
517
+
518
+ # Make a system eigen of a given +instance+.
519
+ def eigenize(instance)
520
+ unless instance.systemT == self then
521
+ raise "Cannot eigenize system #{self.name} to instance #{instance.name}"
522
+ end
523
+ # The instance becames the owner.
524
+ @owner = instance
525
+ # Fill the public namespace
526
+ space = self.public_namespace
527
+ # Interface signals
528
+ # puts "i_name=#{i_name} @to_includes=#{@to_includes.size}"
529
+ self.each_signal do |signal|
530
+ # puts "signal=#{signal.name}"
531
+ space.send(:define_singleton_method,signal.name) do
532
+ RefObject.new(instance.to_ref,signal)
533
+ end
534
+ end
535
+ # Exported objects
536
+ self.each_export do |export|
537
+ # puts "export=#{export.name}"
538
+ space.send(:define_singleton_method,export.name) do
539
+ RefObject.new(instance.to_ref,export)
540
+ end
541
+ end
542
+
543
+ return self
544
+ end
545
+
546
+ # Instantiate the system type to an instance named +i_name+ with
547
+ # possible arguments +args+.
548
+ def instantiate(i_name,*args)
549
+ # Create the eigen type.
550
+ eigen = self.expand(High.names_create(i_name.to_s + ":T"), *args)
551
+
552
+ # Create the instance and sets its eigen system to +eigen+.
553
+ instance = @instance_class.new(i_name,eigen)
554
+ eigen.eigenize(instance)
555
+ # puts "instance interface=#{instance.each_signal.to_a.size}"
556
+ # puts "eigen interface=#{eigen.each_signal.to_a.size}"
557
+
558
+ # Extend the instance.
559
+ instance.eigen_extend(@singleton_instanceO)
560
+ # puts "instance scope= #{instance.systemT.scope}"
561
+ # Add the instance.
562
+ High.top_user.send(:add_systemI,instance)
563
+ # Return the resulting instance
564
+ return instance
565
+ end
566
+
567
+ # Instantiation can also be done throw the call operator.
568
+ alias_method :call, :instantiate
569
+
570
+ # Generates the instantiation capabilities including an instantiation
571
+ # method +name+ for hdl-like instantiation, target instantiation as
572
+ # +klass+, added to the calling object, and
573
+ # whose eigen type is initialized by +ruby_block+.
574
+ #
575
+ # NOTE: actually creates two instantiater, a general one, being
576
+ # registered in the namespace stack, and one for creating an
577
+ # array of instances being registered in the Array class.
578
+ def make_instantiater(name,klass,&ruby_block)
579
+ # puts "make_instantiater with name=#{name}"
580
+ # Set the instanciater.
581
+ @instance_procs = [ ruby_block ]
582
+ # Set the target instantiation class.
583
+ @instance_class = klass
584
+
585
+ # Unnamed types do not have associated access method.
586
+ return if name.empty?
587
+
588
+ obj = self # For using the right self within the proc
589
+
590
+ # Create and register the general instantiater.
591
+ High.space_reg(name) do |*args|
592
+ # puts "Instantiating #{name} with args=#{args.size}"
593
+ # If no arguments, return the system as is
594
+ return obj if args.empty?
595
+ # Are there any generic arguments?
596
+ if ruby_block.arity > 0 then
597
+ # Yes, must specialize the system with the arguments.
598
+ # If arguments, create a new system specialized with them
599
+ return SystemT.new(:"") { include(obj,*args) }
600
+ end
601
+ # It is the case where it is an instantiation
602
+ # Get the names from the arguments.
603
+ i_names = args.shift
604
+ # puts "i_names=#{i_names}(#{i_names.class})"
605
+ i_names = [*i_names]
606
+ instance = nil # The current instance
607
+ i_names.each do |i_name|
608
+ # Instantiate.
609
+ instance = obj.instantiate(i_name,*args)
610
+ end
611
+ # # Return the last instance.
612
+ instance
613
+ end
614
+
615
+ # Create and register the array of instances instantiater.
616
+ ::Array.class_eval do
617
+ define_method(name) { |*args| make(name,*args) }
618
+ end
619
+ end
620
+
621
+ # Missing methods may be immediate values, if not, they are looked up
622
+ include Hmissing
623
+
624
+ # Methods used for describing a system in HDLRuby::High
625
+
626
+ # Declares high-level bit input signals named +names+.
627
+ #
628
+ # Retuns the last declared input.
629
+ def input(*names)
630
+ self.make_inputs(bit,*names)
631
+ end
632
+
633
+ # Declares high-level bit output signals named +names+.
634
+ #
635
+ # Retuns the last declared input.
636
+ def output(*names)
637
+ self.make_outputs(bit,*names)
638
+ end
639
+
640
+ # Declares high-level bit inout signals named +names+.
641
+ #
642
+ # Retuns the last declared input.
643
+ def inout(*names)
644
+ self.make_inouts(bit,*names)
645
+ end
646
+
647
+ # Extend the class according to another +system+.
648
+ def extend(system)
649
+ # Adds the singleton methods
650
+ self.eigen_extend(system)
651
+ # Adds the singleton methods for the instances.
652
+ @singleton_instanceO.eigen_extend(system.singleton_instance)
653
+ end
654
+
655
+ # Casts as an included +system+.
656
+ #
657
+ # NOTE: use the includes of the scope.
658
+ def as(system)
659
+ # return self.scope.as(system.scope)
660
+ return self.scope.as(system)
661
+ end
662
+
663
+ include Hmux
664
+
665
+ # Fills the interface of a low level system.
666
+ def fill_interface(systemTlow)
667
+ # Adds its input signals.
668
+ self.each_input { |input| systemTlow.add_input(input.to_low) }
669
+ # Adds its output signals.
670
+ self.each_output { |output| systemTlow.add_output(output.to_low) }
671
+ # Adds its inout signals.
672
+ self.each_inout { |inout| systemTlow.add_inout(inout.to_low) }
673
+ # Adds the interface of its included systems.
674
+ self.scope.each_included do |included|
675
+ included.fill_interface(systemTlow)
676
+ end
677
+ end
678
+
679
+ # Fills a low level system with self's contents.
680
+ #
681
+ # NOTE: name conflicts are treated in the current NameStack state.
682
+ def fill_low(systemTlow)
683
+ # Fills the interface
684
+ self.fill_interface(systemTlow)
685
+ end
686
+
687
+ # Converts the system to HDLRuby::Low and set its +name+.
688
+ def to_low(name = self.name)
689
+ name = name.to_s
690
+ if name.empty? then
691
+ raise AnyError,
692
+ "Cannot convert a system without a name to HDLRuby::Low."
693
+ end
694
+ # Create the resulting low system type.
695
+ systemTlow = HDLRuby::Low::SystemT.new(High.names_create(name),
696
+ self.scope.to_low)
697
+ # Fills the interface of the new system
698
+ # from the included systems.
699
+ self.fill_low(systemTlow)
700
+ # Return theresulting system.
701
+ return systemTlow
702
+ end
703
+ end
704
+
705
+
706
+
707
+ ##
708
+ # Describes a scope for a system type
709
+ class Scope < Low::Scope
710
+ High = HDLRuby::High
711
+
712
+ # include HMix
713
+ include Hinner
714
+
715
+ include SingletonExtend
716
+
717
+ # The name of the scope if any.
718
+ attr_reader :name
719
+
720
+ # The namespace
721
+ attr_reader :namespace
722
+
723
+ # The return value when building the scope.
724
+ attr_reader :return_value
725
+
726
+ ##
727
+ # Creates a new scope with possible +name+.
728
+ # If the scope is a top scope of a system, this systemT is
729
+ # given by +systemT+.
730
+ #
731
+ # The proc +ruby_block+ is executed for building the scope.
732
+ # If no block is provided, the scope is the top of a system and
733
+ # is filled by the instantiation procedure of the system.
734
+ def initialize(name = :"", systemT = nil, &ruby_block)
735
+ # Initialize the scope structure
736
+ super(name)
737
+
738
+ # Initialize the set of grouped system instances.
739
+ @groupIs = {}
740
+
741
+ # Creates the namespace.
742
+ @namespace = Namespace.new(self)
743
+
744
+ # Register the scope if it is not the top scope of a system
745
+ # (in which case the system has already be registered with
746
+ # the same name).
747
+ unless name.empty? or systemT then
748
+ # Named scope, set the hdl-like access to the scope.
749
+ obj = self # For using the right self within the proc
750
+ High.space_reg(name) { obj }
751
+ end
752
+
753
+ # Initialize the set of exported inner signals and instances
754
+ @exports = {}
755
+ # Initialize the set of included systems.
756
+ @includes = {}
757
+
758
+ # Builds the scope if a ruby block is provided
759
+ # (which means the scope is not the top of a system).
760
+ self.build(&ruby_block) if block_given?
761
+ end
762
+
763
+ # Converts to a namespace user.
764
+ def to_user
765
+ # Already a user.
766
+ return self
767
+ end
768
+
769
+ # Adds a group of system +instances+ named +name+.
770
+ def add_groupI(name, *instances)
771
+ # Ensure name is a symbol and is not already used for another
772
+ # group.
773
+ name = name.to_sym
774
+ if @groupIs.key?(name)
775
+ raise AnyError,
776
+ "Group of system instances named #{name} already exist."
777
+ end
778
+ # Add the group.
779
+ @groupIs[name.to_sym] = instances
780
+ # Sets the parent of the instances.
781
+ instances.each { |instance| instance.parent = self }
782
+ end
783
+
784
+ # Access a group of system instances by +name+.
785
+ #
786
+ # NOTE: the result is a copy of the group for avoiding side effects.
787
+ def get_groupI(name)
788
+ return @groupIs[name.to_sym].clone
789
+ end
790
+
791
+ # Iterates over the group of system instances.
792
+ #
793
+ # Returns an enumerator if no ruby block is given.
794
+ def each_groupI(&ruby_block)
795
+ # No ruby block? Return an enumerator.
796
+ return to_enum(:each_groupI) unless ruby_block
797
+ # A block? Apply it on each input signal instance.
798
+ @groupIs.each(&ruby_block)
799
+ end
800
+
801
+ # Adds a +name+ to export.
802
+ #
803
+ # NOTE: if the name do not corresponds to any inner signal nor
804
+ # instance, raise an exception.
805
+ def add_export(name)
806
+ # Check the name.
807
+ name = name.to_sym
808
+ # Look for construct to make public.
809
+ # Maybe it is an inner signals.
810
+ inner = self.get_inner(name)
811
+ if inner then
812
+ # Yes set it as export.
813
+ @exports[name] = inner
814
+ return
815
+ end
816
+ # No, maybe it is an instance.
817
+ instance = self.get_systemI(name)
818
+ if instance then
819
+ # Yes, set it as export.
820
+ @exports[name] = instance
821
+ return
822
+ end
823
+ # No, error.
824
+ raise AnyError, "Invalid name for export: #{name}"
825
+ end
826
+
827
+ # Iterates over the exported constructs.
828
+ #
829
+ # Returns an enumerator if no ruby block is given.
830
+ def each_export(&ruby_block)
831
+ # No ruby block? Return an enumerator.
832
+ return to_enum(:each_export) unless ruby_block
833
+ # A block? Apply it on each input signal instance.
834
+ @exports.each_value(&ruby_block)
835
+ # And apply on the sub scopes if any.
836
+ @scopes.each {|scope| scope.each_export(&ruby_block) }
837
+ end
838
+
839
+ # Iterates over the included systems.
840
+ def each_included(&ruby_block)
841
+ # No ruby block? Return an enumerator.
842
+ return to_enum(:each_included) unless ruby_block
843
+ # A block? Apply it on each included system.
844
+ @includes.each_value(&ruby_block)
845
+ # And apply on the sub scopes if any.
846
+ @scopes.each {|scope| scope.each_included(&ruby_block) }
847
+ end
848
+
849
+
850
+ # Opens for extension.
851
+ #
852
+ # NOTE: actually executes +ruby_block+ in the context.
853
+ def open(&ruby_block)
854
+ High.space_push(@namespace)
855
+ res = High.top_user.instance_eval(&ruby_block)
856
+ High.space_pop
857
+ # Return the result of the execution so that it can be used
858
+ # as an expression
859
+ res
860
+ end
861
+
862
+
863
+ # Build the scope by executing +ruby_block+.
864
+ #
865
+ # NOTE: used when the scope is not the top of a system.
866
+ def build(&ruby_block)
867
+ # Set the namespace for buidling the scope.
868
+ High.space_push(@namespace)
869
+ # Build the scope.
870
+ @return_value = High.top_user.instance_eval(&ruby_block)
871
+ High.space_pop
872
+ @return_value
873
+ end
874
+
875
+
876
+ # Builds the scope using +base+ as model scope with possible arguments
877
+ # +args+.
878
+ #
879
+ # NOTE: Used by the instantiation procedure of a system.
880
+ def build_top(base,*args)
881
+ # Fills its namespace with the content of the base scope
882
+ # (this latter may already contains access points if it has been
883
+ # opended for extension previously).
884
+ @namespace.concat_namespace(base.namespace)
885
+ High.space_push(@namespace)
886
+ # Execute the instantiation block
887
+ # instance_proc = base.parent.instance_proc if base.parent.respond_to?(:instance_proc)
888
+ # @return_value = High.top_user.instance_exec(*args,&instance_proc) if instance_proc
889
+ base.parent.each_instance_proc do |instance_proc|
890
+ @return_value = High.top_user.instance_exec(*args,&instance_proc)
891
+ end
892
+ High.space_pop
893
+ end
894
+
895
+
896
+ # Methods delegated to the upper system.
897
+
898
+ # Adds input +signal+ in the current system.
899
+ def add_input(signal)
900
+ self.parent.add_input(signal)
901
+ end
902
+
903
+ # Adds output +signal+ in the current system.
904
+ def add_output(signal)
905
+ self.parent.add_output(signal)
906
+ end
907
+
908
+ # Adds inout +signal+ in the current system.
909
+ def add_inout(signal)
910
+ self.parent.add_inout(signal)
911
+ end
912
+
913
+ # Creates and adds a set of inputs typed +type+ from a list of +names+
914
+ # in the current system.
915
+ #
916
+ # NOTE: a name can also be a signal, is which case it is duplicated.
917
+ def make_inputs(type, *names)
918
+ self.parent.make_inputs(type,*names)
919
+ end
920
+
921
+ # Creates and adds a set of outputs typed +type+ from a list of +names+
922
+ # in the current system.
923
+ #
924
+ # NOTE: a name can also be a signal, is which case it is duplicated.
925
+ def make_outputs(type, *names)
926
+ self.parent.make_outputs(type,*names)
927
+ end
928
+
929
+ # Creates and adds a set of inouts typed +type+ from a list of +names+
930
+ # in the current system.
931
+ #
932
+ # NOTE: a name can also be a signal, is which case it is duplicated.
933
+ def make_inouts(type, *names)
934
+ self.parent.make_inouts(type,*names)
935
+ end
936
+
937
+ # Converts to a new reference.
938
+ def to_ref
939
+ return RefObject.new(this,self)
940
+ end
941
+
942
+
943
+ include HScope_missing
944
+
945
+ # Methods used for describing a system in HDLRuby::High
946
+
947
+ # Declares high-level bit input signals named +names+
948
+ # in the current system.
949
+ def input(*names)
950
+ self.parent.input(*names)
951
+ end
952
+
953
+ # Declares high-level bit output signals named +names+
954
+ # in the current system.
955
+ def output(*names)
956
+ self.parent.output(*names)
957
+ end
958
+
959
+ # Declares high-level bit inout signals named +names+
960
+ # in the current system.
961
+ def inout(*names)
962
+ self.parent.inout(*names)
963
+ end
964
+
965
+ # Declares a non-HDLRuby set of code chunks described by +content+ and
966
+ # completed from +ruby_block+ execution result.
967
+ # NOTE: content includes the events to activate the code on and
968
+ # a description of the code as a hash assotiating names
969
+ # to code text.
970
+ def code(*content, &ruby_block)
971
+ # Process the content.
972
+ # Separate events from code chunks descriptions.
973
+ events, chunks = content.partition {|elem| elem.is_a?(Event) }
974
+ # Generates a large hash from the code.
975
+ chunks = chunks.reduce(:merge)
976
+ # Adds the result of the ruby block if any.
977
+ if ruby_block then
978
+ chunks.merge(HDLRuby::High.top_user.instance_eval(&ruby_block))
979
+ end
980
+ # Create the chunk objects.
981
+ chunks = chunks.each.map do |name,content|
982
+ content = [*content]
983
+ # Process the lumps
984
+ content.map! do |lump|
985
+ lump.respond_to?(:to_expr) ? lump.to_expr : lump
986
+ end
987
+ Chunk.new(name,*content)
988
+ end
989
+ # Create the code object.
990
+ res = Code.new
991
+ # Adds the events.
992
+ events.each(&res.method(:add_event))
993
+ # Adds the chunks.
994
+ chunks.each(&res.method(:add_chunk))
995
+ # Adds the resulting code to the current scope.
996
+ HDLRuby::High.top_user.add_code(res)
997
+ # Return the resulting code
998
+ return res
999
+ end
1000
+
1001
+ # Declares a sub scope with possible +name+ and built from +ruby_block+.
1002
+ def sub(name = :"", &ruby_block)
1003
+ # Creates the new scope.
1004
+ scope = Scope.new(name,&ruby_block)
1005
+ # puts "new scope=#{scope}"
1006
+ # Add it
1007
+ self.add_scope(scope)
1008
+ # puts "self=#{self}"
1009
+ # puts "self scopes=#{self.each_scope.to_a.join(",")}"
1010
+ # Use its return value
1011
+ return scope.return_value
1012
+ end
1013
+
1014
+ # Declares a high-level sequential behavior activated on a list of
1015
+ # +events+, and built by executing +ruby_block+.
1016
+ def seq(*events, &ruby_block)
1017
+ # Preprocess the events.
1018
+ events.map! do |event|
1019
+ event.respond_to?(:to_event) ? event.to_event : event
1020
+ end
1021
+ # Create and add the resulting behavior.
1022
+ self.add_behavior(Behavior.new(:seq,*events,&ruby_block))
1023
+ end
1024
+
1025
+ # Declares a high-level parallel behavior activated on a list of
1026
+ # +events+, and built by executing +ruby_block+.
1027
+ def par(*events, &ruby_block)
1028
+ # Preprocess the events.
1029
+ events.map! do |event|
1030
+ event.respond_to?(:to_event) ? event.to_event : event
1031
+ end
1032
+ # Create and add the resulting behavior.
1033
+ self.add_behavior(Behavior.new(:par,*events,&ruby_block))
1034
+ end
1035
+
1036
+ # Declares a high-level timed behavior built by executing +ruby_block+.
1037
+ # By default, timed behavior are sequential.
1038
+ def timed(&ruby_block)
1039
+ # Create and add the resulting behavior.
1040
+ self.add_behavior(TimeBehavior.new(:seq,&ruby_block))
1041
+ end
1042
+
1043
+ # Statements automatically enclosed in a behavior.
1044
+
1045
+ # Creates a new if statement with a +condition+ that when met lead
1046
+ # to the execution of the block in +mode+ generated by the +ruby_block+.
1047
+ #
1048
+ # NOTE:
1049
+ # * the else part is defined through the helse method.
1050
+ # * a behavior is created to enclose the hif.
1051
+ def hif(condition, mode = nil, &ruby_block)
1052
+ self.par do
1053
+ hif(condition,mode,&ruby_block)
1054
+ end
1055
+ end
1056
+
1057
+ # Sets the block executed when the condition is not met to the block
1058
+ # in +mode+ generated by the execution of +ruby_block+.
1059
+ #
1060
+ # Can only be used once.
1061
+ #
1062
+ # NOTE: added to the hif of the last behavior.
1063
+ def helse(mode = nil, &ruby_block)
1064
+ # There is a ruby_block: the helse is assumed to be with
1065
+ # the last statement of the last behavior.
1066
+ statement = self.last_behavior.last_statement
1067
+ # Completes the hif or the hcase statement.
1068
+ unless statement.is_a?(If) or statement.is_a?(Case) then
1069
+ raise AnyError, "Error: helse statement without hif nor hcase (#{statement.class})."
1070
+ end
1071
+ statement.helse(mode, &ruby_block)
1072
+ end
1073
+
1074
+ # Sets the condition check when the condition is not met to the block,
1075
+ # with a +condition+ that when met lead
1076
+ # to the execution of the block in +mode+ generated by the +ruby_block+.
1077
+ def helsif(condition, mode = nil, &ruby_block)
1078
+ # There is a ruby_block: the helse is assumed to be with
1079
+ # the last statement of the last behavior.
1080
+ statement = self.last_behavior.last_statement
1081
+ # Completes the hif statement.
1082
+ unless statement.is_a?(If) then
1083
+ raise AnyError, "Error: helsif statement without hif (#{statement.class})."
1084
+ end
1085
+ statement.helsif(condition, mode, &ruby_block)
1086
+ end
1087
+
1088
+ # Creates a new case statement with a +value+ used for deciding which
1089
+ # block to execute.
1090
+ #
1091
+ # NOTE:
1092
+ # * the when part is defined through the hwhen method.
1093
+ # * a new behavior is created to enclose the hcase.
1094
+ def hcase(value)
1095
+ self.par do
1096
+ hcase(value)
1097
+ end
1098
+ end
1099
+
1100
+ # Sets the block of a case structure executed when the +match+ is met
1101
+ # to the block in +mode+ generated by the execution of +ruby_block+.
1102
+ #
1103
+ # Can only be used once.
1104
+ def hwhen(match, mode = nil, &ruby_block)
1105
+ # There is a ruby_block: the helse is assumed to be with
1106
+ # the last statement of the last behavior.
1107
+ statement = @behaviors.last.last_statement
1108
+ # Completes the hcase statement.
1109
+ unless statement.is_a?(Case) then
1110
+ raise AnyError, "Error: hwhen statement without hcase (#{statement.class})."
1111
+ end
1112
+ statement.hwhen(match, mode, &ruby_block)
1113
+ end
1114
+
1115
+
1116
+ # Sets the constructs corresponding to +names+ as exports.
1117
+ def export(*names)
1118
+ names.each {|name| self.add_export(name) }
1119
+ end
1120
+
1121
+ # Include a +system+ type with possible +args+ instanciation
1122
+ # arguments.
1123
+ def include(system,*args)
1124
+ if @includes.key?(system.name) then
1125
+ raise AnyError, "Cannot include twice the same system."
1126
+ end
1127
+ # puts "Include system=#{system.name}"
1128
+ # Save the name of the included system, it will serve as key
1129
+ # for looking for the included expanded version.
1130
+ include_name = system.name
1131
+ # Expand the system to include
1132
+ system = system.expand(:"",*args)
1133
+ # Add the included system interface to the current one.
1134
+ if self.parent.is_a?(SystemT) then
1135
+ space = self.namespace
1136
+ # Interface signals
1137
+ # puts "i_name=#{i_name} @to_includes=#{@to_includes.size}"
1138
+ system.each_signal_with_included do |signal|
1139
+ # puts "signal=#{signal.name}"
1140
+ space.send(:define_singleton_method,signal.name) do
1141
+ signal
1142
+ end
1143
+ end
1144
+ # Exported objects
1145
+ system.each_export do |export|
1146
+ # puts "export=#{export.name}"
1147
+ space.send(:define_singleton_method,export.name) do
1148
+ export
1149
+ end
1150
+ end
1151
+ end
1152
+ # Adds it the list of includeds
1153
+ @includes[include_name] = system
1154
+ end
1155
+
1156
+ # Casts as an included +system+.
1157
+ def as(system)
1158
+ # puts "as with name: #{system.name}"
1159
+ system = system.name if system.respond_to?(:name)
1160
+ # puts "includes are: #{@includes.keys}"
1161
+ return @includes[system].namespace
1162
+ end
1163
+
1164
+ include Hmux
1165
+
1166
+ # Fills a low level scope with self's contents.
1167
+ #
1168
+ # NOTE: name conflicts are treated in the current NameStack state.
1169
+ def fill_low(scopeLow)
1170
+ # Adds the content of its included systems.
1171
+ @includes.each_value {|system| system.scope.fill_low(scopeLow) }
1172
+ # Adds the declared local system types.
1173
+ # NOTE: in the current version of HDLRuby::High, there should not
1174
+ # be any of them (only eigen systems are real system types).
1175
+ self.each_systemT { |systemT| scopeLow.add_systemT(systemT.to_low) }
1176
+ # Adds the local types.
1177
+ self.each_type { |type| scopeLow.add_type(type.to_low) }
1178
+ # Adds the inner scopes.
1179
+ self.each_scope { |scope| scopeLow.add_scope(scope.to_low) }
1180
+ # Adds the inner signals.
1181
+ self.each_inner { |inner| scopeLow.add_inner(inner.to_low) }
1182
+ # Adds the instances.
1183
+ # Single ones.
1184
+ self.each_systemI do |systemI|
1185
+ # puts "Filling with systemI=#{systemI.name}"
1186
+ systemI_low = scopeLow.add_systemI(systemI.to_low)
1187
+ # Also add the eigen system to the list of local systems.
1188
+ scopeLow.add_systemT(systemI_low.systemT)
1189
+ end
1190
+ # Grouped ones.
1191
+ self.each_groupI do |name,systemIs|
1192
+ systemIs.each.with_index { |systemI,i|
1193
+ # Sets the name of the system instance
1194
+ # (required for conversion of further accesses).
1195
+ # puts "systemI.respond_to?=#{systemI.respond_to?(:name=)}"
1196
+ systemI.name = name.to_s + "[#{i}]"
1197
+ # And convert it to low
1198
+ systemI_low = scopeLow.add_systemI(systemI.to_low())
1199
+ # Also add the eigen system to the list of local systems.
1200
+ scopeLow.add_systemT(systemI_low.systemT)
1201
+ }
1202
+ end
1203
+ # Adds the code chunks.
1204
+ self.each_code { |code| scopeLow.add_code(code.to_low) }
1205
+ # Adds the connections.
1206
+ self.each_connection { |connection|
1207
+ # puts "connection=#{connection}"
1208
+ scopeLow.add_connection(connection.to_low)
1209
+ }
1210
+ # Adds the behaviors.
1211
+ self.each_behavior { |behavior|
1212
+ scopeLow.add_behavior(behavior.to_low)
1213
+ }
1214
+ end
1215
+
1216
+ # Converts the scope to HDLRuby::Low.
1217
+ def to_low()
1218
+ # Create the resulting low scope.
1219
+ scopeLow = HDLRuby::Low::Scope.new()
1220
+ # Push the private namespace for the low generation.
1221
+ High.space_push(@namespace)
1222
+ # Pushes on the name stack for converting the internals of
1223
+ # the system.
1224
+ High.names_push
1225
+ # Adds the content of the actual system.
1226
+ self.fill_low(scopeLow)
1227
+ # Restores the name stack.
1228
+ High.names_pop
1229
+ # Restores the namespace stack.
1230
+ High.space_pop
1231
+ # Return theresulting system.
1232
+ return scopeLow
1233
+ end
1234
+ end
1235
+
1236
+
1237
+ ##
1238
+ # Module bringing high-level properties to Type classes.
1239
+ #
1240
+ # NOTE: by default a type is not specified.
1241
+ module Htype
1242
+ High = HDLRuby::High
1243
+
1244
+ # Type processing
1245
+ include HDLRuby::Tprocess
1246
+
1247
+ # Ensures initialize registers the type name
1248
+ def self.included(base) # built-in Ruby hook for modules
1249
+ base.class_eval do
1250
+ original_method = instance_method(:initialize)
1251
+ define_method(:initialize) do |*args, &block|
1252
+ original_method.bind(self).call(*args, &block)
1253
+ # Registers the name (if not empty).
1254
+ self.register(name) unless name.empty?
1255
+ end
1256
+ end
1257
+ end
1258
+
1259
+ # Tells htype has been included.
1260
+ def htype?
1261
+ return true
1262
+ end
1263
+
1264
+ # Sets the +name+.
1265
+ #
1266
+ # NOTE: can only be done if the name is not already set.
1267
+ def name=(name)
1268
+ unless @name.empty? then
1269
+ raise AnyError, "Name of type already set to: #{@name}."
1270
+ end
1271
+ # Checks and sets the name.
1272
+ name = name.to_sym
1273
+ if name.empty? then
1274
+ raise AnyError, "Cannot set an empty name."
1275
+ end
1276
+ @name = name
1277
+ # Registers the name.
1278
+ self.register(name)
1279
+ end
1280
+
1281
+ # Register the +name+ of the type.
1282
+ def register(name)
1283
+ if self.name.empty? then
1284
+ raise AnyError, "Cannot register with empty name."
1285
+ else
1286
+ # Sets the hdl-like access to the type.
1287
+ obj = self # For using the right self within the proc
1288
+ High.space_reg(name) { obj }
1289
+ end
1290
+ end
1291
+
1292
+
1293
+ # Gets the type as left value.
1294
+ #
1295
+ # NOTE: used for asymetric types like TypeSystemI.
1296
+ def left
1297
+ # By default self.
1298
+ self
1299
+ end
1300
+
1301
+ # Gets the type as right value.
1302
+ #
1303
+ # NOTE: used for asymetric types like TypeSystemI.
1304
+ def right
1305
+ # By default self.
1306
+ self
1307
+ end
1308
+
1309
+ # Type creation in HDLRuby::High.
1310
+
1311
+ # Declares a new type definition with +name+ equivalent to current one.
1312
+ def typedef(name)
1313
+ # Create the new type.
1314
+ typ = TypeDef.new(name,self)
1315
+ # Register it.
1316
+ High.space_reg(name) { typ }
1317
+ # Return it.
1318
+ return typ
1319
+ end
1320
+
1321
+ # Creates a new vector type of range +rng+ and with current type as
1322
+ # base.
1323
+ def [](rng)
1324
+ return TypeVector.new(:"",self,rng)
1325
+ end
1326
+
1327
+ # SignalI creation through the type.
1328
+
1329
+ # Declares high-level input signals named +names+ of the current type.
1330
+ def input(*names)
1331
+ High.top_user.make_inputs(self,*names)
1332
+ end
1333
+
1334
+ # Declares high-level untyped output signals named +names+ of the
1335
+ # current type.
1336
+ def output(*names)
1337
+ # High.top_user.make_outputs(self.instantiate,*names)
1338
+ High.top_user.make_outputs(self,*names)
1339
+ end
1340
+
1341
+ # Declares high-level untyped inout signals named +names+ of the
1342
+ # current type.
1343
+ def inout(*names)
1344
+ # High.top_user.make_inouts(self.instantiate,*names)
1345
+ High.top_user.make_inouts(self,*names)
1346
+ end
1347
+
1348
+ # Declares high-level untyped inner signals named +names+ of the
1349
+ # current type.
1350
+ def inner(*names)
1351
+ High.top_user.make_inners(self,*names)
1352
+ end
1353
+
1354
+ # Declares high-level untyped constant signals by name and
1355
+ # value given by +hsh+ of the current type.
1356
+ def constant(hsh)
1357
+ High.top_user.make_constants(self,hsh)
1358
+ end
1359
+
1360
+ # Computations of expressions
1361
+
1362
+ # Gets the computation method for +operator+.
1363
+ def comp_operator(op)
1364
+ return (op.to_s + ":C").to_sym
1365
+ end
1366
+
1367
+ # Performs unary operation +operator+ on expression +expr+.
1368
+ def unary(operator,expr)
1369
+ # Look for a specific computation method.
1370
+ comp = comp_operator(operator)
1371
+ if self.respond_to?(comp) then
1372
+ # Found, use it.
1373
+ self.send(comp,expr)
1374
+ else
1375
+ # Not found, back to default generation of unary expression.
1376
+ return Unary.new(self.send(operator),operator,expr)
1377
+ end
1378
+ end
1379
+
1380
+ # Performs binary operation +operator+ on expressions +expr0+
1381
+ # and +expr1+.
1382
+ def binary(operator, expr0, expr1)
1383
+ # Look for a specific computation method.
1384
+ comp = comp_operator(operator)
1385
+ if self.respond_to?(comp) then
1386
+ # Found, use it.
1387
+ self.send(comp,expr0,expr1)
1388
+ else
1389
+ # Not found, back to default generation of binary expression.
1390
+ return Binary.new(self.send(operator,expr1.type),operator,
1391
+ expr0,expr1)
1392
+ end
1393
+ end
1394
+
1395
+ # Redefinition of +operator+.
1396
+ def define_operator(operator,&ruby_block)
1397
+ # Register the operator as overloaded.
1398
+ @overloads ||= {}
1399
+ @overloads[operator] = ruby_block
1400
+ # Set the new method for the operator.
1401
+ self.define_singleton_method(comp_operator(operator)) do |*args|
1402
+ # puts "Top user=#{HDLRuby::High.top_user}"
1403
+ HDLRuby::High.top_user.instance_exec do
1404
+ sub do
1405
+ HDLRuby::High.top_user.instance_exec(*args,&ruby_block)
1406
+ end
1407
+ end
1408
+ end
1409
+ end
1410
+
1411
+ # Interates over the overloaded operators.
1412
+ def each_overload(&ruby_block)
1413
+ # No ruby block? Return an enumerator.
1414
+ return to_enum(:each_overload) unless ruby_block
1415
+ # A block? Apply it on each overload if any.
1416
+ @overloads.each(&ruby_block) if @overloads
1417
+ end
1418
+ end
1419
+
1420
+
1421
+ ##
1422
+ # Describes a high-level data type.
1423
+ #
1424
+ # NOTE: by default a type is not specified.
1425
+ class Type < Low::Type
1426
+ High = HDLRuby::High
1427
+
1428
+ include Htype
1429
+
1430
+ # Type creation.
1431
+
1432
+ # Creates a new type named +name+.
1433
+ def initialize(name)
1434
+ # Initialize the type structure.
1435
+ super(name)
1436
+ end
1437
+
1438
+ # Converts the type to HDLRuby::Low and set its +name+.
1439
+ #
1440
+ # NOTE: should be overridden by other type classes.
1441
+ def to_low(name = self.name)
1442
+ return HDLRuby::Low::Type.new(name)
1443
+ end
1444
+ end
1445
+
1446
+
1447
+ # Creates the basic types.
1448
+
1449
+ # Module providing the properties of a basic type.
1450
+ # NOTE: requires method 'to_low' to be defined.
1451
+ module HbasicType
1452
+ # Get all the metods from Low::Bit appart from 'base'
1453
+ extend Forwardable
1454
+ def_delegators :to_low, :signed?, :unsigned?, :fixed?, :float?,
1455
+ :width, :range
1456
+
1457
+ # Get the base type, actually self for leaf types.
1458
+ def base
1459
+ self
1460
+ end
1461
+
1462
+ end
1463
+
1464
+ # Defines a basic type +name+.
1465
+ def self.define_type(name)
1466
+ name = name.to_sym
1467
+ type = Type.new(name)
1468
+ self.send(:define_method,name) { type }
1469
+ return type
1470
+ end
1471
+
1472
+ # The void type
1473
+ Void = define_type(:void)
1474
+ class << Void
1475
+ # Converts the type to HDLRuby::Low.
1476
+ def to_low
1477
+ return Low::Void
1478
+ end
1479
+
1480
+ include HbasicType
1481
+ end
1482
+
1483
+ # The bit type.
1484
+ Bit = define_type(:bit)
1485
+ class << Bit
1486
+ # Converts the type to HDLRuby::Low.
1487
+ def to_low
1488
+ return Low::Bit
1489
+ end
1490
+
1491
+ include HbasicType
1492
+ end
1493
+
1494
+ # The signed bit type.
1495
+ Signed = define_type(:signed)
1496
+ class << Signed
1497
+ # Converts the type to HDLRuby::Low.
1498
+ def to_low
1499
+ return Low::Signed
1500
+ end
1501
+
1502
+ include HbasicType
1503
+ end
1504
+
1505
+ # The unsigned bit type.
1506
+ Unsigned = define_type(:unsigned)
1507
+ class << Unsigned
1508
+ # Converts the type to HDLRuby::Low.
1509
+ def to_low
1510
+ return Low::Unsigned
1511
+ end
1512
+
1513
+ include HbasicType
1514
+ end
1515
+
1516
+ # The float bit type
1517
+ Float = define_type(:float)
1518
+ class << Float
1519
+ # Converts the type to HDLRuby::Low.
1520
+ def to_low
1521
+ return Low::Float
1522
+ end
1523
+
1524
+ include HbasicType
1525
+ end
1526
+
1527
+
1528
+
1529
+
1530
+ ##
1531
+ # Describes a high-level type definition.
1532
+ #
1533
+ # NOTE: type definition are actually type with a name refering to another
1534
+ # type (and equivalent to it).
1535
+ class TypeDef < Low::TypeDef
1536
+ High = HDLRuby::High
1537
+
1538
+ include Htype
1539
+
1540
+ # Type creation.
1541
+
1542
+ # Creates a new type definition named +name+ refering +type+.
1543
+ def initialize(name,type)
1544
+ # Initialize the type structure.
1545
+ super(name,type)
1546
+ end
1547
+
1548
+ # Converts the type to HDLRuby::Low and set its +name+.
1549
+ #
1550
+ # NOTE: should be overridden by other type classes.
1551
+ def to_low(name = self.name)
1552
+ return HDLRuby::Low::TypeDef.new(name,self.def.to_low)
1553
+ end
1554
+ end
1555
+
1556
+
1557
+ ##
1558
+ # Describes a high-level generic type definition.
1559
+ #
1560
+ # NOTE: this type does not correspond to any low-level type
1561
+ class TypeGen< Type
1562
+ High = HDLRuby::High
1563
+
1564
+ # Type creation.
1565
+
1566
+ # Creates a new generic type definition producing a new type by
1567
+ # executing +ruby_block+.
1568
+ def initialize(name,&ruby_block)
1569
+ # Initialize the type structure.
1570
+ super(name)
1571
+
1572
+ # Sets the block to execute when instantiating the type.
1573
+ @instance_proc = ruby_block
1574
+ end
1575
+
1576
+ # Generates the type with +args+ generic parameters.
1577
+ def generate(*args)
1578
+ # Generate the resulting type.
1579
+ gtype = High.top_user.instance_exec(*args,&@instance_proc)
1580
+ # Ensures a type has been produced.
1581
+ gtype = gtype.to_type if gtype.respond_to?(:to_type)
1582
+ unless gtype.is_a?(HDLRuby::Low::Type) then
1583
+ raise AnyError, "Generic type #{self.name} did not produce a valid type: #{gtype.class}"
1584
+ end
1585
+ # Create a new type definition from it.
1586
+ gtype = TypeDef.new(self.name.to_s + "_#{args.join(":")}",
1587
+ gtype)
1588
+ # Adds the possible overloaded operators.
1589
+ self.each_overload do |op,ruby_block|
1590
+ gtype.define_operator(op,&(ruby_block.curry[*args]))
1591
+ end
1592
+ # Returns the resulting type
1593
+ return gtype
1594
+ end
1595
+
1596
+ # Converts the type to HDLRuby::Low and set its +name+.
1597
+ #
1598
+ # NOTE: should be overridden by other type classes.
1599
+ def to_low(name = self.name)
1600
+ return HDLRuby::Low::TypeDef.new(name,self.def.to_low)
1601
+ end
1602
+ end
1603
+
1604
+
1605
+
1606
+ # Methods for vector types.
1607
+ module HvectorType
1608
+ # Converts the type to HDLRuby::Low and set its +name+.
1609
+ def to_low(name = self.name)
1610
+ # Generate and return the new type.
1611
+ return HDLRuby::Low::TypeVector.new(name,self.base.to_low,
1612
+ self.range.to_low)
1613
+ end
1614
+ end
1615
+
1616
+
1617
+ ##
1618
+ # Describes a vector type.
1619
+ # class TypeVector < TypeExtend
1620
+ class TypeVector < Low::TypeVector
1621
+ High = HDLRuby::High
1622
+ include Htype
1623
+ include HvectorType
1624
+ end
1625
+
1626
+
1627
+
1628
+ ##
1629
+ # Describes a signed integer data type.
1630
+ class TypeSigned < TypeVector
1631
+
1632
+ # Creates a new vector type named +name+ from +base+ type and with
1633
+ # +range+.
1634
+ #
1635
+ # NOTE:
1636
+ # * The default range is 32-bit.
1637
+ def initialize(name,range = 31..0)
1638
+ # Initialize the type.
1639
+ super(name,Signed,range)
1640
+ end
1641
+ end
1642
+
1643
+ ##
1644
+ # Describes a unsigned integer data type.
1645
+ class TypeUnsigned < TypeVector
1646
+
1647
+ # Creates a new vector type named +name+ from +base+ type and with
1648
+ # +range+.
1649
+ #
1650
+ # NOTE:
1651
+ # * The default range is 32-bit.
1652
+ def initialize(name,range = 31..0)
1653
+ # Initialize the type.
1654
+ super(name,Unsigned,range)
1655
+ end
1656
+ end
1657
+
1658
+ ##
1659
+ # Describes a float data type.
1660
+ class TypeFloat < TypeVector
1661
+
1662
+ # Creates a new vector type named +name+ from +base+ type and with
1663
+ # +range+.
1664
+ #
1665
+ # NOTE:
1666
+ # * The bits of negative range stands for the exponent
1667
+ # * The default range is for 64-bit IEEE 754 double precision standart
1668
+ def initialize(name,range = 52..-11)
1669
+ # Initialize the type.
1670
+ super(name,Float,range)
1671
+ end
1672
+ end
1673
+
1674
+
1675
+ ##
1676
+ # Describes a tuple type.
1677
+ # class TypeTuple < Tuple
1678
+ class TypeTuple < Low::TypeTuple
1679
+ High = HDLRuby::High
1680
+
1681
+ include Htype
1682
+
1683
+ # Converts the type to HDLRuby::Low and set its +name+.
1684
+ def to_low(name = self.name)
1685
+ return HDLRuby::Low::TypeTuple.new(name,self.direction,
1686
+ *@types.map { |type| type.to_low } )
1687
+ end
1688
+ end
1689
+
1690
+
1691
+ ##
1692
+ # Describes a structure type.
1693
+ class TypeStruct < Low::TypeStruct
1694
+ High = HDLRuby::High
1695
+
1696
+ include Htype
1697
+
1698
+ # Converts the type to HDLRuby::Low and set its +name+.
1699
+ def to_low(name = self.name)
1700
+ return HDLRuby::Low::TypeStruct.new(name,self.direction,
1701
+ @types.map { |name,type| [name,type.to_low] } )
1702
+ end
1703
+ end
1704
+
1705
+
1706
+
1707
+ ## Methods for declaring system types and functions.
1708
+
1709
+ # The type constructors.
1710
+
1711
+ # Creates an unnamed structure type from a +content+.
1712
+ def struct(content)
1713
+ return TypeStruct.new(:"",:little,content)
1714
+ end
1715
+
1716
+ # Methods for declaring types
1717
+
1718
+ # Declares a high-level generic type named +name+, and using +ruby_block+
1719
+ # for construction.
1720
+ def typedef(name, &ruby_block)
1721
+ type = TypeGen.new(name,&ruby_block)
1722
+ if HDLRuby::High.in_system? then
1723
+ # Must be inside a scope.
1724
+ unless HDLRuby::High.top_user.is_a?(Scope) then
1725
+ raise AnyError, "A local type cannot be declared within a #{HDLRuby::High.top_user.class}."
1726
+ end
1727
+ define_singleton_method(name.to_sym) do |*args|
1728
+ if (args.size < ruby_block.arity) then
1729
+ # Not enough arguments get generic type as is.
1730
+ type
1731
+ else
1732
+ # There are arguments, specialize the type.
1733
+ gtype = type.generate(*args)
1734
+ # And add it as a local type of the system.
1735
+ HDLRuby::High.top_user.add_type(gtype)
1736
+ end
1737
+ end
1738
+ else
1739
+ define_method(name.to_sym) do |*args|
1740
+ if (args.size < ruby_block.arity) then
1741
+ # Not enough arguments, get generic type as is.
1742
+ type
1743
+ else
1744
+ # There are arguments, specialize the type.
1745
+ type.generate(*args)
1746
+ end
1747
+ end
1748
+ end
1749
+ end
1750
+
1751
+ # Methods for declaring systems
1752
+
1753
+ # Declares a high-level system type named +name+, with +includes+ mixins
1754
+ # system types and using +ruby_block+ for instantiating.
1755
+ def system(name = :"", *includes, &ruby_block)
1756
+ # print "system ruby_block=#{ruby_block}\n"
1757
+ # Creates the resulting system.
1758
+ return SystemT.new(name,*includes,&ruby_block)
1759
+ end
1760
+
1761
+ # Declares a high-level system instance named +name+, with +includes+
1762
+ # mixins system types and using +ruby_block+ for instantiating.
1763
+ #
1764
+ # NOTE: this is for generating directly an instance without declaring
1765
+ # it system type.
1766
+ def instance(name, *includes, &ruby_block)
1767
+ # Creates the system type.
1768
+ systemT = system(:"",*includes,&ruby_block)
1769
+ # Instantiate it with +name+.
1770
+ return systemT.instantiate(name)
1771
+ end
1772
+
1773
+ # Methods for declaring functions
1774
+
1775
+ # Declares a function named +name+ using +ruby_block+ as body.
1776
+ #
1777
+ # NOTE: a function is a short-cut for a method that creates a scope.
1778
+ def function(name, &ruby_block)
1779
+ if HDLRuby::High.in_system? then
1780
+ define_singleton_method(name.to_sym) do |*args|
1781
+ sub do
1782
+ HDLRuby::High.top_user.instance_exec(*args,&ruby_block)
1783
+ # ruby_block.call(*args)
1784
+ end
1785
+ end
1786
+ else
1787
+ define_method(name.to_sym) do |*args|
1788
+ sub do
1789
+ HDLRuby::High.top_user.instance_exec(*args,&ruby_block)
1790
+ end
1791
+ end
1792
+ end
1793
+ end
1794
+
1795
+
1796
+
1797
+
1798
+ # Classes describing harware instances.
1799
+
1800
+
1801
+ ##
1802
+ # Describes a high-level system instance.
1803
+ class SystemI < Low::SystemI
1804
+ High = HDLRuby::High
1805
+
1806
+ include SingletonExtend
1807
+
1808
+ # Creates a new system instance of system type +systemT+ named +name+.
1809
+ def initialize(name, systemT)
1810
+ # Initialize the system instance structure.
1811
+ super(name,systemT)
1812
+
1813
+ # Sets the hdl-like access to the system instance.
1814
+ obj = self # For using the right self within the proc
1815
+ High.space_reg(name) { obj }
1816
+ end
1817
+
1818
+ # The type of a systemI: for now Void (may change in the future).
1819
+ def type
1820
+ return void
1821
+ end
1822
+
1823
+ # Converts to a new reference.
1824
+ def to_ref
1825
+ if self.name.empty? then
1826
+ # No name, happens if inside the systemI so use this.
1827
+ return this
1828
+ else
1829
+ # A name.
1830
+ return RefObject.new(this,self)
1831
+ end
1832
+ end
1833
+
1834
+ # Connects signals of the system instance according to +connects+.
1835
+ #
1836
+ # NOTE: +connects+ can be a hash table where each entry gives the
1837
+ # correspondance between a system's signal name and an external
1838
+ # signal to connect to, or a list of signals that will be connected
1839
+ # in the order of declaration.
1840
+ def call(*connects)
1841
+ # Checks if it is a connection through is a hash.
1842
+ if connects.size == 1 and connects[0].respond_to?(:to_h) then
1843
+ # Yes, perform a connection by name
1844
+ connects = connects[0].to_h
1845
+ # Performs the connections.
1846
+ connects.each do |key,value|
1847
+ # Gets the signal corresponding to connect.
1848
+ signal = self.get_signal(key)
1849
+ # Check if it is an output.
1850
+ isout = self.get_output(key)
1851
+ # Convert it to a reference.
1852
+ ref = RefObject.new(self.to_ref,signal)
1853
+ # Make the connection.
1854
+ if isout then
1855
+ value <= ref
1856
+ else
1857
+ ref <= value
1858
+ end
1859
+ end
1860
+ else
1861
+ # No, perform a connection is order of declaration
1862
+ connects.each.with_index do |csig,i|
1863
+ # puts "csig=#{csig} i=#{i}"
1864
+ # puts "systemT inputs=#{systemT.each_input.to_a.size}"
1865
+ # Gets i-est signal to connect
1866
+ ssig = self.systemT.get_interface_with_included(i)
1867
+ # Check if it is an output.
1868
+ isout = self.get_output(ssig.name)
1869
+ # Convert it to a reference.
1870
+ ssig = RefObject.new(self.to_ref,ssig)
1871
+ # Make the connection.
1872
+ if isout then
1873
+ csig <= ssig
1874
+ else
1875
+ ssig <= csig
1876
+ end
1877
+ end
1878
+ end
1879
+ end
1880
+
1881
+ # Gets an exported element (signal or system instance) by +name+.
1882
+ def get_export(name)
1883
+ return @systemT.get_export(name)
1884
+ end
1885
+
1886
+
1887
+ # Opens for extension.
1888
+ #
1889
+ # NOTE: actually executes +ruby_block+ in the context of the
1890
+ # systemT.
1891
+ def open(&ruby_block)
1892
+ # Extend the eigen system.
1893
+ @systemT.run(&ruby_block)
1894
+ # Update the methods.
1895
+ @systemT.eigenize(self)
1896
+ self.eigen_extend(@systemT.public_namespace)
1897
+ end
1898
+
1899
+ # include Hmissing
1900
+
1901
+ # Missing methods are looked for in the public namespace of the
1902
+ # system type.
1903
+ def method_missing(m, *args, &ruby_block)
1904
+ # print "method_missing in class=#{self.class} with m=#{m}\n"
1905
+ self.public_namespace.send(m,*args,&ruby_block)
1906
+ end
1907
+
1908
+
1909
+ # Methods to transmit to the systemT
1910
+
1911
+ # Gets the public namespace.
1912
+ def public_namespace
1913
+ self.systemT.public_namespace
1914
+ end
1915
+
1916
+ # Gets the private namespace.
1917
+ def namespace
1918
+ # self.systemT.scope.namespace
1919
+ self.systemT.namespace
1920
+ end
1921
+
1922
+
1923
+ # Converts the instance to HDLRuby::Low and set its +name+.
1924
+ def to_low(name = self.name)
1925
+ # puts "to_low with #{self} (#{self.name}) #{self.systemT}"
1926
+ # Converts the system of the instance to HDLRuby::Low
1927
+ systemTlow = self.systemT.to_low
1928
+ # Creates the resulting HDLRuby::Low instance
1929
+ systemIlow = HDLRuby::Low::SystemI.new(High.names_create(name),
1930
+ systemTlow)
1931
+ # Adds the other systemTs.
1932
+ self.each_systemT do |systemT|
1933
+ systemIlow.add_systemT(systemT.to_low) unless systemT == self.systemT
1934
+ end
1935
+ return systemIlow
1936
+ end
1937
+ end
1938
+
1939
+
1940
+
1941
+ ##
1942
+ # Describes a non-HDLRuby code chunk.
1943
+ class Chunk < HDLRuby::Low::Chunk
1944
+ # Converts the if to HDLRuby::Low.
1945
+ def to_low
1946
+ return HDLRuby::Low::Chunk.new(self.name,
1947
+ *self.each_lump.map do |lump|
1948
+ lump = lump.respond_to?(:to_low) ? lump.to_low : lump.to_s
1949
+ lump
1950
+ end)
1951
+ end
1952
+ end
1953
+
1954
+ ##
1955
+ # Decribes a set of non-HDLRuby code chunks.
1956
+ class Code < HDLRuby::Low::Code
1957
+ # Converts the if to HDLRuby::Low.
1958
+ def to_low
1959
+ # Create the resulting code.
1960
+ res = HDLRuby::Low::Code.new
1961
+ # Add the low-level events.
1962
+ self.each_event { |event| res.add_event(event.to_low) }
1963
+ # Add the low-level code chunks.
1964
+ self.each_chunk { |chunk| res.add_chunk(chunk.to_low) }
1965
+ # Return the resulting code.
1966
+ return res
1967
+ end
1968
+ end
1969
+
1970
+
1971
+ # Class describing namespace in system.
1972
+
1973
+
1974
+
1975
+ # Classes describing hardware statements, connections and expressions
1976
+
1977
+
1978
+ ##
1979
+ # Module giving high-level statement properties
1980
+ module HStatement
1981
+ # Creates a new if statement with a +condition+ enclosing the statement.
1982
+ #
1983
+ # NOTE: the else part is defined through the helse method.
1984
+ def hif(condition)
1985
+ # Creates the if statement.
1986
+ return If.new(condition) { self }
1987
+ end
1988
+ end
1989
+
1990
+
1991
+ ##
1992
+ # Describes a high-level if statement.
1993
+ class If < Low::If
1994
+ High = HDLRuby::High
1995
+
1996
+ include HStatement
1997
+
1998
+ # Creates a new if statement with a +condition+ that when met lead
1999
+ # to the execution of the block in +mode+ generated by the execution of
2000
+ # +ruby_block+.
2001
+ def initialize(condition, mode = nil, &ruby_block)
2002
+ # Create the yes block.
2003
+ yes_block = High.make_block(mode,&ruby_block)
2004
+ # Creates the if statement.
2005
+ super(condition.to_expr,yes_block)
2006
+ end
2007
+
2008
+ # Sets the block executed in +mode+ when the condition is not met to
2009
+ # the block generated by the execution of +ruby_block+.
2010
+ #
2011
+ # Can only be used once.
2012
+ def helse(mode = nil, &ruby_block)
2013
+ # If there is a no block, it is an error.
2014
+ raise AnyError, "Cannot have two helse for a single if statement." if self.no
2015
+ # Create the no block if required
2016
+ no_block = High.make_block(mode,&ruby_block)
2017
+ # Sets the no block.
2018
+ self.no = no_block
2019
+ end
2020
+
2021
+ # Sets the block executed in +mode+ when the condition is not met
2022
+ # but +next_cond+ is met to the block generated by the execution of
2023
+ # +ruby_block+.
2024
+ #
2025
+ # Can only be used if the no-block is not set yet.
2026
+ def helsif(next_cond, mode = nil, &ruby_block)
2027
+ # If there is a no block, it is an error.
2028
+ raise AnyError, "Cannot have an helsif after an helse." if self.no
2029
+ # Create the noif block if required
2030
+ noif_block = High.make_block(mode,&ruby_block)
2031
+ # Adds the noif block.
2032
+ self.add_noif(next_cond.to_expr,noif_block)
2033
+ end
2034
+
2035
+ # Converts the if to HDLRuby::Low.
2036
+ def to_low
2037
+ # no may be nil, so treat it appart
2038
+ noL = self.no ? self.no.to_low : nil
2039
+ # Now generate the low-level if.
2040
+ low = HDLRuby::Low::If.new(self.condition.to_low,
2041
+ self.yes.to_low,noL)
2042
+ self.each_noif {|cond,block| low.add_noif(cond.to_low,block.to_low)}
2043
+ return low
2044
+ end
2045
+ end
2046
+
2047
+
2048
+ ##
2049
+ # Describes a high-level when for a case statement.
2050
+ class When < Low::When
2051
+ High = HDLRuby::High
2052
+
2053
+ # Creates a new when for a casde statement that executes +statement+
2054
+ # on +match+.
2055
+ def initialize(match,statement)
2056
+ super(match,statement)
2057
+ end
2058
+
2059
+ # Converts the if to HDLRuby::Low.
2060
+ def to_low
2061
+ return HDLRuby::Low::When.new(self.match.to_low,
2062
+ self.statement.to_low)
2063
+ end
2064
+ end
2065
+
2066
+
2067
+ ##
2068
+ # Describes a high-level case statement.
2069
+ class Case < Low::Case
2070
+ High = HDLRuby::High
2071
+
2072
+ include HStatement
2073
+
2074
+ # Creates a new case statement with a +value+ that decides which
2075
+ # block to execute.
2076
+ def initialize(value)
2077
+ # Create the yes block.
2078
+ super(value.to_expr)
2079
+ end
2080
+
2081
+ # Sets the block executed in +mode+ when the value matches +match+.
2082
+ # The block is generated by the execution of +ruby_block+.
2083
+ #
2084
+ # Can only be used once for the given +match+.
2085
+ def hwhen(match, mode = nil, &ruby_block)
2086
+ # Create the nu block if required
2087
+ when_block = High.make_block(mode,&ruby_block)
2088
+ # Adds the case.
2089
+ self.add_when(When.new(match.to_expr,when_block))
2090
+ end
2091
+
2092
+ # Sets the block executed in +mode+ when there were no match to
2093
+ # the block generated by the execution of +ruby_block+.
2094
+ #
2095
+ # Can only be used once.
2096
+ def helse(mode = nil, &ruby_block)
2097
+ # Create the nu block if required
2098
+ default_block = High.make_block(mode,&ruby_block)
2099
+ # Sets the default block.
2100
+ self.default = default_block
2101
+ end
2102
+
2103
+ # Converts the case to HDLRuby::Low.
2104
+ def to_low
2105
+ # Create the low level case.
2106
+ caseL = HDLRuby::Low::Case.new(@value.to_low)
2107
+ # Add each when case.
2108
+ self.each_when do |w|
2109
+ caseL.add_when(w.to_low)
2110
+ end
2111
+ # Add the default if any.
2112
+ if self.default then
2113
+ caseL.default = self.default.to_low
2114
+ end
2115
+ return caseL
2116
+ end
2117
+ end
2118
+
2119
+
2120
+ ##
2121
+ # Describes a delay: not synthesizable.
2122
+ class Delay < Low::Delay
2123
+ High = HDLRuby::High
2124
+
2125
+ include HStatement
2126
+
2127
+ def !
2128
+ High.top_user.wait(self)
2129
+ end
2130
+
2131
+ # Converts the delay to HDLRuby::Low.
2132
+ def to_low
2133
+ return HDLRuby::Low::Delay.new(self.value, self.unit)
2134
+ end
2135
+ end
2136
+
2137
+ ##
2138
+ # Describes a high-level wait delay statement.
2139
+ class TimeWait < Low::TimeWait
2140
+ include HStatement
2141
+
2142
+ # Converts the wait statement to HDLRuby::Low.
2143
+ def to_low
2144
+ return HDLRuby::Low::TimeWait.new(self.delay.to_low)
2145
+ end
2146
+ end
2147
+
2148
+
2149
+ ##
2150
+ # Describes a timed loop statement: not synthesizable!
2151
+ class TimeRepeat < Low::TimeRepeat
2152
+ include HStatement
2153
+
2154
+ # Converts the repeat statement to HDLRuby::Low.
2155
+ def to_low
2156
+ return HDLRuby::Low::TimeRepeat.new(self.statement.to_low,
2157
+ self.delay.to_low)
2158
+ end
2159
+ end
2160
+
2161
+
2162
+ ##
2163
+ # Module giving high-level expression properties
2164
+ module HExpression
2165
+ # The system type the expression has been resolved in, if any.
2166
+ attr_reader :systemT
2167
+ # The type of the expression if resolved.
2168
+ attr_reader :type
2169
+
2170
+ # Tell if the expression can be converted to a value.
2171
+ def to_value?
2172
+ return false
2173
+ end
2174
+
2175
+ # Converts to a new value.
2176
+ #
2177
+ # NOTE: to be redefined.
2178
+ def to_value
2179
+ raise AnyError,
2180
+ "Expression cannot be converted to a value: #{self.class}"
2181
+ end
2182
+
2183
+ # Tell if the expression is constant.
2184
+ def constant?
2185
+ # By default not constant.
2186
+ return false unless self.each_node.any?
2187
+ # If any sub node, check if all of them are constants.
2188
+ self.each_node { |node| return false unless node.constant? }
2189
+ return true
2190
+ end
2191
+
2192
+
2193
+ # Converts to a new expression.
2194
+ #
2195
+ # NOTE: to be redefined in case of non-expression class.
2196
+ def to_expr
2197
+ raise AnyError, "Internal error: to_expr not defined yet for class: #{self.class}"
2198
+ end
2199
+
2200
+ # # Converts to a new ref.
2201
+ # def to_ref
2202
+ # return RefObject.new(this,self)
2203
+ # end
2204
+
2205
+ # Casts as +type+.
2206
+ def as(type)
2207
+ return Cast.new(type.to_type,self.to_expr)
2208
+ end
2209
+
2210
+ # Gets the origin method for operation +op+.
2211
+ def self.orig_operator(op)
2212
+ return (op.to_s + "_orig").to_sym
2213
+ end
2214
+ def orig_operator(op)
2215
+ HExpression.orig_operator(op)
2216
+ end
2217
+
2218
+ # Adds the unary operations generation.
2219
+ [:"-@",:"@+",:"~", :abs,
2220
+ :boolean, :bit, :signed, :unsigned].each do |operator|
2221
+ meth = proc do
2222
+ expr = self.to_expr
2223
+ return expr.type.unary(operator,expr)
2224
+ end
2225
+ # Defines the operator method.
2226
+ define_method(operator,&meth)
2227
+ # And save it so that it can still be accessed if overidden.
2228
+ define_method(orig_operator(operator),&meth)
2229
+ end
2230
+
2231
+ # Coerce by forcing convertion of obj to expression.
2232
+ def coerce(obj)
2233
+ if obj.is_a?(HDLRuby::Low::Expression) then
2234
+ # Already an expression, nothing to do.
2235
+ return [obj,self]
2236
+ elsif obj.respond_to?(:to_expr) then
2237
+ # Can be converted to an expression, do it.
2238
+ return [obj.to_expr, self]
2239
+ else
2240
+ return [obj,self]
2241
+ end
2242
+ end
2243
+
2244
+ # Adds the binary operations generation.
2245
+ [:"+",:"-",:"*",:"/",:"%",:"**",
2246
+ :"&",:"|",:"^",
2247
+ :"<<",:">>",:ls,:rs,:lr,:rr,
2248
+ :"==",:"!=",:"<",:">",:"<=",:">="].each do |operator|
2249
+ meth = proc do |right|
2250
+ expr = self.to_expr
2251
+ return expr.type.binary(operator,expr,right.to_expr)
2252
+ end
2253
+ # Defines the operator method.
2254
+ define_method(operator,&meth)
2255
+ # And save it so that it can still be accessed if overidden.
2256
+ define_method(orig_operator(operator),&meth)
2257
+ end
2258
+
2259
+ # Creates an access to elements of range +rng+ of the signal.
2260
+ #
2261
+ # NOTE: +rng+ can be a single expression in which case it is an index.
2262
+ def [](rng)
2263
+ if rng.respond_to?(:to_expr) then
2264
+ # Number range: convert it to an expression.
2265
+ rng = rng.to_expr
2266
+ end
2267
+ if rng.is_a?(HDLRuby::Low::Expression) then
2268
+ # Index case
2269
+ return RefIndex.new(self.type.base,self.to_expr,rng)
2270
+ else
2271
+ # Range case, ensure it is made among expression.
2272
+ first = rng.first.to_expr
2273
+ last = rng.last.to_expr
2274
+ # Abd create the reference.
2275
+ return RefRange.new(self.type.slice(first..last),
2276
+ self.to_expr,first..last)
2277
+ end
2278
+ end
2279
+
2280
+
2281
+ # Converts to a select operator using current expression as
2282
+ # condition for one of the +choices+.
2283
+ #
2284
+ # NOTE: +choices+ can either be a list of arguments or an array.
2285
+ # If +choices+ has only two entries
2286
+ # (and it is not a hash), +value+ will be converted to a boolean.
2287
+ def mux(*choices)
2288
+ # Process the choices.
2289
+ choices = choices.flatten(1) if choices.size == 1
2290
+ choices.map! { |choice| choice.to_expr }
2291
+ # Generate the select expression.
2292
+ return Select.new(choices[0].type,"?",self.to_expr,*choices)
2293
+ end
2294
+
2295
+
2296
+ # Methods for conversion for HDLRuby::Low: type processing, flattening
2297
+ # and so on
2298
+
2299
+ # The type of the expression if any.
2300
+ attr_reader :type
2301
+
2302
+ # Sets the data +type+.
2303
+ def type=(type)
2304
+ # Check and set the type.
2305
+ unless type.respond_to?(:htype?) then
2306
+ raise AnyError, "Invalid class for a type: #{type.class}."
2307
+ end
2308
+ @type = type
2309
+ end
2310
+ # Converts to a select operator using current expression as
2311
+ # condition for one of the +choices+.
2312
+ #
2313
+ # NOTE: +choices+ can either be a list of arguments or an array.
2314
+ # If +choices+ has only two entries
2315
+ # (and it is not a hash), +value+ will be converted to a boolean.
2316
+ def mux(*choices)
2317
+ # Process the choices.
2318
+ choices = choices.flatten(1) if choices.size == 1
2319
+ choices.map! { |choice| choice.to_expr }
2320
+ # Generate the select expression.
2321
+ return Select.new(choices[0].type,"?",self.to_expr,*choices)
2322
+ end
2323
+
2324
+ end
2325
+
2326
+
2327
+ ##
2328
+ # Module giving high-level properties for handling the arrow (<=) operator.
2329
+ module HArrow
2330
+ High = HDLRuby::High
2331
+
2332
+ # Creates a transmit, or connection with an +expr+.
2333
+ #
2334
+ # NOTE: it is converted afterward to an expression if required.
2335
+ def <=(expr)
2336
+ if High.top_user.is_a?(HDLRuby::Low::Block) then
2337
+ # We are in a block, so generate and add a Transmit.
2338
+ High.top_user.
2339
+ add_statement(Transmit.new(self.to_ref,expr.to_expr))
2340
+ else
2341
+ # We are in a system type, so generate and add a Connection.
2342
+ High.top_user.
2343
+ add_connection(Connection.new(self.to_ref,expr.to_expr))
2344
+ end
2345
+ end
2346
+ end
2347
+
2348
+
2349
+ ##
2350
+ # Describes a high-level cast expression
2351
+ class Cast < Low::Cast
2352
+ include HExpression
2353
+
2354
+ # Converts to a new expression.
2355
+ def to_expr
2356
+ return Cast.new(self.type,self.child.to_expr)
2357
+ end
2358
+
2359
+ # Converts the unary expression to HDLRuby::Low.
2360
+ def to_low
2361
+ return HDLRuby::Low::Cast.new(self.type.to_low,self.child.to_low)
2362
+ end
2363
+ end
2364
+
2365
+
2366
+ ##
2367
+ # Describes a high-level unary expression
2368
+ class Unary < Low::Unary
2369
+ include HExpression
2370
+
2371
+ # Converts to a new expression.
2372
+ def to_expr
2373
+ return Unary.new(self.type,self.operator,self.child.to_expr)
2374
+ end
2375
+
2376
+ # Converts the unary expression to HDLRuby::Low.
2377
+ def to_low
2378
+ return HDLRuby::Low::Unary.new(self.type.to_low, self.operator,
2379
+ self.child.to_low)
2380
+ end
2381
+ end
2382
+
2383
+
2384
+ ##
2385
+ # Describes a high-level binary expression
2386
+ class Binary < Low::Binary
2387
+ include HExpression
2388
+
2389
+ # Converts to a new expression.
2390
+ def to_expr
2391
+ return Binary.new(self.type, self.operator,
2392
+ self.left.to_expr, self.right.to_expr)
2393
+ end
2394
+
2395
+ # Converts the binary expression to HDLRuby::Low.
2396
+ def to_low
2397
+ # return HDLRuby::Low::Binary.new(self.operator,
2398
+ return HDLRuby::Low::Binary.new(self.type.to_low, self.operator,
2399
+ self.left.to_low, self.right.to_low)
2400
+ end
2401
+ end
2402
+
2403
+
2404
+ ##
2405
+ # Describes a section operation (generalization of the ternary operator).
2406
+ #
2407
+ # NOTE: choice is using the value of +select+ as an index.
2408
+ class Select < Low::Select
2409
+ include HExpression
2410
+
2411
+ # Converts to a new expression.
2412
+ def to_expr
2413
+ return Select.new(self.type,"?",self.select.to_expr,
2414
+ *self.each_choice.map do |choice|
2415
+ choice.to_expr
2416
+ end)
2417
+ end
2418
+
2419
+ # Converts the selection expression to HDLRuby::Low.
2420
+ def to_low
2421
+ return HDLRuby::Low::Select.new(self.type.to_low,"?",
2422
+ self.select.to_low,
2423
+ *self.each_choice.map do |choice|
2424
+ choice.to_low
2425
+ end)
2426
+ end
2427
+ end
2428
+
2429
+
2430
+ ##
2431
+ # Describes z high-level concat expression.
2432
+ class Concat < Low::Concat
2433
+ include HExpression
2434
+
2435
+ # Converts to a new expression.
2436
+ def to_expr
2437
+ return Concat.new(self.type,
2438
+ self.each_expression.map do |expr|
2439
+ expr.to_expr
2440
+ end
2441
+ )
2442
+ end
2443
+
2444
+ # Converts the concatenation expression to HDLRuby::Low.
2445
+ def to_low
2446
+ return HDLRuby::Low::Concat.new(self.type.to_low,
2447
+ self.each_expression.map do |expr|
2448
+ expr.to_low
2449
+ end
2450
+ )
2451
+ end
2452
+ end
2453
+
2454
+
2455
+ ##
2456
+ # Describes a high-level value.
2457
+ class Value < Low::Value
2458
+ include HExpression
2459
+ include HDLRuby::Vprocess
2460
+
2461
+ # Tell if the expression can be converted to a value.
2462
+ def to_value?
2463
+ return true
2464
+ end
2465
+
2466
+ # Converts to a new value.
2467
+ def to_value
2468
+ # # Already a value.
2469
+ # self
2470
+ return Value.new(self.type,self.content)
2471
+ end
2472
+
2473
+ # Tell if the expression is constant.
2474
+ def constant?
2475
+ # A value is a constant.
2476
+ return true
2477
+ end
2478
+
2479
+ # Converts to a new expression.
2480
+ def to_expr
2481
+ return self.to_value
2482
+ end
2483
+
2484
+ # Converts the value to HDLRuby::Low.
2485
+ def to_low
2486
+ # Clone the content if possible
2487
+ content = self.content.frozen? ? self.content : self.content.clone
2488
+ # Create and return the resulting low-level value
2489
+ return HDLRuby::Low::Value.new(self.type.to_low,self.content)
2490
+ end
2491
+
2492
+ end
2493
+
2494
+
2495
+
2496
+ ##
2497
+ # Module giving high-level reference properties.
2498
+ module HRef
2499
+ # Properties of expressions are also required
2500
+ def self.included(klass)
2501
+ klass.class_eval do
2502
+ include HExpression
2503
+ include HArrow
2504
+
2505
+ # Converts to a new expression.
2506
+ def to_expr
2507
+ self.to_ref
2508
+ end
2509
+ end
2510
+ end
2511
+
2512
+ # Converts to a new reference.
2513
+ #
2514
+ # NOTE: to be redefined in case of non-reference class.
2515
+ def to_ref
2516
+ raise AnyError, "Internal error: to_ref not defined yet for class: #{self.class}"
2517
+ end
2518
+
2519
+ # Converts to a new event.
2520
+ def to_event
2521
+ return Event.new(:change,self.to_ref)
2522
+ end
2523
+
2524
+ # Iterate over the elements.
2525
+ #
2526
+ # Returns an enumerator if no ruby block is given.
2527
+ def each(&ruby_block)
2528
+ # No ruby block? Return an enumerator.
2529
+ return to_enum(:each) unless ruby_block
2530
+ # A block? Apply it on each element.
2531
+ self.type.range.heach do |i|
2532
+ yield(self[i])
2533
+ end
2534
+ end
2535
+
2536
+ # Reference can be used like enumerator
2537
+ include Enumerable
2538
+ end
2539
+
2540
+
2541
+
2542
+ ##
2543
+ # Describes a high-level object reference: no low-level equivalent!
2544
+ class RefObject < Low::Ref
2545
+ include HRef
2546
+
2547
+ # The base of the reference
2548
+ attr_reader :base
2549
+
2550
+ # The refered object.
2551
+ attr_reader :object
2552
+
2553
+ # Creates a new reference from a +base+ reference and named +object+.
2554
+ def initialize(base,object)
2555
+ if object.respond_to?(:type) then
2556
+ # Typed object, so typed reference.
2557
+ super(object.type)
2558
+ else
2559
+ # Untyped object, so untyped reference.
2560
+ super(void)
2561
+ end
2562
+ # Check and set the base (it must be convertible to a reference).
2563
+ unless base.respond_to?(:to_ref)
2564
+ raise AnyError, "Invalid base for a RefObject: #{base}"
2565
+ end
2566
+ @base = base
2567
+ # Set the object
2568
+ @object = object
2569
+ end
2570
+
2571
+ # Tell if the expression is constant.
2572
+ def constant?
2573
+ return self.base.constant?
2574
+ end
2575
+
2576
+ # Converts to a new reference.
2577
+ def to_ref
2578
+ return RefObject.new(@base,@object)
2579
+ end
2580
+
2581
+ # Converts the name reference to a HDLRuby::Low::RefName.
2582
+ def to_low
2583
+ # return HDLRuby::Low::RefName.new(@base.to_ref.to_low,@object.name)
2584
+ return HDLRuby::Low::RefName.new(self.type.to_low,
2585
+ @base.to_ref.to_low,@object.name)
2586
+ end
2587
+
2588
+ # Missing methods are looked for into the refered object.
2589
+ def method_missing(m, *args, &ruby_block)
2590
+ @object.send(m,*args,&ruby_block)
2591
+ end
2592
+
2593
+ end
2594
+
2595
+
2596
+ ##
2597
+ # Describes a high-level concat reference.
2598
+ class RefConcat < Low::RefConcat
2599
+ include HRef
2600
+
2601
+ # Converts to a new reference.
2602
+ def to_ref
2603
+ return RefConcat.new(self.type,
2604
+ self.each_ref.map do |ref|
2605
+ ref.to_ref
2606
+ end
2607
+ )
2608
+ end
2609
+
2610
+ # Converts the concat reference to HDLRuby::Low.
2611
+ def to_low
2612
+ return HDLRuby::Low::RefConcat.new(self.type.to_low,
2613
+ self.each_ref.map do |ref|
2614
+ ref.to_low
2615
+ end
2616
+ )
2617
+ end
2618
+ end
2619
+
2620
+ ##
2621
+ # Describes a high-level index reference.
2622
+ class RefIndex < Low::RefIndex
2623
+ include HRef
2624
+
2625
+ # Converts to a new reference.
2626
+ def to_ref
2627
+ return RefIndex.new(self.type,
2628
+ self.ref.to_ref,self.index.to_expr)
2629
+ end
2630
+
2631
+ # Converts the index reference to HDLRuby::Low.
2632
+ def to_low
2633
+ return HDLRuby::Low::RefIndex.new(self.type.to_low,
2634
+ self.ref.to_low,self.index.to_low)
2635
+ end
2636
+ end
2637
+
2638
+ ##
2639
+ # Describes a high-level range reference.
2640
+ class RefRange < Low::RefRange
2641
+ include HRef
2642
+
2643
+ # Converts to a new reference.
2644
+ def to_ref
2645
+ return RefRange.new(self.type,self.ref.to_expr,
2646
+ self.range.first.to_expr..self.range.last.to_expr)
2647
+ end
2648
+
2649
+ # Converts the range reference to HDLRuby::Low.
2650
+ def to_low
2651
+ return HDLRuby::Low::RefRange.new(self.type.to_low,
2652
+ self.ref.to_low,self.range.to_low)
2653
+ end
2654
+ end
2655
+
2656
+ ##
2657
+ # Describes a high-level name reference.
2658
+ class RefName < Low::RefName
2659
+ include HRef
2660
+
2661
+ # Converts to a new reference.
2662
+ def to_ref
2663
+ return RefName.new(self.ref.to_ref,self.name)
2664
+ end
2665
+
2666
+ # Converts the name reference to HDLRuby::Low.
2667
+ def to_low
2668
+ # puts "To low for ref with name=#{self.name} and subref=#{self.ref}"
2669
+ return HDLRuby::Low::RefName.new(self.type.to_low,
2670
+ self.ref.to_low,self.name)
2671
+ end
2672
+ end
2673
+
2674
+ ##
2675
+ # Describes a this reference.
2676
+ class RefThis < Low::RefThis
2677
+ High = HDLRuby::High
2678
+ include HRef
2679
+
2680
+ # Converts to a new reference.
2681
+ def to_ref
2682
+ return RefThis.new
2683
+ end
2684
+
2685
+ # Gets the enclosing system type.
2686
+ def system
2687
+ return High.cur_system
2688
+ end
2689
+
2690
+ # Gets the enclosing behavior if any.
2691
+ def behavior
2692
+ return High.cur_behavior
2693
+ end
2694
+
2695
+ # Gets the enclosing block if any.
2696
+ def block
2697
+ return High.cur_block
2698
+ end
2699
+
2700
+ # Converts the this reference to HDLRuby::Low.
2701
+ def to_low
2702
+ return HDLRuby::Low::RefThis.new
2703
+ end
2704
+ end
2705
+
2706
+
2707
+ # Gives access to the *this* reference.
2708
+ def this
2709
+ RefThis.new
2710
+ end
2711
+
2712
+
2713
+ ##
2714
+ # Describes a high-level event.
2715
+ class Event < Low::Event
2716
+ # Converts to a new event.
2717
+ def to_event
2718
+ return Event.new(self.type,self.ref.to_ref)
2719
+ end
2720
+
2721
+ # Inverts the event: create a negedge if posedge, a posedge if negedge.
2722
+ #
2723
+ # NOTE: raise an execption if the event is neigther pos nor neg edge.
2724
+ def invert
2725
+ if self.type == :posedge then
2726
+ return Event.new(:negedge,self.ref.to_ref)
2727
+ elsif self.type == :negedge then
2728
+ return Event.new(:posedge,self.ref.to_ref)
2729
+ else
2730
+ raise AnyError, "Event cannot be inverted: #{self.type}"
2731
+ end
2732
+ end
2733
+
2734
+ # Converts the event to HDLRuby::Low.
2735
+ def to_low
2736
+ return HDLRuby::Low::Event.new(self.type,self.ref.to_low)
2737
+ end
2738
+ end
2739
+
2740
+
2741
+ ##
2742
+ # Decribes a transmission statement.
2743
+ class Transmit < Low::Transmit
2744
+ High = HDLRuby::High
2745
+
2746
+ include HStatement
2747
+
2748
+ # Creates a new transmission from a +right+ expression to a +left+
2749
+ # reference, ensuring left is not a constant.
2750
+ def initialize(left,right)
2751
+ if left.constant? then
2752
+ raise AnyError, "Cannot assign to constant: #{left}"
2753
+ end
2754
+ super(left,right)
2755
+ end
2756
+
2757
+ # Converts the transmission to a comparison expression.
2758
+ #
2759
+ # NOTE: required because the <= operator is ambigous and by
2760
+ # default produces a Transmit or a Connection.
2761
+ def to_expr
2762
+ # Remove the transission from the block.
2763
+ High.top_user.delete_statement!(self)
2764
+ # Generate an expression.
2765
+ return Binary.new(
2766
+ self.left.to_expr.type.send(:<=,self.right.to_expr.type),
2767
+ :<=,self.left.to_expr,self.right.to_expr)
2768
+ end
2769
+
2770
+ # Converts the transmit to HDLRuby::Low.
2771
+ def to_low
2772
+ return HDLRuby::Low::Transmit.new(self.left.to_low,
2773
+ self.right.to_low)
2774
+ end
2775
+ end
2776
+
2777
+ ##
2778
+ # Describes a connection.
2779
+ class Connection < Low::Connection
2780
+ High = HDLRuby::High
2781
+
2782
+ # Converts the connection to a comparison expression.
2783
+ #
2784
+ # NOTE: required because the <= operator is ambigous and by
2785
+ # default produces a Transmit or a Connection.
2786
+ def to_expr
2787
+ # Remove the connection from the system type.
2788
+ High.top_user.delete_connection(self)
2789
+ # Generate an expression.
2790
+ return Binary.new(:<=,self.left,self.right)
2791
+ end
2792
+
2793
+ # Creates a new behavior sensitive to +event+ including the connection
2794
+ # converted to a transmission, and replace the former by the new
2795
+ # behavior.
2796
+ def at(event)
2797
+ # Creates the behavior.
2798
+ left, right = self.left, self.right
2799
+ # Detached left and right from their connection since they will
2800
+ # be put in a new behavior instead.
2801
+ left.parent = right.parent = nil
2802
+ # Create the new behavior replacing the connection.
2803
+ behavior = Behavior.new(:par,event) do
2804
+ left <= right
2805
+ end
2806
+ # Adds the behavior.
2807
+ High.top_user.add_behavior(behavior)
2808
+ # Remove the connection
2809
+ High.top_user.delete_connection!(self)
2810
+ end
2811
+
2812
+ # Creates a new behavior with an if statement from +condition+
2813
+ # enclosing the connection converted to a transmission, and replace the
2814
+ # former by the new behavior.
2815
+ #
2816
+ # NOTE: the else part is defined through the helse method.
2817
+ def hif(condition)
2818
+ # Creates the behavior.
2819
+ left, right = self.left, self.right
2820
+ # Detached left and right from their connection since they will
2821
+ # be put in a new behavior instead.
2822
+ left.parent = right.parent = nil
2823
+ # Create the new behavior replacing the connection.
2824
+ behavior = Behavior.new(:par) do
2825
+ hif(condition) do
2826
+ left <= right
2827
+ end
2828
+ end
2829
+ # Adds the behavior.
2830
+ High.top_user.add_behavior(behavior)
2831
+ # Remove the connection
2832
+ High.top_user.delete_connection!(self)
2833
+ end
2834
+
2835
+ # Converts the connection to HDLRuby::Low.
2836
+ def to_low
2837
+ return HDLRuby::Low::Connection.new(self.left.to_low,
2838
+ self.right.to_low)
2839
+ end
2840
+ end
2841
+
2842
+
2843
+ ##
2844
+ # Describes a high-level signal.
2845
+ class SignalI < Low::SignalI
2846
+ High = HDLRuby::High
2847
+
2848
+ include HRef
2849
+
2850
+ # The valid bounding directions.
2851
+ DIRS = [ :no, :input, :output, :inout, :inner ]
2852
+
2853
+ # The bounding direction.
2854
+ attr_reader :dir
2855
+
2856
+ # Tells if the signal can be read.
2857
+ attr_reader :can_read
2858
+
2859
+ # Tells if the signal can be written.
2860
+ attr_reader :can_write
2861
+
2862
+ # Creates a new signal named +name+ typed as +type+ with
2863
+ # +dir+ as bounding direction and possible +value+.
2864
+ #
2865
+ # NOTE: +dir+ can be :input, :output, :inout or :inner
2866
+ def initialize(name,type,dir,value = nil)
2867
+ # Check the value.
2868
+ value = value.to_expr if value
2869
+ # Initialize the type structure.
2870
+ super(name,type,value)
2871
+
2872
+ unless name.empty? then
2873
+ # Named signal, set the hdl-like access to the signal.
2874
+ obj = self # For using the right self within the proc
2875
+ High.space_reg(name) { obj }
2876
+ end
2877
+
2878
+ # Hierarchical type allows access to sub references, so generate
2879
+ # the corresponding methods.
2880
+ if type.struct? then
2881
+ type.each_name do |name|
2882
+ self.define_singleton_method(name) do
2883
+ RefObject.new(self.to_ref,
2884
+ SignalI.new(name,type.get_type(name),dir))
2885
+ end
2886
+ end
2887
+ end
2888
+
2889
+ # Check and set the bound.
2890
+ self.dir = dir
2891
+
2892
+ # Set the read and write authorisations.
2893
+ @can_read = 1.to_expr
2894
+ @can_write = 1.to_expr
2895
+ end
2896
+
2897
+ # Sets the +condition+ when the signal can be read.
2898
+ def can_read=(condition)
2899
+ @can_read = condition.to_expr
2900
+ end
2901
+
2902
+ # Sets the +condition+ when the signal can be write.
2903
+ def can_write=(condition)
2904
+ @can_write = condition.to_expr
2905
+ end
2906
+
2907
+ # Sets the direction to +dir+.
2908
+ def dir=(dir)
2909
+ unless DIRS.include?(dir) then
2910
+ raise AnyError, "Invalid bounding for signal #{self.name} direction: #{dir}."
2911
+ end
2912
+ @dir = dir
2913
+ end
2914
+
2915
+ # Creates a positive edge event from the signal.
2916
+ def posedge
2917
+ return Event.new(:posedge,self.to_ref)
2918
+ end
2919
+
2920
+ # Creates a negative edge event from the signal.
2921
+ def negedge
2922
+ return Event.new(:negedge,self.to_ref)
2923
+ end
2924
+
2925
+ # Creates an edge event from the signal.
2926
+ def edge
2927
+ return Event.new(:edge,self.to_ref)
2928
+ end
2929
+
2930
+ # Converts to a new reference.
2931
+ def to_ref
2932
+ return RefObject.new(this,self)
2933
+ end
2934
+
2935
+ # Converts to a new expression.
2936
+ def to_expr
2937
+ return self.to_ref
2938
+ end
2939
+
2940
+ # Coerce by converting signal to an expression.
2941
+ def coerce(obj)
2942
+ return [obj,self.to_expr]
2943
+ end
2944
+
2945
+ # Converts the system to HDLRuby::Low and set its +name+.
2946
+ def to_low(name = self.name)
2947
+ return HDLRuby::Low::SignalI.new(name,self.type.to_low)
2948
+ end
2949
+ end
2950
+
2951
+
2952
+ ##
2953
+ # Describes a high-level constant signal.
2954
+ class SignalC < Low::SignalC
2955
+ High = HDLRuby::High
2956
+
2957
+ include HRef
2958
+
2959
+ # Creates a new constant signal named +name+ typed as +type+
2960
+ # and +value+.
2961
+ def initialize(name,type,value)
2962
+ # Check the value is a constant.
2963
+ value = value.to_expr
2964
+ unless value.constant? then
2965
+ raise AnyError,"Non-constant value assignment to constant."
2966
+ end
2967
+ # Initialize the type structure.
2968
+ super(name,type,value)
2969
+
2970
+ unless name.empty? then
2971
+ # Named signal, set the hdl-like access to the signal.
2972
+ obj = self # For using the right self within the proc
2973
+ High.space_reg(name) { obj }
2974
+ end
2975
+
2976
+ # Hierarchical type allows access to sub references, so generate
2977
+ # the corresponding methods.
2978
+ if type.struct? then
2979
+ type.each_name do |name|
2980
+ self.define_singleton_method(name) do
2981
+ RefObject.new(self.to_ref,
2982
+ SignalC.new(name,type.get_type(name),
2983
+ value[name]))
2984
+ end
2985
+ end
2986
+ end
2987
+ end
2988
+
2989
+ # Converts to a new reference.
2990
+ def to_ref
2991
+ return RefObject.new(this,self)
2992
+ end
2993
+
2994
+ # Converts to a new expression.
2995
+ def to_expr
2996
+ return self.to_ref
2997
+ end
2998
+
2999
+ # Coerce by converting signal to an expression.
3000
+ def coerce(obj)
3001
+ return [obj,self.to_expr]
3002
+ end
3003
+
3004
+ # Converts the system to HDLRuby::Low and set its +name+.
3005
+ def to_low(name = self.name)
3006
+ return HDLRuby::Low::SignalC.new(name,self.type.to_low,
3007
+ self.value.to_low)
3008
+ end
3009
+ end
3010
+
3011
+ ##
3012
+ # Module giving the properties of a high-level block.
3013
+ module HBlock
3014
+ High = HDLRuby::High
3015
+
3016
+ # The namespace
3017
+ attr_reader :namespace
3018
+
3019
+ # The return value when building the scope.
3020
+ attr_reader :return_value
3021
+
3022
+ # Build the block by executing +ruby_block+.
3023
+ def build(&ruby_block)
3024
+ High.space_push(@namespace)
3025
+ @return_value = High.top_user.instance_eval(&ruby_block)
3026
+ High.space_pop
3027
+ @return_value
3028
+ end
3029
+
3030
+ # Opens the block.
3031
+ alias_method :open, :build
3032
+
3033
+ # Converts to a new reference.
3034
+ def to_ref
3035
+ return RefObject.new(this,self)
3036
+ end
3037
+
3038
+ include HScope_missing
3039
+
3040
+ # Creates and adds a new block executed in +mode+, with possible
3041
+ # +name+ and built by executing +ruby_block+.
3042
+ def add_block(mode = nil, name = :"", &ruby_block)
3043
+ # Creates the block.
3044
+ block = High.make_block(mode,name,&ruby_block)
3045
+ # Adds it as a statement.
3046
+ self.add_statement(block)
3047
+ # Use its return value.
3048
+ return block.return_value
3049
+ end
3050
+
3051
+ # Creates a new parallel block with possible +name+ and
3052
+ # built from +ruby_block+.
3053
+ def par(name = :"", &ruby_block)
3054
+ return :par unless ruby_block
3055
+ self.add_block(:par,name,&ruby_block)
3056
+ end
3057
+
3058
+ # Creates a new sequential block with possible +name+ and
3059
+ # built from +ruby_block+.
3060
+ def seq(name = :"", &ruby_block)
3061
+ return :seq unless ruby_block
3062
+ self.add_block(:seq,name,&ruby_block)
3063
+ end
3064
+
3065
+ # Creates a new block with the current mode with possible +name+ and
3066
+ # built from +ruby_block+.
3067
+ def sub(name = :"", &ruby_block)
3068
+ self.add_block(self.mode,name,&ruby_block)
3069
+ end
3070
+
3071
+ # Get the current mode of the block.
3072
+ #
3073
+ # NOTE: for name coherency purpose only.
3074
+ def block
3075
+ return self.mode
3076
+ end
3077
+
3078
+ # Need to be able to declare select operators
3079
+ include Hmux
3080
+
3081
+ # Creates a new if statement with a +condition+ that when met lead
3082
+ # to the execution of the block in +mode+ generated by the
3083
+ # +ruby_block+.
3084
+ #
3085
+ # NOTE: the else part is defined through the helse method.
3086
+ def hif(condition, mode = nil, &ruby_block)
3087
+ # Creates the if statement.
3088
+ self.add_statement(If.new(condition,mode,&ruby_block))
3089
+ end
3090
+
3091
+ # Sets the block executed when the condition is not met to the block
3092
+ # in +mode+ generated by the execution of +ruby_block+.
3093
+ #
3094
+ # Can only be used once.
3095
+ def helse(mode = nil, &ruby_block)
3096
+ # There is a ruby_block: the helse is assumed to be with
3097
+ # the hif in the same block.
3098
+ # Completes the hif or the hcase statement.
3099
+ statement = @statements.last
3100
+ unless statement.is_a?(If) or statement.is_a?(Case) then
3101
+ raise AnyError, "Error: helse statement without hif nor hcase (#{statement.class})."
3102
+ end
3103
+ statement.helse(mode, &ruby_block)
3104
+ end
3105
+
3106
+ # Sets the condition check when the condition is not met to the block,
3107
+ # with a +condition+ that when met lead
3108
+ # to the execution of the block in +mode+ generated by the +ruby_block+.
3109
+ def helsif(condition, mode = nil, &ruby_block)
3110
+ # There is a ruby_block: the helse is assumed to be with
3111
+ # the hif in the same block.
3112
+ # Completes the hif statement.
3113
+ statement = @statements.last
3114
+ unless statement.is_a?(If) then
3115
+ raise AnyError,
3116
+ "Error: helsif statement without hif (#{statement.class})."
3117
+ end
3118
+ statement.helsif(condition, mode, &ruby_block)
3119
+ end
3120
+
3121
+
3122
+
3123
+ # Creates a new case statement with a +value+ used for deciding which
3124
+ # block to execute.
3125
+ #
3126
+ # NOTE: the when part is defined through the hwhen method.
3127
+ def hcase(value)
3128
+ # Creates the case statement.
3129
+ self.add_statement(Case.new(value))
3130
+ end
3131
+
3132
+ # Sets the block of a case structure executed when the +match+ is met
3133
+ # to the block in +mode+ generated by the execution of +ruby_block+.
3134
+ #
3135
+ # Can only be used once.
3136
+ def hwhen(match, mode = nil, &ruby_block)
3137
+ # There is a ruby_block: the helse is assumed to be with
3138
+ # the hif in the same block.
3139
+ # Completes the hcase statement.
3140
+ statement = @statements.last
3141
+ unless statement.is_a?(Case) then
3142
+ raise AnyError,
3143
+ "Error: hwhen statement without hcase (#{statement.class})."
3144
+ end
3145
+ statement.hwhen(match, mode, &ruby_block)
3146
+ end
3147
+ end
3148
+
3149
+
3150
+ ##
3151
+ # Describes a high-level block.
3152
+ class Block < Low::Block
3153
+ High = HDLRuby::High
3154
+
3155
+ include HBlock
3156
+ include Hinner
3157
+
3158
+ # Creates a new +mode+ sort of block, with possible +name+
3159
+ # and build it by executing +ruby_block+.
3160
+ def initialize(mode, name=:"", &ruby_block)
3161
+ # Initialize the block.
3162
+ super(mode,name)
3163
+
3164
+ unless name.empty? then
3165
+ # Named block, set the hdl-like access to the block.
3166
+ obj = self # For using the right self within the proc
3167
+ High.space_reg(name) { obj }
3168
+ end
3169
+
3170
+ # Creates the namespace.
3171
+ @namespace = Namespace.new(self)
3172
+
3173
+ # puts "methods = #{self.methods.sort}"
3174
+ build(&ruby_block)
3175
+ end
3176
+
3177
+ # Converts the block to HDLRuby::Low.
3178
+ def to_low
3179
+ # Create the resulting block
3180
+ blockL = HDLRuby::Low::Block.new(self.mode)
3181
+ # Push the namespace for the low generation.
3182
+ High.space_push(@namespace)
3183
+ # Pushes on the name stack for converting the internals of
3184
+ # the block.
3185
+ High.names_push
3186
+ # Add the inner signals
3187
+ self.each_inner { |inner| blockL.add_inner(inner.to_low) }
3188
+ # Add the statements
3189
+ self.each_statement do |statement|
3190
+ blockL.add_statement(statement.to_low)
3191
+ end
3192
+ # Restores the name stack.
3193
+ High.names_pop
3194
+ # Restores the namespace stack.
3195
+ High.space_pop
3196
+ # Return the resulting block
3197
+ return blockL
3198
+ end
3199
+ end
3200
+
3201
+
3202
+ # Describes a timed block.
3203
+ #
3204
+ # NOTE:
3205
+ # * this is the only kind of block that can include time statements.
3206
+ # * this kind of block is not synthesizable!
3207
+ class TimeBlock < Low::TimeBlock
3208
+ High = HDLRuby::High
3209
+
3210
+ include HBlock
3211
+
3212
+ # Creates a new +type+ sort of block with possible +name+
3213
+ # and build it by executing +ruby_block+.
3214
+ def initialize(type, name = :"", &ruby_block)
3215
+ # Initialize the block.
3216
+ super(type,name)
3217
+
3218
+ unless name.empty? then
3219
+ # Named block, set the hdl-like access to the block.
3220
+ obj = self # For using the right self within the proc
3221
+ High.space_reg(name) { obj }
3222
+ end
3223
+
3224
+ # Creates the namespace.
3225
+ @namespace = Namespace.new(self)
3226
+
3227
+ build(&ruby_block)
3228
+ end
3229
+
3230
+ # Adds a wait +delay+ statement in the block.
3231
+ def wait(delay)
3232
+ self.add_statement(TimeWait.new(delay))
3233
+ end
3234
+
3235
+ # Adds a loop until +delay+ statement in the block in +mode+ whose
3236
+ # loop content is built using +ruby_block+.
3237
+ def repeat(delay, mode = nil, &ruby_block)
3238
+ # Build the content block.
3239
+ content = High.make_block(mode,&ruby_block)
3240
+ # Create and add the statement.
3241
+ self.add_statement(TimeRepeat.new(content,delay))
3242
+ end
3243
+
3244
+ # Converts the time block to HDLRuby::Low.
3245
+ def to_low
3246
+ # Create the resulting block
3247
+ blockL = HDLRuby::Low::TimeBlock.new(self.mode)
3248
+ # Add the inner signals
3249
+ self.each_inner { |inner| blockL.add_inner(inner.to_low) }
3250
+ # Add the statements
3251
+ self.each_statement do |statement|
3252
+ blockL.add_statement(statement.to_low)
3253
+ end
3254
+ # Return the resulting block
3255
+ return blockL
3256
+ end
3257
+ end
3258
+
3259
+
3260
+ # Creates a block executed in +mode+, with possible +name+,
3261
+ # that can be timed or not depending on the enclosing object and build
3262
+ # it by executing the enclosing +ruby_block+.
3263
+ #
3264
+ # NOTE: not a method to include since it can only be used with
3265
+ # a behavior or a block. Hence set as module method.
3266
+ def self.make_block(mode = nil, name = :"", &ruby_block)
3267
+ unless mode then
3268
+ # No type of block given, get a default one.
3269
+ if top_user.is_a?(Block) then
3270
+ # There is an upper block, use its mode.
3271
+ mode = top_user.mode
3272
+ else
3273
+ # There is no upper block, use :par as default.
3274
+ mode = :par
3275
+ end
3276
+ end
3277
+ if top_user.is_a?(TimeBlock) then
3278
+ return TimeBlock.new(mode,name,&ruby_block)
3279
+ else
3280
+ return Block.new(mode,name,&ruby_block)
3281
+ end
3282
+ end
3283
+
3284
+ # Creates a specifically timed block in +mode+, with possible +name+
3285
+ # and build it by executing the enclosing +ruby_block+.
3286
+ #
3287
+ # NOTE: not a method to include since it can only be used with
3288
+ # a behavior or a block. Hence set as module method.
3289
+ def self.make_time_block(mode = nil, name = :"", &ruby_block)
3290
+ unless mode then
3291
+ # No type of block given, get a default one.
3292
+ if top_user.is_a?(Block) then
3293
+ # There is an upper block, use its mode.
3294
+ mode = block.mode
3295
+ else
3296
+ # There is no upper block, use :par as default.
3297
+ mode = :par
3298
+ end
3299
+ end
3300
+ return TimeBlock.new(mode,name,&ruby_block)
3301
+ end
3302
+
3303
+ ##
3304
+ # Describes a high-level behavior.
3305
+ class Behavior < Low::Behavior
3306
+ High = HDLRuby::High
3307
+
3308
+ # Creates a new behavior executing +block+ activated on a list of
3309
+ # +events+, and built by executing +ruby_block+.
3310
+ # +mode+ can be either :seq or :par for respectively sequential or
3311
+ # parallel.
3312
+ def initialize(mode,*events,&ruby_block)
3313
+ # Initialize the behavior with it.
3314
+ super(nil)
3315
+ # # Save the Location for debugging information
3316
+ # @location = caller_locations
3317
+ # Sets the current behavior
3318
+ @@cur_behavior = self
3319
+ # Add the events.
3320
+ events.each { |event| self.add_event(event) }
3321
+ # Create and add the block.
3322
+ self.block = High.make_block(mode,&ruby_block)
3323
+ # Unset the current behavior
3324
+ @@cur_behavior = nil
3325
+ end
3326
+
3327
+ # Sets an event to the behavior.
3328
+ # NOTE: currently actually adds an event if there are already some!
3329
+ alias_method :at, :add_event
3330
+
3331
+ # Converts the time behavior to HDLRuby::Low.
3332
+ def to_low
3333
+ # Create the low level block.
3334
+ blockL = self.block.to_low
3335
+ # Create the low level events.
3336
+ eventLs = self.each_event.map { |event| event.to_low }
3337
+ # Create and return the resulting low level behavior.
3338
+ behaviorL = HDLRuby::Low::Behavior.new(blockL)
3339
+ eventLs.each(&behaviorL.method(:add_event))
3340
+ return behaviorL
3341
+ end
3342
+ end
3343
+
3344
+ ##
3345
+ # Describes a high-level timed behavior.
3346
+ class TimeBehavior < Low::TimeBehavior
3347
+ High = HDLRuby::High
3348
+
3349
+ # Creates a new timed behavior built by executing +ruby_block+.
3350
+ # +mode+ can be either :seq or :par for respectively sequential or
3351
+ def initialize(mode, &ruby_block)
3352
+ # Create a default par block for the behavior.
3353
+ block = High.make_time_block(mode,&ruby_block)
3354
+ # Initialize the behavior with it.
3355
+ super(block)
3356
+ end
3357
+
3358
+ # Converts the time behavior to HDLRuby::Low.
3359
+ def to_low
3360
+ # Create the low level block.
3361
+ blockL = self.block.to_low
3362
+ # Create the low level events.
3363
+ eventLs = self.each_event.map { |event| event.to_low }
3364
+ # Create and return the resulting low level behavior.
3365
+ behaviorL = HDLRuby::Low::TimeBehavior.new(blockL)
3366
+ eventLs.each(&behaviorL.method(:add_event))
3367
+ return behaviorL
3368
+ end
3369
+ end
3370
+
3371
+
3372
+
3373
+
3374
+
3375
+ # Handle the namespaces for accessing the hardware referencing methods.
3376
+
3377
+ # The universe, i.e., the top system type.
3378
+ Universe = SystemT.new(:"") {}
3379
+
3380
+ # The universe does not have input, output, nor inout.
3381
+ class << Universe
3382
+ undef_method :input
3383
+ undef_method :output
3384
+ undef_method :inout
3385
+ undef_method :add_input
3386
+ undef_method :add_output
3387
+ undef_method :add_inout
3388
+ end
3389
+
3390
+
3391
+ # include Hmissing
3392
+
3393
+ # The namespace stack: never empty, the top is a nameless system without
3394
+ # input nor output.
3395
+ Namespaces = [Universe.scope.namespace]
3396
+ private_constant :Namespaces
3397
+
3398
+ # Pushes +namespace+.
3399
+ def self.space_push(namespace)
3400
+ # Emsure namespace is really a namespace.
3401
+ namespace = namespace.to_namespace
3402
+ # Adds the namespace to the top.
3403
+ Namespaces.push(namespace)
3404
+ end
3405
+
3406
+ # Inserts +namespace+ at +index+.
3407
+ def self.space_insert(index,namespace)
3408
+ Namespaces.insert(index.to_i,namespace.to_namespace)
3409
+ end
3410
+
3411
+ # Pops a namespace.
3412
+ def self.space_pop
3413
+ if Namespaces.size <= 1 then
3414
+ raise AnyError, "Internal error: cannot pop further namespaces."
3415
+ end
3416
+ Namespaces.pop
3417
+ end
3418
+
3419
+ # Tells if +namespace+ in included within the stack.
3420
+ def self.space_include?(namespace)
3421
+ return Namespaces.include?(namespace)
3422
+ end
3423
+
3424
+ # Gets the index of a +namespace+ within the stack.
3425
+ def self.space_index(namespace)
3426
+ return Namespaces.index(namespace)
3427
+ end
3428
+
3429
+ # Gets the top of the namespaces stack.
3430
+ def self.space_top
3431
+ Namespaces[-1]
3432
+ end
3433
+
3434
+ # sets the top namespace.
3435
+ def self.space_top=(top)
3436
+ unless top.is_a?(Namespace) then
3437
+ raise "Invalid class for a Namspace: #{top.class}"
3438
+ end
3439
+ Namespaces[-1] = top
3440
+ end
3441
+
3442
+
3443
+ # Gets construct whose namespace is the top of the namespaces stack.
3444
+ def self.top_user
3445
+ self.space_top.user
3446
+ end
3447
+
3448
+ # Gather the result of the execution of +method+ from all the users
3449
+ # of the namespaces.
3450
+ def self.from_users(method)
3451
+ Namespaces.reverse_each.reduce([]) do |res,space|
3452
+ user = space.user
3453
+ if user.respond_to?(method) then
3454
+ res += [*user.send(method)]
3455
+ end
3456
+ end
3457
+ end
3458
+
3459
+ # Iterates over each namespace.
3460
+ #
3461
+ # Returns an enumerator if no ruby block is given.
3462
+ def self.space_each(&ruby_block)
3463
+ # No ruby block? Return an enumerator.
3464
+ return to_enum(:space_each) unless ruby_block
3465
+ # A block? Apply it on each system instance.
3466
+ Namespaces.each(&ruby_block)
3467
+ end
3468
+
3469
+ # Tells if within a system type.
3470
+ def self.in_system?
3471
+ return Namespaces.size > 1
3472
+ end
3473
+
3474
+ # Gets the enclosing system type if any.
3475
+ def self.cur_system
3476
+ if Namespaces.size <= 1 then
3477
+ raise AnyError, "Not within a system type."
3478
+ else
3479
+ return Namespaces.reverse_each.find do |space|
3480
+ space.user.is_a?(Scope) and space.user.parent.is_a?(SystemT)
3481
+ end.user.parent
3482
+ end
3483
+ end
3484
+
3485
+ # The current behavior: by default none.
3486
+ @@cur_behavior = nil
3487
+
3488
+ # Gets the enclosing behavior if any.
3489
+ def self.cur_behavior
3490
+ return @@cur_behavior
3491
+ end
3492
+
3493
+ # Tell if we are in a behavior.
3494
+ def self.in_behavior?
3495
+ top_user.is_a?(Block)
3496
+ end
3497
+
3498
+ # Gets the enclosing block if any.
3499
+ #
3500
+ # NOTE: +level+ allows to get an upper block of the currently enclosing
3501
+ # block.
3502
+ def self.cur_block(level = 0)
3503
+ if Namespaces[-1-level].user.is_a?(Scope) then
3504
+ raise AnyError,
3505
+ "Not within a block: #{Namespaces[-1-level].user.class}"
3506
+ elsif Namespaces[-1-level].user.is_a?(Block) then
3507
+ return Namespaces[-1-level].user
3508
+ else
3509
+ return cur_block(level+1)
3510
+ end
3511
+ end
3512
+
3513
+ # Registers hardware referencing method +name+ to the current namespace.
3514
+ def self.space_reg(name,&ruby_block)
3515
+ # print "registering #{name} in #{Namespaces[-1]}\n"
3516
+ Namespaces[-1].add_method(name,&ruby_block)
3517
+ end
3518
+
3519
+ # Looks up and calls method +name+ from the namespace stack with arguments
3520
+ # +args+ and block +ruby_block+.
3521
+ def self.space_call(name,*args,&ruby_block)
3522
+ # print "space_call with name=#{name}\n"
3523
+ # Ensures name is a symbol.
3524
+ name = name.to_sym
3525
+ # Look from the top of the namespace stack.
3526
+ Namespaces.reverse_each do |space|
3527
+ # puts "space=#{space.singleton_methods}"
3528
+ if space.respond_to?(name) then
3529
+ # print "Found is space user with class=#{space.user.class}\n"
3530
+ # The method is found, call it.
3531
+ return space.send(name,*args,&ruby_block)
3532
+ elsif space.user.respond_to?(name) then
3533
+ # The method is found in the user, call it.
3534
+ return space.user.send(name,*args,&ruby_block)
3535
+ end
3536
+ end
3537
+ # Look in the global methods.
3538
+ if HDLRuby::High.respond_to?(name) then
3539
+ # Found.
3540
+ return HDLRuby::High.send(name,*args,&ruby_block)
3541
+ end
3542
+ # Not found.
3543
+ raise NotDefinedError,
3544
+ "undefined HDLRuby construct, local variable or method `#{name}'."
3545
+ end
3546
+
3547
+
3548
+
3549
+
3550
+
3551
+
3552
+
3553
+ # Extends the standard classes for support of HDLRuby.
3554
+
3555
+
3556
+ # Extends the Numeric class for conversion to a high-level expression.
3557
+ class ::Numeric
3558
+
3559
+ # Tell if the expression can be converted to a value.
3560
+ def to_value?
3561
+ return true
3562
+ end
3563
+
3564
+ # Converts to a new high-level value.
3565
+ def to_value
3566
+ to_expr
3567
+ end
3568
+
3569
+ # Converts to a new delay in picoseconds.
3570
+ def ps
3571
+ return Delay.new(self,:ps)
3572
+ end
3573
+
3574
+ # Converts to a new delay in nanoseconds.
3575
+ def ns
3576
+ return Delay.new(self,:ns)
3577
+ end
3578
+
3579
+ # Converts to a new delay in microseconds.
3580
+ def us
3581
+ return Delay.new(self,:us)
3582
+ end
3583
+
3584
+ # Converts to a new delay in milliseconds.
3585
+ def ms
3586
+ return Delay.new(self,:ms)
3587
+ end
3588
+
3589
+ # Converts to a new delay in seconds.
3590
+ def s
3591
+ return Delay.new(self,:s)
3592
+ end
3593
+ end
3594
+
3595
+ # Extends the Fixnum class for computing for conversion to expression.
3596
+ class ::Fixnum
3597
+ # Converts to a new high-level expression.
3598
+ def to_expr
3599
+ return Value.new(Integer,self)
3600
+ end
3601
+ end
3602
+
3603
+ # Extends the Bignum class for computing for conversion to expression.
3604
+ class ::Bignum
3605
+ # Converts to a new high-level expression.
3606
+ def to_expr
3607
+ return Value.new(Bignum,self)
3608
+ end
3609
+ end
3610
+
3611
+ # Extends the Float class for computing the bit width and conversion
3612
+ # to expression.
3613
+ class ::Float
3614
+ # Converts to a new high-level expression.
3615
+ def to_expr
3616
+ return Value.new(Real,self)
3617
+ end
3618
+
3619
+ # Gets the bit width
3620
+ def width
3621
+ return 64
3622
+ end
3623
+ end
3624
+
3625
+ # Extends the String class for computing conversion to expression.
3626
+ class ::String
3627
+ # Converts to a new high-level expression.
3628
+ def to_expr
3629
+ # Convert the string to a bit string.
3630
+ bstr = BitString.new(self)
3631
+ # Use it to create the new value.
3632
+ return Value.new(Bit[bstr.width],self)
3633
+ end
3634
+ end
3635
+
3636
+
3637
+ # Extends the Hash class for declaring signals of structure types.
3638
+ class ::Hash
3639
+
3640
+ # Converts to a new type.
3641
+ def to_type
3642
+ return TypeStruct.new(:"",:little,self)
3643
+ end
3644
+
3645
+ # Declares a new type definition with +name+ equivalent to current one.
3646
+ def typedef(name)
3647
+ return self.to_type.typedef(name)
3648
+ end
3649
+
3650
+ # Declares high-level input signals named +names+ of the current type.
3651
+ #
3652
+ # Retuns the last declared input.
3653
+ def input(*names)
3654
+ res = nil
3655
+ names.each do |name|
3656
+ res = HDLRuby::High.top_user.
3657
+ add_input(SignalI.new(name,
3658
+ TypeStruct.new(:"",:little,self),:input))
3659
+ end
3660
+ return res
3661
+ end
3662
+
3663
+ # Declares high-level untyped output signals named +names+ of the
3664
+ # current type.
3665
+ #
3666
+ # Retuns the last declared output.
3667
+ def output(*names)
3668
+ res = nil
3669
+ names.each do |name|
3670
+ res = HDLRuby::High.top_user.
3671
+ add_output(SignalI.new(name,
3672
+ TypeStruct.new(:"",:little,self),:output))
3673
+ end
3674
+ return res
3675
+ end
3676
+
3677
+ # Declares high-level untyped inout signals named +names+ of the
3678
+ # current type.
3679
+ #
3680
+ # Retuns the last declared inout.
3681
+ def inout(*names)
3682
+ res = nil
3683
+ names.each do |name|
3684
+ res = HDLRuby::High.top_user.
3685
+ add_inout(SignalI.new(name,
3686
+ TypeStruct.new(:"",:little,self),:inout))
3687
+ end
3688
+ return res
3689
+ end
3690
+
3691
+ # Declares high-level untyped inner signals named +names+ of the
3692
+ # current type.
3693
+ #
3694
+ # Retuns the last declared inner.
3695
+ def inner(*names)
3696
+ res = nil
3697
+ names.each do |name|
3698
+ res = HDLRuby::High.top_user.
3699
+ add_inner(SignalI.new(name,
3700
+ TypeStruct.new(:"",:little,self),:inner))
3701
+ end
3702
+ return res
3703
+ end
3704
+
3705
+ # Declares high-level untyped constant signals by name and value given
3706
+ # by +hsh+ of the current type.
3707
+ #
3708
+ # Retuns the last declared constant.
3709
+ def constant(hsh)
3710
+ res = nil
3711
+ hsh.each do |name,value|
3712
+ res = HDLRuby::High.top_user.
3713
+ add_inner(SignalC.new(name,
3714
+ TypeStruct.new(:"",:little,self),:inner,value))
3715
+ end
3716
+ return res
3717
+ end
3718
+ end
3719
+
3720
+
3721
+ # Extends the Array class for conversion to a high-level expression.
3722
+ class ::Array
3723
+ include HArrow
3724
+
3725
+ # Converts to a new high-level expression.
3726
+ def to_expr
3727
+ # expr = Concat.new
3728
+ expr = Concat.new(TypeTuple.new(:"",:little,*self.map do |elem|
3729
+ elem.to_expr.type
3730
+ end))
3731
+ self.each {|elem| expr.add_expression(elem.to_expr) }
3732
+ expr
3733
+ end
3734
+
3735
+ # Converts to a new high-level reference.
3736
+ def to_ref
3737
+ # expr = RefConcat.new
3738
+ expr = RefConcat.new(TypeTuple.new(:"",:little,*self.map do |elem|
3739
+ elem.to_ref.type
3740
+ end))
3741
+ self.each {|elem| expr.add_ref(elem.to_ref) }
3742
+ expr
3743
+ end
3744
+
3745
+ # Converts to a new type.
3746
+ def to_type
3747
+ if self.size == 1 and
3748
+ ( self[0].is_a?(Range) or self[0].respond_to?(:to_i) ) then
3749
+ # Vector type case
3750
+ return bit[*self]
3751
+ else
3752
+ # Tuple type case.
3753
+ return TypeTuple.new(:"",:little,*self)
3754
+ end
3755
+ end
3756
+
3757
+ # Declares a new type definition with +name+ equivalent to current one.
3758
+ def typedef(name)
3759
+ return self.to_type.typedef(name)
3760
+ end
3761
+
3762
+ # SignalI creation through the array take as type.
3763
+
3764
+ # Declares high-level input signals named +names+ of the current type.
3765
+ def input(*names)
3766
+ High.top_user.make_inputs(self.to_type,*names)
3767
+ end
3768
+
3769
+ # Declares high-level untyped output signals named +names+ of the
3770
+ # current type.
3771
+ def output(*names)
3772
+ High.top_user.make_outputs(self.to_type,*names)
3773
+ end
3774
+
3775
+ # Declares high-level untyped inout signals named +names+ of the
3776
+ # current type.
3777
+ def inout(*names)
3778
+ High.top_user.make_inouts(self.to_type,*names)
3779
+ end
3780
+
3781
+ # Declares high-level inner signals named +names+ of the
3782
+ # current type.
3783
+ def inner(*names)
3784
+ High.top_user.make_inners(self.to_type,*names)
3785
+ end
3786
+
3787
+ # Declares high-level inner constants named from +hsh+ with names
3788
+ # and corresponding values.
3789
+ def constant(hsh)
3790
+ High.top_user.make_constants(self.to_type,hsh)
3791
+ end
3792
+
3793
+ # Creates a hcase statement executing +ruby_block+ on the element of
3794
+ # the array selected by +value+
3795
+ def hcase(value,&ruby_block)
3796
+ High.cur_block.hcase(value)
3797
+ self.each.with_index do |elem,i|
3798
+ High.cur_block.hwhen(i) { ruby_block.call(elem) }
3799
+ end
3800
+ end
3801
+
3802
+ # Array construction shortcuts
3803
+
3804
+ # Create an array whose number of elements is given by the content
3805
+ # of the current array, filled by +obj+ objects.
3806
+ # If +obj+ is nil, +ruby_block+ is used instead for filling the array.
3807
+ def call(obj = nil, &ruby_block)
3808
+ unless self.size == 1 then
3809
+ raise AnyError, "Invalid array for call opertor."
3810
+ end
3811
+ number = self[0].to_i
3812
+ if obj then
3813
+ return Array.new(number,obj)
3814
+ else
3815
+ return Array.new(number,&ruby_block)
3816
+ end
3817
+ end
3818
+
3819
+ # Create an array of instances of system +name+, using +args+ as
3820
+ # arguments.
3821
+ #
3822
+ # NOTE: the array must have a single element that is an integer.
3823
+ def make(name,*args)
3824
+ # Check the array and get the number of elements.
3825
+ size = self[0]
3826
+ unless self.size == 1 and size.is_a?(::Integer)
3827
+ raise AnyError,
3828
+ "Invalid array for declaring a list of instances."
3829
+ end
3830
+ # Get the system to instantiate.
3831
+ systemT = High.space_call(name)
3832
+ # Get the name of the instance from the arguments.
3833
+ nameI = args.shift.to_s
3834
+ # Create the instances.
3835
+ instances = size.times.map do |i|
3836
+ systemT.instantiate((nameI + "[#{i}]").to_sym,*args)
3837
+ end
3838
+ nameI = nameI.to_sym
3839
+ # Add them to the top system
3840
+ High.space_top.user.add_groupI(nameI,*instances)
3841
+ # Register and return the result.
3842
+ High.space_reg(nameI) { High.space_top.user.get_groupI(nameI) }
3843
+ return High.space_top.user.get_groupI(nameI)
3844
+ end
3845
+ end
3846
+
3847
+
3848
+ # Extends the symbol class for auto declaration of input or output.
3849
+ class ::Symbol
3850
+ High = HDLRuby::High
3851
+
3852
+ # Tell if the expression can be converted to a value.
3853
+ def to_value?
3854
+ return true
3855
+ end
3856
+
3857
+ # Converts to a new value.
3858
+ #
3859
+ # Returns nil if no value can be obtained from it.
3860
+ def to_value
3861
+ str = self.to_s
3862
+ return nil if str[0] != "_" # Bit string are prefixed by "_"
3863
+ # Remove the "_" not needed any longer.
3864
+ str = str[1..-1]
3865
+ # Get and check the type
3866
+ type = str[0]
3867
+ if type == "0" or type == "1" or type == "z" or type == "Z" then
3868
+ # Default binary
3869
+ type = "b"
3870
+ else
3871
+ # Not a default type
3872
+ str = str[1..-1]
3873
+ end
3874
+ return nil if str.empty?
3875
+ return nil unless ["b","u","s"].include?(type)
3876
+ # Get the width if any.
3877
+ if str[0].match(/[0-9]/) then
3878
+ width = str.scan(/[0-9]*/)[0]
3879
+ else
3880
+ width = nil
3881
+ end
3882
+ # puts "width=#{width}"
3883
+ old_str = str # Save the string it this state since its first chars
3884
+ # can be erroneously considered as giving the width
3885
+ str = str[width.size..-1] if width
3886
+ # Get the base and the value
3887
+ base = str[0]
3888
+ # puts "base=#{base}\n"
3889
+ unless ["b", "o", "d", "h"].include?(base) then
3890
+ # No base found, default is bit
3891
+ base = "b"
3892
+ # And the width was actually a part of the value.
3893
+ value = old_str
3894
+ width = nil
3895
+ else
3896
+ # Get the value.
3897
+ value = str[1..-1]
3898
+ end
3899
+ # puts "value=#{value}"
3900
+ # Compute the bit width and the value
3901
+ case base
3902
+ when "b" then
3903
+ # base 2, compute the width
3904
+ width = width ? width.to_i : value.size
3905
+ # Check the value
3906
+ return nil unless value.match(/^[0-1zxZX]+$/)
3907
+ when "o" then
3908
+ # base 8, compute the width
3909
+ width = width ? width.to_i : value.size * 3
3910
+ # Check the value
3911
+ if value.match(/^[0-7xXzZ]+$/) then
3912
+ # 4-state value, conpute the correspondig bit string.
3913
+ value = value.each_char.map do |c|
3914
+ c = c.upcase
3915
+ if c == "X" or c.upcase == "Z" then
3916
+ c * 3
3917
+ else
3918
+ c.to_i(8).to_s(2).rjust(3,"0")
3919
+ end
3920
+ end.join
3921
+ else
3922
+ # Invalid value
3923
+ return nil
3924
+ end
3925
+ when "d" then
3926
+ # base 10, compute the width
3927
+ width = width ? width.to_i : value.to_i.to_s(2).size + 1
3928
+ # Check the value
3929
+ return nil unless value.match(/^[0-9]+$/)
3930
+ # Compute it (base 10 values cannot be 4-state!)
3931
+ value = value.to_i.to_s(2)
3932
+ when "h" then
3933
+ # base 16, compute the width
3934
+ width = width ? width.to_i : value.size * 4
3935
+ # Check the value
3936
+ if value.match(/^[0-9a-fA-FxXzZ]+$/) then
3937
+ # 4-state value, conpute the correspondig bit string.
3938
+ value = value.each_char.map do |c|
3939
+ c = c.upcase
3940
+ if c == "X" or c.upcase == "Z" then
3941
+ c * 4
3942
+ else
3943
+ c.to_i(16).to_s(2).rjust(4,"0")
3944
+ end
3945
+ end.join
3946
+ else
3947
+ # Invalid value
3948
+ return nil
3949
+ end
3950
+ else
3951
+ # Unknown base
3952
+ return nil
3953
+ end
3954
+ # Compute the type.
3955
+ case type
3956
+ when "b" then
3957
+ type = bit[width]
3958
+ when "u" then
3959
+ type = unsigned[width]
3960
+ when "s" then
3961
+ type = signed[width]
3962
+ else
3963
+ # Unknown type
3964
+ return nil
3965
+ end
3966
+ # puts "type.width=#{type.width}, value=#{value}"
3967
+ # Create and return the value.
3968
+ return Value.new(type,value)
3969
+ end
3970
+
3971
+ alias_method :to_expr, :to_value
3972
+ end
3973
+
3974
+ # Extends the range class to support to_low
3975
+ class ::Range
3976
+ # Convert the first and last to HDLRuby::Low
3977
+ def to_low
3978
+ first = self.first
3979
+ first = first.respond_to?(:to_low) ? first.to_low : first
3980
+ last = self.last
3981
+ last = last.respond_to?(:to_low) ? last.to_low : last
3982
+ return (first..last)
3983
+ end
3984
+
3985
+ # Iterates over the range as hardware.
3986
+ #
3987
+ # Returns an enumerator if no ruby block is given.
3988
+ def heach(&ruby_block)
3989
+ # No ruby block? Return an enumerator.
3990
+ return to_enum(:heach) unless ruby_block
3991
+ # Order the bounds to be able to iterate.
3992
+ first,last = self.first, self.last
3993
+ first,last = first > last ? [last,first] : [first,last]
3994
+ # Iterate.
3995
+ (first..last).each(&ruby_block)
3996
+ end
3997
+ end
3998
+
3999
+
4000
+
4001
+
4002
+ # Methods for managing the conversion to HDLRuby::Low
4003
+
4004
+ # Methods for generating uniq names in context
4005
+
4006
+ # The stack of names for creating new names without conflicts.
4007
+ NameStack = [ Set.new ]
4008
+
4009
+ # Pushes on the name stack.
4010
+ def self.names_push
4011
+ NameStack.push(Set.new)
4012
+ end
4013
+
4014
+ # Pops from the name stack.
4015
+ def self.names_pop
4016
+ NameStack.pop
4017
+ end
4018
+
4019
+ # Adds a +name+ to the top of the stack.
4020
+ def self.names_add(name)
4021
+ NameStack[-1].add(name.to_s)
4022
+ end
4023
+
4024
+ # Checks if a +name+ is present in the stack.
4025
+ def self.names_has?(name)
4026
+ NameStack.find do |names|
4027
+ names.include?(name)
4028
+ end
4029
+ end
4030
+
4031
+ # Creates and adds the new name from +base+ that do not collides with the
4032
+ # exisiting names.
4033
+ def self.names_create(base)
4034
+ base = base.to_s.clone
4035
+ # Create a non-conflicting name
4036
+ if self.names_has?(base) then
4037
+ count = 0
4038
+ while (self.names_has?(base + count.to_s)) do
4039
+ count += 1
4040
+ end
4041
+ base << count.to_s
4042
+ end
4043
+ # Add and return it
4044
+ self.names_add(base)
4045
+ # puts "created name: #{base}"
4046
+ return base.to_sym
4047
+ end
4048
+
4049
+
4050
+
4051
+
4052
+ # Standard vector types.
4053
+ Integer = TypeSigned.new(:integer)
4054
+ Natural = TypeUnsigned.new(:natural)
4055
+ Bignum = TypeSigned.new(:bignum,HDLRuby::Infinity..0)
4056
+ Real = TypeFloat.new(:float)
4057
+
4058
+
4059
+ end
4060
+
4061
+ # Tell if already configured.
4062
+ $HDLRuby_configure = false
4063
+
4064
+ # Enters in HDLRuby::High mode.
4065
+ def self.configure_high
4066
+ if $HDLRuby_configure then
4067
+ # Already configured.
4068
+ return
4069
+ end
4070
+ # Now HDLRuby will be configured.
4071
+ $HDLRuby_configure = true
4072
+ include HDLRuby::High
4073
+ class << self
4074
+ # For main, missing methods are looked for in the namespaces.
4075
+ def method_missing(m, *args, &ruby_block)
4076
+ # print "method_missing in class=#{self.class} with m=#{m}\n"
4077
+ # Is the missing method an immediate value?
4078
+ value = m.to_value
4079
+ return value if value and args.empty?
4080
+ # puts "Universe methods: #{Universe.namespace.methods}"
4081
+ # Not a value, but maybe it is in the namespaces
4082
+ if Namespaces[-1].respond_to?(m) then
4083
+ # Yes use it.
4084
+ Namespaces[-1].send(m,*args,&ruby_block)
4085
+ else
4086
+ # puts "here: #{m}"
4087
+ # No, true error
4088
+ raise NotDefinedError, "undefined HDLRuby construct, local variable or method `#{m}'."
4089
+ end
4090
+ end
4091
+ end
4092
+
4093
+ # Generate the standard signals
4094
+ $clk = Universe.scope.inner :__universe__clk__
4095
+ $rst = Universe.scope.inner :__universe__rst__
4096
+
4097
+
4098
+
4099
+ # Tells HDLRuby has finised booting.
4100
+ def self.booting?
4101
+ false
4102
+ end
4103
+ end