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:
parent
2ab73788f7
commit
7fd658f966
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)):
|
||||
|
@ -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)):
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user