1
0
mirror of https://github.com/myhdl/myhdl.git synced 2024-12-14 07:44:38 +08:00

Custom code support; migrate tests and call them test_custom.py

This commit is contained in:
Jan Decaluwe 2016-02-10 18:45:49 +01:00
parent 2ab73788f7
commit 7fd658f966
6 changed files with 106 additions and 62 deletions

View File

@ -26,7 +26,8 @@ import inspect
from myhdl import ModuleError
from myhdl._instance import _Instantiator
from myhdl._util import _flatten
from myhdl._extractHierarchy import _MemInfo, _makeMemInfo
from myhdl._extractHierarchy import (_MemInfo, _makeMemInfo,
_UserVerilogCode, _UserVhdlCode)
from myhdl._Signal import _Signal, _isListOfSigs
@ -75,6 +76,8 @@ class _Module(object):
def __init__(self, modfunc):
self.modfunc = modfunc
self.__name__ = self.name = modfunc.__name__
self.sourcefile = inspect.getsourcefile(modfunc)
self.sourceline = inspect.getsourcelines(modfunc)[0]
self.count = 0
def __call__(self, *args, **kwargs):
@ -101,6 +104,13 @@ class _ModuleInstance(object):
self.update()
# self.inferInterface(*args, **kwargs)
self.name = self.__name__ = mod.__name__ + '_' + str(mod.count)
self.verilog_code = self.vhdl_code = None
if hasattr(mod, 'verilog_code'):
self.verilog_code = _UserVerilogCode(mod.verilog_code, self.symdict, mod.name,
mod.modfunc, mod.sourcefile, mod.sourceline)
if hasattr(mod, 'vhdl_code'):
self.vhdl_code = _UserVhdlCode(mod.vhdl_code, self.symdict, mod.name,
mod.modfunc, mod.sourcefile, mod.sourceline)
def verify(self):
for inst in self.subs:
@ -122,6 +132,8 @@ class _ModuleInstance(object):
if isinstance(inst, _Instantiator):
usedsigdict.update(inst.sigdict)
usedlosdict.update(inst.losdict)
if self.symdict is None:
self.symdict = {}
# Special case: due to attribute reference transformation, the
# sigdict and losdict from Instantiator objects may contain new
# references. Therefore, update the symdict with them.

View File

@ -40,7 +40,8 @@ class _AttrRefTransformer(ast.NodeTransformer):
def visit_Attribute(self, node):
self.generic_visit(node)
reserved = ('next', 'posedge', 'negedge', 'max', 'min', 'val', 'signed')
reserved = ('next', 'posedge', 'negedge', 'max', 'min', 'val', 'signed',
'verilog_code', 'vhdl_code')
if node.attr in reserved:
return node

View File

@ -73,7 +73,11 @@ def _flatten(*args):
arglist = []
for arg in args:
if isinstance(arg, _ModuleInstance):
arg = arg.subs
if arg.vhdl_code is not None:
arglist.append(arg.vhdl_code)
continue
else:
arg = arg.subs
if id(arg) in _userCodeMap['vhdl']:
arglist.append(_userCodeMap['vhdl'][id(arg)])
elif isinstance(arg, (list, tuple, set)):

View File

@ -67,7 +67,11 @@ def _flatten(*args):
arglist = []
for arg in args:
if isinstance(arg, _ModuleInstance):
arg = arg.subs
if arg.verilog_code is not None:
arglist.append(arg.verilog_code)
continue
else:
arg = arg.subs
if id(arg) in _userCodeMap['verilog']:
arglist.append(_userCodeMap['verilog'][id(arg)])
elif isinstance(arg, (list, tuple, set)):

View File

