Skip to content

Commit ffedbdc

Browse files
committed
Merge branch 'fix_stream_cast' into develop
2 parents 54d0398 + 1d6e215 commit ffedbdc

File tree

5 files changed

+226
-6
lines changed

5 files changed

+226
-6
lines changed

tests/extension/thread_/stream_cast/thread_stream_cast.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ def mkLed():
2727
strm = vthread.Stream(m, 'mystream', clk, rst)
2828
a = strm.source('a')
2929
b = strm.source('b')
30-
a = strm.Cast(a, 64, 0)
31-
b = strm.Cast(b, 64, 0)
30+
a = strm.Cast(a, 64, 4)
31+
b = strm.Cast(b, 64, 4)
3232
c = a * b
3333
c = strm.Cast(c, 32, 0)
3434
strm.sink(c, 'c')
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_reinterpret_cast
7+
8+
9+
def test(request):
10+
veriloggen.reset()
11+
12+
simtype = request.config.getoption('--sim')
13+
14+
rslt = thread_stream_reinterpret_cast.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: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
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+
a = strm.ReinterpretCast(a, 64, 2)
31+
b = strm.ReinterpretCast(b, 64, 2)
32+
c = a * b
33+
c = strm.ReinterpretCast(c, 32, 0)
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+
for i in range(size):
46+
a = ram_a.read(i + offset)
47+
b = ram_b.read(i + offset)
48+
sum = a * b >> 2
49+
ram_c.write(i + offset, sum)
50+
51+
def check(size, offset_stream, offset_seq):
52+
all_ok = True
53+
for i in range(size):
54+
st = ram_c.read(i + offset_stream)
55+
sq = ram_c.read(i + offset_seq)
56+
if vthread.verilog.NotEql(st, sq):
57+
all_ok = False
58+
if all_ok:
59+
print('# verify: PASSED')
60+
else:
61+
print('# verify: FAILED')
62+
63+
def comp(size):
64+
# stream
65+
offset = 0
66+
myaxi.dma_read(ram_a, offset, 0, size)
67+
myaxi.dma_read(ram_b, offset, 512, size)
68+
comp_stream(size, offset)
69+
myaxi.dma_write(ram_c, offset, 1024, size)
70+
71+
# sequential
72+
offset = size
73+
myaxi.dma_read(ram_a, offset, 0, size)
74+
myaxi.dma_read(ram_b, offset, 512, size)
75+
comp_sequential(size, offset)
76+
myaxi.dma_write(ram_c, offset, 1024 * 2, size)
77+
78+
# verification
79+
check(size, 0, offset)
80+
81+
vthread.finish()
82+
83+
th = vthread.Thread(m, 'th_comp', clk, rst, comp)
84+
fsm = th.start(32)
85+
86+
return m
87+
88+
89+
def mkTest(memimg_name=None):
90+
m = Module('test')
91+
92+
# target instance
93+
led = mkLed()
94+
95+
# copy paras and ports
96+
params = m.copy_params(led)
97+
ports = m.copy_sim_ports(led)
98+
99+
clk = ports['CLK']
100+
rst = ports['RST']
101+
102+
memory = axi.AxiMemoryModel(m, 'memory', clk, rst, memimg_name=memimg_name)
103+
memory.connect(ports, 'myaxi')
104+
105+
uut = m.Instance(led, 'uut',
106+
params=m.connect_params(led),
107+
ports=m.connect_ports(led))
108+
109+
#simulation.setup_waveform(m, uut)
110+
simulation.setup_clock(m, clk, hperiod=5)
111+
init = simulation.setup_reset(m, rst, m.make_reset(), period=100)
112+
113+
init.add(
114+
Delay(1000000),
115+
Systask('finish'),
116+
)
117+
118+
return m
119+
120+
121+
def run(filename='tmp.v', simtype='iverilog', outputfile=None):
122+
123+
if outputfile is None:
124+
outputfile = os.path.splitext(os.path.basename(__file__))[0] + '.out'
125+
126+
memimg_name = 'memimg_' + outputfile
127+
128+
test = mkTest(memimg_name=memimg_name)
129+
130+
if filename is not None:
131+
test.to_verilog(filename)
132+
133+
sim = simulation.Simulator(test, sim=simtype)
134+
rslt = sim.run(outputfile=outputfile)
135+
lines = rslt.splitlines()
136+
if simtype == 'verilator' and lines[-1].startswith('-'):
137+
rslt = '\n'.join(lines[:-1])
138+
return rslt
139+
140+
141+
if __name__ == '__main__':
142+
rslt = run(filename='tmp.v')
143+
print(rslt)

veriloggen/stream/stypes.py

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,18 +1323,48 @@ def _implement(self, m, seq, svalid=None, senable=None):
13231323
signed = self.get_signed()
13241324

13251325
rdata = self.right.sig_data
1326+
rwidth = self.right.bit_length()
13261327
rpoint = self.right.get_point()
13271328
rsigned = self.right.get_signed()
13281329

1330+
rdata_src = m.Wire(self.name('src'), rwidth, signed=rsigned)
1331+
rdata_src.assign(rdata)
1332+
13291333
if rpoint > self.point:
1330-
rdata = fx.shift_right(rdata, rpoint - self.point, rsigned)
1334+
rdata_src = fx.shift_right(rdata_src, rpoint - self.point, rsigned)
13311335
elif rpoint < self.point:
1332-
rdata = fx.shift_left(rdata, self.point - rpoint, rsigned)
1336+
rdata_src = fx.shift_left(rdata_src, self.point - rpoint, rsigned)
1337+
1338+
data = m.Wire(self.name('data'), width, signed=signed)
1339+
self.sig_data = data
1340+
1341+
m.Assign(data(rdata_src))
1342+
1343+
def eval(self):
1344+
return self
1345+
1346+
1347+
class ReinterpretCast(Cast):
1348+
1349+
def _implement(self, m, seq, svalid=None, senable=None):
1350+
if self.latency != 0:
1351+
raise ValueError("Latency mismatch '%d' vs '%s'" %
1352+
(self.latency, 0))
1353+
1354+
width = self.bit_length()
1355+
signed = self.get_signed()
1356+
1357+
rdata = self.right.sig_data
1358+
rwidth = self.right.bit_length()
1359+
rsigned = self.right.get_signed()
1360+
1361+
rdata_src = m.Wire(self.name('src'), rwidth, signed=rsigned)
1362+
rdata_src.assign(rdata)
13331363

13341364
data = m.Wire(self.name('data'), width, signed=signed)
13351365
self.sig_data = data
13361366

1337-
m.Assign(data(rdata))
1367+
m.Assign(data(rdata_src))
13381368

13391369
def eval(self):
13401370
return self
@@ -1568,7 +1598,7 @@ def Split(data, width=None, point=None, signed=None, num_chunks=None):
15681598
v = Slice(data, i + width - 1, i)
15691599
v.latency = 0
15701600

1571-
ret.append(Cast(v, width, point, signed))
1601+
ret.append(ReinterpretCast(v, width, point, signed))
15721602

15731603
ret.reverse()
15741604
return ret

0 commit comments

Comments
 (0)