Skip to content

Commit c3f4b68

Browse files
committed
Method hooking for nested modules is supported. Some examples are added.
1 parent 82c5f0b commit c3f4b68

File tree

15 files changed

+554
-11
lines changed

15 files changed

+554
-11
lines changed

examples/seq_example/test_seq_example.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import seq_example
2-
from veriloggen import *
32

43
expected_verilog = """
54
module test #

tests/lib_fsm_/hook/lib_fsm_hook.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,15 @@ def mkLed():
5050
fsm.goto(init)
5151

5252
#fsm.make_always()
53+
# make_alway() is called when to_veirlog() is called.
5354
m.add_hook(fsm.make_always, args=(), kwargs={})
5455

5556
return m
5657

5758
if __name__ == '__main__':
5859
led = mkLed()
60+
# to_verilog() method is immuatable.
61+
# Hooked methods are called for the copied object to keep the internal state.
62+
dummy = led.to_verilog()
5963
verilog = led.to_verilog()
6064
print(verilog)

tests/lib_fsm_/hook/test_lib_fsm_hook.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363

6464
def test():
6565
test_module = lib_fsm_hook.mkLed()
66+
dummy = test_module.to_verilog()
6667
code = test_module.to_verilog()
6768

6869
from pyverilog.vparser.parser import VerilogParser
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
TARGET=*.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 *.out tmp.v uut.vcd
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import sys
2+
import os
3+
4+
# the next line can be removed after installation
5+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
6+
7+
from veriloggen import *
8+
9+
def mkLed():
10+
m = Module('blinkled')
11+
width = m.Parameter('WIDTH', 8)
12+
clk = m.Input('CLK')
13+
rst = m.Input('RST')
14+
led = m.OutputReg('LED', width, initval=0)
15+
count = m.Reg('count', 32, initval=0)
16+
17+
"""
18+
led = 0
19+
while True:
20+
count = 0
21+
while count < 1024:
22+
count += 1
23+
led += 1
24+
"""
25+
26+
fsm = lib.FSM(m, 'fsm', clk, rst)
27+
28+
fsm.add( led(0) )
29+
fsm.goto_next()
30+
31+
init = fsm.current()
32+
fsm.add( count(0) )
33+
fsm.goto_next()
34+
35+
head = fsm.current()
36+
cond = count < 1024
37+
fsm.goto_next(cond=cond)
38+
39+
fsm.add( count.inc() )
40+
fsm.goto_next()
41+
42+
fsm.add( count.inc() )
43+
fsm.goto(head)
44+
fsm.inc()
45+
46+
tail = fsm.current()
47+
fsm.goto_from(head, tail, cond=Not(cond))
48+
49+
fsm.add( led.inc() )
50+
fsm.goto(init)
51+
52+
#fsm.make_always()
53+
# make_alway() is called when to_veirlog() is called.
54+
m.add_hook(fsm.make_always, args=(), kwargs={})
55+
56+
return m
57+
58+
def mkTop():
59+
m = Module('top')
60+
led = mkLed()
61+
params = m.copy_params(led)
62+
ports = m.copy_ports(led)
63+
m.Instance(led, 'inst_' + led.name,
64+
connect_same_name(*params.values()),
65+
connect_same_name(*ports.values()))
66+
return m
67+
68+
if __name__ == '__main__':
69+
top = mkTop()
70+
# to_verilog() method is immuatable.
71+
# Hooked methods are called for the copied object to keep the internal state.
72+
dummy = top.to_verilog()
73+
verilog = top.to_verilog()
74+
print(verilog)
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import lib_fsm_hook_nested
2+
3+
expected_verilog = """
4+
module top #
5+
(
6+
parameter WIDTH = 8
7+
)
8+
(
9+
input CLK,
10+
input RST,
11+
output [WIDTH-1:0] LED
12+
);
13+
14+
blinkled
15+
#(
16+
.WIDTH(WIDTH)
17+
)
18+
inst_blinkled
19+
(
20+
.CLK(CLK),
21+
.RST(RST),
22+
.LED(LED)
23+
);
24+
endmodule
25+
26+
module blinkled #
27+
(
28+
parameter WIDTH = 8
29+
)
30+
(
31+
input CLK,
32+
input RST,
33+
output reg [WIDTH-1:0] LED
34+
);
35+
reg [32-1:0] count;
36+
reg [32-1:0] fsm;
37+
localparam fsm_init = 0;
38+
localparam fsm_1 = 1;
39+
localparam fsm_2 = 2;
40+
localparam fsm_3 = 3;
41+
localparam fsm_4 = 4;
42+
localparam fsm_5 = 5;
43+
44+
always @(posedge CLK) begin
45+
if(RST) begin
46+
fsm <= fsm_init;
47+
LED <= 0;
48+
count <= 0;
49+
end else begin
50+
case(fsm)
51+
fsm_init: begin
52+
LED <= 0;
53+
fsm <= fsm_1;
54+
end
55+
fsm_1: begin
56+
count <= 0;
57+
fsm <= fsm_2;
58+
end
59+
fsm_2: begin
60+
if(count < 1024) begin
61+
fsm <= fsm_3;
62+
end
63+
if(!(count < 1024)) begin
64+
fsm <= fsm_5;
65+
end
66+
end
67+
fsm_3: begin
68+
count <= count + 1;
69+
fsm <= fsm_4;
70+
end
71+
fsm_4: begin
72+
count <= count + 1;
73+
fsm <= fsm_2;
74+
end
75+
fsm_5: begin
76+
LED <= LED + 1;
77+
fsm <= fsm_1;
78+
end
79+
endcase
80+
end
81+
end
82+
83+
endmodule
84+
"""
85+
86+
def test():
87+
test_module = lib_fsm_hook_nested.mkTop()
88+
dummy = test_module.to_verilog()
89+
code = test_module.to_verilog()
90+
91+
from pyverilog.vparser.parser import VerilogParser
92+
from pyverilog.ast_code_generator.codegen import ASTCodeGenerator
93+
parser = VerilogParser()
94+
expected_ast = parser.parse(expected_verilog)
95+
codegen = ASTCodeGenerator()
96+
expected_code = codegen.visit(expected_ast)
97+
98+
assert(expected_code == code)

tests/lib_seq_/basic/Makefile

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
TARGET=*.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 *.out tmp.v uut.vcd
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import sys
2+
import os
3+
4+
# the next line can be removed after installation
5+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
6+
7+
from veriloggen import *
8+
9+
def mkLed():
10+
m = Module('blinkled')
11+
interval = m.Parameter('INTERVAL', 16)
12+
clk = m.Input('CLK')
13+
rst = m.Input('RST')
14+
led = m.OutputReg('LED', 8, initval=0)
15+
count = m.Reg('count', 32, initval=0)
16+
17+
seq = lib.Seq(m, 'seq', clk, rst)
18+
seq.add( Systask('display', 'LED:%d count:%d', led, count) )
19+
seq.add( count(count + 1), cond=count<interval-1 )
20+
seq.add( count(0), cond=count==interval-1 )
21+
seq.add( led(led + 1), cond=count==interval-1 )
22+
23+
seq.make_always()
24+
25+
return m
26+
27+
def mkTest():
28+
m = Module('test')
29+
30+
# target instance
31+
led = mkLed()
32+
33+
# copy paras and ports
34+
params = m.copy_params(led)
35+
ports = m.copy_sim_ports(led)
36+
37+
clk = ports['CLK']
38+
rst = ports['RST']
39+
40+
uut = m.Instance(led, 'uut',
41+
params=m.connect_params(led),
42+
ports=m.connect_ports(led))
43+
44+
#lib.simulation.setup_waveform(m, uut)
45+
lib.simulation.setup_clock(m, clk, hperiod=5)
46+
init = lib.simulation.setup_reset(m, rst, m.make_reset(), period=100)
47+
48+
init.add(
49+
Delay(1000),
50+
Systask('finish'),
51+
)
52+
53+
return m
54+
55+
if __name__ == '__main__':
56+
test = mkTest()
57+
verilog = test.to_verilog()
58+
print(verilog)

0 commit comments

Comments
 (0)