HDLRuby 2.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (224) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +5 -0
  4. data/.yardopts +1 -0
  5. data/Gemfile +4 -0
  6. data/HDLRuby.gemspec +36 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +2774 -0
  9. data/README.pdf +0 -0
  10. data/Rakefile +10 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/exe/hdrcc +3 -0
  14. data/lib/HDLRuby/alcc.rb +137 -0
  15. data/lib/HDLRuby/backend/hruby_allocator.rb +69 -0
  16. data/lib/HDLRuby/backend/hruby_c_allocator.rb +76 -0
  17. data/lib/HDLRuby/hdr_samples/adder.rb +7 -0
  18. data/lib/HDLRuby/hdr_samples/adder_assign_error.rb +11 -0
  19. data/lib/HDLRuby/hdr_samples/adder_bench.rb +27 -0
  20. data/lib/HDLRuby/hdr_samples/adder_gen.rb +7 -0
  21. data/lib/HDLRuby/hdr_samples/adder_nodef_error.rb +7 -0
  22. data/lib/HDLRuby/hdr_samples/addsub.rb +19 -0
  23. data/lib/HDLRuby/hdr_samples/addsubz.rb +22 -0
  24. data/lib/HDLRuby/hdr_samples/alu.rb +47 -0
  25. data/lib/HDLRuby/hdr_samples/calculator.rb +48 -0
  26. data/lib/HDLRuby/hdr_samples/counter_bench.rb +83 -0
  27. data/lib/HDLRuby/hdr_samples/dff.rb +9 -0
  28. data/lib/HDLRuby/hdr_samples/dff_bench.rb +66 -0
  29. data/lib/HDLRuby/hdr_samples/dff_counter.rb +20 -0
  30. data/lib/HDLRuby/hdr_samples/include.rb +14 -0
  31. data/lib/HDLRuby/hdr_samples/instance_open.rb +23 -0
  32. data/lib/HDLRuby/hdr_samples/mei8.rb +256 -0
  33. data/lib/HDLRuby/hdr_samples/mei8_bench.rb +309 -0
  34. data/lib/HDLRuby/hdr_samples/multer_gen.rb +8 -0
  35. data/lib/HDLRuby/hdr_samples/multer_seq.rb +29 -0
  36. data/lib/HDLRuby/hdr_samples/neural/a.rb +9 -0
  37. data/lib/HDLRuby/hdr_samples/neural/a_sub.rb +5 -0
  38. data/lib/HDLRuby/hdr_samples/neural/bw.rb +23 -0
  39. data/lib/HDLRuby/hdr_samples/neural/counter.rb +16 -0
  40. data/lib/HDLRuby/hdr_samples/neural/dadz.rb +9 -0
  41. data/lib/HDLRuby/hdr_samples/neural/dadz_sub.rb +4 -0
  42. data/lib/HDLRuby/hdr_samples/neural/forward.rb +153 -0
  43. data/lib/HDLRuby/hdr_samples/neural/forward_sub.rb +62 -0
  44. data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand.rb +41 -0
  45. data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand_typedef.rb +47 -0
  46. data/lib/HDLRuby/hdr_samples/neural/mem.rb +30 -0
  47. data/lib/HDLRuby/hdr_samples/neural/random.rb +23 -0
  48. data/lib/HDLRuby/hdr_samples/neural/selector.rb +29 -0
  49. data/lib/HDLRuby/hdr_samples/neural/sigmoid.rb +20 -0
  50. data/lib/HDLRuby/hdr_samples/neural/z.rb +33 -0
  51. data/lib/HDLRuby/hdr_samples/prog.obj +256 -0
  52. data/lib/HDLRuby/hdr_samples/ram.rb +18 -0
  53. data/lib/HDLRuby/hdr_samples/register_with_code_bench.rb +98 -0
  54. data/lib/HDLRuby/hdr_samples/rom.rb +10 -0
  55. data/lib/HDLRuby/hdr_samples/struct.rb +14 -0
  56. data/lib/HDLRuby/hdr_samples/sumprod.rb +29 -0
  57. data/lib/HDLRuby/hdr_samples/sw_encrypt_bench.rb +103 -0
  58. data/lib/HDLRuby/hdr_samples/sw_encrypt_cpu_bench.rb +261 -0
  59. data/lib/HDLRuby/hdr_samples/sw_encrypt_cpusim_bench.rb +302 -0
  60. data/lib/HDLRuby/hdr_samples/system_open.rb +11 -0
  61. data/lib/HDLRuby/hdr_samples/tuple.rb +16 -0
  62. data/lib/HDLRuby/hdr_samples/with_channel.rb +118 -0
  63. data/lib/HDLRuby/hdr_samples/with_class.rb +199 -0
  64. data/lib/HDLRuby/hdr_samples/with_decoder.rb +17 -0
  65. data/lib/HDLRuby/hdr_samples/with_fsm.rb +34 -0
  66. data/lib/HDLRuby/hdr_samples/with_reconf.rb +103 -0
  67. data/lib/HDLRuby/hdrcc.rb +623 -0
  68. data/lib/HDLRuby/high_samples/_adder_fault.rb +23 -0
  69. data/lib/HDLRuby/high_samples/_generic_transmission2.rb +146 -0
  70. data/lib/HDLRuby/high_samples/adder.rb +21 -0
  71. data/lib/HDLRuby/high_samples/adder_common_errors.rb +25 -0
  72. data/lib/HDLRuby/high_samples/addsub.rb +33 -0
  73. data/lib/HDLRuby/high_samples/addsubz.rb +37 -0
  74. data/lib/HDLRuby/high_samples/after.rb +28 -0
  75. data/lib/HDLRuby/high_samples/all_signals.rb +29 -0
  76. data/lib/HDLRuby/high_samples/alu.rb +61 -0
  77. data/lib/HDLRuby/high_samples/anonymous.rb +41 -0
  78. data/lib/HDLRuby/high_samples/before.rb +28 -0
  79. data/lib/HDLRuby/high_samples/blockblock.rb +26 -0
  80. data/lib/HDLRuby/high_samples/bugs/dadz.rb +22 -0
  81. data/lib/HDLRuby/high_samples/bugs/misample_instan.rb +20 -0
  82. data/lib/HDLRuby/high_samples/bugs/misample_updown.rb +22 -0
  83. data/lib/HDLRuby/high_samples/bugs/sample_add.rb +16 -0
  84. data/lib/HDLRuby/high_samples/bugs/sample_barrel.rb +13 -0
  85. data/lib/HDLRuby/high_samples/bugs/sample_daice.rb +57 -0
  86. data/lib/HDLRuby/high_samples/bugs/sample_kumiawase.rb +52 -0
  87. data/lib/HDLRuby/high_samples/bugs/sample_multi.rb +18 -0
  88. data/lib/HDLRuby/high_samples/bugs/sample_sub.rb +14 -0
  89. data/lib/HDLRuby/high_samples/bugs/z2.rb +32 -0
  90. data/lib/HDLRuby/high_samples/case.rb +32 -0
  91. data/lib/HDLRuby/high_samples/case2.rb +30 -0
  92. data/lib/HDLRuby/high_samples/change.rb +23 -0
  93. data/lib/HDLRuby/high_samples/clocks.rb +35 -0
  94. data/lib/HDLRuby/high_samples/comparer.rb +21 -0
  95. data/lib/HDLRuby/high_samples/conditionals.rb +29 -0
  96. data/lib/HDLRuby/high_samples/dff.rb +23 -0
  97. data/lib/HDLRuby/high_samples/each.rb +28 -0
  98. data/lib/HDLRuby/high_samples/exporter.rb +42 -0
  99. data/lib/HDLRuby/high_samples/functions.rb +60 -0
  100. data/lib/HDLRuby/high_samples/if_seq.rb +26 -0
  101. data/lib/HDLRuby/high_samples/inherit_as_dff.rb +32 -0
  102. data/lib/HDLRuby/high_samples/inherit_dff.rb +36 -0
  103. data/lib/HDLRuby/high_samples/instance.rb +37 -0
  104. data/lib/HDLRuby/high_samples/memory.rb +64 -0
  105. data/lib/HDLRuby/high_samples/multi_file.rb +27 -0
  106. data/lib/HDLRuby/high_samples/overload.rb +32 -0
  107. data/lib/HDLRuby/high_samples/paper_after.rb +49 -0
  108. data/lib/HDLRuby/high_samples/ram.rb +27 -0
  109. data/lib/HDLRuby/high_samples/registers.rb +139 -0
  110. data/lib/HDLRuby/high_samples/rom.rb +23 -0
  111. data/lib/HDLRuby/high_samples/scopeblockname.rb +37 -0
  112. data/lib/HDLRuby/high_samples/scopescope.rb +26 -0
  113. data/lib/HDLRuby/high_samples/shift.rb +31 -0
  114. data/lib/HDLRuby/high_samples/shift2.rb +40 -0
  115. data/lib/HDLRuby/high_samples/simple_instance.rb +31 -0
  116. data/lib/HDLRuby/high_samples/test_all.sh +10 -0
  117. data/lib/HDLRuby/high_samples/typedef.rb +24 -0
  118. data/lib/HDLRuby/high_samples/values.rb +70 -0
  119. data/lib/HDLRuby/high_samples/vector.rb +22 -0
  120. data/lib/HDLRuby/high_samples/with_decoder.rb +30 -0
  121. data/lib/HDLRuby/high_samples/with_fsm.rb +46 -0
  122. data/lib/HDLRuby/high_samples/with_pipe.rb +43 -0
  123. data/lib/HDLRuby/high_samples/with_seq.rb +25 -0
  124. data/lib/HDLRuby/hruby_bstr.rb +1085 -0
  125. data/lib/HDLRuby/hruby_check.rb +317 -0
  126. data/lib/HDLRuby/hruby_db.rb +432 -0
  127. data/lib/HDLRuby/hruby_error.rb +44 -0
  128. data/lib/HDLRuby/hruby_high.rb +4103 -0
  129. data/lib/HDLRuby/hruby_low.rb +4735 -0
  130. data/lib/HDLRuby/hruby_low2c.rb +1986 -0
  131. data/lib/HDLRuby/hruby_low2high.rb +738 -0
  132. data/lib/HDLRuby/hruby_low2seq.rb +248 -0
  133. data/lib/HDLRuby/hruby_low2sym.rb +126 -0
  134. data/lib/HDLRuby/hruby_low2vhd.rb +1437 -0
  135. data/lib/HDLRuby/hruby_low_bool2select.rb +295 -0
  136. data/lib/HDLRuby/hruby_low_cleanup.rb +193 -0
  137. data/lib/HDLRuby/hruby_low_fix_types.rb +437 -0
  138. data/lib/HDLRuby/hruby_low_mutable.rb +1803 -0
  139. data/lib/HDLRuby/hruby_low_resolve.rb +165 -0
  140. data/lib/HDLRuby/hruby_low_skeleton.rb +129 -0
  141. data/lib/HDLRuby/hruby_low_with_bool.rb +141 -0
  142. data/lib/HDLRuby/hruby_low_with_port.rb +167 -0
  143. data/lib/HDLRuby/hruby_low_with_var.rb +302 -0
  144. data/lib/HDLRuby/hruby_low_without_bit2vector.rb +88 -0
  145. data/lib/HDLRuby/hruby_low_without_concat.rb +162 -0
  146. data/lib/HDLRuby/hruby_low_without_connection.rb +113 -0
  147. data/lib/HDLRuby/hruby_low_without_namespace.rb +718 -0
  148. data/lib/HDLRuby/hruby_low_without_outread.rb +107 -0
  149. data/lib/HDLRuby/hruby_low_without_select.rb +206 -0
  150. data/lib/HDLRuby/hruby_serializer.rb +398 -0
  151. data/lib/HDLRuby/hruby_tools.rb +37 -0
  152. data/lib/HDLRuby/hruby_types.rb +239 -0
  153. data/lib/HDLRuby/hruby_values.rb +64 -0
  154. data/lib/HDLRuby/hruby_verilog.rb +1888 -0
  155. data/lib/HDLRuby/hruby_verilog_name.rb +52 -0
  156. data/lib/HDLRuby/low_samples/adder.yaml +97 -0
  157. data/lib/HDLRuby/low_samples/after.yaml +228 -0
  158. data/lib/HDLRuby/low_samples/before.yaml +223 -0
  159. data/lib/HDLRuby/low_samples/blockblock.yaml +48 -0
  160. data/lib/HDLRuby/low_samples/bugs/sample_add.yaml +97 -0
  161. data/lib/HDLRuby/low_samples/bugs/sample_daice.yaml +444 -0
  162. data/lib/HDLRuby/low_samples/bugs/sample_kumiawase.yaml +332 -0
  163. data/lib/HDLRuby/low_samples/bugs/sample_sub.yaml +97 -0
  164. data/lib/HDLRuby/low_samples/bugs/seqpar.yaml +184 -0
  165. data/lib/HDLRuby/low_samples/case.yaml +327 -0
  166. data/lib/HDLRuby/low_samples/change.yaml +135 -0
  167. data/lib/HDLRuby/low_samples/clocks.yaml +674 -0
  168. data/lib/HDLRuby/low_samples/cloner.rb +22 -0
  169. data/lib/HDLRuby/low_samples/comparer.yaml +85 -0
  170. data/lib/HDLRuby/low_samples/conditionals.yaml +133 -0
  171. data/lib/HDLRuby/low_samples/dff.yaml +107 -0
  172. data/lib/HDLRuby/low_samples/each.yaml +1328 -0
  173. data/lib/HDLRuby/low_samples/exporter.yaml +226 -0
  174. data/lib/HDLRuby/low_samples/functions.yaml +298 -0
  175. data/lib/HDLRuby/low_samples/generic_transmission.yaml +597 -0
  176. data/lib/HDLRuby/low_samples/inherit_as_dff.yaml +125 -0
  177. data/lib/HDLRuby/low_samples/inherit_dff.yaml +107 -0
  178. data/lib/HDLRuby/low_samples/load_yaml.rb +11 -0
  179. data/lib/HDLRuby/low_samples/memory.yaml +678 -0
  180. data/lib/HDLRuby/low_samples/namespace_extractor.rb +23 -0
  181. data/lib/HDLRuby/low_samples/overload.yaml +226 -0
  182. data/lib/HDLRuby/low_samples/paper_after.yaml +431 -0
  183. data/lib/HDLRuby/low_samples/port_maker.rb +14 -0
  184. data/lib/HDLRuby/low_samples/ram.yaml +207 -0
  185. data/lib/HDLRuby/low_samples/registers.yaml +228 -0
  186. data/lib/HDLRuby/low_samples/rom.yaml +2950 -0
  187. data/lib/HDLRuby/low_samples/shift.yaml +230 -0
  188. data/lib/HDLRuby/low_samples/shift2.yaml +2095 -0
  189. data/lib/HDLRuby/low_samples/simple_instance.yaml +102 -0
  190. data/lib/HDLRuby/low_samples/test_all.sh +43 -0
  191. data/lib/HDLRuby/low_samples/typedef.yaml +115 -0
  192. data/lib/HDLRuby/low_samples/values.yaml +577 -0
  193. data/lib/HDLRuby/low_samples/variable_maker.rb +14 -0
  194. data/lib/HDLRuby/low_samples/vector.yaml +56 -0
  195. data/lib/HDLRuby/low_samples/with_seq.yaml +188 -0
  196. data/lib/HDLRuby/low_samples/yaml2hdr.rb +10 -0
  197. data/lib/HDLRuby/low_samples/yaml2vhd.rb +19 -0
  198. data/lib/HDLRuby/sim/Makefile +19 -0
  199. data/lib/HDLRuby/sim/hruby_sim.h +590 -0
  200. data/lib/HDLRuby/sim/hruby_sim_calc.c +2362 -0
  201. data/lib/HDLRuby/sim/hruby_sim_core.c +589 -0
  202. data/lib/HDLRuby/sim/hruby_sim_list.c +93 -0
  203. data/lib/HDLRuby/sim/hruby_sim_vizualize.c +91 -0
  204. data/lib/HDLRuby/sim/hruby_value_pool.c +64 -0
  205. data/lib/HDLRuby/std/channel.rb +354 -0
  206. data/lib/HDLRuby/std/clocks.rb +165 -0
  207. data/lib/HDLRuby/std/counters.rb +82 -0
  208. data/lib/HDLRuby/std/decoder.rb +214 -0
  209. data/lib/HDLRuby/std/fsm.rb +516 -0
  210. data/lib/HDLRuby/std/pipeline.rb +220 -0
  211. data/lib/HDLRuby/std/reconf.rb +309 -0
  212. data/lib/HDLRuby/test_hruby_bstr.rb +2259 -0
  213. data/lib/HDLRuby/test_hruby_high.rb +594 -0
  214. data/lib/HDLRuby/test_hruby_high_low.rb +99 -0
  215. data/lib/HDLRuby/test_hruby_low.rb +934 -0
  216. data/lib/HDLRuby/v_samples/adder.v +10 -0
  217. data/lib/HDLRuby/v_samples/dff.v +12 -0
  218. data/lib/HDLRuby/v_samples/ram.v +20 -0
  219. data/lib/HDLRuby/v_samples/rom.v +270 -0
  220. data/lib/HDLRuby/version.rb +3 -0
  221. data/lib/HDLRuby.rb +11 -0
  222. data/makedoc +1 -0
  223. data/metadata.yaml +4 -0
  224. metadata +299 -0
