Skip to content

Commit b581f22

Browse files
committed
Merge branch 'develop' into feature_axi_stream
2 parents 46dd058 + 5e66227 commit b581f22

File tree

7 files changed

+237
-17
lines changed

7 files changed

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

veriloggen/stream/graph.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ def visit__Accumulator(self, node):
217217
if node.interval is not None:
218218
interval = self.visit(node.interval)
219219
initval = self.visit(node.initval)
220+
if node.offset is not None:
221+
offset = self.visit(node.offset)
220222
if node.dependency is not None:
221223
dependency = self.visit(node.dependency)
222224
if node.enable is not None:
@@ -229,6 +231,8 @@ def visit__Accumulator(self, node):
229231
if node.interval is not None:
230232
self.graph.add_edge(interval, node, label='interval')
231233
self.graph.add_edge(initval, node, label='initval')
234+
if node.offset is not None:
235+
self.graph.add_edge(offset, node, label='offset')
232236
if node.dependency is not None:
233237
self.graph.add_edge(dependency, node, label='dependency')
234238
if node.enable is not None:

veriloggen/stream/scheduler.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ def visit__Accumulator(self, node):
125125
interval = (self.visit(node.interval)
126126
if node.interval is not None else None)
127127
initval = self.visit(node.initval)
128+
offset = (self.visit(node.offset)
129+
if node.offset is not None else None)
128130
dependency = (self.visit(node.dependency)
129131
if node.dependency is not None else None)
130132
enable = self.visit(node.enable) if node.enable is not None else None
@@ -136,6 +138,8 @@ def visit__Accumulator(self, node):
136138
if node.interval is not None:
137139
node.interval = self.fill_gap(node.interval, mine)
138140
node.initval = self.fill_gap(node.initval, mine)
141+
if node.offset is not None:
142+
node.offset = self.fill_gap(node.offset, mine)
139143
if node.enable is not None:
140144
node.enable = self.fill_gap(node.enable, mine)
141145
if node.reset is not None:

veriloggen/stream/stypes.py

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2465,13 +2465,15 @@ class _Accumulator(_UnaryOperator):
24652465
latency = 1
24662466
ops = (vtypes.Plus, )
24672467

