mirror of
https://github.com/myhdl/myhdl.git
synced 2024-12-14 07:44:38 +08:00
user-defined verilog
bug fixes with hierarchical naming
This commit is contained in:
parent
28258b40ff
commit
26a43394c4
@ -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,6 +407,9 @@ class Signal(object):
|
||||
|
||||
# representation
|
||||
def __str__(self):
|
||||
if self._name:
|
||||
return self._name
|
||||
else:
|
||||
return str(self._val)
|
||||
|
||||
def __repr__(self):
|
||||
|
@ -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:
|
||||
|
@ -48,7 +48,7 @@ __author__ = "Jan Decaluwe <jan@jandecaluwe.com>"
|
||||
__revision__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
|
||||
__version__ = "0.5dev3"
|
||||
__version__ = "0.5dev4"
|
||||
|
||||
import warnings
|
||||
|
||||
|
@ -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:
|
||||
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)
|
||||
|
||||
|
||||
|
||||
@ -173,7 +196,15 @@ class _HierExtr(object):
|
||||
elif event == "return":
|
||||
|
||||
if not self.skip:
|
||||
if _isGenSeq(arg):
|
||||
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):
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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()
|
||||
|
77
myhdl/test/toVerilog/test_bugreports.py
Normal file
77
myhdl/test/toVerilog/test_bugreports.py
Normal file
@ -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)
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user