Skip to content

Commit 8fa5ae4

Browse files
committed
stream_extern_ram
1 parent 445efb1 commit 8fa5ae4

File tree

5 files changed

+248
-4
lines changed

5 files changed

+248
-4
lines changed

tests/extension/thread_/stream_extern/thread_stream_extern.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def mkLed():
3737
strm.sink(b, 'b')
3838

3939
def comp_stream(size, offset):
40-
strm.set_source('a', ram_a, offset, size * 2)
40+
strm.set_source('a', ram_a, offset, size)
4141
strm.set_sink('b', ram_b, offset, size)
4242
strm.run()
4343
strm.join()
@@ -65,13 +65,13 @@ def check(size, offset_stream, offset_seq):
6565
def comp(size):
6666
# stream
6767
offset = 0
68-
myaxi.dma_read(ram_a, offset, 0, size * 2)
68+
myaxi.dma_read(ram_a, offset, 0, size)
6969
comp_stream(size, offset)
7070
myaxi.dma_write(ram_b, offset, 1024, size)
7171

7272
# sequential
7373
offset = size * 4
74-
myaxi.dma_read(ram_a, offset, 0, size * 2)
74+
myaxi.dma_read(ram_a, offset, 0, size)
7575
comp_sequential(size, offset)
7676
myaxi.dma_write(ram_b, offset, 1024 * 2, size)
7777

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

veriloggen/stream/stypes.py

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3135,8 +3135,17 @@ def _implement(self, m, seq, svalid=None, senable=None):
31353135
class FromExtern(_UnaryOperator):
31363136
latency = 1
31373137

3138-
def __init__(self, right, latency=1):
3138+
def __init__(self, right, width=None, point=None, signed=True, latency=1):
31393139
_UnaryOperator.__init__(self, right)
3140+
3141+
if width is not None:
3142+
self.width = width
3143+
3144+
if point is not None:
3145+
self.point = point
3146+
3147+
self.signed = signed
3148+
31403149
self.latency = latency
31413150

31423151
self.graph_label = 'FromExtern'
@@ -3160,6 +3169,50 @@ def _implement(self, m, seq, svalid=None, senable=None):
31603169
self.sig_data = data
31613170

31623171

3172+
class ReadRAM(_UnaryOperator):
3173+
latency = 1
3174+
3175+
def __init__(self, ram, addr, width=None, point=None, signed=True, port=0):
3176+
_UnaryOperator.__init__(self, addr)
3177+
3178+
self.ram = ram
3179+
3180+
if width is None:
3181+
self.width = ram.datawidth
3182+
else:
3183+
self.width = width
3184+
3185+
if point is None:
3186+
self.point = 0 if not hasattr(ram, 'point') else ram.point
3187+
else:
3188+
self.point = point
3189+
3190+
self.signed = signed
3191+
self.port = port
3192+
3193+
self.graph_label = 'Read ' + ram.name if hasattr(ram, 'name') else 'Read RAM'
3194+
self.graph_shape = 'box'
3195+
3196+
def _implement(self, m, seq, svalid=None, senable=None):
3197+
datawidth = self.bit_length()
3198+
addrwidth = int(log(self.ram.length, 2))
3199+
signed = self.get_signed()
3200+
3201+
rdata = m.Wire(self.name('rdata'), datawidth, signed=signed)
3202+
3203+
raddr = m.Wire(self.name('raddr'), addrwidth)
3204+
raddr.assign(self.right.sig_data)
3205+
3206+
if hasattr(self.ram, 'connect'):
3207+
self.ram.connect(self.port, raddr, 0, 0)
3208+
rdata.assign(self.ram.rdata(self.port))
3209+
3210+
elif hasattr(self.ram, 'connect_rtl'):
3211+
self.ram.connect_rtl(self.port, raddr, 0, 0, rdata)
3212+
3213+
self.sig_data = rdata
3214+
3215+
31633216
def make_condition(*cond, **kwargs):
31643217
ready = kwargs['ready'] if 'ready' in kwargs else None
31653218

0 commit comments

Comments
 (0)