Skip to content

Commit 719caba

Browse files
committed
ToExtern and FromExtern
1 parent 47b778c commit 719caba

File tree

4 files changed

+275
-0
lines changed

4 files changed

+275
-0
lines changed
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
7+
8+
9+
def test(request):
10+
veriloggen.reset()
11+
12+
simtype = request.config.getoption('--sim')
13+
14+
rslt = thread_stream_extern.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: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
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+
strm = vthread.Stream(m, 'mystream', clk, rst)
27+
28+
a = strm.source('a')
29+
30+
# to extern
31+
extout = strm.ToExtern(a)
32+
extin = strm.FromExtern(extout, latency=1)
33+
34+
# from extern
35+
b = a + extin + 1
36+
37+
strm.sink(b, 'b')
38+
39+
def comp_stream(size, offset):
40+
strm.set_source('a', ram_a, offset, size * 2)
41+
strm.set_sink('b', ram_b, offset, size)
42+
strm.run()
43+
strm.join()
44+
45+
def comp_sequential(size, offset):
46+
for i in range(size):
47+
a = ram_a.read(i + offset)
48+
extout = a
49+
extin = extout + 100
50+
b = a + extin + 1
51+
ram_b.write(i + offset, b)
52+
53+
def check(size, offset_stream, offset_seq):
54+
all_ok = True
55+
for i in range(size):
56+
st = ram_b.read(i + offset_stream)
57+
sq = ram_b.read(i + offset_seq)
58+
if vthread.verilog.NotEql(st, sq):
59+
all_ok = False
60+
if all_ok:
61+
print('# verify: PASSED')
62+
else:
63+
print('# verify: FAILED')
64+
65+
def comp(size):
66+
# stream
67+
offset = 0
68+
myaxi.dma_read(ram_a, offset, 0, size * 2)
69+
comp_stream(size, offset)
70+
myaxi.dma_write(ram_b, offset, 1024, size)
71+
72+
# sequential
73+
offset = size * 4
74+
myaxi.dma_read(ram_a, offset, 0, size * 2)
75+
comp_sequential(size, offset)
76+
myaxi.dma_write(ram_b, 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+
# extern behavior in RTL
87+
ext_seq = Seq(m, 'ext_seq', clk, rst)
88+
ext_seq.If(extout.valid)(
89+
extin.data(extout.data + 100)
90+
)
91+
92+
strm.draw_graph()
93+
94+
return m
95+
96+
97+
def mkTest(memimg_name=None):
98+
m = Module('test')
99+
100+
# target instance
101+
led = mkLed()
102+
103+
# copy paras and ports
104+
params = m.copy_params(led)
105+
ports = m.copy_sim_ports(led)
106+
107+
clk = ports['CLK']
108+
rst = ports['RST']
109+
110+
memory = axi.AxiMemoryModel(m, 'memory', clk, rst, memimg_name=memimg_name)
111+
memory.connect(ports, 'myaxi')
112+
113+
uut = m.Instance(led, 'uut',
114+
params=m.connect_params(led),
115+
ports=m.connect_ports(led))
116+
117+
#simulation.setup_waveform(m, uut)
118+
simulation.setup_clock(m, clk, hperiod=5)
119+
init = simulation.setup_reset(m, rst, m.make_reset(), period=100)
120+
121+
init.add(
122+
Delay(1000000),
123+
Systask('finish'),
124+
)
125+
126+
return m
127+
128+
129+
def run(filename='tmp.v', simtype='iverilog', outputfile=None):
130+
131+
if outputfile is None:
132+
outputfile = os.path.splitext(os.path.basename(__file__))[0] + '.out'
133+
134+
memimg_name = 'memimg_' + outputfile
135+
136+
test = mkTest(memimg_name=memimg_name)
137+
138+
if filename is not None:
139+
test.to_verilog(filename)
140+
141+
sim = simulation.Simulator(test, sim=simtype)
142+
rslt = sim.run(outputfile=outputfile)
143+
lines = rslt.splitlines()
144+
if simtype == 'verilator' and lines[-1].startswith('-'):
145+
rslt = '\n'.join(lines[:-1])
146+
return rslt
147+
148+
149+
if __name__ == '__main__':
150+
rslt = run(filename='tmp.v')
151+
print(rslt)

veriloggen/stream/stypes.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3083,6 +3083,83 @@ def _implement(self, m, seq, svalid=None, senable=None):
30833083
self.sig_data = rdata
30843084

30853085

3086+
class ToExtern(_UnaryOperator):
3087+
latency = 1
3088+
3089+
def __init__(self, right):
3090+
_UnaryOperator.__init__(self, right)
3091+
3092+
self.graph_label = 'ToExtern'
3093+
self.graph_shape = 'box'
3094+
3095+
@property
3096+
def data(self):
3097+
return self.sig_data
3098+
3099+
def eval(self):
3100+
return self
3101+
3102+
def _implement(self, m, seq, svalid=None, senable=None):
3103+
width = self.bit_length()
3104+
signed = self.get_signed()
3105+
rdata = self.right.sig_data
3106+
3107+
self.valid = svalid
3108+
self.enable = senable
3109+
3110+
if self.latency == 0:
3111+
data = m.Wire(self.name('data'), width, signed=signed)
3112+
data.assign(rdata)
3113+
self.sig_data = data
3114+
3115+
elif self.latency == 1:
3116+
data = m.Reg(self.name('data'), width, initval=0, signed=signed)
3117+
self.sig_data = data
3118+
seq(data(rdata), cond=senable)
3119+
3120+
else:
3121+
prev_data = None
3122+
3123+
for i in range(self.latency):
3124+
data = m.Reg(self.name('data_d%d' % i),
3125+
width, initval=0, signed=signed)
3126+
if i == 0:
3127+
seq(data(self.op(rdata)), cond=senable)
3128+
else:
3129+
seq(data(prev_data), cond=senable)
3130+
prev_data = data
3131+
3132+
self.sig_data = data
3133+
3134+
3135+
class FromExtern(_UnaryOperator):
3136+
latency = 1
3137+
3138+
def __init__(self, right, latency=1):
3139+
_UnaryOperator.__init__(self, right)
3140+
self.latency = latency
3141+
3142+
self.graph_label = 'FromExtern'
3143+
self.graph_shape = 'box'
3144+
3145+
@property
3146+
def data(self):
3147+
return self.sig_data
3148+
3149+
def eval(self):
3150+
return self
3151+
3152+
def _implement(self, m, seq, svalid=None, senable=None):
3153+
width = self.bit_length()
3154+
signed = self.get_signed()
3155+
3156+
self.valid = svalid
3157+
self.enable = senable
3158+
3159+
data = m.Reg(self.name('data'), width, initval=0, signed=signed)
3160+
self.sig_data = data
3161+
3162+
30863163
def make_condition(*cond, **kwargs):
30873164
ready = kwargs['ready'] if 'ready' in kwargs else None
30883165

0 commit comments

Comments
 (0)