diff --git a/myhdl/_Simulation.py b/myhdl/_Simulation.py index 80ec07c1..cdfdd9b1 100644 --- a/myhdl/_Simulation.py +++ b/myhdl/_Simulation.py @@ -32,12 +32,11 @@ from myhdl import Cosimulation, StopSimulation, _SuspendSimulation from myhdl import _simulator, SimulationError from myhdl._simulator import _signals, _siglist, _futureEvents from myhdl._Waiter import _Waiter, _inferWaiter, _SignalWaiter,_SignalTupleWaiter -from myhdl._util import _flatten, _printExcInfo +from myhdl._util import _printExcInfo from myhdl._instance import _Instantiator +from myhdl._module import _ModuleInstance from myhdl._ShadowSignal import _ShadowSignal - - schedule = _futureEvents.append class _error: @@ -45,7 +44,22 @@ class _error: _error.ArgType = "Inappriopriate argument type" _error.MultipleCosim = "Only a single cosimulator argument allowed" _error.DuplicatedArg = "Duplicated argument" - + +# flatten Module objects out +def _flatten(*args): + arglist = [] + for arg in args: + if isinstance(arg, _ModuleInstance): + arg = arg.subs + if isinstance(arg, (list, tuple, set)): + for item in arg: + arglist.extend(_flatten(item)) + else: + arglist.append(arg) + return arglist + + + class Simulation(object): """ Simulation class. @@ -70,8 +84,8 @@ class Simulation(object): self._finished = False del _futureEvents[:] del _siglist[:] - - + + def _finalize(self): cosim = self._cosim if cosim: @@ -86,8 +100,8 @@ class Simulation(object): for s in _signals: s._clear() self._finished = True - - + + def runc(self, duration=0, quiet=0): simrunc.run(sim=self, duration=duration, quiet=quiet) @@ -201,7 +215,7 @@ class Simulation(object): self._finalize() # now reraise the exepction raise - + def _makeWaiters(arglist): waiters = [] @@ -231,4 +245,3 @@ def _makeWaiters(arglist): if hasattr(sig, '_waiter'): waiters.append(sig._waiter) return waiters, cosim - diff --git a/myhdl/__init__.py b/myhdl/__init__.py index 5da14d1b..7d6fbe89 100644 --- a/myhdl/__init__.py +++ b/myhdl/__init__.py @@ -82,6 +82,8 @@ class AlwaysCombError(Error): pass class InstanceError(Error): pass +class ModuleError(Error): + pass class CosimulationError(Error): pass class ExtractHierarchyError(Error): @@ -130,6 +132,7 @@ from ._always_comb import always_comb from ._always_seq import always_seq, ResetSignal from ._always import always from ._instance import instance +from ._module import module from ._enum import enum, EnumType, EnumItemType from ._traceSignals import traceSignals @@ -159,6 +162,7 @@ __all__ = ["bin", "Simulation", "instances", "instance", + "module", "always_comb", "always_seq", "ResetSignal", diff --git a/myhdl/_always.py b/myhdl/_always.py index 9f8fb379..2aa3be4e 100644 --- a/myhdl/_always.py +++ b/myhdl/_always.py @@ -29,7 +29,7 @@ from myhdl._delay import delay from myhdl._Signal import _Signal, _WaiterList, posedge, negedge from myhdl._Waiter import _Waiter, _SignalWaiter, _SignalTupleWaiter, \ _DelayWaiter, _EdgeWaiter, _EdgeTupleWaiter -from myhdl._instance import _Instantiator +from myhdl._instance import _Instantiator, _getCallInfo class _error: pass @@ -40,6 +40,7 @@ _error.DecNrOfArgs = "decorator should have arguments" def always(*args): + modname, modctxt = _getCallInfo() for arg in args: if isinstance(arg, _Signal): arg._read = True @@ -56,16 +57,16 @@ def always(*args): raise AlwaysError(_error.ArgType) if func.__code__.co_argcount > 0: raise AlwaysError(_error.NrOfArgs) - return _Always(func, args) + return _Always(func, args, modname=modname, modctxt=modctxt) return _always_decorator class _Always(_Instantiator): - def __init__(self, func, senslist): + def __init__(self, func, senslist, modname, modctxt): self.func = func self.senslist = tuple(senslist) - super(_Always, self).__init__(self.genfunc) + super(_Always, self).__init__(self.genfunc, modname=modname, modctxt=modctxt) @property def funcobj(self): diff --git a/myhdl/_always_comb.py b/myhdl/_always_comb.py index fffb4768..bfe6c5fe 100644 --- a/myhdl/_always_comb.py +++ b/myhdl/_always_comb.py @@ -30,7 +30,7 @@ from myhdl import AlwaysCombError from myhdl._Signal import _Signal, _isListOfSigs from myhdl._util import _isGenFunc, _dedent from myhdl._Waiter import _Waiter, _SignalWaiter, _SignalTupleWaiter -from myhdl._instance import _Instantiator +from myhdl._instance import _getCallInfo from myhdl._always import _Always class _error: @@ -43,51 +43,22 @@ _error.EmbeddedFunction = "embedded functions in always_comb function argument n _error.EmptySensitivityList= "sensitivity list is empty" def always_comb(func): + modname, modctxt = _getCallInfo() if not isinstance( func, FunctionType): raise AlwaysCombError(_error.ArgType) if _isGenFunc(func): raise AlwaysCombError(_error.ArgType) if func.__code__.co_argcount > 0: raise AlwaysCombError(_error.NrOfArgs) - c = _AlwaysComb(func) + c = _AlwaysComb(func, modname=modname, modctxt=modctxt) return c -# class _AlwaysComb(_Instantiator): class _AlwaysComb(_Always): -# def __init__(self, func, symdict): -# self.func = func -# self.symdict = symdict -# s = inspect.getsource(func) -# # remove decorators -# s = re.sub(r"@.*", "", s) -# s = s.lstrip() -# tree = compiler.parse(s) -# v = _SigNameVisitor(symdict) -# compiler.walk(tree, v) -# self.inputs = v.inputs -# self.outputs = v.outputs -# senslist = [] -# for n in self.inputs: -# s = self.symdict[n] -# if isinstance(s, Signal): -# senslist.append(s) -# else: # list of sigs -# senslist.extend(s) -# self.senslist = tuple(senslist) -# self.gen = self.genfunc() -# if len(self.senslist) == 0: -# raise AlwaysCombError(_error.EmptySensitivityList) -# if len(self.senslist) == 1: -# W = _SignalWaiter -# else: -# W = _SignalTupleWaiter -# self.waiter = W(self.gen) - - def __init__(self, func): + def __init__(self, func, modname, modctxt): senslist = [] - super(_AlwaysComb, self).__init__(func, senslist) + super(_AlwaysComb, self).__init__(func, senslist, modname=modname, modctxt=modctxt) inouts = self.inouts | self.inputs.intersection(self.outputs) if inouts: diff --git a/myhdl/_always_seq.py b/myhdl/_always_seq.py index 94354098..8105aa2c 100644 --- a/myhdl/_always_seq.py +++ b/myhdl/_always_seq.py @@ -32,6 +32,7 @@ from myhdl._delay import delay from myhdl._Signal import _Signal, _WaiterList,_isListOfSigs from myhdl._Waiter import _Waiter, _EdgeWaiter, _EdgeTupleWaiter from myhdl._always import _Always +from myhdl._instance import _getCallInfo # evacuate this later AlwaysSeqError = AlwaysError @@ -59,6 +60,7 @@ class ResetSignal(_Signal): def always_seq(edge, reset): + modname, modctxt = _getCallInfo() if not isinstance(edge, _WaiterList): raise AlwaysSeqError(_error.EdgeType) edge.sig._read = True @@ -76,13 +78,13 @@ def always_seq(edge, reset): raise AlwaysSeqError(_error.ArgType) if func.__code__.co_argcount > 0: raise AlwaysSeqError(_error.NrOfArgs) - return _AlwaysSeq(func, edge, reset) + return _AlwaysSeq(func, edge, reset, modname=modname, modctxt=modctxt) return _always_seq_decorator class _AlwaysSeq(_Always): - def __init__(self, func, edge, reset): + def __init__(self, func, edge, reset, modname, modctxt): senslist = [edge] self.reset = reset if reset is not None: @@ -97,7 +99,7 @@ class _AlwaysSeq(_Always): else: self.genfunc = self.genfunc_no_reset - super(_AlwaysSeq, self).__init__(func, senslist) + super(_AlwaysSeq, self).__init__(func, senslist, modname=modname, modctxt=modctxt) if self.inouts: raise AlwaysSeqError(_error.SigAugAssign, v.inouts) diff --git a/myhdl/_getHierarchy.py b/myhdl/_getHierarchy.py new file mode 100644 index 00000000..8a4559c3 --- /dev/null +++ b/myhdl/_getHierarchy.py @@ -0,0 +1,63 @@ +# This file is part of the myhdl library, a Python package for using +# Python as a Hardware Description Language. +# +# Copyright (C) 2003-2016 Jan Decaluwe +# +# The myhdl library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 2.1 of the +# License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +""" myhdl _getHierarchy module. + +""" + +from __future__ import absolute_import + +from myhdl._extractHierarchy import _Instance +from myhdl._instance import _Instantiator +from myhdl._module import _ModuleInstance + +class _Hierarchy(object): + def __init__(self, name, modinst): + self.top = modinst + self.hierarchy = hierarchy = [] + self.absnames = absnames = {} + _getHierarchyHelper(1, modinst, hierarchy) + # compatibility with _extractHierarchy + # walk the hierarchy to define relative and absolute names + names = {} + top_inst = hierarchy[0] + obj, subs = top_inst.obj, top_inst.subs + names[id(obj)] = name + absnames[id(obj)] = name + for inst in hierarchy: + obj, subs = inst.obj, inst.subs + inst.name = names[id(obj)] + tn = absnames[id(obj)] + for sn, so in subs: + names[id(so)] = sn + absnames[id(so)] = "%s_%s" % (tn, sn) + # print (names) + # print(absnames) + +def _getHierarchy(name, modinst): + h = _Hierarchy(name, modinst) + return h + +def _getHierarchyHelper(level, modinst, hierarchy): + subs = [(s.name, s) for s in modinst.subs] + inst = _Instance(level, modinst, subs, modinst.sigdict, modinst.memdict) + hierarchy.append(inst) + for inst in modinst.subs: + if isinstance(inst, _ModuleInstance): + _getHierarchyHelper(level+1, inst, hierarchy) diff --git a/myhdl/_instance.py b/myhdl/_instance.py index 44e17879..adc3216c 100644 --- a/myhdl/_instance.py +++ b/myhdl/_instance.py @@ -21,6 +21,7 @@ from __future__ import absolute_import +import inspect from types import FunctionType from myhdl import InstanceError @@ -34,19 +35,42 @@ class _error: _error.NrOfArgs = "decorated generator function should not have arguments" _error.ArgType = "decorated object should be a generator function" +def _getCallInfo(): + """Get info of the callers of e.g. an instantiator decorator. + + For hierarchy extraction, instantator decorators should only be used + within a module context. This function is hack to get info to check + that. It uses theframe stack: + 0: this function + 1: the instantiator decorator + 2: the module function that defines instances + 3: the caller of the module function, e.g. the ModuleInstance class. + """ + from myhdl import _module + modname = inspect.stack()[2][3] + modctxt = False + f_locals = inspect.stack()[3][0].f_locals + if 'self' in f_locals: + print f_locals['self'].__class__ + modctxt = isinstance(f_locals['self'], _module._ModuleInstance) + return modname, modctxt + def instance(genfunc): + modname, modctxt = _getCallInfo() if not isinstance(genfunc, FunctionType): raise InstanceError(_error.ArgType) if not _isGenFunc(genfunc): raise InstanceError(_error.ArgType) if genfunc.__code__.co_argcount > 0: raise InstanceError(_error.NrOfArgs) - return _Instantiator(genfunc) + return _Instantiator(genfunc, modname=modname, modctxt=modctxt) class _Instantiator(object): - def __init__(self, genfunc): + def __init__(self, genfunc, modname, modctxt): + self.modname = modname + self.modctxt = modctxt self.genfunc = genfunc self.gen = genfunc() # infer symdict @@ -73,6 +97,12 @@ class _Instantiator(object): self.outputs = v.outputs self.inouts = v.inouts self.embedded_func = v.embedded_func + self.sigdict = v.sigdict + self.losdict = v.losdict + + @property + def name(self): + return self.funcobj.__name__ @property def funcobj(self): diff --git a/myhdl/_module.py b/myhdl/_module.py new file mode 100644 index 00000000..2f7bbf6b --- /dev/null +++ b/myhdl/_module.py @@ -0,0 +1,95 @@ +# This file is part of the myhdl library, a Python package for using +# Python as a Hardware Description Language. +# +# Copyright (C) 2003-2016 Jan Decaluwe +# +# The myhdl library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 2.1 of the +# License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +""" Module with the @module decorator function. """ +from __future__ import absolute_import + +import functools +import inspect + +from myhdl import ModuleError +from myhdl._instance import _Instantiator +from myhdl._util import _flatten +from myhdl._extractHierarchy import _MemInfo, _makeMemInfo + + +class _error: + pass +_error.ArgType = "A module should return module or instantiator objects" +_error.InstanceError = "%s: submodule %s should be encapsulated in a module decorator" + +def module(modfunc): + return _Module(modfunc) + +class _Module(object): + + def __init__(self, modfunc): + self.modfunc = modfunc + self.__name__ = self.name = modfunc.__name__ + self.count = 0 + + def __call__(self, *args, **kwargs): + modinst = _ModuleInstance(self, *args, **kwargs) + self.count += 1 + return modinst + +class _ModuleInstance(object): + + def __init__(self, mod, *args, **kwargs): + self.mod = mod + self.sigdict = {} + self.memdict = {} + # flatten, but keep ModuleInstance objects + self.subs = _flatten(mod.modfunc(*args, **kwargs)) + self.verifyMod() + self.updateMod() + self.inferInterface(*args, **kwargs) + self.name = self.__name__ = mod.__name__ + '_' + str(mod.count) + + def verifyMod(self): + for inst in self.subs: + # print (inst.name, type(inst)) + if not isinstance(inst, (_ModuleInstance, _Instantiator)): + raise ModuleError(_error.ArgType) + if isinstance(inst, _Instantiator): + if not inst.modctxt: + raise ModuleError(_error.InstanceError % (self.mod.name, inst.modname)) + + def updateMod(self): + losdict = {} + for inst in self.subs: + if isinstance(inst, _Instantiator): + self.sigdict.update(inst.sigdict) + losdict.update(inst.losdict) + else: + # reset instantiation counter + self.mod.count = 0 + # compatibility patches from _extractHierarchy + for s in self.sigdict.values(): + s._markUsed() + for n, l in losdict.items(): + m = _makeMemInfo(l) + self.memdict[n] = m + m._used = True + + def inferInterface(self, *args, **kwargs): + from myhdl.conversion._analyze import _analyzeTopFunc + intf = _analyzeTopFunc(self.mod.modfunc, *args, **kwargs) + self.argnames = intf.argnames + self.argdict = intf.argdict diff --git a/myhdl/_simulator.py b/myhdl/_simulator.py index 264e65b9..779efa3c 100644 --- a/myhdl/_simulator.py +++ b/myhdl/_simulator.py @@ -25,6 +25,8 @@ now -- function that returns the current simulation time """ + + _signals = [] _siglist = [] _futureEvents = [] diff --git a/myhdl/_visitors.py b/myhdl/_visitors.py index 50c0b709..86f5dcb4 100644 --- a/myhdl/_visitors.py +++ b/myhdl/_visitors.py @@ -13,6 +13,8 @@ class _SigNameVisitor(ast.NodeVisitor): self.inouts = set() self.embedded_func = None self.context = 'input' + self.sigdict = {} + self.losdict = {} def visit_Module(self, node): for n in node.body: @@ -34,20 +36,24 @@ class _SigNameVisitor(ast.NodeVisitor): self.generic_visit(node) def visit_Name(self, node): - id = node.id - if id not in self.symdict: + n = node.id + if n not in self.symdict: return - s = self.symdict[id] + s = self.symdict[n] if isinstance(s, (_Signal, intbv)) or _isListOfSigs(s): if self.context == 'input': - self.inputs.add(id) + self.inputs.add(n) elif self.context == 'output': - self.outputs.add(id) + self.outputs.add(n) elif self.context == 'inout': - self.inouts.add(id) + self.inouts.add(n) else: print(self.context) raise AssertionError("bug in _SigNameVisitor") + if isinstance(s, _Signal): + self.sigdict[n] = s + elif _isListOfSigs(s): + self.losdict[n] = s def visit_Assign(self, node): self.context = 'output' diff --git a/myhdl/conversion/_toVHDL.py b/myhdl/conversion/_toVHDL.py index dca792e1..99e2de90 100644 --- a/myhdl/conversion/_toVHDL.py +++ b/myhdl/conversion/_toVHDL.py @@ -55,6 +55,8 @@ from myhdl._util import _flatten from myhdl._compat import integer_types, class_types, StringIO from myhdl._ShadowSignal import _TristateSignal, _TristateDriver +from myhdl._module import _ModuleInstance +from myhdl._getHierarchy import _getHierarchy _version = myhdl.__version__.replace('.','') _shortversion = _version.replace('dev','') @@ -70,6 +72,8 @@ def _checkArgs(arglist): def _flatten(*args): arglist = [] for arg in args: + if isinstance(arg, _ModuleInstance): + arg = arg.subs if id(arg) in _userCodeMap['vhdl']: arglist.append(_userCodeMap['vhdl'][id(arg)]) elif isinstance(arg, (list, tuple, set)): @@ -125,18 +129,28 @@ class _ToVHDLConvertor(object): from myhdl import _traceSignals if _traceSignals._tracing: raise ToVHDLError("Cannot use toVHDL while tracing signals") - if not callable(func): - raise ToVHDLError(_error.FirstArgType, "got %s" % type(func)) + if not isinstance(func, _ModuleInstance): + if not callable(func): + raise ToVHDLError(_error.FirstArgType, "got %s" % type(func)) _converting = 1 if self.name is None: name = func.__name__ + if isinstance(func, _ModuleInstance): + name = func.mod.__name__ else: name = str(self.name) - try: - h = _HierExtr(name, func, *args, **kwargs) - finally: - _converting = 0 + + if isinstance(func, _ModuleInstance): + try: + h = _getHierarchy(name, func) + finally: + _converting = 0 + else: + try: + h = _HierExtr(name, func, *args, **kwargs) + finally: + _converting = 0 if self.directory is None: directory = '' @@ -170,7 +184,10 @@ class _ToVHDLConvertor(object): _annotateTypes(genlist) ### infer interface - intf = _analyzeTopFunc(func, *args, **kwargs) + if isinstance(func, _ModuleInstance): + intf = func # already inferred + else: + intf = _analyzeTopFunc(func, *args, **kwargs) intf.name = name # sanity checks on interface for portname in intf.argnames: diff --git a/myhdl/conversion/_toVerilog.py b/myhdl/conversion/_toVerilog.py index be213ea7..b2051f60 100644 --- a/myhdl/conversion/_toVerilog.py +++ b/myhdl/conversion/_toVerilog.py @@ -52,6 +52,9 @@ from myhdl.conversion._analyze import (_analyzeSigs, _analyzeGens, _analyzeTopFu from myhdl._Signal import _Signal from myhdl._ShadowSignal import _TristateSignal, _TristateDriver +from myhdl._module import _ModuleInstance +from myhdl._getHierarchy import _getHierarchy + _converting = 0 _profileFunc = None @@ -63,6 +66,8 @@ def _checkArgs(arglist): def _flatten(*args): arglist = [] for arg in args: + if isinstance(arg, _ModuleInstance): + arg = arg.subs if id(arg) in _userCodeMap['verilog']: arglist.append(_userCodeMap['verilog'][id(arg)]) elif isinstance(arg, (list, tuple, set)): @@ -120,18 +125,28 @@ class _ToVerilogConvertor(object): from myhdl import _traceSignals if _traceSignals._tracing: raise ToVerilogError("Cannot use toVerilog while tracing signals") - if not callable(func): - raise ToVerilogError(_error.FirstArgType, "got %s" % type(func)) + if not isinstance(func, _ModuleInstance): + if not callable(func): + raise ToVerilogError(_error.FirstArgType, "got %s" % type(func)) _converting = 1 if self.name is None: name = func.__name__ + if isinstance(func, _ModuleInstance): + name = func.mod.__name__ else: name = str(self.name) - try: - h = _HierExtr(name, func, *args, **kwargs) - finally: - _converting = 0 + + if isinstance(func, _ModuleInstance): + try: + h = _getHierarchy(name, func) + finally: + _converting = 0 + else: + try: + h = _HierExtr(name, func, *args, **kwargs) + finally: + _converting = 0 if self.directory is None: directory = '' @@ -151,9 +166,14 @@ class _ToVerilogConvertor(object): genlist = _analyzeGens(arglist, h.absnames) siglist, memlist = _analyzeSigs(h.hierarchy) _annotateTypes(genlist) - - intf = _analyzeTopFunc(func, *args, **kwargs) + + ### infer interface + if isinstance(func, _ModuleInstance): + intf = func # already inferred + else: + intf = _analyzeTopFunc(func, *args, **kwargs) intf.name = name + doc = _makeDoc(inspect.getdoc(func)) self._convert_filter(h, intf, siglist, memlist, genlist) diff --git a/myhdl/conversion/_verify.py b/myhdl/conversion/_verify.py index 34e4192f..655e0792 100644 --- a/myhdl/conversion/_verify.py +++ b/myhdl/conversion/_verify.py @@ -12,6 +12,7 @@ import myhdl from myhdl._Simulation import Simulation from myhdl.conversion._toVHDL import toVHDL from myhdl.conversion._toVerilog import toVerilog +from myhdl._module import _ModuleInstance _version = myhdl.__version__.replace('.','') # strip 'dev' for version @@ -22,7 +23,7 @@ _simulators = {} sim = namedtuple('sim', 'name hdl analyze elaborate simulate skiplines skipchars ignore') -def registerSimulator(name=None, hdl=None, analyze=None, elaborate=None, simulate=None, +def registerSimulator(name=None, hdl=None, analyze=None, elaborate=None, simulate=None, skiplines=None, skipchars=None, ignore=None): if not isinstance(name, str) or (name.strip() == ""): raise ValueError("Invalid simulator name") @@ -96,7 +97,7 @@ class _VerificationClass(object): __slots__ = ("simulator", "_analyzeOnly") def __init__(self, analyzeOnly=False): - self.simulator = None + self.simulator = None self._analyzeOnly = analyzeOnly @@ -112,6 +113,8 @@ class _VerificationClass(object): name = toVerilog.name elif hdl == 'VHDL' and toVHDL.name is not None: name = toVHDL.name + elif isinstance(func, _ModuleInstance): + name = func.mod.__name__ else: name = func.__name__ @@ -129,10 +132,16 @@ class _VerificationClass(object): skipchars = hdlsim.skipchars ignore = hdlsim.ignore - if hdl == "VHDL": - inst = toVHDL(func, *args, **kwargs) + if isinstance(func, _ModuleInstance): + if hdl == "VHDL": + inst = toVHDL(func) + else: + inst = toVerilog(func) else: - inst = toVerilog(func, *args, **kwargs) + if hdl == "VHDL": + inst = toVHDL(func, *args, **kwargs) + else: + inst = toVerilog(func, *args, **kwargs) if hdl == "VHDL": if not os.path.exists("work"): @@ -178,7 +187,7 @@ class _VerificationClass(object): if ret != 0: print("Elaboration failed", file=sys.stderr) return ret - + g = tempfile.TemporaryFile(mode='w+t') #print(simulate) ret = subprocess.call(simulate, stdout=g, shell=True) diff --git a/myhdl/test/conversion/general/test_bin2gray.py b/myhdl/test/conversion/general/test_bin2gray.py index f1745c41..2e9bc3db 100644 --- a/myhdl/test/conversion/general/test_bin2gray.py +++ b/myhdl/test/conversion/general/test_bin2gray.py @@ -5,6 +5,7 @@ path = os.path from myhdl import * from myhdl.conversion import verify +@module def bin2gray2(B, G, width): """ Gray encoder. @@ -22,14 +23,15 @@ def bin2gray2(B, G, width): G.next[i] = Bext[i+1] ^ Bext[i] return logic +@module def bin2gray(B, G, width): - + """ Gray encoder. B -- input intbv signal, binary encoded G -- output intbv signal, gray encoded width -- bit width - + """ @always_comb @@ -40,9 +42,9 @@ def bin2gray(B, G, width): G.next[i] = Bext[i+1] ^ Bext[i] return logic - - - + + +@module def bin2grayBench(width, bin2gray): B = Signal(intbv(0)[width:]) @@ -67,8 +69,7 @@ def bin2grayBench(width, bin2gray): def test1(): - assert verify(bin2grayBench, width=8, bin2gray=bin2gray) == 0 - -def test2(): - assert verify(bin2grayBench, width=8, bin2gray=bin2gray2) == 0 + assert verify(bin2grayBench(width=8, bin2gray=bin2gray)) == 0 +def test2(): + assert verify(bin2grayBench(width=8, bin2gray=bin2gray2)) == 0 diff --git a/myhdl/test/conversion/general/test_fsm.py b/myhdl/test/conversion/general/test_fsm.py index a1408e71..5412da8e 100644 --- a/myhdl/test/conversion/general/test_fsm.py +++ b/myhdl/test/conversion/general/test_fsm.py @@ -12,6 +12,7 @@ t_State_b = enum('SEARCH', 'CONFIRM', 'SYNC') t_State_oh = enum('SEARCH', 'CONFIRM', 'SYNC', encoding="one_hot") t_State_oc = enum('SEARCH', 'CONFIRM', 'SYNC', encoding="one_cold") +@module def FramerCtrl(SOF, state, syncFlag, clk, reset_n, t_State): """ Framing control FSM. @@ -55,8 +56,7 @@ def FramerCtrl(SOF, state, syncFlag, clk, reset_n, t_State): return FSM - - +@module def FSMBench(FramerCtrl, t_State): SOF = Signal(bool(0)) @@ -110,5 +110,5 @@ def FSMBench(FramerCtrl, t_State): def test(): - assert verify(FSMBench, FramerCtrl, t_State_b) == 0 + assert verify(FSMBench(FramerCtrl, t_State_b)) == 0 diff --git a/myhdl/test/conversion/general/test_inc.py b/myhdl/test/conversion/general/test_inc.py index c9ccd560..3e00df7c 100644 --- a/myhdl/test/conversion/general/test_inc.py +++ b/myhdl/test/conversion/general/test_inc.py @@ -12,6 +12,7 @@ from myhdl.conversion import verify ACTIVE_LOW, INACTIVE_HIGH = bool(0), bool(1) +@module def incRef(count, enable, clock, reset, n): """ Incrementer with enable. @@ -32,6 +33,7 @@ def incRef(count, enable, clock, reset, n): count.next = (count + 1) % n return logic +@module def inc(count, enable, clock, reset, n): """ Incrementer with enable. @@ -54,6 +56,7 @@ def inc(count, enable, clock, reset, n): return incProcess +@module def inc2(count, enable, clock, reset, n): @always(clock.posedge, reset.negedge) @@ -69,6 +72,7 @@ def inc2(count, enable, clock, reset, n): return incProcess +@module def incFunc(count, enable, clock, reset, n): def incFuncFunc(cnt, enable): count_next = intbv(0, min=0, max=n) @@ -87,6 +91,7 @@ def incFunc(count, enable, clock, reset, n): return incFuncGen +@module def incTask(count, enable, clock, reset, n): def incTaskFunc(cnt, enable, reset, n): @@ -109,6 +114,7 @@ def incTask(count, enable, clock, reset, n): return incTaskGen +@module def incTaskFreeVar(count, enable, clock, reset, n): def incTaskFunc(): @@ -126,6 +132,7 @@ def incTaskFreeVar(count, enable, clock, reset, n): return incTaskGen +@module def IncBench(inc): NR_CYCLES = 201 @@ -163,18 +170,18 @@ def IncBench(inc): def test_incReg(): - assert verify(IncBench, incRef) == 0 + assert verify(IncBench(incRef)) == 0 def test_inc(): - assert verify(IncBench, inc) == 0 + assert verify(IncBench(inc)) == 0 def test_inc2(): - assert verify(IncBench, inc2) == 0 + assert verify(IncBench(inc2)) == 0 def testIncTask(): - assert verify(IncBench, incTask) == 0 + assert verify(IncBench(incTask)) == 0 def testIncFunc(): - assert verify(IncBench, incFunc) == 0 + assert verify(IncBench(incFunc)) == 0