HDLRuby 2.11.12 → 3.1.0
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.
- checksums.yaml +4 -4
- data/README.html +3274 -0
- data/README.md +660 -128
- data/ext/hruby_sim/hruby_sim_calc.c +2 -0
- data/lib/HDLRuby/backend/hruby_allocator.rb +2 -2
- data/lib/HDLRuby/backend/hruby_c_allocator.rb +7 -7
- data/lib/HDLRuby/hdr_samples/constant_in_function.rb +2 -1
- data/lib/HDLRuby/hdr_samples/mei8_bench.rb +1 -1
- data/lib/HDLRuby/hdr_samples/with_bram.rb +3 -3
- data/lib/HDLRuby/hdr_samples/with_bram_frame_stack.rb +105 -0
- data/lib/HDLRuby/hdr_samples/with_bram_stack.rb +69 -0
- data/lib/HDLRuby/hdr_samples/with_ref_expr.rb +30 -0
- data/lib/HDLRuby/hdr_samples/with_sequencer.rb +185 -0
- data/lib/HDLRuby/hdr_samples/with_sequencer_deep.rb +91 -0
- data/lib/HDLRuby/hdr_samples/with_sequencer_enumerable.rb +439 -0
- data/lib/HDLRuby/hdr_samples/with_sequencer_enumerator.rb +89 -0
- data/lib/HDLRuby/hdr_samples/with_sequencer_func.rb +63 -0
- data/lib/HDLRuby/hdr_samples/with_sequencer_sync.rb +120 -0
- data/lib/HDLRuby/hdrcc.rb +16 -3
- data/lib/HDLRuby/hdrlib.rb +1 -1
- data/lib/HDLRuby/hruby_db.rb +2 -2
- data/lib/HDLRuby/hruby_high.rb +61 -25
- data/lib/HDLRuby/hruby_high_fullname.rb +3 -1
- data/lib/HDLRuby/hruby_low.rb +2 -2
- data/lib/HDLRuby/hruby_low2c.rb +58 -43
- data/lib/HDLRuby/hruby_low2hdr.rb +66 -40
- data/lib/HDLRuby/hruby_low2high.rb +86 -44
- data/lib/HDLRuby/hruby_low2seq.rb +26 -18
- data/lib/HDLRuby/hruby_low2sym.rb +14 -13
- data/lib/HDLRuby/hruby_low2vhd.rb +78 -43
- data/lib/HDLRuby/hruby_low_bool2select.rb +61 -46
- data/lib/HDLRuby/hruby_low_casts_without_expression.rb +56 -44
- data/lib/HDLRuby/hruby_low_cleanup.rb +18 -16
- data/lib/HDLRuby/hruby_low_fix_types.rb +64 -32
- data/lib/HDLRuby/hruby_low_mutable.rb +53 -118
- data/lib/HDLRuby/hruby_low_resolve.rb +26 -31
- data/lib/HDLRuby/hruby_low_with_bool.rb +33 -16
- data/lib/HDLRuby/hruby_low_with_port.rb +3 -3
- data/lib/HDLRuby/hruby_low_with_var.rb +23 -9
- data/lib/HDLRuby/hruby_low_without_concat.rb +19 -13
- data/lib/HDLRuby/hruby_low_without_namespace.rb +47 -32
- data/lib/HDLRuby/hruby_low_without_parinseq.rb +18 -12
- data/lib/HDLRuby/hruby_low_without_select.rb +36 -23
- data/lib/HDLRuby/hruby_low_without_subsignals.rb +79 -39
- data/lib/HDLRuby/hruby_rcsim.rb +79 -64
- data/lib/HDLRuby/hruby_rsim.rb +64 -15
- data/lib/HDLRuby/hruby_rsim_mute.rb +2 -3
- data/lib/HDLRuby/hruby_rsim_vcd.rb +28 -25
- data/lib/HDLRuby/hruby_types.rb +5 -5
- data/lib/HDLRuby/hruby_values.rb +19 -8
- data/lib/HDLRuby/hruby_verilog.rb +191 -65
- data/lib/HDLRuby/hruby_verilog_name.rb +49 -42
- data/lib/HDLRuby/soft/stacks.rb +219 -0
- data/lib/HDLRuby/std/bram.rb +9 -5
- data/lib/HDLRuby/std/clocks.rb +1 -1
- data/lib/HDLRuby/std/fsm.rb +39 -10
- data/lib/HDLRuby/std/sequencer.rb +2085 -0
- data/lib/HDLRuby/std/sequencer_func.rb +533 -0
- data/lib/HDLRuby/std/sequencer_sync.rb +400 -0
- data/lib/HDLRuby/std/std.rb +13 -0
- data/lib/HDLRuby/version.rb +1 -1
- data/tuto/adder_sat_flags_vcd.png +0 -0
- data/tuto/addsub_vcd.png +0 -0
- data/tuto/alu_vcd.png +0 -0
- data/tuto/bit_pong_vcd.png +0 -0
- data/tuto/checksum_vcd.png +0 -0
- data/tuto/circuit_hdr.odg +0 -0
- data/tuto/circuit_hdr.png +0 -0
- data/tuto/circuit_hie.odg +0 -0
- data/tuto/circuit_hie.png +0 -0
- data/tuto/circuit_view.odg +0 -0
- data/tuto/circuit_view.png +0 -0
- data/tuto/clock_counter_vcd.png +0 -0
- data/tuto/counter_ext_vcd.png +0 -0
- data/tuto/fact_vcd.png +0 -0
- data/tuto/hw_flow.odg +0 -0
- data/tuto/hw_flow.png +0 -0
- data/tuto/maxxer_vcd.png +0 -0
- data/tuto/pingpong0_vcd.png +0 -0
- data/tuto/pingpong1_vcd.png +0 -0
- data/tuto/pingpong2_vcd.png +0 -0
- data/tuto/ram_vcd.png +0 -0
- data/tuto/serializer_vcd.png +0 -0
- data/tuto/sw_flow.odg +0 -0
- data/tuto/sw_flow.png +0 -0
- data/tuto/the_counter_vcd.png +0 -0
- data/tuto/tutorial_sw.html +2359 -0
- data/tuto/tutorial_sw.md +2890 -0
- data/tuto/tutorial_sw.pdf +0 -0
- data/tuto/tutorial_sw_jp.md +417 -0
- metadata +46 -2
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
require 'std/bram'
|
|
2
|
+
|
|
3
|
+
module HDLRuby::High::Soft
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# Declare the possible commands for the stack.
|
|
7
|
+
PUSH = 0 # Pushes the value of input din into the stack.
|
|
8
|
+
POP = 1 # Pops din values for the stack. If din is negative, allocates din elements on the stack.
|
|
9
|
+
READ = 2 # Read the value address din and output it on dout.
|
|
10
|
+
WRITE = 3 # Write the value at the top of the stack at address din.
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# Describe a stack based on a BRAM (compatible with FPGA's)
|
|
17
|
+
# - 'widthD': data bit width
|
|
18
|
+
# - 'size' : the size of the stack
|
|
19
|
+
system :bram_stack do |widthD, size|
|
|
20
|
+
# Compute the address width.
|
|
21
|
+
widthA = (size-1).width
|
|
22
|
+
|
|
23
|
+
# Compute the bit width of the stack pointer register.
|
|
24
|
+
widthS = (size+1).width
|
|
25
|
+
|
|
26
|
+
# Declare the inputs and outputs.
|
|
27
|
+
input :clk, :rst, :ce
|
|
28
|
+
input :cmd
|
|
29
|
+
[widthD].input :din
|
|
30
|
+
[widthD].output :dout
|
|
31
|
+
output :empty, :full
|
|
32
|
+
|
|
33
|
+
# Declare the BRAM containing the stack data.
|
|
34
|
+
inner rwb: 1
|
|
35
|
+
[widthA].inner :addr
|
|
36
|
+
[widthD].inner :brin, :brout
|
|
37
|
+
bram(widthA,widthD).(:bramI).(clk,rwb,addr,brin,brout)
|
|
38
|
+
|
|
39
|
+
# Declare the stack pointer register and the top of stack value.
|
|
40
|
+
[widthS].inner sp: size
|
|
41
|
+
[widthD].inner :top
|
|
42
|
+
|
|
43
|
+
# Tells if the stack is empty or full.
|
|
44
|
+
empty <= (sp == size)
|
|
45
|
+
full <= (sp == 0)
|
|
46
|
+
|
|
47
|
+
# The output bus is the top of the stack.
|
|
48
|
+
dout <= top
|
|
49
|
+
|
|
50
|
+
# The clock process handling the access.
|
|
51
|
+
seq(clk.posedge) do
|
|
52
|
+
# By default, read before the top of the memory.
|
|
53
|
+
rwb <= 1
|
|
54
|
+
hif(rst) do
|
|
55
|
+
# sp is set to size (stack empty).
|
|
56
|
+
sp <= size
|
|
57
|
+
top <= 0
|
|
58
|
+
end
|
|
59
|
+
helsif(ce) do
|
|
60
|
+
# Now depending on the command.
|
|
61
|
+
hcase(cmd)
|
|
62
|
+
hwhen(PUSH) do
|
|
63
|
+
# Is the stack full?
|
|
64
|
+
hif(~full) do
|
|
65
|
+
# No, can push onto the stack.
|
|
66
|
+
# Update the top register.
|
|
67
|
+
top <= din
|
|
68
|
+
# Update the bram.
|
|
69
|
+
brin <= din
|
|
70
|
+
rwb <= 0
|
|
71
|
+
# Finally, decrease sp.
|
|
72
|
+
sp <= sp - 1
|
|
73
|
+
# The address is the top of the stack
|
|
74
|
+
addr <= sp
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
hwhen(POP) do
|
|
78
|
+
# Is the stack empty?
|
|
79
|
+
hif(~empty) do
|
|
80
|
+
# No, can pop from the stack.
|
|
81
|
+
# Update the top register.
|
|
82
|
+
top <= brout
|
|
83
|
+
# Finally, increase sp.
|
|
84
|
+
sp <= sp + 1
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
hif(~ce | cmd != PUSH) do
|
|
89
|
+
# By default the address is the top of the stack + 1
|
|
90
|
+
addr <= sp + 1
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
# Describe a frame stack based on a BRAM (compatible with FPGA's)
|
|
98
|
+
# - 'widthD': data bit width
|
|
99
|
+
# - 'size' : the size of the stack
|
|
100
|
+
# - 'depth' : the maximum number of frames.
|
|
101
|
+
system :bram_frame_stack do |widthD, size, depth|
|
|
102
|
+
# Compute the address width.
|
|
103
|
+
widthA = (size-1).width
|
|
104
|
+
|
|
105
|
+
# Compute the bit width of the frame pointers.
|
|
106
|
+
widthF = (size+1).width
|
|
107
|
+
|
|
108
|
+
# compute the bit width of the frame stack pointer.
|
|
109
|
+
widthS = (depth+1).width
|
|
110
|
+
|
|
111
|
+
# Create the type used for accessing the frame stack.
|
|
112
|
+
typedef(:locT) { { frame: bit[widthS], offset: bit[widthF] } }
|
|
113
|
+
|
|
114
|
+
# Declare the inputs and outputs.
|
|
115
|
+
input :clk, :rst, :ce
|
|
116
|
+
[2].input :cmd
|
|
117
|
+
locT.input :loc
|
|
118
|
+
[widthD].input :din
|
|
119
|
+
[widthD].output :dout
|
|
120
|
+
output :empty, :full
|
|
121
|
+
|
|
122
|
+
# Declare the frame index stac pointer.
|
|
123
|
+
[widthS].inner :sp
|
|
124
|
+
|
|
125
|
+
# Declare the frame index table.
|
|
126
|
+
bit[widthF][-depth].inner :indexes
|
|
127
|
+
|
|
128
|
+
# Declare the BRAM containing the frames data.
|
|
129
|
+
inner rwb: 1
|
|
130
|
+
[widthA].inner :addr
|
|
131
|
+
[widthD].inner :brin, :brout
|
|
132
|
+
bram(widthA,widthD).(:bramI).(clk,rwb,addr,brin,brout)
|
|
133
|
+
|
|
134
|
+
# Tells if the stack is empty or full.
|
|
135
|
+
empty <= (sp == depth)
|
|
136
|
+
full <= (sp == 0)
|
|
137
|
+
|
|
138
|
+
# The input data is always the input of the bram.
|
|
139
|
+
brin <= din
|
|
140
|
+
|
|
141
|
+
# The output is always the output of the bram.
|
|
142
|
+
dout <= brout
|
|
143
|
+
|
|
144
|
+
# The clock process handling the access.
|
|
145
|
+
seq(clk.posedge) do
|
|
146
|
+
# By default, read before the top of the memory.
|
|
147
|
+
rwb <= 1
|
|
148
|
+
hif(rst) do
|
|
149
|
+
# sp is set to depth (stack empty).
|
|
150
|
+
sp <= depth
|
|
151
|
+
end
|
|
152
|
+
helsif(ce) do
|
|
153
|
+
# Now depending on the command.
|
|
154
|
+
hcase(cmd)
|
|
155
|
+
hwhen(PUSH) do
|
|
156
|
+
# Is the stack full or is the frame to push empty?
|
|
157
|
+
hif(~(full | loc.offset == 0)) do
|
|
158
|
+
# No, we can proceed.
|
|
159
|
+
# Decrease sp.
|
|
160
|
+
sp <= sp - 1
|
|
161
|
+
# Adds the frame.
|
|
162
|
+
hif(~empty) do
|
|
163
|
+
indexes[sp] <= loc.offset + indexes[sp+1]
|
|
164
|
+
end
|
|
165
|
+
helse do
|
|
166
|
+
indexes[sp] <= loc.offset
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
hwhen(POP) do
|
|
171
|
+
# Is the stack empty?
|
|
172
|
+
hif(~empty) do
|
|
173
|
+
# No, can pop a frame from the stack.
|
|
174
|
+
# Increase sp.
|
|
175
|
+
sp <= sp + 1
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
hwhen(READ) do
|
|
179
|
+
# Read access, is the frame valid?
|
|
180
|
+
cur_frame = sp+loc.frame
|
|
181
|
+
hif (~(empty | cur_frame >= depth)) do
|
|
182
|
+
# The frame is valid. Is the offset valid?
|
|
183
|
+
addr_calc = indexes[cur_frame] - loc.offset - 1
|
|
184
|
+
hif ((cur_frame < depth-1) &
|
|
185
|
+
(addr_calc > indexes[cur_frame+1])) do
|
|
186
|
+
# Not the first frame and the address is valid.
|
|
187
|
+
addr <= addr_calc
|
|
188
|
+
end
|
|
189
|
+
helsif ((cur_frame == depth-1) &
|
|
190
|
+
(addr_calc + 1 > 0)) do
|
|
191
|
+
# The first frame and the address is valid.
|
|
192
|
+
addr <= addr_calc
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
hwhen(WRITE) do
|
|
197
|
+
# Write access, is the frame valid?
|
|
198
|
+
cur_frame = sp+loc.frame
|
|
199
|
+
hif (~(empty | cur_frame >= depth)) do
|
|
200
|
+
# The frame is valid. Is the offset valid?
|
|
201
|
+
addr_calc = indexes[cur_frame] - loc.offset - 1
|
|
202
|
+
hif ((cur_frame < depth-1) &
|
|
203
|
+
(addr_calc > indexes[cur_frame+1])) do
|
|
204
|
+
# Not the first frame and the address is valid.
|
|
205
|
+
addr <= addr_calc
|
|
206
|
+
rwb <= 0
|
|
207
|
+
end
|
|
208
|
+
helsif ((cur_frame == depth-1) &
|
|
209
|
+
(addr_calc + 1 > 0)) do
|
|
210
|
+
# The first frame and the address is valid.
|
|
211
|
+
addr <= addr_calc
|
|
212
|
+
rwb <= 0
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
end
|
data/lib/HDLRuby/std/bram.rb
CHANGED
|
@@ -3,18 +3,22 @@ module HDLRuby::High::Std
|
|
|
3
3
|
# Describe a RAM compatibile with BRAM of FPGAs.
|
|
4
4
|
# - 'widthA': address bit width
|
|
5
5
|
# - 'widthD': data bit width
|
|
6
|
-
|
|
6
|
+
# - 'size': the size of the memory.
|
|
7
|
+
system :bram do |widthA, widthD, size = nil|
|
|
8
|
+
# Process size if required.
|
|
9
|
+
size = 2**widthA unless size
|
|
10
|
+
# puts "widthA=#{widthA} widthD=#{widthD} size=#{size}"
|
|
11
|
+
|
|
12
|
+
# Declares the io of the ram.
|
|
7
13
|
input :clk, :rwb
|
|
8
14
|
[widthA].input :addr
|
|
9
15
|
[widthD].input :din
|
|
10
16
|
[widthD].output :dout
|
|
11
17
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
bit[widthD][-2**widthA].inner mem: [ :"_b#{"0"*widthD}".to_value ] * 2**widthA
|
|
18
|
+
bit[widthD][-size].inner mem: [ :"_b#{"0"*widthD}".to_value ] * size
|
|
15
19
|
|
|
16
20
|
par(clk.negedge) do
|
|
17
|
-
hif(rwb ==
|
|
21
|
+
hif(rwb == 0) { mem[addr] <= din }
|
|
18
22
|
dout <= mem[addr]
|
|
19
23
|
end
|
|
20
24
|
end
|
data/lib/HDLRuby/std/clocks.rb
CHANGED
|
@@ -135,8 +135,8 @@ module HDLRuby::High::Std
|
|
|
135
135
|
end
|
|
136
136
|
|
|
137
137
|
|
|
138
|
-
# Enhnace the events with multiply operator.
|
|
139
138
|
class HDLRuby::High::Event
|
|
139
|
+
# Enhance the events with multiply operator.
|
|
140
140
|
|
|
141
141
|
# Creates a new event activated every +times+ occurences of the
|
|
142
142
|
# current event.
|
data/lib/HDLRuby/std/fsm.rb
CHANGED
|
@@ -31,8 +31,10 @@ module HDLRuby::High::Std
|
|
|
31
31
|
|
|
32
32
|
# Creates a new fsm type with +name+.
|
|
33
33
|
# +options+ allows to specify the type of fsm:
|
|
34
|
-
# synchronous (default)
|
|
35
|
-
#
|
|
34
|
+
# - :sync, :synchronous : synchronous (default)
|
|
35
|
+
# - :async, :asynchronous : asynchronous
|
|
36
|
+
# - :dual : dual front
|
|
37
|
+
# - :seq, :blocking : use blocking assignments
|
|
36
38
|
def initialize(name,*options)
|
|
37
39
|
# Check and set the name
|
|
38
40
|
@name = name.to_sym
|
|
@@ -40,6 +42,7 @@ module HDLRuby::High::Std
|
|
|
40
42
|
@dual = false
|
|
41
43
|
@type = :sync # By default, the FSM is synchronous.
|
|
42
44
|
@sequential = true # By default, the default next state is the next one in the list.
|
|
45
|
+
@blocking = false # By default, use non-blocking assignments (par)
|
|
43
46
|
options.each do |opt|
|
|
44
47
|
case opt
|
|
45
48
|
when :sync,:synchronous then
|
|
@@ -50,10 +53,23 @@ module HDLRuby::High::Std
|
|
|
50
53
|
@dual = true
|
|
51
54
|
when :static then
|
|
52
55
|
@sequential = false
|
|
56
|
+
when :seq then
|
|
57
|
+
@blocking = true
|
|
58
|
+
when :blocking then
|
|
59
|
+
@blocking = true
|
|
53
60
|
else
|
|
54
61
|
raise AnyError, "Invalid option for a fsm: :#{type}"
|
|
55
62
|
end
|
|
56
63
|
end
|
|
64
|
+
if @blocking then
|
|
65
|
+
define_singleton_method(:fsm_block) do |*args,&ruby_block|
|
|
66
|
+
send(:seq,*args,&ruby_block)
|
|
67
|
+
end
|
|
68
|
+
else
|
|
69
|
+
define_singleton_method(:fsm_block) do |*args,&ruby_block|
|
|
70
|
+
send(:par,*args,&ruby_block)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
57
73
|
|
|
58
74
|
# Initialize the internals of the FSM.
|
|
59
75
|
|
|
@@ -127,7 +143,8 @@ module HDLRuby::High::Std
|
|
|
127
143
|
# sub do
|
|
128
144
|
HDLRuby::High.space_push(namespace)
|
|
129
145
|
# Execute the instantiation block
|
|
130
|
-
return_value = HDLRuby::High.top_user.instance_exec(&ruby_block)
|
|
146
|
+
# return_value = HDLRuby::High.top_user.instance_exec(&ruby_block)
|
|
147
|
+
return_value = HDLRuby::High.top_user.instance_exec(&ruby_block) if ruby_block
|
|
131
148
|
|
|
132
149
|
# Expands the extra state processing so that al all the
|
|
133
150
|
# parts of the state machine are in par (clear synthesis).
|
|
@@ -171,7 +188,8 @@ module HDLRuby::High::Std
|
|
|
171
188
|
# Create the fsm code
|
|
172
189
|
|
|
173
190
|
# Control part: update of the state.
|
|
174
|
-
par(mk_ev.call) do
|
|
191
|
+
# par(mk_ev.call) do
|
|
192
|
+
fsm_block(mk_ev.call) do
|
|
175
193
|
hif(mk_rst.call) do
|
|
176
194
|
# Reset: current state is to put to 0.
|
|
177
195
|
this.cur_state_sig <= 0
|
|
@@ -194,13 +212,18 @@ module HDLRuby::High::Std
|
|
|
194
212
|
event = []
|
|
195
213
|
end
|
|
196
214
|
# The process
|
|
197
|
-
par(*event) do
|
|
215
|
+
# par(*event) do
|
|
216
|
+
fsm_block(*event) do
|
|
198
217
|
# The operative code.
|
|
199
218
|
oper_code = proc do
|
|
200
219
|
# The default code.
|
|
201
220
|
default_codes.each(&:call)
|
|
202
221
|
# Depending on the state.
|
|
203
|
-
|
|
222
|
+
if (type == :sync) then
|
|
223
|
+
hcase(this.next_state_sig)
|
|
224
|
+
else
|
|
225
|
+
hcase(this.cur_state_sig)
|
|
226
|
+
end
|
|
204
227
|
states.each do |st|
|
|
205
228
|
# Register the working state (for the gotos)
|
|
206
229
|
this.work_state = st
|
|
@@ -241,8 +264,6 @@ module HDLRuby::High::Std
|
|
|
241
264
|
st.gotos.each(&:call)
|
|
242
265
|
else
|
|
243
266
|
# No gotos, by default the next step is
|
|
244
|
-
# current + 1
|
|
245
|
-
# this.next_state_sig <= this.cur_state_sig + 1
|
|
246
267
|
if sequential then
|
|
247
268
|
this.next_state_sig <= this.cur_state_sig + 1
|
|
248
269
|
end
|
|
@@ -251,6 +272,7 @@ module HDLRuby::High::Std
|
|
|
251
272
|
end
|
|
252
273
|
# By default set the next state to 0.
|
|
253
274
|
helse do
|
|
275
|
+
# hprint("Unknow state case: ",this.cur_state_sig,"\n")
|
|
254
276
|
this.next_state_sig <= 0
|
|
255
277
|
end
|
|
256
278
|
|
|
@@ -260,7 +282,8 @@ module HDLRuby::High::Std
|
|
|
260
282
|
event = mk_ev.call
|
|
261
283
|
event = event.invert if @dual
|
|
262
284
|
# The extra code.
|
|
263
|
-
par(*event) do
|
|
285
|
+
# par(*event) do
|
|
286
|
+
fsm_block(*event) do
|
|
264
287
|
# Build the extra synchronous part.
|
|
265
288
|
sync_code = proc do
|
|
266
289
|
hcase(this.cur_state_sig)
|
|
@@ -289,7 +312,8 @@ module HDLRuby::High::Std
|
|
|
289
312
|
|
|
290
313
|
# Extra asynchronous operative part.
|
|
291
314
|
if extra_asyncs.any? then
|
|
292
|
-
par do
|
|
315
|
+
# par do
|
|
316
|
+
fsm_block do
|
|
293
317
|
# Build the extra synchronous part.
|
|
294
318
|
async_code = proc do
|
|
295
319
|
hcase(this.cur_state_sig)
|
|
@@ -325,6 +349,11 @@ module HDLRuby::High::Std
|
|
|
325
349
|
|
|
326
350
|
|
|
327
351
|
## The interface for building the fsm
|
|
352
|
+
|
|
353
|
+
# Gets the current number of states.
|
|
354
|
+
def size
|
|
355
|
+
@states.size
|
|
356
|
+
end
|
|
328
357
|
|
|
329
358
|
# Sets the event synchronizing the fsm.
|
|
330
359
|
def for_event(event = nil,&ruby_block)
|