Skip to content

Commit a198dc7

Browse files
committed
fixed point with negative point value is supported.
1 parent 07ac5db commit a198dc7

File tree

9 files changed

+306
-54
lines changed

9 files changed

+306
-54
lines changed

tests/extension/thread_/stream_fixed/thread_stream_fixed.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def mkLed():
1919

2020
datawidth = 32
2121
addrwidth = 10
22-
point = 32
22+
point = 4
2323
myaxi = vthread.AXIM(m, 'myaxi', clk, rst, datawidth)
2424
ram_a = vthread.FixedRAM(m, 'ram_a', clk, rst, datawidth, addrwidth,
2525
point=point)
@@ -32,14 +32,14 @@ def mkLed():
3232
a = strm.source('a', point=point)
3333
b = strm.source('b', point=point)
3434
const = strm.constant('const', point=point)
35-
c = a + b + const
35+
c = a * b + const
3636
strm.sink(c, 'c')
3737

3838
def comp_stream(size, offset):
3939
strm.set_source('a', ram_a, offset, size)
4040
strm.set_source('b', ram_b, offset, size)
4141
strm.set_sink('c', ram_c, offset, size)
42-
const = vthread.fixed.FixedConst(0.0, point=point)
42+
const = vthread.fixed.FixedConst(1, point=point)
4343
strm.set_constant('const', const)
4444
strm.run()
4545
strm.join()
@@ -48,10 +48,10 @@ def comp_sequential(size, offset):
4848
for i in range(size):
4949
a = ram_a.read(i + offset)
5050
b = ram_b.read(i + offset)
51-
const = vthread.fixed.FixedConst(0.0, point=point)
52-
c = a + b + const
51+
const = vthread.fixed.FixedConst(1, point=point)
52+
c = a * b + const
5353
ram_c.write(i + offset, c)
54-
#print('a = %f, b = %f, const = %f, c = %f' % (a, b, const, c))
54+
print('a = %10g, b = %10g, const = %10g, c = %10g' % (a, b, const, c))
5555

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

veriloggen/stream/stream.py

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -329,24 +329,25 @@ def get_name(obj):
329329
self.dump_base)
330330
base_char = ('b' if base == 2 else
331331
'o' if base == 8 else
332-
'd' if base == 10 and input_var.point == 0 else
333-
#'f' if base == 10 and input_var.point > 0 else
332+
'd' if base == 10 and input_var.point <= 0 else
333+
# 'f' if base == 10 and input_var.point > 0 else
334334
'g' if base == 10 and input_var.point > 0 else
335335
'x')
336336
prefix = ('0b' if base == 2 else
337337
'0o' if base == 8 else
338338
' ' if base == 10 else
339339
'0x')
340340

341-
#if base_char == 'f':
341+
# if base_char == 'f':
342342
# point_length = int(math.ceil(input_var.point / math.log(base, 2)))
343343
# point_length = max(point_length, 8)
344344
# fmt_list = [prefix, '%',
345345
# '%d.%d' % (longest_var_len + 1, point_length), base_char]
346-
if base_char == 'g':
347-
fmt_list = [prefix, '%', base_char]
348-
else:
349-
fmt_list = [prefix, '%', '%d' % (longest_var_len + 1), base_char]
346+
# if base_char == 'g':
347+
# fmt_list = [prefix, '%', base_char]
348+
# else:
349+
# fmt_list = [prefix, '%', '%d' % (longest_var_len + 1), base_char]
350+
fmt_list = [prefix, '%', '%d' % (longest_var_len + 1), base_char]
350351

351352
if input_var not in all_vars:
352353
fmt_list.append(' (unused)')
@@ -359,24 +360,25 @@ def get_name(obj):
359360
self.dump_base)
360361
base_char = ('b' if base == 2 else
361362
'o' if base == 8 else
362-
'd' if base == 10 and output_var.point == 0 else
363-
#'f' if base == 10 and output_var.point > 0 else
363+
'd' if base == 10 and output_var.point <= 0 else
364+
# 'f' if base == 10 and output_var.point > 0 else
364365
'g' if base == 10 and output_var.point > 0 else
365366
'x')
366367
prefix = ('0b' if base == 2 else
367368
'0o' if base == 8 else
368369
' ' if base == 10 else
369370
'0x')
370371