2468-
def __init__(self, right, size=None, interval=None, initval=None,
2468+
def __init__(self, right, size=None, interval=None, initval=None, offset=None,
24692469
dependency=None, enable=None, reset=None, width=32, signed=True):
24702470

24712471
self.size = _to_constant(size) if size is not None else None
24722472
self.interval = _to_constant(interval) if interval is not None else None
24732473
self.initval = (_to_constant(initval)
24742474
if initval is not None else _to_constant(0))
2475+
self.offset = (_to_constant(offset)
2476+
if offset is not None else None)
24752477

24762478
if not isinstance(self.initval, _Constant):
24772479
raise TypeError("initval must be Constant, not '%s'" %
@@ -2664,8 +2666,9 @@ class ReduceAdd(_Accumulator):
26642666

26652667
def __init__(self, right, size=None, interval=None, initval=0,
26662668
enable=None, reset=None, width=32, signed=True):
2669+
offset = None
26672670
dependency = None
2668-
_Accumulator.__init__(self, right, size, interval, initval,
2671+
_Accumulator.__init__(self, right, size, interval, initval, offset,
26692672
dependency, enable, reset, width, signed)
26702673
self.graph_label = 'ReduceAdd'
26712674

@@ -2675,8 +2678,9 @@ class ReduceSub(_Accumulator):
26752678

26762679
def __init__(self, right, size=None, interval=None, initval=0,
26772680
enable=None, reset=None, width=32, signed=True):
2681+
offset = None
26782682
dependency = None
2679-
_Accumulator.__init__(self, right, size, interval, initval,
2683+
_Accumulator.__init__(self, right, size, interval, initval, offset,
26802684
dependency, enable, reset, width, signed)
26812685
self.graph_label = 'ReduceSub'
26822686

@@ -2687,8 +2691,9 @@ class ReduceMul(_Accumulator):
26872691

26882692
def __init__(self, right, size=None, interval=None, initval=0,
26892693
enable=None, reset=None, width=32, signed=True):
2694+
offset = None
26902695
dependency = None
2691-
_Accumulator.__init__(self, right, size, interval, initval,
2696+
_Accumulator.__init__(self, right, size, interval, initval, offset,
26922697
dependency, enable, reset, width, signed)
26932698
self.graph_label = 'ReduceMul'
26942699

@@ -2700,8 +2705,9 @@ class ReduceDiv(_Accumulator):
27002705
def __init__(self, right, size=None, interval=None, initval=0,
27012706
enable=None, reset=None, width=32, signed=True):
27022707
raise NotImplementedError()
2708+
offset = None
27032709
dependency = None
2704-
_Accumulator.__init__(self, right, size, interval, initval,
2710+
_Accumulator.__init__(self, right, size, interval, initval, offset,
27052711
dependency, enable, reset, width, signed)
27062712
self.graph_label = 'ReduceDiv'
27072713

@@ -2711,8 +2717,9 @@ class ReduceMax(_Accumulator):
27112717

27122718
def __init__(self, right, size=None, interval=None, initval=0,
27132719
enable=None, reset=None, width=32, signed=True):
2720+
offset = None
27142721
dependency = None
2715-
_Accumulator.__init__(self, right, size, interval, initval,
2722+
_Accumulator.__init__(self, right, size, interval, initval, offset,
27162723
dependency, enable, reset, width, signed)
27172724
self.graph_label = 'ReduceMax'
27182725

@@ -2722,8 +2729,9 @@ class ReduceMin(_Accumulator):
27222729

27232730
def __init__(self, right, size=None, interval=None, initval=0,
27242731
enable=None, reset=None, width=32, signed=True):
2732+
offset = None
27252733
dependency = None
2726-
_Accumulator.__init__(self, right, size, interval, initval,
2734+
_Accumulator.__init__(self, right, size, interval, initval, offset,
27272735
dependency, enable, reset, width, signed)
27282736
self.graph_label = 'ReduceMin'
27292737

@@ -2732,8 +2740,9 @@ class ReduceCustom(_Accumulator):
27322740

27332741
def __init__(self, ops, right, size=None, interval=None, initval=0,
27342742
enable=None, reset=None, width=32, signed=True, label=None):
2743+
offset = None
27352744
dependency = None
2736-
_Accumulator.__init__(self, right, size, interval, initval,
2745+
_Accumulator.__init__(self, right, size, interval, initval, offset,
27372746
dependency, enable, reset, width, signed)
27382747
if not isinstance(ops, (tuple, list)):
27392748
ops = tuple([ops])
@@ -2743,10 +2752,10 @@ def __init__(self, ops, right, size=None, interval=None, initval=0,
27432752

27442753
class Counter(_Accumulator):
27452754

2746-
def __init__(self, size=None, step=1, interval=None, initval=0,
2755+
def __init__(self, size=None, step=1, interval=None, initval=0, offset=None,
27472756
dependency=None, enable=None, reset=None, width=32, signed=False):
27482757

2749-
_Accumulator.__init__(self, step, size, interval, initval,
2758+
_Accumulator.__init__(self, step, size, interval, initval, offset,
27502759
dependency, enable, reset, width, signed)
27512760
self.graph_label = 'Counter'
27522761

@@ -2759,6 +2768,7 @@ def _implement(self, m, seq, svalid=None, senable=None):
27592768
interval_data = self.interval.sig_data if self.interval is not None else None
27602769

27612770
initval_data = self.initval.sig_data
2771+
offset_data = self.offset.sig_data if self.offset is not None else None
27622772
width = self.bit_length()
27632773
signed = self.get_signed()
27642774

@@ -2770,7 +2780,10 @@ def _implement(self, m, seq, svalid=None, senable=None):
27702780
initval=initval_data, signed=signed)
27712781

27722782
next_count_value = count + step
2773-
if self.size is not None:
2783+
if self.size is not None and self.offset is not None:
2784+
next_count_value = vtypes.Mux(count >= size_data - step,
2785+
offset_data, next_count_value)
2786+
elif self.size is not None:
27742787
next_count_value = vtypes.Mux(count >= size_data - step,
27752788
next_count_value - size_data, next_count_value)
27762789

@@ -2835,10 +2848,11 @@ def __init__(self, size, interval=None,
28352848
right = dependency
28362849

28372850
initval = 0
2851+
offset = None
28382852
width = 1
28392853
signed = False
28402854

2841-
_Accumulator.__init__(self, right, size, interval, initval,
2855+
_Accumulator.__init__(self, right, size, interval, initval, offset,
28422856
dependency, enable, reset, width, signed)
28432857
self.graph_label = 'Pulse'
28442858

@@ -2911,10 +2925,10 @@ def ReduceCustomValid(ops, right, size, interval=None, initval=0,
29112925
return data, valid
29122926

29132927

2914-
def CounterValid(size, step=1, interval=None, initval=0,
2928+
def CounterValid(size, step=1, interval=None, initval=0, offset=None,
29152929
dependency=None, enable=None, reset=None, width=32, signed=False):
29162930

2917-
data = Counter(size, step, interval, initval,
2931+
data = Counter(size, step, interval, initval, offset,
29182932
dependency, enable, reset, width, signed)
29192933
valid = Pulse(size, dependency=dependency, enable=enable, reset=reset)
29202934

0 commit comments

Comments
 (0)