Skip to content

Commit 0cc2e3a

Browse files
committed
Merge branch 'feature_fsm_extension' into develop
2 parents 2cce16b + b912485 commit 0cc2e3a

File tree

9 files changed

+468
-88
lines changed

9 files changed

+468
-88
lines changed

tests/extension/fsm_/as_module/fsm_as_module.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ def mkLed():
3333
fsm.goto_next()
3434

3535
# jump by using label "init"
36-
fsm.goto(dst=init, cond=(count < 1024), else_dst=fsm.next).inc()
36+
fsm.goto(dst=init, cond=(count < 1024), else_dst=fsm.next)
37+
fsm.inc()
3738

3839
fsm(led(led + 1))
3940
# jump by using label "here"

tests/extension/fsm_/branch/fsm_branch.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ def add_if_else(fsm, ifelse):
2323
index_merge = fsm.current + len(ifelse.true_statements) + len(ifelse.false_statements) + 1
2424
index_true = fsm.current + 1 if ifelse.true_statements else index_merge
2525

26-
fsm.goto( dst=index_true, cond=ifelse.condition, else_dst=index_else ).inc()
26+
fsm.goto( dst=index_true, cond=ifelse.condition, else_dst=index_else )
27+
fsm.inc()
2728

2829
# then
2930
for i, s in enumerate(ifelse.true_statements):
@@ -32,7 +33,8 @@ def add_if_else(fsm, ifelse):
3233
fsm.goto_next()
3334
else:
3435
fsm( *s )
35-
fsm.goto(index_merge).inc()
36+
fsm.goto(index_merge)
37+
fsm.inc()
3638

3739
# else
3840
for i, s in enumerate(ifelse.false_statements):

tests/extension/fsm_/make_case/fsm_make_case.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
import os
55

66
# the next line can be removed after installation
7-
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))))
7+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(
8+
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))))
89

910
from veriloggen import *
1011

12+
1113
def mkLed():
1214
m = Module('blinkled')
1315
width = m.Parameter('WIDTH', 8)
@@ -20,27 +22,29 @@ def mkLed():
2022
# get the initial index (= 0)
2123
init = fsm.current
2224

23-
fsm( count(count + 1) )
25+
fsm(count(count + 1))
2426
fsm.goto_next()
25-
fsm( count(count + 2) )
27+
fsm(count(count + 2))
2628
fsm.goto_next()
27-
29+
2830
# get the current index (= 2)
2931
here = fsm.current
30-
fsm( count(count + 3) )
32+
fsm(count(count + 3))
3133
fsm.goto_next()
3234

3335
# jump by using label "init"
34-
fsm.goto( dst=init, cond=(count < 1024), else_dst=fsm.next ).inc()
35-
36-
fsm( led(led + 1) )
36+
fsm.goto(dst=init, cond=(count < 1024), else_dst=fsm.next)
37+
fsm.inc()
38+
39+
fsm(led(led + 1))
3740
# jump by using label "here"
3841
fsm.goto(here)
3942

4043
fsm.make_always()
4144

4245
return m
4346

47+
4448
if __name__ == '__main__':
4549
led = mkLed()
4650
verilog = led.to_verilog()

tests/extension/fsm_/make_if/fsm_make_if.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
import os
55

66
# the next line can be removed after installation
7-
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))))
7+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(
8+
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))))
89

910
from veriloggen import *
1011

12+
1113
def mkLed():
1214
m = Module('blinkled')
1315
width = m.Parameter('WIDTH', 8)
@@ -20,27 +22,29 @@ def mkLed():
2022
# get the initial index (= 0)
2123
init = fsm.current
2224

23-
fsm( count(count + 1) )
25+
fsm(count(count + 1))
2426
fsm.goto_next()
25-
fsm( count(count + 2) )
27+
fsm(count(count + 2))
2628
fsm.goto_next()
27-
29+
2830
# get the current index (= 2)
2931
here = fsm.current
30-
fsm( count(count + 3) )
32+
fsm(count(count + 3))
3133
fsm.goto_next()
3234