371-
#if base_char == 'f':
372+
# if base_char == 'f':
372373
# point_length = int(math.ceil(output_var.point / math.log(base, 2)))
373374
# point_length = max(point_length, 8)
374375
# fmt_list = [prefix, '%',
375376
# '%d.%d' % (longest_var_len + 1, point_length), base_char]
376-
if base_char == 'g':
377-
fmt_list = [prefix, '%', base_char]
378-
else:
379-
fmt_list = [prefix, '%', '%d' % (longest_var_len + 1), base_char]
377+
# if base_char == 'g':
378+
# fmt_list = [prefix, '%', base_char]
379+
# else:
380+
# fmt_list = [prefix, '%', '%d' % (longest_var_len + 1), base_char]
381+
fmt_list = [prefix, '%', '%d' % (longest_var_len + 1), base_char]
380382

381383
if output_var not in all_vars:
382384
fmt_list.append(' (unused)')
@@ -391,24 +393,25 @@ def get_name(obj):
391393
self.dump_base)
392394
base_char = ('b' if base == 2 else
393395
'o' if base == 8 else
394-
'd' if base == 10 and var.point == 0 else
395-
#'f' if base == 10 and var.point > 0 else
396+
'd' if base == 10 and var.point <= 0 else
397+
# 'f' if base == 10 and var.point > 0 else
396398
'g' if base == 10 and var.point > 0 else
397399
'x')
398400
prefix = ('0b' if base == 2 else
399401
'0o' if base == 8 else
400402
' ' if base == 10 else
401403
'0x')
402404

403-
#if base_char == 'f':
405+
# if base_char == 'f':
404406
# point_length = int(math.ceil(var.point / math.log(base, 2)))
405407
# point_length = max(point_length, 8)
406408
# fmt_list = [prefix, '%',
407409
# '%d.%d' % (longest_var_len + 1, point_length), base_char]
408-
if base_char == 'g':
409-
fmt_list = [prefix, '%', base_char]
410-
else:
411-
fmt_list = [prefix, '%', '%d' % (longest_var_len + 1), base_char]
410+
# if base_char == 'g':
411+
# fmt_list = [prefix, '%', base_char]
412+
# else:
413+
# fmt_list = [prefix, '%', '%d' % (longest_var_len + 1), base_char]
414+
fmt_list = [prefix, '%', '%d' % (longest_var_len + 1), base_char]
412415

413416
var.dump_fmt = ''.join(fmt_list)
414417

@@ -437,11 +440,13 @@ def get_name(obj):
437440
enables.append(enable)
438441
age = seq.Prev(self.dump_step, stage) - 1
439442

440-
if input_var.point == 0:
441-
sig_data = input_var.sig_data
442-
else:
443+
if input_var.point > 0:
443444
sig_data = vtypes.Div(vtypes.SystemTask('itor', input_var.sig_data),
444445
1.0 * (2 ** input_var.point))
446+
elif input_var.point < 0:
447+
sig_data = vtypes.Times(input_var.sig_data, 2 ** -input_var.point)
448+
else:
449+
sig_data = input_var.sig_data
445450

446451
seq.If(enable, vtypes.Not(self.dump_mask))(
447452
vtypes.Display(fmt, self.dump_step, stage, age, sig_data)
@@ -470,11 +475,13 @@ def get_name(obj):
470475
enables.append(enable)
471476
age = seq.Prev(self.dump_step, stage) - 1
472477

473-
if var.point == 0:
474-
sig_data = var.sig_data
475-
else:
478+
if var.point > 0:
476479
sig_data = vtypes.Div(vtypes.SystemTask('itor', var.sig_data),
477480
1.0 * (2 ** var.point))
481+
elif var.point < 0:
482+
sig_data = vtypes.Times(var.sig_data, 2 ** -var.point)
483+
else:
484+
sig_data = var.sig_data
478485

479486
seq.If(enable, vtypes.Not(self.dump_mask))(
480487
vtypes.Display(fmt, self.dump_step, stage, age, sig_data)
@@ -504,11 +511,13 @@ def get_name(obj):
504511
enables.append(enable)
505512
age = seq.Prev(self.dump_step, stage) - 1
506513

507-
if output_var.point == 0:
508-
sig_data = output_var.output_sig_data
509-
else:
514+
if output_var.point > 0:
510515
sig_data = vtypes.Div(vtypes.SystemTask('itor', output_var.output_sig_data),
511516
1.0 * (2 ** output_var.point))
517+
elif output_var.point < 0:
518+
sig_data = vtypes.Times(output_var.output_sig_data, 2 ** -output_var.point)
519+
else:
520+
sig_data = output_var.output_sig_data
512521

513522
seq.If(enable, vtypes.Not(self.dump_mask))(
514523
vtypes.Display(fmt, self.dump_step, stage, age, sig_data)

0 commit comments

Comments
 (0)