Skip to content

Commit e1c7400

Browse files
committed
add stypes.Xorshift
1 parent e0fd2fe commit e1c7400

File tree

4 files changed

+264
-0
lines changed

4 files changed

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

veriloggen/stream/stypes.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3630,6 +3630,76 @@ def _implement(self, m, seq, svalid=None, senable=None):
36303630
seq(count(next_count_value), cond=enable_cond)
36313631

36323632

3633+
class Xorshift(_Accumulator):
3634+
3635+
def __init__(self, initval=0x12345678, dependency=None, enable=None, reset=None,
3636+
reg_initval=None, width=32):
3637+
right = 0
3638+
size = None
3639+
interval = None
3640+
offset = None
3641+
signed = False
3642+
3643+
_Accumulator.__init__(self, right, size, interval, initval, offset,
3644+
dependency, enable, reset, reg_initval, width, signed)
3645+
self.graph_label = 'XorShift'
3646+
3647+
def _implement(self, m, seq, svalid=None, senable=None):
3648+
if self.latency != 1:
3649+
raise ValueError("Latency mismatch '%d' vs '%s'" %
3650+
(self.latency, 1))
3651+
3652+
initval_data = self.initval.sig_data
3653+
width = self.get_width()
3654+
signed = self.get_signed()
3655+
3656+
reg_initval_data = self.reg_initval.sig_data
3657+
3658+
data = m.Reg(self.name('data'), width,
3659+
initval=reg_initval_data, signed=signed)
3660+
3661+
randval = m.Reg(self.name('randval'), width,
3662+
initval=reg_initval_data, signed=signed)
3663+
3664+
self.sig_data = data
3665+
3666+
enabledata = self.enable.sig_data if self.enable is not None else None
3667+
resetdata = self.reset.sig_data if self.reset is not None else None
3668+
3669+
reset_cond = m.Wire(self.name('reset_cond'))
3670+
if self.reset is not None:
3671+
reset_cond.assign(resetdata)
3672+
current_randval = m.WireLike(randval, name=self.name('current_count'))
3673+
current_randval.assign(vtypes.Mux(reset_cond, initval_data, randval))
3674+
else:
3675+
reset_cond.assign(0)
3676+
current_randval = randval
3677+
3678+
if width == 32:
3679+
next_value = current_randval ^ (current_randval << 13)
3680+
next_value = next_value ^ (next_value >> 17)
3681+
next_value = next_value ^ (next_value << 5)
3682+
elif width == 64:
3683+
next_value = current_randval ^ (current_randval << 13)
3684+
next_value = next_value ^ (next_value >> 7)
3685+
next_value = next_value ^ (next_value << 17)
3686+
else:
3687+
raise ValueError("Invalid width value '%d', please specify 32 or 64" % width)
3688+
3689+
enable_cond = _and_vars(svalid, senable)
3690+
3691+
if self.reset is not None:
3692+
enable_reset_cond = _and_vars(enable_cond, reset_cond)
3693+
seq(data(initval_data), cond=enable_reset_cond)
3694+
3695+
seq(data(current_randval), cond=enable_cond)
3696+
3697+
if self.enable is not None:
3698+
enable_cond = _and_vars(enable_cond, enabledata)
3699+
3700+
seq(randval(next_value), cond=enable_cond)
3701+
3702+
36333703
class Pulse(_Accumulator):
36343704
ops = ()
36353705

0 commit comments

Comments
 (0)