diff --git a/myhdl/__init__.py b/myhdl/__init__.py index ca0141f1..c83a26c7 100644 --- a/myhdl/__init__.py +++ b/myhdl/__init__.py @@ -48,7 +48,7 @@ __author__ = "Jan Decaluwe " __revision__ = "$Revision$" __date__ = "$Date$" -__version__ = "0.5a" +__version__ = "0.5a1" import warnings diff --git a/myhdl/_extractHierarchy.py b/myhdl/_extractHierarchy.py index 3b7e1086..c450d94f 100644 --- a/myhdl/_extractHierarchy.py +++ b/myhdl/_extractHierarchy.py @@ -26,6 +26,7 @@ __revision__ = "$Revision$" __date__ = "$Date$" import sys +import inspect from inspect import currentframe, getframeinfo, getouterframes import re import string @@ -35,7 +36,7 @@ from compiler import ast import linecache from sets import Set -from myhdl import Signal, ExtractHierarchyError +from myhdl import Signal, ExtractHierarchyError, ToVerilogError from myhdl._util import _isGenFunc from myhdl._isGenSeq import _isGenSeq from myhdl._always_comb import _AlwaysComb @@ -72,22 +73,32 @@ def _makeMemInfo(mem): def _isMem(mem): return id(mem) in _memInfoMap -_customVerilogMap = {} +_userDefinedVerilogMap = {} -class _CustomVerilog(object): - __slots__ = ['code', 'namespace'] - def __init__(self, code, namespace): +class _UserDefinedVerilog(object): + __slots__ = ['code', 'namespace', 'sourcefile', 'funcname', 'sourceline'] + def __init__(self, code, namespace, sourcefile, funcname, sourceline): self.code = code self.namespace = namespace + self.sourcefile = sourcefile + self.funcname = funcname + self.sourceline = sourceline def __str__(self): - code = self.code % self.namespace + try: + code = self.code % self.namespace + except: + type, value, tb = sys.exc_info() + info = "in file %s, function %s starting on line %s:\n " % \ + (self.sourcefile, self.funcname, self.sourceline) + msg = "%s: %s" % (type, value) + raise ToVerilogError("Error in user defined Verilog code", msg, info) code = "\n%s\n" % code return code -def _addCustomVerilog(arg, code, namespace): - assert id(arg) not in _customVerilogMap - _customVerilogMap[id(arg)] = _CustomVerilog(code, namespace) +def _addUserDefinedVerilog(arg, code, namespace, sourcefile, funcname, sourceline): + assert id(arg) not in _userDefinedVerilogMap + _userDefinedVerilogMap[id(arg)] = _UserDefinedVerilog(code, namespace, sourcefile, funcname, sourceline) def _isListOfSigs(obj): @@ -202,7 +213,10 @@ class _HierExtr(object): code = frame.f_locals["__verilog__"] namespace = frame.f_globals.copy() namespace.update(frame.f_locals) - _addCustomVerilog(arg, code, namespace) + sourcefile = inspect.getsourcefile(frame) + funcname = frame.f_code.co_name + sourceline = inspect.getsourcelines(frame)[1] + _addUserDefinedVerilog(arg, code, namespace, sourcefile, funcname, sourceline) # building hierarchy only makes sense if there are generators if isGenSeq and arg: sigdict = {} diff --git a/myhdl/_toVerilog/_analyze.py b/myhdl/_toVerilog/_analyze.py index a20b0714..85ad36e6 100644 --- a/myhdl/_toVerilog/_analyze.py +++ b/myhdl/_toVerilog/_analyze.py @@ -43,7 +43,7 @@ from myhdl._always_comb import _AlwaysComb from myhdl._always import _Always from myhdl._toVerilog import _error, _access, _kind, _context, \ _ToVerilogMixin, _Label -from myhdl._extractHierarchy import _isMem, _CustomVerilog +from myhdl._extractHierarchy import _isMem, _UserDefinedVerilog myhdlObjects = myhdl.__dict__.values() builtinObjects = __builtin__.__dict__.values() @@ -115,7 +115,7 @@ def _analyzeSigs(hierarchy): def _analyzeGens(top, absnames): genlist = [] for g in top: - if isinstance(g, _CustomVerilog): + if isinstance(g, _UserDefinedVerilog): ast = g elif isinstance(g, (_AlwaysComb, _Always)): f = g.func diff --git a/myhdl/_toVerilog/_convert.py b/myhdl/_toVerilog/_convert.py index ee236ff9..852ce714 100644 --- a/myhdl/_toVerilog/_convert.py +++ b/myhdl/_toVerilog/_convert.py @@ -26,6 +26,7 @@ __revision__ = "$Revision$" __date__ = "$Date$" import sys +import traceback import inspect import compiler from compiler import ast as astNode @@ -39,7 +40,7 @@ import myhdl from myhdl import * from myhdl import ToVerilogError, ToVerilogWarning from myhdl._extractHierarchy import _HierExtr, _isMem, _getMemInfo, \ - _CustomVerilog, _customVerilogMap + _UserDefinedVerilog, _userDefinedVerilogMap from myhdl._always_comb import _AlwaysComb from myhdl._always import _Always @@ -53,14 +54,14 @@ _profileFunc = None def _checkArgs(arglist): for arg in arglist: - if not type(arg) in (GeneratorType, _AlwaysComb, _Always, _CustomVerilog): + if not type(arg) in (GeneratorType, _AlwaysComb, _Always, _UserDefinedVerilog): raise ToVerilogError(_error.ArgType, arg) def _flatten(*args): arglist = [] for arg in args: - if id(arg) in _customVerilogMap: - arglist.append(_customVerilogMap[id(arg)]) + if id(arg) in _userDefinedVerilogMap: + arglist.append(_userDefinedVerilogMap[id(arg)]) elif isinstance(arg, (list, tuple, Set)): for item in arg: arglist.extend(_flatten(item)) @@ -249,7 +250,7 @@ def _convertGens(genlist, vfile): blockBuf = StringIO() funcBuf = StringIO() for ast in genlist: - if isinstance(ast, _CustomVerilog): + if isinstance(ast, _UserDefinedVerilog): blockBuf.write(str(ast)) continue if ast.kind == _kind.ALWAYS: diff --git a/myhdl/test/toVerilog/test_custom.py b/myhdl/test/toVerilog/test_custom.py index a0bea7e7..c4a7f743 100644 --- a/myhdl/test/toVerilog/test_custom.py +++ b/myhdl/test/toVerilog/test_custom.py @@ -44,10 +44,7 @@ def incGen(count, enable, clock, reset, n): if enable: count.next = (count + 1) % n - - - - + def inc(count, enable, clock, reset, n): """ Incrementer with enable. @@ -86,6 +83,37 @@ end return incProcess +def incErr(count, enable, clock, reset, n): + + @always(clock.posedge, reset.negedge) + def incProcess(): + # make it fail in conversion + import types + if reset == ACTIVE_LOW: + count.next = 0 + else: + if enable: + count.next = (count + 1) % n + + count.driven = "reg" + + __verilog__ = \ +""" +always @(posedge %(clock)s, negedge %(reset)s) begin + if (reset == 0) begin + %(count)s <= 0; + end + else begin + if (enable) begin + %(count)s <= (%(countq)s + 1) %% %(n)s; + end + end +end +""" + + return incProcess + + def inc_comb(nextCount, count, n): @@ -240,6 +268,21 @@ class TestInc(TestCase): self.assertEqual(e.kind, _error.NotSupported) else: self.fail() + + def testIncErr(self): + m = 8 + n = 2 ** m + count_v = Signal(intbv(0)[m:]) + 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) + except ToVerilogError, e: + pass + else: + self.fail() + + if __name__ == '__main__': diff --git a/setup.py b/setup.py index b0de57f7..0c312163 100644 --- a/setup.py +++ b/setup.py @@ -29,7 +29,7 @@ Topic :: Scientific/Engineering :: Electronic Design Automation (EDA) setup(name="myhdl", - version="0.5dev5", + version="0.5a1", description="Python as a Hardware Description Language", long_description = "See home page.", author="Jan Decaluwe",