Skip to content

Commit e9f2fd8

Browse files
committed
Supporting the execution as software for veriloggen.thread methods. Some intrinsic methods are also able to be executed as software.
1 parent c47ce66 commit e9f2fd8

File tree

22 files changed

+679
-208
lines changed

22 files changed

+679
-208
lines changed

examples/thread_axi_slave_ipxact/thread_axi_slave_ipxact.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ def blink(size):
4949
saxi.write(1, 0) # unset busy
5050

5151
th = vthread.Thread(m, 'th_blink', clk, rst, blink)
52-
th.add_intrinsics(wait)
52+
th.add_intrinsic(wait, 'wait')
53+
5354
fsm = th.start(16)
5455

5556
return m
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
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_exec_as_sw
7+
8+
9+
def test(request):
10+
veriloggen.reset()
11+
12+
simtype = request.config.getoption('--sim')
13+
14+
rslt = thread_exec_as_sw.run(filename=None, simtype=simtype,
15+
outputfile=os.path.splitext(os.path.basename(__file__))[0] + '.out')
16+
17+
verify_rslt = [line for line in rslt.splitlines() if line.startswith('# verify:')][0]
18+
assert(verify_rslt == '# verify: PASSED')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
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+
13+
14+
def mkLed():
15+
m = Module('blinkled')
16+
clk = m.Input('CLK')
17+
rst = m.Input('RST')
18+
led = m.OutputReg('LED', 8, initval=0)
19+
20+
datawidth = 32
21+
addrwidth = 10
22+
myram = vthread.RAM(m, 'myram', clk, rst, datawidth, addrwidth)
23+
24+
def blink(times):
25+
all_ok = True
26+
27+
write_sum = 0
28+
for i in range(times):
29+
wdata = i
30+
myram.write(i, wdata)
31+
write_sum += wdata
32+
print('wdata = %d' % wdata)
33+
34+
read_sum = 0
35+
for i in range(times):
36+
rdata = myram.read(i)
37+
read_sum += rdata
38+
print('rdata = %d' % rdata)
39+
#if vthread.verilog.NotEql(rdata, i):
40+
if rdata != i:
41+
all_ok = False
42+
43+
print('read_sum = %d' % read_sum)
44+
45+
#if vthread.verilog.NotEql(read_sum, write_sum):
46+
if read_sum != write_sum:
47+
all_ok = False
48+
49+
led.value = 0
50+
for i in range(times):
51+
led.value += 1
52+
print(led, i)
53+
54+
if all_ok and led == times:
55+
print('# verify: PASSED')
56+
else:
57+
print('# verify: FAILED')
58+
59+
# as SW
60+
print("as SW")
61+
blink(100)
62+
63+
print("as HW")
64+
65+
# as HW
66+
th = vthread.Thread(m, 'th_blink', clk, rst, blink)
67+
fsm = th.start(100)
68+
69+
return m
70+
71+
72+
def mkTest():
73+
m = Module('test')
74+
75+
# target instance
76+
led = mkLed()
77+
78+
# copy paras and ports
79+
params = m.copy_params(led)
80+
ports = m.copy_sim_ports(led)
81+
82+
clk = ports['CLK']
83+
rst = ports['RST']
84+
85+
uut = m.Instance(led, 'uut',
86+
params=m.connect_params(led),
87+
ports=m.connect_ports(led))
88+
89+
# vcd_name = os.path.splitext(os.path.basename(__file__))[0] + '.vcd'
90+
# simulation.setup_waveform(m, uut, dumpfile=vcd_name)
91+
simulation.setup_clock(m, clk, hperiod=5)
92+
init = simulation.setup_reset(m, rst, m.make_reset(), period=100)
93+
94+
init.add(
95+
Delay(1000000),
96+
Systask('finish'),
97+
)
98+
99+
return m
100+
101+
102+
def run(filename='tmp.v', simtype='iverilog', outputfile=None):
103+
104+
if outputfile is None:
105+
outputfile = os.path.splitext(os.path.basename(__file__))[0] + '.out'
106+
107+
test = mkTest()
108+
109+
if filename is not None:
110+
test.to_verilog(filename)
111+
112+
sim = simulation.Simulator(test, sim=simtype)
113+
rslt = sim.run(outputfile=outputfile)
114+
115+
return rslt
116+
117+
118+
if __name__ == '__main__':
119+
rslt = run(filename='tmp.v')
120+
print(rslt)

tests/extension/thread_/intrinsic_function/thread_intrinsic_function.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ def blink(times):
4646

4747
th = vthread.Thread(m, 'th_blink', clk, rst, blink)
4848

49-
# add intrinsics
50-
th.add_intrinsics(send, wait)
49+
# add intrinsic functions
50+
th.add_intrinsic(send, 'send')
51+
th.add_intrinsic(wait, 'wait')
5152