3335
# jump by using label "init"
34-
fsm.goto( dst=init, cond=(count < 1024), else_dst=fsm.next ).inc()
35-
36-
fsm( led(led + 1) )
36+
fsm.goto(dst=init, cond=(count < 1024), else_dst=fsm.next)
37+
fsm.inc()
38+
39+
fsm(led(led + 1))
3740
# jump by using label "here"
3841
fsm.goto(here)
39-
42+
4043
fsm.make_always(case=False)
4144

4245
return m
4346

47+
4448
if __name__ == '__main__':
4549
led = mkLed()
4650
verilog = led.to_verilog()

tests/extension/fsm_/state/Makefile

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
TARGET=$(shell ls *.py | grep -v test | grep -v parsetab.py)
2+
ARGS=
3+
4+
PYTHON=python3
5+
#PYTHON=python
6+
#OPT=-m pdb
7+
#OPT=-m cProfile -s time
8+
#OPT=-m cProfile -o profile.rslt
9+
10+
.PHONY: all
11+
all: test
12+
13+
.PHONY: run
14+
run:
15+
$(PYTHON) $(OPT) $(TARGET) $(ARGS)
16+
17+
.PHONY: test
18+
test:
19+
$(PYTHON) -m pytest -vv
20+
21+
.PHONY: check
22+
check:
23+
$(PYTHON) $(OPT) $(TARGET) $(ARGS) > tmp.v
24+
iverilog -tnull -Wall tmp.v
25+
rm -f tmp.v
26+
27+
.PHONY: clean
28+
clean:
29+
rm -rf *.pyc __pycache__ parsetab.py .cache *.out *.png *.dot tmp.v uut.vcd
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
from __future__ import absolute_import
2+
from __future__ import print_function
3+
import sys
4+
import os
5+
6+
# the next line can be removed after installation
7+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(
8+
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))))
9+
10+
from veriloggen import *
11+
12+
13+
def mkLed():
14+
m = Module('blinkled')
15+
clk = m.Input('CLK')
16+
rst = m.Input('RST')
17+
valid = m.OutputReg('valid', initval=0)
18+
counter = m.Reg('counter', 8, initval=0)
19+
20+
fsm = FSM(m, 'fsm', clk, rst)
21+
22+
s0 = fsm.init
23+
s1 = fsm.State(s0).If(valid).goto_next()
24+
s2 = fsm.State(s1).If(valid).goto_next()
25+
s3 = fsm.State(s2).If(counter[0] == 0).goto(fsm.next)
26+
s1_ = fsm.State(s2).Elif(counter[1] == 1).goto(s1)
27+
s2_ = fsm.State(s2).Else.goto(s2)
28+
s0_ = fsm.State(s3).goto(s0)
29+
30+
fsm.Always.If(counter <= 2 ** 8 - 1)(
31+
counter.inc()
32+
).Else(
33+
counter(0)
34+
)
35+
36+
fsm.State(s0).If(counter == 10)(
37+
valid(0)
38+
).Else(
39+
valid(1)
40+
)
41+
42+
fsm.State(s1).If(counter == 20)(
43+
valid(0)
44+
).Else(
45+
valid(1)
46+
)
47+
48+
fsm.State(s2).If(counter == 30)(
49+
valid(0)
50+
).Else(
51+
valid(1)
52+
)
53+
54+
fsm.State(s0_).If(counter == 40)(
55+
valid(0)
56+
).Else(
57+
valid(1)
58+
)
59+
60+
return m
61+
62+
63+
def mkTest():
64+
m = Module('test')
65+
clk = m.Reg('CLK')
66+
rst = m.Reg('RST')
67+
valid = m.Wire('valid')
68+
69+
uut = m.Instance(mkLed(), 'uut',
70+
ports=(('CLK', clk), ('RST', rst), ('valid', valid)))
71+
72+
# simulation.setup_waveform(m, uut)
73+
simulation.setup_clock(m, clk, hperiod=5)
74+
init = simulation.setup_reset(m, rst, period=100)
75+
76+
init.add(
77+
Delay(1000),
78+
Systask('finish'),
79+
)
80+
81+
return m
82+
83+
84+
if __name__ == '__main__':
85+
test = mkTest()
86+
verilog = test.to_verilog('tmp.v')
87+
print(verilog)
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
from __future__ import absolute_import
2+
from __future__ import print_function
3+
import veriloggen
4+
import fsm_state
5+
6+
expected_verilog = """
7+
module test;
8+
9+
reg CLK;
10+
reg RST;
11+
wire valid;
12+
13+
blinkled
14+
uut
15+
(
16+
.CLK(CLK),
17+
.RST(RST),
18+
.valid(valid)
19+
);
20+
21+
22+
initial begin
23+
CLK = 0;
24+
forever begin
25+
#5 CLK = !CLK;
26+
end
27+
end
28+
29+
30+
initial begin
31+
RST = 0;
32+
#100;
33+
RST = 1;
34+
#100;
35+
RST = 0;
36+
#1000;
37+
$finish;
38+
end
39+
40+
41+
endmodule
42+
43+
44+
45+
module blinkled
46+
(
47+
input CLK,
48+
input RST,
49+
output reg valid
50+
);
51+
52+
reg [8-1:0] counter;
53+
reg [32-1:0] fsm;
54+
localparam fsm_init = 0;
55+
localparam fsm_1 = 1;
56+
localparam fsm_2 = 2;
57+
localparam fsm_3 = 3;
58+
59+
always @(posedge CLK) begin
60+
if(RST) begin
61+
fsm <= fsm_init;
62+
valid <= 0;
63+
counter <= 0;
64+
end else begin
65+
if(counter <= 255) begin
66+
counter <= counter + 1;
67+
end else begin
68+
counter <= 0;
69+
end
70+
case(fsm)
71+
fsm_init: begin
72+
if(counter == 10) begin
73+
valid <= 0;
74+
end else begin
75+
valid <= 1;
76+
end
77+
if(counter == 40) begin
78+
valid <= 0;
79+
end else begin
80+
valid <= 1;
81+
end
82+
if(valid) begin
83+
fsm <= fsm_1;
84+
end
85+
end
86+
fsm_1: begin
87+
if(counter == 20) begin
88+
valid <= 0;
89+
end else begin
90+
valid <= 1;
91+
end
92+
if(valid) begin
93+
fsm <= fsm_2;
94+
end
95+
end
96+
fsm_2: begin
97+
if(counter == 30) begin
98+
valid <= 0;
99+
end else begin
100+
valid <= 1;
101+
end
102+
if(counter[0] == 0) begin
103+
fsm <= fsm_3;
104+
end
105+
if(!(counter[0] == 0) && (counter[1] == 1)) begin
106+
fsm <= fsm_1;
107+
end
108+
if(!(counter[0] == 0) && !(counter[1] == 1)) begin
109+
fsm <= fsm_2;
110+
end
111+
end
112+
fsm_3: begin
113+
fsm <= fsm_init;
114+
end
115+
endcase
116+
end
117+
end
118+
119+
120+
endmodule
121+
"""
122+
123+
124+
def test():
125+
veriloggen.reset()
126+
test_module = fsm_state.mkTest()
127+
code = test_module.to_verilog()
128+
129+
from pyverilog.vparser.parser import VerilogParser
130+
from pyverilog.ast_code_generator.codegen import ASTCodeGenerator
131+
parser = VerilogParser()
132+
expected_ast = parser.parse(expected_verilog)
133+
codegen = ASTCodeGenerator()
134+
expected_code = codegen.visit(expected_ast)
135+
136+
assert(expected_code == code)

0 commit comments

Comments
 (0)