1
0
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:
jand 2005-11-13 21:09:42 +00:00
parent 28258b40ff
commit 26a43394c4
11 changed files with 178 additions and 27 deletions

View File

@ -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) + ")"

View File

@ -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:

View File

@ -48,7 +48,7 @@ __author__ = "Jan Decaluwe <jan@jandecaluwe.com>"
__revision__ = "$Revision$"
__date__ = "$Date$"
__version__ = "0.5dev3"
__version__ = "0.5dev4"
import warnings

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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()

View 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)

View File

@ -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

View File

@ -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",