5253
fsm = th.start(10)
5354

tests/extension/thread_/intrinsic_verilog/thread_intrinsic_verilog.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ def blink(times):
4747

4848
th = vthread.Thread(m, 'th_blink', clk, rst, blink)
4949

50-
# add intrinsics
51-
th.add_intrinsics(send, wait)
50+
# add intrinsic functions
51+
th.add_intrinsic(send, 'send')
52+
th.add_intrinsic(wait, 'wait')
5253

5354
fsm = th.start(10)
5455

veriloggen/stream/stypes.py

+10-4
Original file line numberDiff line numberDiff line change
@@ -4421,7 +4421,7 @@ def _implement(self, m, seq, svalid=None, senable=None):
44214421

44224422

44234423
class FromExtern(_UnaryOperator):
4424-
__intrinsics__ = ('write')
4424+
__intrinsics__ = {'write': '_intrinsic_write'}
44254425
latency = 1
44264426

44274427
def __init__(self, right, width=None, point=None, signed=True, latency=1):
@@ -4458,13 +4458,16 @@ def _implement(self, m, seq, svalid=None, senable=None):
44584458
data = fx.FixedReg(m, self.name('data'), width, point, initval=0, signed=signed)
44594459
self.sig_data = data
44604460

4461-
def write(self, fsm, value):
4461+
def _intrinsic_write(self, fsm, value):
44624462
cond = fsm.here
44634463

44644464
self.seq.If(cond)(
44654465
self.sig_data(value)
44664466
)
44674467

4468+
def write(self, value):
4469+
raise NotImplementedError("only intrinsic method is implemented.")
4470+
44684471

44694472
class _LineBufferOut(_UnaryOperator):
44704473
latency = 1
@@ -4766,20 +4769,23 @@ def _implement(self, m, seq, svalid=None, senable=None):
47664769

47674770

47684771
class Reg(Predicate):
4769-
__intrinsics__ = ('write')
4772+
__intrinsics__ = {'write': '_intrinsic_write'}
47704773

47714774
def __init__(self, data, when=None):
47724775
Predicate.__init__(self, data, when)
47734776
self.graph_label = 'Reg'
47744777
self.graph_shape = 'box'
47754778

4776-
def write(self, fsm, value):
4779+
def _intrinsic_write(self, fsm, value):
47774780
cond = fsm.here
47784781

47794782
self.seq.If(cond)(
47804783
self.sig_data(value)
47814784
)
47824785

4786+
def write(self, value):
4787+
raise NotImplementedError("only intrinsic method is implemented.")
4788+
47834789

47844790
class ReadRAM(_SpecialOperator):
47854791
latency = 1

veriloggen/thread/__init__.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@
1515

1616
from . import fixed
1717

18-
__intrinsics__ = []
19-
__intrinsics__.extend(__ttypes_intrinsics__)
20-
__intrinsics__.extend(__util_intrinsics__)
18+
__intrinsics__ = {}
19+
__intrinsics__.update(__ttypes_intrinsics__)
20+
__intrinsics__.update(__util_intrinsics__)

veriloggen/thread/axim.py

+37-18
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,34 @@
1818
class AXIM(axi.AxiMaster, _MutexFunction):
1919
""" AXI Master Interface with DMA controller """
2020

21-
__intrinsics__ = ('read', 'write', 'write_fence',
22-
'dma_read', 'dma_read_async',
23-
'dma_write', 'dma_write_async',
24-
'dma_read_bank', 'dma_read_bank_async',
25-
'dma_write_bank', 'dma_write_bank_async',
26-
'dma_read_block', 'dma_read_block_async',
27-
'dma_write_block', 'dma_write_block_async',
28-
'dma_read_packed', 'dma_read_packed_async',
29-
'dma_write_packed', 'dma_write_packed_async',
30-
'dma_read_bcast', 'dma_read_bcast_async',
31-
'dma_wait_read', 'dma_wait_write',
32-
'dma_wait_write_idle', 'dma_wait_write_response',
33-
'dma_wait',
34-
'set_global_base_addr',) + _MutexFunction.__intrinsics__
21+
__intrinsics__ = {'read': 'read',
22+
'write': 'write',
23+
'write_fence': 'write_fence',
24+
'dma_read': 'dma_read',
25+
'dma_read_async': 'dma_read_async',
26+
'dma_write': 'dma_write',
27+
'dma_write_async': 'dma_write_async',
28+
'dma_read_bank': 'dma_read_bank',
29+
'dma_read_bank_async': 'dma_read_bank_async',
30+
'dma_write_bank': 'dma_write_bank',
31+
'dma_write_bank_async': 'dma_write_bank_async',
32+
'dma_read_block': 'dma_read_block',
33+
'dma_read_block_async': 'dma_read_block_async',
34+
'dma_write_block': 'dma_write_block',
35+
'dma_write_block_async': 'dma_write_block_async',
36+
'dma_read_packed': 'dma_read_packed',
37+
'dma_read_packed_async': 'dma_read_packed_async',
38+
'dma_write_packed': 'dma_write_packed',
39+
'dma_write_packed_async': 'dma_write_packed_async',
40+
'dma_read_bcast': 'dma_read_bcast',
41+
'dma_read_bcast_async': 'dma_read_bcast_async',
42+
'dma_wait_read': 'dma_wait_read',
43+
'dma_wait_write': 'dma_wait_write',
44+
'dma_wait_write_idle': 'dma_wait_write_idle',
45+
'dma_wait_write_response': 'dma_wait_write_response',
46+
'dma_wait': 'dma_wait',
47+
'set_global_base_addr': 'set_global_base_addr',
48+
} | _MutexFunction.__intrinsics__
3549

