Skip to content

Commit f224a09

Browse files
committed
Merge branch 'develop' into feature_axi_stream
2 parents 4f918bc + fa9fe65 commit f224a09

File tree

8 files changed

+369
-68
lines changed

8 files changed

+369
-68
lines changed

tests/extension/thread_/stream_counter/thread_stream_counter.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ def mkLed():
2727
strm = vthread.Stream(m, 'mystream', clk, rst)
2828
cnt1 = strm.Counter()
2929
cnt2 = strm.Counter(initval=1)
30-
cnt3 = strm.Counter(initval=2, size=3)
30+
cnt3 = strm.Counter(initval=2, size=5)
3131
cnt4 = strm.Counter(initval=3, interval=3)
32-
cnt5 = strm.Counter(initval=4, interval=3, size=4)
32+
cnt5 = strm.Counter(initval=4, interval=3, size=7)
3333
cnt6 = strm.Counter(initval=4, step=2, interval=2)
3434
a = strm.source('a')
3535
b = strm.source('b')
@@ -48,10 +48,10 @@ def comp_sequential(size, offset):
4848
for i in range(size):
4949
cnt1 = cnt
5050
cnt2 = 1 + cnt
51-
cnt3 = cnt%3 + 2
52-
cnt4 = (cnt//3) + 3
53-
cnt5 = (cnt//3)%4 + 4
54-
cnt6 = (cnt//2)*2 + 4
51+
cnt3 = (cnt + 2) % 5
52+
cnt4 = (cnt // 3) + 3
53+
cnt5 = ((cnt // 3) + 4) % 7
54+
cnt6 = (cnt // 2) * 2 + 4
5555
a = ram_a.read(i + offset)
5656
b = ram_b.read(i + offset)
5757
sum = a + b - a - b + cnt1 + cnt2 + cnt3 + cnt4 + cnt5 + cnt6
@@ -65,6 +65,7 @@ def check(size, offset_stream, offset_seq):
6565
sq = ram_c.read(i + offset_seq)
6666
if vthread.verilog.NotEql(st, sq):
6767
all_ok = False
68+
print(i, st, sq)
6869
if all_ok:
6970
print('# verify: PASSED')
7071
else:
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: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from __future__ import absolute_import
2+
from __future__ import print_function
3+
4+
import os
5+
import veriloggen
6+
import thread_stream_counter_enable
7+
8+
9+
def test(request):
10+
veriloggen.reset()
11+
12+
simtype = request.config.getoption('--sim')
13+
14+
rslt = thread_stream_counter_enable.run(filename=None, simtype=simtype,
15+
outputfile=os.path.splitext(os.path.basename(__file__))[0] + '.out')
16+
17+
verify_rslt = rslt.splitlines()[-1]
18+
assert(verify_rslt == '# verify: PASSED')
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
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+
import veriloggen.thread as vthread
12+
import veriloggen.types.axi as axi
13+
14+
15+
def mkLed():
16+
m = Module('blinkled')
17+
clk = m.Input('CLK')
18+
rst = m.Input('RST')
19+
20+
datawidth = 32
21+
addrwidth = 10
22+
myaxi = vthread.AXIM(m, 'myaxi', clk, rst, datawidth)
23+
ram_a = vthread.RAM(m, 'ram_a', clk, rst, datawidth, addrwidth)
24+
ram_b = vthread.RAM(m, 'ram_b', clk, rst, datawidth, addrwidth)
25+
ram_c = vthread.RAM(m, 'ram_c', clk, rst, datawidth, addrwidth)
26+
27+
strm = vthread.Stream(m, 'mystream', clk, rst)
28+
a = strm.source('a')
29+
b = strm.source('b')
30+
x = strm.Counter(initval=0, size=4)
31+
y = strm.Counter(initval=0, size=4, enable=x==3)
32+
z = strm.Counter(initval=0, size=4, enable=y==3)
33+
c = a + b - a - b + z + y + x
34+
strm.sink(c, 'c')
35+
36+
def comp_stream(size, offset):
37+
strm.set_source('a', ram_a, offset, size)
38+
strm.set_source('b', ram_b, offset, size)
39+
strm.set_sink('c', ram_c, offset, size)
40+
strm.run()
41+
strm.join()
42+
43+
def comp_sequential(size, offset):
44+
sum = 0
45+
x = 0
46+
y = 0
47+
z = 0
48+
for i in range(size):
49+
a = ram_a.read(i + offset)
50+
b = ram_b.read(i + offset)
51+
sum = a + b - a - b + z + y + x
52+
ram_c.write(i + offset, sum)
53+
if y == 3:
54+
z += 1
55+
if z == 4:
56+
z = 0
57+
if x == 3:
58+
y += 1
59+
if y == 4:
60+
y = 0
61+
x += 1
62+
if x == 4:
63+
x = 0
64+
65+
def check(size, offset_stream, offset_seq):
66+
all_ok = True
67+
for i in range(size):
68+
st = ram_c.read(i + offset_stream)
69+
sq = ram_c.read(i + offset_seq)
70+
if vthread.verilog.NotEql(st, sq):
71+
all_ok = False
72+
if all_ok:
73+
print('# verify: PASSED')
74+
else:
75+
print('# verify: FAILED')
76+
77+
def comp(size):
78+
# stream
79+
offset = 0
80+
myaxi.dma_read(ram_a, offset, 0, size)
81+
myaxi.dma_read(ram_b, offset, 512, size)
82+
comp_stream(size, offset)
83+
myaxi.dma_write(ram_c, offset, 1024, size)
84+
85+
# sequential
86+
offset = size
87+
myaxi.dma_read(ram_a, offset, 0, size)
88+
myaxi.dma_read(ram_b, offset, 512, size)
89+
comp_sequential(size, offset)
90+
myaxi.dma_write(ram_c, offset, 1024 * 2, size)
91+
92+
# verification
93+
check(size, 0, offset)
94+
95+
vthread.finish()
96+
97+
th = vthread.Thread(m, 'th_comp', clk, rst, comp)
98+
fsm = th.start(32)
99+
100+
return m
101+
102+
103+
def mkTest(memimg_name=None):
104+
m = Module('test')
105+
106+
# target instance
107+
led = mkLed()
108+
109+
# copy paras and ports
110+
params = m.copy_params(led)
111+
ports = m.copy_sim_ports(led)
112+
113+
clk = ports['CLK']
114+
rst = ports['RST']
115+
116+
memory = axi.AxiMemoryModel(m, 'memory', clk, rst, memimg_name=memimg_name)
117+
memory.connect(ports, 'myaxi')
118+
119+
uut = m.Instance(led, 'uut',
120+
params=m.connect_params(led),
121+
ports=m.connect_ports(led))
122+
123+
#simulation.setup_waveform(m, uut)
124+
simulation.setup_clock(m, clk, hperiod=5)
125+
init = simulation.setup_reset(m, rst, m.make_reset(), period=100)
126+
127+
init.add(
128+
Delay(1000000),
129+
Systask('finish'),
130+
)
131+
132+
return m
133+
134+
135+
def run(filename='tmp.v', simtype='iverilog', outputfile=None):
136+
137+
if outputfile is None:
138+
outputfile = os.path.splitext(os.path.basename(__file__))[0] + '.out'
139+
140+
memimg_name = 'memimg_' + outputfile
141+
142+
test = mkTest(memimg_name=memimg_name)
143+
144+
if filename is not None:
145+
test.to_verilog(filename)
146+
147+
sim = simulation.Simulator(test, sim=simtype)
148+
rslt = sim.run(outputfile=outputfile)
149+
lines = rslt.splitlines()
150+
if simtype == 'verilator' and lines[-1].startswith('-'):
151+
rslt = '\n'.join(lines[:-1])
152+
return rslt
153+
154+
155+
if __name__ == '__main__':
156+
rslt = run(filename='tmp.v')
157+
print(rslt)

veriloggen/stream/graph.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,12 +213,16 @@ def visit__Accumulator(self, node):
213213

214214
right = self.visit(node.right)
215215
initval = self.visit(node.initval)
216+
if node.dependency is not None:
217+
dependency = self.visit(node.dependency)
216218
if node.enable is not None:
217219
enable = self.visit(node.enable)
218220
if node.reset is not None:
219221
reset = self.visit(node.reset)
220222
self.graph.add_edge(right, node, label='data')
221223
self.graph.add_edge(initval, node, label='initval')
224+
if node.dependency is not None:
225+
self.graph.add_edge(dependency, node, label='dependency')
222226
if node.enable is not None:
223227
self.graph.add_edge(enable, node, label='enable')
224228
if node.reset is not None:

veriloggen/stream/scheduler.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,11 @@ def visit__Accumulator(self, node):
122122
return node._get_end_stage()
123123
right = self.visit(node.right)
124124
initval = self.visit(node.initval)
125+
dependency = (self.visit(node.dependency)
126+
if node.dependency is not None else None)
125127
enable = self.visit(node.enable) if node.enable is not None else None
126128
reset = self.visit(node.reset) if node.reset is not None else None
127-
mine = self.max_stage(right, initval, enable, reset)
129+
mine = self.max_stage(right, initval, dependency, enable, reset)
128130
node.right = self.fill_gap(node.right, mine)
129131
node.initval = self.fill_gap(node.initval, mine)
130132
if node.enable is not None:

0 commit comments

Comments
 (0)