HDLRuby 2.0.8

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