3650
def __init__(self, m, name, clk, rst, datawidth=32, addrwidth=32,
3751
waddr_id_width=0, wdata_id_width=0, wresp_id_width=0,
@@ -1709,7 +1723,8 @@ def unpack_write_req(self, v):
17091723

17101724

17111725
class AXIMVerify(AXIM):
1712-
__intrinsics__ = ('read_delayed', 'write_delayed') + AXIM.__intrinsics__
1726+
__intrinsics__ = {'read_delayed': 'read_delayed',
1727+
'write_delayed': 'write_delayed'} | AXIM.__intrinsics__
17131728

17141729
def read_delayed(self, fsm, global_addr, delay):
17151730
if self.use_global_base_addr:
@@ -1803,8 +1818,11 @@ def write_delayed(self, fsm, global_addr, value, delay):
18031818
class AXIMLite(axi.AxiLiteMaster, _MutexFunction):
18041819
""" AXI-Lite Master Interface """
18051820

1806-
__intrinsics__ = ('read', 'write', 'write_fence',
1807-
'set_global_base_addr',) + _MutexFunction.__intrinsics__
1821+
__intrinsics__ = {'read': 'read',
1822+
'write': 'write',
1823+
'write_fence': 'write_fence',
1824+
'set_global_base_addr': 'set_global_base_addr'
1825+
} | _MutexFunction.__intrinsics__
18081826

18091827
def __init__(self, m, name, clk, rst, datawidth=32, addrwidth=32,
18101828
waddr_cache_mode=axi.AxCACHE_NONCOHERENT, raddr_cache_mode=axi.AxCACHE_NONCOHERENT,
@@ -1897,7 +1915,8 @@ def set_global_base_addr(self, fsm, addr):
18971915

18981916

18991917
class AXIMLiteVerify(AXIMLite):
1900-
__intrinsics__ = ('read_delayed', 'write_delayed') + AXIMLite.__intrinsics__
1918+
__intrinsics__ = {'read_delayed': 'read_delayed',
1919+
'write_delayed': 'write_delayed'} | AXIMLite.__intrinsics__
19011920

19021921
def read_delayed(self, fsm, global_addr, delay):
19031922
if self.use_global_base_addr:

veriloggen/thread/axis.py

+12-4
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,12 @@ def __init__(self, m, name, clk, rst, datawidth=32, addrwidth=32,
4242

4343

4444
class AXISRegister(AXIS):
45-
__intrinsics__ = ('read', 'write', 'write_flag', 'wait',
46-
'wait_flag') + _MutexFunction.__intrinsics__
45+
__intrinsics__ = {'read': 'read',
46+
'write': 'write',
47+
'write_flag': 'write_flag',
48+
'wait': 'wait',
49+
'wait_flag': 'wait_flag',
50+
} | _MutexFunction.__intrinsics__
4751

4852
def __init__(self, m, name, clk, rst, datawidth=32, addrwidth=32,
4953
waddr_id_width=0, wdata_id_width=0, wresp_id_width=0,
@@ -242,8 +246,12 @@ def wait_flag(self, fsm, addr, value, resetvalue=0, polarity=True):
242246

243247

244248
class AXISLiteRegister(AXISLite):
245-
__intrinsics__ = ('read', 'write', 'write_flag', 'wait',
246-
'wait_flag') + _MutexFunction.__intrinsics__
249+
__intrinsics__ = {'read': 'read',
250+
'write': 'write',
251+
'write_flag': 'write_flag',
252+
'wait': 'wait',
253+
'wait_flag': 'wait_flag',
254+
} | _MutexFunction.__intrinsics__
247255

248256
def __init__(self, m, name, clk, rst, datawidth=32, addrwidth=32,
249257
noio=False, length=4, fsm_as_module=False):

0 commit comments

Comments
 (0)