@@ -0,0 +1,516 @@
1
+ module HDLRuby::High::Std
2
+
3
+ ##
4
+ # Standard HDLRuby::High library: fsm generator.
5
+ #
6
+ ########################################################################
7
+
8
+
9
+ ##
10
+ # Describes a high-level fsm type.
11
+ class FsmT
12
+ include HDLRuby::High::HScope_missing
13
+
14
+ # The state class
15
+ class State
16
+ attr_accessor :value, :name, :code, :gotos
17
+ end
18
+
19
+ # The name of the FSM type.
20
+ attr_reader :name
21
+
22
+ # The namespace associated with the FSM
23
+ attr_reader :namespace
24
+
25
+ # The reset codes for the synchronous and the asynchronous operative
26
+ # parts of the fsm
27
+ attr_reader :reset_sync, :reset_async
28
+
29
+ # The current and next state signals.
30
+ attr_accessor :cur_state_sig, :next_state_sig, :work_state
31
+
32
+ # Creates a new fsm type with +name+.
33
+ # +options+ allows to specify the type of fsm:
34
+ # synchronous (default) / asynchronous and
35
+ # mono-front(default) / dual front
36
+ def initialize(name,*options)
37
+ # Check and set the name
38
+ @name = name.to_sym
39
+ # Check and set the type of fsm depending of the options.
40
+ @dual = false
41
+ @type = :sync
42
+ options.each do |opt|
43
+ case opt
44
+ when :sync,:synchronous then
45
+ @type = :sync
46
+ when :async, :asynchronous then
47
+ @type = :async
48
+ when :dual then
49
+ @dual = true
50
+ else
51
+ raise AnyError, "Invalid option for a fsm: :#{type}"
52
+ end
53
+ end
54
+
55
+ # Initialize the internals of the FSM.
56
+
57
+
58
+ # Initialize the environment for building the FSM
59
+
60
+ # The main states.
61
+ @states = []
62
+
63
+ # The extra synchronous states.
64
+ @extra_syncs = []
65
+ # The extra asynchronous states.
66
+ @extra_asyncs = []
67
+
68
+ # The default code of the operative part.
69
+ @default_codes = []
70
+
71
+ # The current and next state signals
72
+ @cur_state_sig = nil
73
+ @next_state_sig = nil
74
+
75
+ # The event synchronizing the fsm
76
+ @mk_ev = proc { $clk.posedge }
77
+
78
+ # The reset check.
79
+ @mk_rst = proc { $rst }
80
+
81
+ # The code executed in case of reset.
82
+ # (By default, nothing).
83
+ @reset_sync = nil
84
+ @reset_async = nil
85
+
86
+ # Creates the namespace to execute the fsm block in.
87
+ @namespace = Namespace.new(self)
88
+
89
+ # Generates the function for setting up the fsm
90
+ # provided there is a name.
91
+ obj = self # For using the right self within the proc
92
+ HDLRuby::High.space_reg(@name) do |&ruby_block|
93
+ if ruby_block then
94
+ # Builds the fsm.
95
+ obj.build(&ruby_block)
96
+ else
97
+ # Return the fsm as is.
98
+ return obj
99
+ end
100
+ end unless name.empty?
101
+
102
+ end
103
+
104
+ ## builds the fsm by executing +ruby_block+.
105
+ def build(&ruby_block)
106
+ # Use local variable for accessing the attribute since they will
107
+ # be hidden when opening the sytem.
108
+ states = @states
109
+ namespace = @namespace
110
+ this = self
111
+ mk_ev = @mk_ev
112
+ mk_rst = @mk_rst
113
+ type = @type
114
+ dual = @dual
115
+ extra_syncs = @extra_syncs
116
+ extra_asyncs = @extra_asyncs
117
+ default_codes = @default_codes
118
+
119
+ return_value = nil
120
+
121
+ # Enters the current system
122
+ HDLRuby::High.cur_system.open do
123
+ sub do
124
+ HDLRuby::High.space_push(namespace)
125
+ # Execute the instantiation block
126
+ return_value =HDLRuby::High.top_user.instance_exec(&ruby_block)
127
+
128
+ # Expands the extra state processing so that al all the
129
+ # parts of the state machine are in par (clear synthesis).
130
+ [extra_syncs,extra_asyncs].each do |extras|
131
+ # Set the values of the extra states from their name.
132
+ extras.each do |extra|
133
+ st = states.find {|st| st.name == extra.name }
134
+ unless st then
135
+ raise "Unknown state name: #{extra.name}"
136
+ end
137
+ extra.value = st.value
138
+ end
139
+ # Fills the holes in the extra syncs and asyncs.
140
+ if extras.any? then
141
+ # Sort by value in a new array using counter sort.
142
+ results = [ nil ] * states.size
143
+ extras.each {|st| results[st.value] = st }
144
+ # Fill the whole with empty states.
145
+ results.map!.with_index do |st,i|
146
+ unless st then
147
+ st = State.new
148
+ st.value = i
149
+ st.code = proc {}
150
+ end
151
+ st
152
+ end
153
+ # Replace the content of extras
154
+ extras.clear
155
+ results.each {|st| extras << st }
156
+ end
157
+ end
158
+
159
+ # Create the state register.
160
+ name = HDLRuby.uniq_name
161
+ # Declare the state register.
162
+ this.cur_state_sig = [states.size.width].inner(name)
163
+ # Declare the next state wire.
164
+ name = HDLRuby.uniq_name
165
+ this.next_state_sig = [states.size.width].inner(name)
166
+
167
+ # Create the fsm code
168
+
169
+ # Control part: update of the state.
170
+ par(mk_ev.call) do
171
+ hif(mk_rst.call) do
172
+ # Reset: current state is to put to 0.
173
+ this.cur_state_sig <= 0
174
+ end
175
+ helse do
176
+ # No reset: current state is updated with
177
+ # next state value.
178
+ this.cur_state_sig <= this.next_state_sig
179
+ end
180
+ end
181
+
182
+ # Operative main-part: one case per state.
183
+ # (clock-dependent if synchronous mode).
184
+ if type == :sync then
185
+ # Synchronous case.
186
+ event = mk_ev.call
187
+ event = event.invert if dual
188
+ else
189
+ # Asynchronous case: no event required.
190
+ event = []
191
+ end
192
+ # The process
193
+ par(*event) do
194
+ # The operative code.
195
+ oper_code = proc do
196
+ # The default code.
197
+ default_codes.each(&:call)
198
+ # Depending on the state.
199
+ hcase(this.cur_state_sig)
200
+ states.each do |st|
201
+ # Register the working state (for the gotos)
202
+ this.work_state = st
203
+ hwhen(st.value) do
204
+ # Generate the content of the state.
205
+ st.code.call
206
+ end
207
+ end
208
+ end
209
+ # Is there reset code?
210
+ if type == :sync and this.reset_sync then
211
+ # Yes in case of synchronous fsm,
212
+ # use it before the operative code.
213
+ hif(mk_rst.call) do
214
+ this.reset_sync.call
215
+ end
216
+ helse(&oper_code)
217
+ elsif type == :async and this.reset_async then
218
+ # Yes in case of asynchronous fsm,
219
+ # use it before the operative code.
220
+ hif(mk_rst.call) do
221
+ this.reset_async.call
222
+ end
223
+ helse(&oper_code)
224
+ else
225
+ # Use only the operative code.
226
+ oper_code.call
227
+ end
228
+ end
229
+
230
+ # Control part: computation of the next state.
231
+ # (clock-independent)
232
+ hcase(this.cur_state_sig)
233
+ states.each do |st|
234
+ hwhen(st.value) do
235
+ if st.gotos.any? then
236
+ # Gotos were present, use them.
237
+ st.gotos.each(&:call)
238
+ else
239
+ # No gotos, by default the next step is
240
+ # current + 1
241
+ # this.next_state_sig <= mux(mk_rst.call , 0, this.cur_state_sig + 1)
242
+ this.next_state_sig <= this.cur_state_sig + 1
243
+ end
244
+ end
245
+ end
246
+ # By default set the next state to 0.
247
+ helse do
248
+ this.next_state_sig <= 0
249
+ end
250
+
251
+ # Operative additional parts.
252
+ # Extra synchronous operative part.
253
+ if extra_syncs.any? then
254
+ event = mk_ev.call
255
+ event = event.invert if @dual
256
+ # The extra code.
257
+ par(*event) do
258
+ # Build the extra synchronous part.
259
+ sync_code = proc do
260
+ hcase(this.cur_state_sig)
261
+ extra_syncs.each do |st|
262
+ hwhen(st.value) do
263
+ # Generate the content of the state.
264
+ st.code.call
265
+ end
266
+ end
267
+ end
268
+ # Place it.
269
+ if this.reset_sync then
270
+ # There some synchronous reset code, use
271
+ # it.
272
+ hif(mk_rst.call) do
273
+ this.reset_sync.call
274
+ end
275
+ helse(&sync_code)
276
+ else
277
+ # No syncrhonous code, place the extra
278
+ # synchronous states as is.
279
+ sync_code.call
280
+ end
281
+ end
282
+ end
283
+
284
+ # Extra asynchronous operative part.
285
+ if extra_asyncs.any? then
286
+ par do
287
+ # Build the extra synchronous part.
288
+ async_code = proc do
289
+ hcase(this.cur_state_sig)
290
+ extra_asyncs.each do |st|
291
+ hwhen(st.value) do
292
+ # Generate the content of the state.
293
+ st.code.call
294
+ end
295
+ end
296
+ end
297
+ # Place it with possible reset.
298
+ if this.reset_async then
299
+ # There some synchronous reset code, use
300
+ # it.
301
+ hif(mk_rst.call) do
302
+ this.reset_async.call
303
+ end
304
+ helse(&sync_code)
305
+ else
306
+ # No syncrhonous code, place the extra
307
+ # synchronous states as is.
308
+ sync_code.call
309
+ end
310
+ end
311
+ end
312
+
313
+ HDLRuby::High.space_pop
314
+ end
315
+ end
316
+
317
+ return return_value
318
+ end
319
+
320
+
321
+ ## The interface for building the fsm
322
+
323
+ # Sets the event synchronizing the fsm.
324
+ def for_event(event = nil,&ruby_block)
325
+ if event then
326
+ # An event is passed as argument, use it.
327
+ @mk_ev = proc { event.to_event }
328
+ else
329
+ # No event given, use the ruby_block as event generator.
330
+ @mk_ev = ruby_block
331
+ end
332
+ end
333
+
334
+ # Sets the reset.
335
+ def for_reset(reset = nil,&ruby_block)
336
+ if reset then
337
+ # An reset is passed as argument, use it.
338
+ @mk_rst = proc { reset.to_expr }
339
+ else
340
+ # No reset given, use the ruby_block as event generator.
341
+ @mk_rst = ruby_block
342
+ end
343
+ end
344
+
345
+ # Adds a code to be executed in case of reset.
346
+ # +type+ indicates if it is the synchronous part or the
347
+ # asynchronous part that is to reset.
348
+ def reset(type = @type,&ruby_block)
349
+ if type == :sync or type == :synchronous then
350
+ # Reset of the synchronous part.
351
+ if @reset_sync then
352
+ raise AnyError.new("Reset of the synchronous part already declared.")
353
+ end
354
+ @reset_sync = ruby_block
355
+ elsif type == :async or type == :asynchronous then
356
+ # Reset if the asynchronous part.
357
+ if @reset_async then
358
+ raise AnyError.new("Reset of the asynchronosu part already declared.")
359
+ end
360
+ else
361
+ raise AnyError.new("Invalid fsm type for declaring a reset code: #{type}")
362
+ end
363
+ end
364
+
365
+ # Adds a default operative code.
366
+ def default(&ruby_block)
367
+ @default_codes << ruby_block
368
+ end
369
+
370
+ # Declares a new state with +name+ and executing +ruby_block+.
371
+ def state(name = :"", &ruby_block)
372
+ # Create the resulting state
373
+ result = State.new
374
+ # Its value is the current number of states
375
+ result.value = @states.size
376
+ result.name = name.to_sym
377
+ result.code = ruby_block
378
+ result.gotos = []
379
+ # Add it to the list of states.
380
+ @states << result
381
+ # Return it.
382
+ return result
383
+ end
384
+
385
+ # Declares an extra synchronous code to execute for state +name+.
386
+ def sync(name, &ruby_block)
387
+ # Create the resulting state.
388
+ result = State.new
389
+ result.name = name.to_sym
390
+ result.code = ruby_block
391
+ # Add it to the lis of extra synchronous states.
392
+ @extra_syncs << result
393
+ # Return it
394
+ return result
395
+ end
396
+
397
+ # Declares an extra asynchronous code to execute for state +name+.
398
+ def async(name, &ruby_block)
399
+ # Create the resulting state.
400
+ result = State.new
401
+ result.name = name.to_sym
402
+ result.code = ruby_block
403
+ # Add it to the lis of extra synchronous states.
404
+ @extra_asyncs << result
405
+ # Return it
406
+ return result
407
+ end
408
+
409
+ # Sets the next state. Arguments can be:
410
+ #
411
+ # +name+: the name of the next state.
412
+ # +expr+, +names+: an expression with the list of the next statements
413
+ # in order of the value of the expression, the last
414
+ # one being necesserily the default case.
415
+ def goto(*args)
416
+ # Make reference to the fsm attributes.
417
+ next_state_sig = @next_state_sig
418
+ states = @states
419
+ # Add the code of the goto to the working state.
420
+ @work_state.gotos << proc do
421
+ # Depending on the first argument type.
422
+ unless args[0].is_a?(Symbol) then
423
+ # expr + names arguments.
424
+ # Get the predicate
425
+ pred = args.shift
426
+ # hif or hcase?
427
+ if args.size <= 2 then
428
+ # 2 or less cases, generate an hif
429
+ arg = args.shift
430
+ hif(pred) do
431
+ next_state_sig <=
432
+ (states.detect { |st| st.name == arg }).value
433
+ end
434
+ arg = args.shift
435
+ if arg then
436
+ # There is an else.
437
+ helse do
438
+ next_state_sig <=
439
+ (states.detect { |st| st.name == arg }).value
440
+ end
441
+ end
442
+ else
443
+ # More than 2, generate a hcase
444
+ hcase (pred)
445
+ args[0..-2].each.with_index do |arg,i|
446
+ # Ensure the argument is a symbol.
447
+ arg = arg.to_sym
448
+ # Make the when statement.
449
+ hwhen(i) do
450
+ next_state_sig <=
451
+ (states.detect { |st| st.name == arg }).value
452
+ end
453
+ end
454
+ # The last name is the default case.
455
+ # Ensure it is a symbol.
456
+ arg = args[-1].to_sym
457
+ # Make the default statement.
458
+ helse do
459
+ next_state_sig <=
460
+ (states.detect { |st| st.name == arg }).value
461
+ end
462
+ end
463
+ else
464
+ # single name argument, check it.
465
+ raise AnyError, "Invalid argument for a goto: if no expression is given only a single name can be used." if args.size > 1
466
+ # Ensure the name is a symbol.
467
+ name = args[0].to_sym
468
+ # Get the state with name.
469
+ next_state_sig <= (states.detect { |st| st.name == name }).value
470
+ end
471
+ end
472
+ end
473
+
474
+ end
475
+
476
+
477
+ ## Declare a new fsm.
478
+ # The arguments can be any of (but in this order):
479
+ #
480
+ # - +name+:: name.
481
+ # - +clk+:: clock.
482
+ # - +event+:: clock event.
483
+ # - +rst+:: reset. (must be declared AFTER clock or clock event).
484
+ #
485
+ # If provided, +ruby_block+ the fsm is directly instantiated with it.
486
+ def fsm(*args, &ruby_block)
487
+ # Sets the name if any
488
+ unless args[0].respond_to?(:to_event) then
489
+ name = args.shift.to_sym
490
+ else
491
+ name = :""
492
+ end
493
+ # Get the options from the arguments.
494
+ options, args = args.partition {|arg| arg.is_a?(Symbol) }
495
+ # Create the fsm.
496
+ fsmI = FsmT.new(name,*options)
497
+
498
+ # Process the clock event if any.
499
+ unless args.empty? then
500
+ fsmI.for_event(args.shift)
501
+ end
502
+ # Process the reset if any.
503
+ unless args.empty? then
504
+ fsmI.for_reset(args.shift)
505
+ end
506
+ # Is there a ruby block?
507
+ if ruby_block then
508
+ # Yes, generate the fsm.
509
+ fsmI.build(&ruby_block)
510
+ else
511
+ # No return the fsm structure for later generation.
512
+ return fsmI
513
+ end
514
+ end
515
+
516
+ end