@ -14,6 +14,7 @@ from myhdl.conversion._misc import _error
ACTIVE_LOW, INACTIVE_HIGH = 0, 1
@module
def incRef(count, enable, clock, reset, n):
""" Incrementer with enable.
@ -35,11 +36,12 @@ def incRef(count, enable, clock, reset, n):
return logic
@module
def incGen(count, enable, clock, reset, n):
""" Generator with __vhdl__ is not permitted """
""" Generator with vhdl_code is not permitted """
@instance
def logic():
__vhdl__ = "Template string"
incGen.vhdl_code = "Template string"
while 1:
yield clock.posedge, reset.negedge
if reset == ACTIVE_LOW:
@ -50,6 +52,7 @@ def incGen(count, enable, clock, reset, n):
return logic
@module
def inc(count, enable, clock, reset, n):
""" Incrementer with enable.
@ -71,14 +74,14 @@ def inc(count, enable, clock, reset, n):
count.driven = "reg"
__vhdl__ = \
inc.vhdl_code = \
"""
process (%(clock)s, %(reset)s) begin
if (%(reset)s = '0') then
%(count)s <= (others => '0');
elsif rising_edge(%(clock)s) then
if (%(enable)s = '1') then
%(count)s <= (%(count)s + 1) mod %(n)s;
process ($clock, $reset) begin
if ($reset = '0') then
$count <= (others => '0');
elsif rising_edge($clock) then
if ($enable = '1') then
$count <= ($count + 1) mod $n;
end if;
end if;
end process;
@ -87,6 +90,8 @@ end process;
return incProcess
@module
def incErr(count, enable, clock, reset, n):
@always(clock.posedge, reset.negedge)
@ -101,15 +106,15 @@ def incErr(count, enable, clock, reset, n):
count.driven = "reg"
__vhdl__ = \
incErr.vhdl_code = \
"""
always @(posedge %(clock)s, negedge %(reset)s) begin
if (%(reset)s == 0) begin
%(count)s <= 0;
always @(posedge $clock, negedge $reset) begin
if ($reset == 0) begin
$count <= 0;
end
else begin
if (%(enable)s) begin
%(count)s <= (%(countq)s + 1) %% %(n)s;
if ($enable) begin
$count <= ($countq + 1) %% $n;
end
end
end
@ -119,6 +124,7 @@ end
@module
def inc_comb(nextCount, count, n):
@always_comb
@ -129,17 +135,20 @@ def inc_comb(nextCount, count, n):
nextCount.driven = "wire"
__vhdl__ =\
inc_comb.vhdl_code =\
"""
%(nextCount)s <= (%(count)s + 1) mod %(n)s;
$nextCount <= ($count + 1) mod $n;
"""
return logic
@module
def inc_seq(count, nextCount, enable, clock, reset):
@always(clock.posedge, reset.negedge)
def logic():
# make if fail in conversion
import types
if reset == ACTIVE_LOW:
count.next = 0
else:
@ -148,14 +157,14 @@ def inc_seq(count, nextCount, enable, clock, reset):
count.driven = True
__vhdl__ = \
inc_seq.vhdl_code = \
"""
process (%(clock)s, %(reset)s) begin
if (%(reset)s = '0') then
%(count)s <= (others => '0');
elsif rising_edge(%(clock)s) then
if (%(enable)s = '1') then
%(count)s <= %(nextCount)s;
process ($clock, $reset) begin
if ($reset = '0') then
$count <= (others => '0');
elsif rising_edge($clock) then
if ($enable = '1') then
$count <= $nextCount;
end if;
end if;
end process;
@ -163,6 +172,7 @@ end process;
return logic
@module
def inc2(count, enable, clock, reset, n):
nextCount = Signal(intbv(0, min=0, max=n))
@ -173,11 +183,13 @@ def inc2(count, enable, clock, reset, n):
return comb, seq
@module
def inc3(count, enable, clock, reset, n):
inc2_inst = inc2(count, enable, clock, reset, n)
return inc2_inst
@module
def clockGen(clock):
@instance
def logic():
@ -191,6 +203,7 @@ NRTESTS = 1000
ENABLES = tuple([min(1, randrange(5)) for i in range(NRTESTS)])
@module
def stimulus(enable, clock, reset):
@instance
def logic():
@ -209,6 +222,7 @@ def stimulus(enable, clock, reset):
return logic
@module
def check(count, enable, clock, reset, n):
@instance
def logic():
@ -226,7 +240,7 @@ def check(count, enable, clock, reset, n):
print(count)
return logic
@module
def customBench(inc):
m = 8
@ -246,20 +260,20 @@ def customBench(inc):
def testIncRef():
assert conversion.verify(customBench, incRef) == 0
assert conversion.verify(customBench(incRef)) == 0
def testInc():
assert conversion.verify(customBench, inc) == 0
assert conversion.verify(customBench(inc)) == 0
def testInc2():
assert conversion.verify(customBench, inc2) == 0
assert conversion.verify(customBench(inc2)) == 0
def testInc3():
assert conversion.verify(customBench, inc3) == 0
assert conversion.verify(customBench(inc3)) == 0
def testIncGen():
try:
assert conversion.verify(customBench, incGen) == 0
assert conversion.verify(customBench(incGen)) == 0
except ConversionError as e:
pass
else:
@ -267,7 +281,7 @@ def testIncGen():
def testIncErr():
try:
assert conversion.verify(customBench, incErr) == 0
assert conversion.verify(customBench(incErr)) == 0
except ConversionError as e:
pass
else:

View File

@ -17,6 +17,7 @@ from myhdl.conversion._misc import _error
ACTIVE_LOW, INACTIVE_HIGH = 0, 1
@module
def incRef(count, enable, clock, reset, n):
""" Incrementer with enable.
@ -38,21 +39,23 @@ def incRef(count, enable, clock, reset, n):
return logic
@module
def incGen(count, enable, clock, reset, n):
""" Generator with __verilog__ is not permitted """
""" Generator with verilog_code is not permitted """
@instance
def logic():
__verilog__ = "Template string"
incGen.verilog_code = "Template string"
while 1:
yield clock.posedge, reset.negedge
if reset == ACTIVE_LOW:
count.next = 0
else:
if enable:
count.next = (count + 1) % n
yield clock.posedge, reset.negedge
if reset == ACTIVE_LOW:
count.next = 0
else:
if enable:
count.next = (count + 1) % n
return logic
@module
def inc(count, enable, clock, reset, n):
""" Incrementer with enable.
@ -74,15 +77,15 @@ def inc(count, enable, clock, reset, n):
count.driven = "reg"
__verilog__ = \
inc.verilog_code = \
"""
always @(posedge %(clock)s, negedge %(reset)s) begin
always @(posedge $clock, negedge $reset) begin
if (reset == 0) begin
%(count)s <= 0;
$count <= 0;
end
else begin
if (enable) begin
%(count)s <= (%(count)s + 1) %% %(n)s;
$count <= ($count + 1) % $n;
end
end
end
@ -91,6 +94,7 @@ end
return incProcess
@module
def incErr(count, enable, clock, reset, n):
@always(clock.posedge, reset.negedge)
@ -105,15 +109,15 @@ def incErr(count, enable, clock, reset, n):
count.driven = "reg"
__verilog__ = \
incErr.verilog_code = \
"""
always @(posedge %(clock)s, negedge %(reset)s) begin
always @(posedge $clock, negedge $reset) begin
if (reset == 0) begin
%(count)s <= 0;
$count <= 0;
end
else begin
if (enable) begin
%(count)s <= (%(countq)s + 1) %% %(n)s;
$count <= ($countq + 1) % $n;
end
end
end
@ -123,6 +127,7 @@ end
@module
def inc_comb(nextCount, count, n):
@always_comb
@ -133,17 +138,20 @@ def inc_comb(nextCount, count, n):
nextCount.driven = "wire"
__verilog__ =\
inc_comb.verilog_code =\
"""
assign %(nextCount)s = (%(count)s + 1) %% %(n)s;
assign $nextCount = ($count + 1) % $n;
"""
return logic
@module
def inc_seq(count, nextCount, enable, clock, reset):
@always(clock.posedge, reset.negedge)
def logic():
# make it fail in conversion
import types
if reset == ACTIVE_LOW:
count.next = 0
else:
@ -152,22 +160,22 @@ def inc_seq(count, nextCount, enable, clock, reset):
count.driven = "reg"
__verilog__ = \
inc_seq.verilog_code = \
"""
always @(posedge %(clock)s, negedge %(reset)s) begin
always @(posedge $clock, negedge $reset) begin
if (reset == 0) begin
%(count)s <= 0;
$count <= 0;
end
else begin
if (enable) begin
%(count)s <= %(nextCount)s;
$count <= $nextCount;
end
end
end
"""
# return nothing - cannot be simulated
return []
return logic
@module
def inc2(count, enable, clock, reset, n):
nextCount = Signal(intbv(0, min=0, max=n))
@ -178,6 +186,7 @@ def inc2(count, enable, clock, reset, n):
return comb, seq
@module
def inc3(count, enable, clock, reset, n):
inc2_inst = inc2(count, enable, clock, reset, n)
return inc2_inst
@ -233,7 +242,7 @@ class TestInc(TestCase):
clock, reset = [Signal(bool()) for i in range(2)]
inc_inst_ref = incRef(count, enable, clock, reset, n=n)
inc_inst = toVerilog(incVer, count, enable, clock, reset, n=n)
inc_inst = toVerilog(incVer(count, enable, clock, reset, n=n))
# inc_inst = inc(count, enable, clock, reset, n=n)
inc_inst_v = inc_v(incVer.__name__, count_v, enable, clock, reset)
clk_1 = self.clockGen(clock)
@ -271,7 +280,7 @@ class TestInc(TestCase):
enable = Signal(bool(0))
clock, reset = [Signal(bool()) for i in range(2)]
try:
inc_inst = toVerilog(incGen, count_v, enable, clock, reset, n=n)
inc_inst = toVerilog(incGen(count_v, enable, clock, reset, n=n))
except ConversionError as e:
self.assertEqual(e.kind, _error.NotSupported)
else:
@ -284,7 +293,7 @@ class TestInc(TestCase):
enable = Signal(bool(0))
clock, reset = [Signal(bool()) for i in range(2)]
try:
inc_inst = toVerilog(incErr, count_v, enable, clock, reset, n=n)
inc_inst = toVerilog(incErr(count_v, enable, clock, reset, n=n))
except ConversionError as e:
pass
else: