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,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