diff --git a/myhdl/_Signal.py b/myhdl/_Signal.py index 17a4d8f8..7def9f8a 100644 --- a/myhdl/_Signal.py +++ b/myhdl/_Signal.py @@ -191,6 +191,14 @@ class Signal(object): return self._min min = property(_get_min, None) + # support for the 'driven' attribute + def _get_driven(self): + return self._driven + def _set_driven(self, val): + assert val in ("reg", "wire") + self._driven = val + driven = property(_get_driven, _set_driven, None, "'driven' access methods") + # set next methods def _setNextBool(self, val): if not val in (0, 1): @@ -399,7 +407,10 @@ class Signal(object): # representation def __str__(self): - return str(self._val) + if self._name: + return self._name + else: + return str(self._val) def __repr__(self): return "Signal(" + repr(self._val) + ")" diff --git a/myhdl/_Simulation.py b/myhdl/_Simulation.py index b8bcb6ec..85de0795 100644 --- a/myhdl/_Simulation.py +++ b/myhdl/_Simulation.py @@ -221,6 +221,8 @@ def _checkArgs(arglist): waiters.append(_SignalTupleWaiter(cosim._waiter())) elif isinstance(arg, _Waiter): waiters.append(arg) + elif arg == True: + pass else: raise SimulationError(_error.ArgType, str(type(arg))) if id(arg) in ids: diff --git a/myhdl/__init__.py b/myhdl/__init__.py index b5823c40..a1aba4d0 100644 --- a/myhdl/__init__.py +++ b/myhdl/__init__.py @@ -48,7 +48,7 @@ __author__ = "Jan Decaluwe " __revision__ = "$Revision$" __date__ = "$Date$" -__version__ = "0.5dev3" +__version__ = "0.5dev4" import warnings diff --git a/myhdl/_extractHierarchy.py b/myhdl/_extractHierarchy.py index bb9fbb53..3b7e1086 100644 --- a/myhdl/_extractHierarchy.py +++ b/myhdl/_extractHierarchy.py @@ -48,8 +48,6 @@ class _error: pass _error.NoInstances = "No instances found" -_filelinemap = {} - _memInfoMap = {} class _MemInfo(object): @@ -74,6 +72,24 @@ def _makeMemInfo(mem): def _isMem(mem): return id(mem) in _memInfoMap +_customVerilogMap = {} + +class _CustomVerilog(object): + __slots__ = ['code', 'namespace'] + def __init__(self, code, namespace): + self.code = code + self.namespace = namespace + + def __str__(self): + code = self.code % self.namespace + 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 _isListOfSigs(obj): if obj and isinstance(obj, list): for e in obj: @@ -106,7 +122,8 @@ class _HierExtr(object): global _profileFunc global _memInfoMap _memInfoMap = {} - self.skipNames = ('always_comb', 'always', '_always_decorator', 'instances', 'processes', 'posedge', 'negedge') + self.skipNames = ('always_comb', 'always', '_always_decorator', \ + 'instances', 'processes', 'posedge', 'negedge') self.skip = 0 self.hierarchy = hierarchy = [] self.absnames = absnames = {} @@ -139,8 +156,11 @@ class _HierExtr(object): # streamline hierarchy hierarchy.reverse() +## from pprint import pprint +## pprint(hierarchy) + # print hierarchy # walk the hierarchy to define relative and absolute names - # in this case, we'll use the names from the lowest levels + # use names as high as possible in hierarchy to avoid ambiguity names = {} obj, subs = hierarchy[0][1] names[id(obj)] = name @@ -150,13 +170,16 @@ class _HierExtr(object): assert id(obj) in names tn = absnames[id(obj)] for sn, so in subs: - names[id(so)] = sn + if not id(so) in names: + names[id(so)] = sn absnames[id(so)] = "%s_%s" % (tn, sn) if isinstance(so, (tuple, list)): for i, soi in enumerate(so): - names[id(soi)] = "%s[%s]" % (sn, i) + if not(id(soi)) in names: + names[id(soi)] = "%s_%s" % (sn, i) absnames[id(soi)] = "%s_%s_%s" % (tn, sn, i) m[1] = names[id(obj)] +## pprint(hierarchy) @@ -172,8 +195,16 @@ class _HierExtr(object): elif event == "return": - if not self.skip: - if _isGenSeq(arg): + if not self.skip: + isGenSeq = _isGenSeq(arg) + if isGenSeq: + if "__verilog__" in frame.f_locals: + code = frame.f_locals["__verilog__"] + namespace = frame.f_globals.copy() + namespace.update(frame.f_locals) + _addCustomVerilog(arg, code, namespace) + # building hierarchy only makes sense if there are generators + if isGenSeq and arg: sigdict = {} memdict = {} for dict in (frame.f_globals, frame.f_locals): @@ -215,9 +246,9 @@ class _HierExtr(object): self.hierarchy.append(inst) self.level -= 1 - func_name = frame.f_code.co_name - if func_name in self.skipNames: - self.skip = 0 + func_name = frame.f_code.co_name + if func_name in self.skipNames: + self.skip = 0 diff --git a/myhdl/_isGenSeq.py b/myhdl/_isGenSeq.py index 873b4fb9..27ae9c36 100644 --- a/myhdl/_isGenSeq.py +++ b/myhdl/_isGenSeq.py @@ -37,8 +37,8 @@ def _isGenSeq(obj): return True if not isinstance(obj, (ListType, TupleType, Set)): return False - if not obj: - return False +## if not obj: +## return False for e in obj: if not _isGenSeq(e): return False diff --git a/myhdl/_toVerilog/_analyze.py b/myhdl/_toVerilog/_analyze.py index 08b96e3c..a2069a50 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 +from myhdl._extractHierarchy import _isMem, _CustomVerilog myhdlObjects = myhdl.__dict__.values() builtinObjects = __builtin__.__dict__.values() @@ -74,14 +74,19 @@ def _analyzeSigs(hierarchy): delta = curlevel - level curlevel = level assert(delta >= -1) + #print + #print curlevel + #print delta + #print prefixes if delta == -1: prefixes.append(name) - elif delta == 0: - prefixes.pop() - prefixes.append(name) else: - prefixes = prefixes[:curlevel] + prefixes = prefixes[:curlevel-1] + prefixes.append(name) + assert prefixes[-1] == name + #print prefixes # signals + #print sigdict for n, s in sigdict.items(): if s._name is not None: continue @@ -125,7 +130,9 @@ def _analyzeSigs(hierarchy): def _analyzeGens(top, absnames): genlist = [] for g in top: - if isinstance(g, (_AlwaysComb, _Always)): + if isinstance(g, _CustomVerilog): + ast = g + elif isinstance(g, (_AlwaysComb, _Always)): f = g.func s = inspect.getsource(f) # remove decorators diff --git a/myhdl/_toVerilog/_convert.py b/myhdl/_toVerilog/_convert.py index e7870495..f19d1f17 100644 --- a/myhdl/_toVerilog/_convert.py +++ b/myhdl/_toVerilog/_convert.py @@ -38,8 +38,9 @@ import warnings import myhdl from myhdl import * from myhdl import ToVerilogError, ToVerilogWarning -from myhdl._extractHierarchy import _HierExtr, _isMem, _getMemInfo -from myhdl._util import _flatten +from myhdl._extractHierarchy import _HierExtr, _isMem, _getMemInfo, \ + _CustomVerilog, _customVerilogMap + from myhdl._always_comb import _AlwaysComb from myhdl._always import _Always from myhdl._toVerilog import _error, _access, _kind,_context, \ @@ -52,9 +53,21 @@ _profileFunc = None def _checkArgs(arglist): for arg in arglist: - if not type(arg) in (GeneratorType, _AlwaysComb, _Always): + if not type(arg) in (GeneratorType, _AlwaysComb, _Always, _CustomVerilog): raise ToVerilogError(_error.ArgType, arg) +def _flatten(*args): + arglist = [] + for arg in args: + if id(arg) in _customVerilogMap: + arglist.append(_customVerilogMap[id(arg)]) + elif isinstance(arg, (list, tuple, Set)): + for item in arg: + arglist.extend(_flatten(item)) + else: + arglist.append(arg) + return arglist + class _ToVerilogConvertor(object): @@ -93,6 +106,7 @@ class _ToVerilogConvertor(object): siglist, memlist = _analyzeSigs(h.hierarchy) arglist = _flatten(h.top) + # print h.top _checkArgs(arglist) genlist = _analyzeGens(arglist, h.absnames) intf = _analyzeTopFunc(func, *args, **kwargs) @@ -239,6 +253,9 @@ def _convertGens(genlist, vfile): blockBuf = StringIO() funcBuf = StringIO() for ast in genlist: + if isinstance(ast, _CustomVerilog): + blockBuf.write(str(ast)) + continue if ast.kind == _kind.ALWAYS: Visitor = _ConvertAlwaysVisitor elif ast.kind == _kind.INITIAL: diff --git a/myhdl/test/test_Signal.py b/myhdl/test/test_Signal.py index e0e09f89..5a50d745 100644 --- a/myhdl/test/test_Signal.py +++ b/myhdl/test/test_Signal.py @@ -61,9 +61,9 @@ class SigTest(TestCase): self.negedgeWaiters = [object() for i in range(7)] def testPublicInterface(self): - """ public interface of a sig: val, next, posedge, negedge, min, max""" + """ public interface of a sig: val, next, posedge, negedge, min, max, driven""" s1 = Signal(1) - expected = ['next', 'val', 'posedge', 'negedge', 'min', 'max'] + expected = ['next', 'val', 'posedge', 'negedge', 'min', 'max', 'driven'] iface = [attr for attr in dir(s1) if attr[0] != '_'] expected.sort() iface.sort() diff --git a/myhdl/test/toVerilog/test_bugreports.py b/myhdl/test/toVerilog/test_bugreports.py new file mode 100644 index 00000000..ea09db46 --- /dev/null +++ b/myhdl/test/toVerilog/test_bugreports.py @@ -0,0 +1,77 @@ +from myhdl import * + +from util import verilogCompile + +############################# +# bug report (Tom Dillon) +# conflicts in reg/wire names +############################# + +width = 8 + +def add(x,a,b) : + def logic() : + x.next = a + b + L0 = always_comb(logic) + return L0 + +def add3(x,a,b,c) : + x0 = Signal(intbv(0,min=-2**(width-1),max=2**(width-1))) + A0 = add(x0,a,b) + A1 = add(x,x0,c) + + return instances() + +def TestModule(x,a,b,c,d,e) : + x0 = Signal(intbv(0,min=-2**(width-1),max=2**(width-1))) + + A0 = add3(x0,a,b,c) + A1 = add3(x,x0,d,e) + + return instances() + + +x,a,b,c,d,e = [Signal(intbv(0,min=-2**(width-1),max=2**(width-1))) for i in range(6)] + +toVerilog(TestModule, x,a,b,c,d,e) +verilogCompile(TestModule.func_name) + + +############################## +# Bug report (Tom Dillon) +# Conflicts in reg/wire names +############################### + + +def add(x,a,b) : + def logic() : + x.next = a + b + L0 = always_comb(logic) + return L0 + +def add4(x,a,b,c,d) : + xL = [Signal(intbv(0,min=-2**(width+2),max=2**(width+2))) for i in range(2)] + + #xl0 = Signal(intbv(0,min=-2**(width+2),max=2**(width+2))) + #xl1 = Signal(intbv(0,min=-2**(width+2),max=2**(width+2))) + + A0 = add(xL[0],a,b) + A1 = add(xL[1],xL[0],c) + A2 = add(x, xL[1],d) + + return instances() + +def TestModule(x,a,b,c,d,e): + x0 = Signal(intbv(0,min=-2**(width+2),max=2**(width+2))) + + A0 = add4(x0,a,b,c,d) + A1 = add4(x,x0,e,a,b) + + return instances() + +width = 8 + +x,a,b,c,d,e = [Signal(intbv(0,min=-2**(width-1),max=2**(width-1))) for i in range(6)] + +toVerilog(TestModule, x,a,b,c,d,e) +verilogCompile(TestModule.func_name) diff --git a/myhdl/test/toVerilog/util.py b/myhdl/test/toVerilog/util.py index 14a56b02..d870176c 100644 --- a/myhdl/test/toVerilog/util.py +++ b/myhdl/test/toVerilog/util.py @@ -21,6 +21,12 @@ def setupCosimulationCver(**kwargs): "%s.v tb_%s.v " % (name, name) return Cosimulation(cmd, **kwargs) +def verilogCompileCver(name): + cmd = "cver -c %s.v" % name + os.system(cmd) + setupCosimulation = setupCosimulationIcarus setupCosimulation = setupCosimulationCver + +verilogCompile = verilogCompileCver diff --git a/setup.py b/setup.py index 6fe77f94..a6d40ea3 100644 --- a/setup.py +++ b/setup.py @@ -29,7 +29,7 @@ Topic :: Scientific/Engineering :: Electronic Design Automation (EDA) setup(name="myhdl", - version="0.5dev3", + version="0.5dev4", description="Python as a Hardware Description Language", long_description = "See home page.", author="Jan Decaluwe",