mirror of
https://github.com/myhdl/myhdl.git
synced 2025-01-24 21:52:56 +08:00
Initial MEP:107 support.
All arguments in the top level must be signals, apart from that, you can access attributes in generators. --HG-- branch : mep107
This commit is contained in:
parent
247d0379e2
commit
e0b6219bed
@ -31,6 +31,7 @@ from myhdl._util import _isGenFunc, _dedent
|
||||
from myhdl._cell_deref import _cell_deref
|
||||
from myhdl._Waiter import _Waiter, _SignalWaiter, _SignalTupleWaiter
|
||||
from myhdl._instance import _Instantiator
|
||||
from myhdl._resolverefs import _AttrRefTransformer
|
||||
|
||||
class _error:
|
||||
pass
|
||||
@ -40,7 +41,7 @@ _error.Scope = "always_comb argument should be a local function"
|
||||
_error.SignalAsInout = "signal (%s) used as inout in always_comb function argument"
|
||||
_error.EmbeddedFunction = "embedded functions in always_comb function argument not supported"
|
||||
_error.EmptySensitivityList= "sensitivity list is empty"
|
||||
|
||||
|
||||
def always_comb(func):
|
||||
if not isinstance( func, FunctionType):
|
||||
raise AlwaysCombError(_error.ArgType)
|
||||
@ -63,7 +64,7 @@ def always_comb(func):
|
||||
raise NameError(n)
|
||||
c = _AlwaysComb(func, symdict)
|
||||
return c
|
||||
|
||||
|
||||
|
||||
INPUT, OUTPUT, INOUT = range(3)
|
||||
|
||||
@ -115,7 +116,7 @@ class _SigNameVisitor(ast.NodeVisitor):
|
||||
raise AlwaysCombError(_error.SignalAsInout % id)
|
||||
else:
|
||||
raise AssertionError("bug in always_comb")
|
||||
|
||||
|
||||
def visit_Assign(self, node):
|
||||
self.context = OUTPUT
|
||||
for n in node.targets:
|
||||
@ -136,7 +137,7 @@ class _SigNameVisitor(ast.NodeVisitor):
|
||||
self.visit(node.target)
|
||||
self.context = INPUT
|
||||
self.visit(node.value)
|
||||
|
||||
|
||||
def visit_ClassDef(self, node):
|
||||
pass # skip
|
||||
|
||||
@ -146,7 +147,7 @@ class _SigNameVisitor(ast.NodeVisitor):
|
||||
def visit_Print(self, node):
|
||||
pass # skip
|
||||
|
||||
|
||||
|
||||
|
||||
class _AlwaysComb(_Instantiator):
|
||||
|
||||
@ -186,7 +187,9 @@ class _AlwaysComb(_Instantiator):
|
||||
s = _dedent(s)
|
||||
tree = ast.parse(s)
|
||||
# print ast.dump(tree)
|
||||
v = _SigNameVisitor(symdict)
|
||||
v = _AttrRefTransformer(self)
|
||||
v.visit(tree)
|
||||
v = _SigNameVisitor(self.symdict)
|
||||
v.visit(tree)
|
||||
self.inputs = v.inputs
|
||||
self.outputs = v.outputs
|
||||
@ -217,7 +220,7 @@ class _AlwaysComb(_Instantiator):
|
||||
while 1:
|
||||
func()
|
||||
yield senslist
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -34,10 +34,11 @@ from myhdl import ExtractHierarchyError, ToVerilogError, ToVHDLError
|
||||
from myhdl._Signal import _Signal, _isListOfSigs
|
||||
from myhdl._util import _isGenFunc
|
||||
from myhdl._misc import _isGenSeq
|
||||
from myhdl._resolverefs import _resolveRefs
|
||||
|
||||
|
||||
_profileFunc = None
|
||||
|
||||
|
||||
class _error:
|
||||
pass
|
||||
_error.NoInstances = "No instances found"
|
||||
@ -46,8 +47,8 @@ _error.InconsistentToplevel = "Inconsistent top level %s for %s - should be 1"
|
||||
|
||||
|
||||
class _Instance(object):
|
||||
__slots__ = ['level', 'obj', 'subs', 'sigdict', 'memdict', 'name', 'func', 'argdict']
|
||||
def __init__(self, level, obj, subs, sigdict, memdict, func, argdict):
|
||||
__slots__ = ['level', 'obj', 'subs', 'sigdict', 'memdict', 'name', 'func', 'argdict', 'objdict']
|
||||
def __init__(self, level, obj, subs, sigdict, memdict, func, argdict, objdict=None):
|
||||
self.level = level
|
||||
self.obj = obj
|
||||
self.subs = subs
|
||||
@ -55,7 +56,9 @@ class _Instance(object):
|
||||
self.memdict = memdict
|
||||
self.func = func
|
||||
self.argdict = argdict
|
||||
|
||||
if objdict:
|
||||
self.objdict = objdict
|
||||
|
||||
|
||||
_memInfoMap = {}
|
||||
|
||||
@ -79,7 +82,7 @@ def _makeMemInfo(mem):
|
||||
if key not in _memInfoMap:
|
||||
_memInfoMap[key] = _MemInfo(mem)
|
||||
return _memInfoMap[key]
|
||||
|
||||
|
||||
def _isMem(mem):
|
||||
return id(mem) in _memInfoMap
|
||||
|
||||
@ -108,10 +111,10 @@ class _UserCode(object):
|
||||
self.raiseError(msg, info)
|
||||
code = "\n%s\n" % code
|
||||
return code
|
||||
|
||||
|
||||
def _interpolate(self):
|
||||
return string.Template(self.code).substitute(self.namespace)
|
||||
|
||||
|
||||
class _UserCodeDepr(_UserCode):
|
||||
def _interpolate(self):
|
||||
return self.code % self.namespace
|
||||
@ -119,18 +122,18 @@ class _UserCodeDepr(_UserCode):
|
||||
class _UserVerilogCode(_UserCode):
|
||||
def raiseError(self, msg, info):
|
||||
raise ToVerilogError("Error in user defined Verilog code", msg, info)
|
||||
|
||||
|
||||
class _UserVhdlCode(_UserCode):
|
||||
def raiseError(self, msg, info):
|
||||
raise ToVHDLError("Error in user defined VHDL code", msg, info)
|
||||
|
||||
|
||||
class _UserVerilogCodeDepr(_UserVerilogCode, _UserCodeDepr):
|
||||
pass
|
||||
|
||||
class _UserVhdlCodeDepr(_UserVhdlCode, _UserCodeDepr):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
||||
class _UserVerilogInstance(_UserVerilogCode):
|
||||
def __str__(self):
|
||||
args = inspect.getargspec(self.func)[0]
|
||||
@ -159,8 +162,8 @@ class _UserVhdlInstance(_UserVhdlCode):
|
||||
s += "\n %s=>%s" % (arg, signame)
|
||||
s += "\n );\n\n"
|
||||
return s
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def _addUserCode(specs, arg, funcname, func, frame):
|
||||
classMap = {
|
||||
@ -170,7 +173,7 @@ def _addUserCode(specs, arg, funcname, func, frame):
|
||||
'vhdl_code' :_UserVhdlCode,
|
||||
'verilog_instance' : _UserVerilogInstance,
|
||||
'vhdl_instance' :_UserVhdlInstance,
|
||||
|
||||
|
||||
}
|
||||
namespace = frame.f_globals.copy()
|
||||
namespace.update(frame.f_locals)
|
||||
@ -192,13 +195,13 @@ def _addUserCode(specs, arg, funcname, func, frame):
|
||||
assert id(arg) not in _userCodeMap[hdl]
|
||||
code = specs[spec]
|
||||
_userCodeMap[hdl][id(arg)] = classMap[spec](code, namespace, funcname, func, sourcefile, sourceline)
|
||||
|
||||
|
||||
|
||||
class _CallFuncVisitor(object):
|
||||
|
||||
def __init__(self):
|
||||
self.linemap = {}
|
||||
|
||||
|
||||
def visitAssign(self, node):
|
||||
if isinstance(node.expr, ast.CallFunc):
|
||||
self.lineno = None
|
||||
@ -207,13 +210,13 @@ class _CallFuncVisitor(object):
|
||||
|
||||
def visitName(self, node):
|
||||
self.lineno = node.lineno
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class _HierExtr(object):
|
||||
|
||||
|
||||
def __init__(self, name, dut, *args, **kwargs):
|
||||
|
||||
|
||||
global _profileFunc
|
||||
_memInfoMap.clear()
|
||||
for hdl in _userCodeMap:
|
||||
@ -262,28 +265,28 @@ class _HierExtr(object):
|
||||
names[id(soi)] = sni
|
||||
absnames[id(soi)] = "%s_%s_%s" % (tn, sn, i)
|
||||
|
||||
|
||||
|
||||
def extractor(self, frame, event, arg):
|
||||
if event == "call":
|
||||
|
||||
|
||||
funcname = frame.f_code.co_name
|
||||
# skip certain functions
|
||||
if funcname in self.skipNames:
|
||||
self.skip +=1
|
||||
if not self.skip:
|
||||
self.level += 1
|
||||
|
||||
|
||||
elif event == "return":
|
||||
|
||||
|
||||
funcname = frame.f_code.co_name
|
||||
func = frame.f_globals.get(funcname)
|
||||
func = frame.f_globals.get(funcname)
|
||||
if func is None:
|
||||
# Didn't find a func in the global space, try the local "self"
|
||||
# argument and see if it has a method called *funcname*
|
||||
obj = frame.f_locals.get('self')
|
||||
if hasattr(obj, funcname):
|
||||
func = getattr(obj, funcname)
|
||||
|
||||
func = getattr(obj, funcname)
|
||||
|
||||
if not self.skip:
|
||||
isGenSeq = _isGenSeq(arg)
|
||||
if isGenSeq:
|
||||
@ -298,65 +301,75 @@ class _HierExtr(object):
|
||||
spec = "%s_instance" % hdl
|
||||
if func and hasattr(func, spec) and getattr(func, spec):
|
||||
specs[spec] = getattr(func, spec)
|
||||
if specs:
|
||||
if specs:
|
||||
_addUserCode(specs, arg, funcname, func, frame)
|
||||
# building hierarchy only makes sense if there are generators
|
||||
if isGenSeq and arg:
|
||||
sigdict = {}
|
||||
memdict = {}
|
||||
argdict = {}
|
||||
argdict = {}
|
||||
if func:
|
||||
arglist = inspect.getargspec(func).args
|
||||
arglist = inspect.getargspec(func).args
|
||||
else:
|
||||
arglist = []
|
||||
cellvars = frame.f_code.co_cellvars
|
||||
for dict in (frame.f_globals, frame.f_locals):
|
||||
for n, v in dict.items():
|
||||
# extract signals and memories
|
||||
# also keep track of whether they are used in generators
|
||||
# only include objects that are used in generators
|
||||
symdict = frame.f_globals.copy()
|
||||
symdict.update(frame.f_locals)
|
||||
cellvars = []
|
||||
cellvars.extend(frame.f_code.co_cellvars)
|
||||
if self.level > 1:
|
||||
objlist = _resolveRefs(symdict, arg)
|
||||
cellvars.extend(objlist)
|
||||
#for dict in (frame.f_globals, frame.f_locals):
|
||||
for n, v in symdict.items():
|
||||
# extract signals and memories
|
||||
# also keep track of whether they are used in generators
|
||||
# only include objects that are used in generators
|
||||
## if not n in cellvars:
|
||||
## continue
|
||||
if isinstance(v, _Signal):
|
||||
sigdict[n] = v
|
||||
if n in cellvars:
|
||||
v._markUsed()
|
||||
if _isListOfSigs(v):
|
||||
m = _makeMemInfo(v)
|
||||
memdict[n] = m
|
||||
if n in cellvars:
|
||||
m._used = True
|
||||
# save any other variable in argdict
|
||||
if (n in arglist) and (n not in sigdict) and (n not in memdict):
|
||||
argdict[n] = v
|
||||
|
||||
if isinstance(v, _Signal):
|
||||
sigdict[n] = v
|
||||
if n in cellvars:
|
||||
v._markUsed()
|
||||
if _isListOfSigs(v):
|
||||
m = _makeMemInfo(v)
|
||||
memdict[n] = m
|
||||
if n in cellvars:
|
||||
m._used = True
|
||||
# save any other variable in argdict
|
||||
if (n in arglist) and (n not in sigdict) and (n not in memdict):
|
||||
argdict[n] = v
|
||||
|
||||
subs = []
|
||||
for n, sub in frame.f_locals.items():
|
||||
for elt in _inferArgs(arg):
|
||||
if elt is sub:
|
||||
subs.append((n, sub))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
inst = _Instance(self.level, arg, subs, sigdict, memdict, func, argdict)
|
||||
self.hierarchy.append(inst)
|
||||
|
||||
|
||||
self.level -= 1
|
||||
|
||||
|
||||
if funcname in self.skipNames:
|
||||
self.skip -= 1
|
||||
|
||||
|
||||
|
||||
def _inferArgs(arg):
|
||||
c = [arg]
|
||||
if isinstance(arg, (tuple, list)):
|
||||
c += list(arg)
|
||||
return c
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -42,6 +42,7 @@ from myhdl._extractHierarchy import _isMem, _getMemInfo, _UserCode
|
||||
from myhdl._Signal import _Signal, _WaiterList
|
||||
from myhdl._ShadowSignal import _ShadowSignal, _SliceSignal
|
||||
from myhdl._util import _isTupleOfInts, _dedent
|
||||
from myhdl._resolverefs import _AttrRefTransformer
|
||||
|
||||
myhdlObjects = myhdl.__dict__.values()
|
||||
builtinObjects = __builtin__.__dict__.values()
|
||||
@ -72,7 +73,7 @@ def _makeAST(f):
|
||||
tree.sourcefile = inspect.getsourcefile(f)
|
||||
tree.lineoffset = inspect.getsourcelines(f)[1]-1
|
||||
return tree
|
||||
|
||||
|
||||
def _analyzeSigs(hierarchy, hdl='Verilog'):
|
||||
curlevel = 0
|
||||
siglist = []
|
||||
@ -81,7 +82,7 @@ def _analyzeSigs(hierarchy, hdl='Verilog'):
|
||||
open, close = '[', ']'
|
||||
if hdl == 'VHDL':
|
||||
open, close = '(', ')'
|
||||
|
||||
|
||||
for inst in hierarchy:
|
||||
level = inst.level
|
||||
name = inst.name
|
||||
@ -91,8 +92,8 @@ def _analyzeSigs(hierarchy, hdl='Verilog'):
|
||||
curlevel = level
|
||||
assert(delta >= -1)
|
||||
if delta > -1: # same or higher level
|
||||
prefixes = prefixes[:curlevel-1]
|
||||
# skip processing and prefixing in context without signals
|
||||
prefixes = prefixes[:curlevel-1]
|
||||
# skip processing and prefixing in context without signals
|
||||
if not (sigdict or memdict):
|
||||
prefixes.append("")
|
||||
continue
|
||||
@ -100,6 +101,10 @@ def _analyzeSigs(hierarchy, hdl='Verilog'):
|
||||
for n, s in sigdict.items():
|
||||
if s._name is not None:
|
||||
continue
|
||||
if '.' in n:
|
||||
n = n.replace('.', '_')
|
||||
while n in sigdict:
|
||||
n = n + '_'
|
||||
if isinstance(s, _SliceSignal):
|
||||
continue
|
||||
s._name = _makeName(n, prefixes)
|
||||
@ -133,10 +138,10 @@ def _analyzeSigs(hierarchy, hdl='Verilog'):
|
||||
raise ConversionError(_error.InconsistentType, s._name)
|
||||
if s._nrbits != m.elObj._nrbits:
|
||||
raise ConversionError(_error.InconsistentBitWidth, s._name)
|
||||
|
||||
|
||||
return siglist, memlist
|
||||
|
||||
|
||||
|
||||
|
||||
def _analyzeGens(top, absnames):
|
||||
genlist = []
|
||||
@ -158,21 +163,24 @@ def _analyzeGens(top, absnames):
|
||||
if f.func_code.co_freevars:
|
||||
for n, c in zip(f.func_code.co_freevars, f.func_closure):
|
||||
obj = _cell_deref(c)
|
||||
if isinstance(g, _AlwaysComb):
|
||||
if not ( isinstance(obj, (int, long, EnumType,_Signal)) or \
|
||||
_isMem(obj) or _isTupleOfInts(obj)
|
||||
):
|
||||
info = "File %s, line %s: " % (tree.sourcefile, tree.lineoffset)
|
||||
print type(obj)
|
||||
raise ConversionError(_error.UnsupportedType, n, info)
|
||||
tree.symdict[n] = obj
|
||||
# currently, only intbv as automatic nonlocals (until Python 3.0)
|
||||
if isinstance(obj, intbv):
|
||||
tree.nonlocaldict[n] = obj
|
||||
tree.name = absnames.get(id(g), str(_Label("BLOCK"))).upper()
|
||||
v = _AttrRefTransformer(tree)
|
||||
v.visit(tree)
|
||||
v = _FirstPassVisitor(tree)
|
||||
v.visit(tree)
|
||||
if isinstance(g, _AlwaysComb):
|
||||
objs = [tree.symdict[objname] for objname in tree.objlist]
|
||||
for obj in objs:
|
||||
if not ( isinstance(obj, (int, long, EnumType,_Signal)) or \
|
||||
_isMem(obj) or _isTupleOfInts(obj)
|
||||
):
|
||||
info = "File %s, line %s: " % (tree.sourcefile, tree.lineoffset)
|
||||
print type(obj)
|
||||
raise ConversionError(_error.UnsupportedType, n, info)
|
||||
v = _AnalyzeAlwaysCombVisitor(tree, g.senslist)
|
||||
elif isinstance(g, _AlwaysSeq):
|
||||
v = _AnalyzeAlwaysSeqVisitor(tree, g.senslist, g.reset, g.sigregs, g.varregs)
|
||||
@ -192,6 +200,8 @@ def _analyzeGens(top, absnames):
|
||||
tree.nonlocaldict = {}
|
||||
tree.callstack = []
|
||||
tree.name = absnames.get(id(g), str(_Label("BLOCK"))).upper()
|
||||
v = _AttrRefTransformer(tree)
|
||||
v.visit(tree)
|
||||
v = _FirstPassVisitor(tree)
|
||||
v.visit(tree)
|
||||
v = _AnalyzeBlockVisitor(tree)
|
||||
@ -203,15 +213,15 @@ def _analyzeGens(top, absnames):
|
||||
class _FirstPassVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
|
||||
"""First pass visitor.
|
||||
|
||||
|
||||
Prune unsupported contructs, and add some useful attributes.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
def __init__(self, tree):
|
||||
self.tree = tree
|
||||
self.toplevel = True
|
||||
|
||||
|
||||
def visit_Tuple(self, node):
|
||||
if isinstance(node.ctx, ast.Store):
|
||||
self.raiseError(node, _error.NotSupported, "tuple assignment")
|
||||
@ -266,13 +276,13 @@ class _FirstPassVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
def visit_TryFinally(self, node):
|
||||
self.raiseError(node, _error.NotSupported, "try-finally statement")
|
||||
|
||||
|
||||
|
||||
def visit_Assign(self, node):
|
||||
if len(node.targets) > 1:
|
||||
self.raiseError(node, _error.NotSupported, "multiple assignments")
|
||||
self.visit(node.targets[0])
|
||||
self.visit(node.value)
|
||||
|
||||
|
||||
def visit_Call(self, node):
|
||||
if node.starargs:
|
||||
self.raiseError(node, _error.NotSupported, "extra positional arguments")
|
||||
@ -280,12 +290,12 @@ class _FirstPassVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.raiseError(node, _error.NotSupported, "extra named arguments")
|
||||
# f = eval(_unparse(node.node), self.tree.symdict)
|
||||
self.generic_visit(node)
|
||||
|
||||
|
||||
def visit_Compare(self, node):
|
||||
if len(node.ops) != 1:
|
||||
self.raiseError(node, _error.NotSupported, "chained comparison")
|
||||
self.generic_visit(node)
|
||||
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
if node.args.vararg or node.args.kwarg:
|
||||
self.raiseError(node, _error.NotSupported, "extra positional or named arguments")
|
||||
@ -301,7 +311,7 @@ class _FirstPassVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
node.doc = node.body[0].value.s
|
||||
node.body = node.body[1:]
|
||||
self.visitList(node.body)
|
||||
|
||||
|
||||
def flattenIf(self, node, tests, else_, co):
|
||||
""" Flatten if-then-else as in compiler package."""
|
||||
if node:
|
||||
@ -323,7 +333,7 @@ class _FirstPassVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
node.ignore = True
|
||||
return # skip
|
||||
self.generic_visit(node)
|
||||
|
||||
|
||||
# add fields that match old compiler package
|
||||
tests = [(node.test, node.body)]
|
||||
else_ = []
|
||||
@ -337,7 +347,7 @@ class _FirstPassVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.raiseError(node, _error.NotSupported, "printing to a file with >> syntax")
|
||||
if not node.nl:
|
||||
self.raiseError(node, _error.NotSupported, "printing without newline")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -405,10 +415,10 @@ def _getNritems(obj):
|
||||
return len(obj._type)
|
||||
else:
|
||||
raise TypeError("Unexpected type")
|
||||
|
||||
|
||||
|
||||
class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
|
||||
|
||||
def __init__(self, tree):
|
||||
tree.sigdict = {}
|
||||
tree.vardict = {}
|
||||
@ -441,7 +451,7 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
if not hasType(n.obj, bool):
|
||||
self.raiseError(node, _error.NotSupported, "non-boolean argument in logical operator")
|
||||
node.obj = bool()
|
||||
|
||||
|
||||
def visit_UnaryOp(self, node):
|
||||
self.visit(node.operand)
|
||||
op = node.op
|
||||
@ -465,7 +475,7 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
if isinstance(obj, _Signal) and isinstance(obj._init, modbv):
|
||||
if not obj._init._hasFullRange():
|
||||
self.raiseError(node, _error.ModbvRange, n)
|
||||
|
||||
|
||||
def setAttr(self, node):
|
||||
if node.attr != 'next':
|
||||
self.raiseError(node, _error.NotSupported, "attribute assignment")
|
||||
@ -505,7 +515,7 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
obj._setName(n+suf)
|
||||
if node.obj is None: # attribute lookup failed
|
||||
self.raiseError(node, _error.UnsupportedAttribute, node.attr)
|
||||
|
||||
|
||||
def visit_Assign(self, node):
|
||||
target, value = node.targets[0], node.value
|
||||
self.access = _access.OUTPUT
|
||||
@ -557,7 +567,7 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
|
||||
def visit_Break(self, node):
|
||||
self.labelStack[-2].isActive = True
|
||||
|
||||
|
||||
def visit_Call(self, node):
|
||||
self.visit(node.func)
|
||||
self.access = _access.UNKNOWN
|
||||
@ -655,7 +665,7 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
if isinstance(val, bool):
|
||||
val = int(val) # cast bool to int first
|
||||
if isinstance(val, (EnumItemType, int, long)):
|
||||
node.case = (node.left, val)
|
||||
node.case = (node.left, val)
|
||||
# check whether it can be part of an edge check
|
||||
n = node.left.id
|
||||
if n in self.tree.sigdict:
|
||||
@ -680,7 +690,7 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
|
||||
def visit_Str(self, node):
|
||||
node.obj = node.s
|
||||
|
||||
|
||||
def visit_Continue(self, node):
|
||||
self.labelStack[-1].isActive = True
|
||||
|
||||
@ -693,20 +703,20 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.visit(node.target)
|
||||
var = node.target.id
|
||||
self.tree.vardict[var] = int(-1)
|
||||
|
||||
|
||||
cf = node.iter
|
||||
self.visit(cf)
|
||||
self.require(node, isinstance(cf, ast.Call), "Expected (down)range call")
|
||||
f = self.getObj(cf.func)
|
||||
self.require(node, f in (range, downrange), "Expected (down)range call")
|
||||
|
||||
|
||||
for stmt in node.body:
|
||||
self.visit(stmt)
|
||||
self.refStack.pop()
|
||||
self.require(node, not node.orelse, "for-else not supported")
|
||||
self.labelStack.pop()
|
||||
self.labelStack.pop()
|
||||
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
raise AssertionError("subclass must implement this")
|
||||
|
||||
@ -816,7 +826,7 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
sig._driven = 'wire'
|
||||
if not isinstance(sig, _Signal):
|
||||
# print "not a signal: %s" % n
|
||||
pass
|
||||
pass
|
||||
else:
|
||||
if sig._type is bool:
|
||||
node.edge = sig.posedge
|
||||
@ -835,7 +845,7 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.tree.outputs.add(n)
|
||||
elif self.access == _access.UNKNOWN:
|
||||
pass
|
||||
else:
|
||||
else:
|
||||
self.raiseError(node, _error.NotSupported, "Augmented signal assignment")
|
||||
if n in self.tree.vardict:
|
||||
obj = self.tree.vardict[n]
|
||||
@ -887,7 +897,7 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
node.obj = __builtin__.__dict__[n]
|
||||
else:
|
||||
self.raiseError(node, _error.UnboundLocal, n)
|
||||
|
||||
|
||||
def visit_Return(self, node):
|
||||
self.raiseError(node, _error.NotSupported, "return statement")
|
||||
|
||||
@ -945,7 +955,7 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
if len(node.args) > nr:
|
||||
self.raiseError(node, _error.FormatString, "too many arguments")
|
||||
self.generic_visit(node)
|
||||
|
||||
|
||||
def visit_Subscript(self, node):
|
||||
if isinstance(node.slice, ast.Slice):
|
||||
self.accessSlice(node)
|
||||
@ -970,7 +980,7 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
else:
|
||||
rightind = 0
|
||||
node.obj = node.obj[leftind:rightind]
|
||||
|
||||
|
||||
def accessIndex(self, node):
|
||||
self.visit(node.value)
|
||||
self.access = _access.INPUT
|
||||
@ -1033,15 +1043,15 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.raiseError(node, _error.UnsupportedYield)
|
||||
node.senslist = senslist
|
||||
|
||||
|
||||
|
||||
class _AnalyzeBlockVisitor(_AnalyzeVisitor):
|
||||
|
||||
|
||||
def __init__(self, tree):
|
||||
_AnalyzeVisitor.__init__(self, tree)
|
||||
for n, v in self.tree.symdict.items():
|
||||
if isinstance(v, _Signal):
|
||||
self.tree.sigdict[n] = v
|
||||
|
||||
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
self.refStack.push()
|
||||
@ -1058,7 +1068,7 @@ class _AnalyzeBlockVisitor(_AnalyzeVisitor):
|
||||
self.tree.kind = _kind.INITIAL
|
||||
self.refStack.pop()
|
||||
|
||||
|
||||
|
||||
def visit_Module(self, node):
|
||||
self.generic_visit(node)
|
||||
for n in self.tree.outputs:
|
||||
@ -1069,8 +1079,8 @@ class _AnalyzeBlockVisitor(_AnalyzeVisitor):
|
||||
for n in self.tree.inputs:
|
||||
s = self.tree.sigdict[n]
|
||||
s._markRead()
|
||||
|
||||
|
||||
|
||||
|
||||
def visit_Return(self, node):
|
||||
### value should be None
|
||||
if node.value is None:
|
||||
@ -1084,7 +1094,7 @@ class _AnalyzeBlockVisitor(_AnalyzeVisitor):
|
||||
|
||||
|
||||
class _AnalyzeAlwaysCombVisitor(_AnalyzeBlockVisitor):
|
||||
|
||||
|
||||
def __init__(self, tree, senslist):
|
||||
_AnalyzeBlockVisitor.__init__(self, tree)
|
||||
self.tree.senslist = senslist
|
||||
@ -1124,10 +1134,10 @@ class _AnalyzeAlwaysCombVisitor(_AnalyzeBlockVisitor):
|
||||
for n in self.tree.outmems:
|
||||
m = _getMemInfo(self.tree.symdict[n])
|
||||
m._driven = "wire"
|
||||
|
||||
|
||||
|
||||
|
||||
class _AnalyzeAlwaysSeqVisitor(_AnalyzeBlockVisitor):
|
||||
|
||||
|
||||
def __init__(self, tree, senslist, reset, sigregs, varregs):
|
||||
_AnalyzeBlockVisitor.__init__(self, tree)
|
||||
self.tree.senslist = senslist
|
||||
@ -1135,22 +1145,22 @@ class _AnalyzeAlwaysSeqVisitor(_AnalyzeBlockVisitor):
|
||||
self.tree.sigregs = sigregs
|
||||
self.tree.varregs = varregs
|
||||
|
||||
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
self.refStack.push()
|
||||
for n in node.body:
|
||||
self.visit(n)
|
||||
self.tree.kind = _kind.ALWAYS_SEQ
|
||||
self.refStack.pop()
|
||||
|
||||
|
||||
|
||||
class _AnalyzeAlwaysDecoVisitor(_AnalyzeBlockVisitor):
|
||||
|
||||
|
||||
def __init__(self, tree, senslist):
|
||||
_AnalyzeBlockVisitor.__init__(self, tree)
|
||||
self.tree.senslist = senslist
|
||||
|
||||
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
self.refStack.push()
|
||||
for n in node.body:
|
||||
@ -1158,10 +1168,10 @@ class _AnalyzeAlwaysDecoVisitor(_AnalyzeBlockVisitor):
|
||||
self.tree.kind = _kind.ALWAYS_DECO
|
||||
self.refStack.pop()
|
||||
|
||||
|
||||
|
||||
|
||||
class _AnalyzeFuncVisitor(_AnalyzeVisitor):
|
||||
|
||||
|
||||
def __init__(self, tree, args, keywords):
|
||||
_AnalyzeVisitor.__init__(self, tree)
|
||||
self.args = args
|
||||
@ -1169,7 +1179,7 @@ class _AnalyzeFuncVisitor(_AnalyzeVisitor):
|
||||
self.tree.hasReturn = False
|
||||
self.tree.returnObj = None
|
||||
|
||||
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
self.refStack.push()
|
||||
argnames = [arg.id for arg in node.args.args]
|
||||
@ -1253,7 +1263,7 @@ class _AnalyzeTopFuncVisitor(_AnalyzeVisitor):
|
||||
self.argdict = {}
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
|
||||
|
||||
self.name = node.name
|
||||
argnames = [arg.id for arg in node.args.args]
|
||||
if isboundmethod(self.func):
|
||||
@ -1261,12 +1271,12 @@ class _AnalyzeTopFuncVisitor(_AnalyzeVisitor):
|
||||
self.raiseError(node, _error.NotSupported,
|
||||
"first method argument name other than 'self'")
|
||||
# skip self
|
||||
argnames = argnames[1:]
|
||||
argnames = argnames[1:]
|
||||
i=-1
|
||||
for i, arg in enumerate(self.args):
|
||||
n = argnames[i]
|
||||
if isinstance(arg, _Signal):
|
||||
self.argdict[n] = arg
|
||||
self.argdict[n] = arg
|
||||
if _isMem(arg):
|
||||
self.raiseError(node, _error.ListAsPort, n)
|
||||
for n in argnames[i+1:]:
|
||||
|
@ -60,7 +60,7 @@ def _checkArgs(arglist):
|
||||
for arg in arglist:
|
||||
if not isinstance(arg, (GeneratorType, _Instantiator, _UserVhdlCode)):
|
||||
raise ToVHDLError(_error.ArgType, arg)
|
||||
|
||||
|
||||
def _flatten(*args):
|
||||
arglist = []
|
||||
for arg in args:
|
||||
@ -72,7 +72,7 @@ def _flatten(*args):
|
||||
else:
|
||||
arglist.append(arg)
|
||||
return arglist
|
||||
|
||||
|
||||
def _makeDoc(doc, indent=''):
|
||||
if doc is None:
|
||||
return ''
|
||||
@ -150,11 +150,11 @@ class _ToVHDLConvertor(object):
|
||||
_constDict.clear()
|
||||
_extConstDict.clear()
|
||||
|
||||
siglist, memlist = _analyzeSigs(h.hierarchy, hdl='VHDL')
|
||||
arglist = _flatten(h.top)
|
||||
# print h.top
|
||||
_checkArgs(arglist)
|
||||
genlist = _analyzeGens(arglist, h.absnames)
|
||||
siglist, memlist = _analyzeSigs(h.hierarchy, hdl='VHDL')
|
||||
# print h.top
|
||||
_annotateTypes(genlist)
|
||||
|
||||
### infer interface
|
||||
@ -175,14 +175,14 @@ class _ToVHDLConvertor(object):
|
||||
_enumPortTypeSet.add(obj)
|
||||
|
||||
doc = _makeDoc(inspect.getdoc(func))
|
||||
|
||||
|
||||
needPck = len(_enumPortTypeSet) > 0
|
||||
lib = self.library
|
||||
arch = self.architecture
|
||||
numeric = self.numeric_ports
|
||||
|
||||
|
||||
self._convert_filter(h, intf, siglist, memlist, genlist)
|
||||
|
||||
|
||||
if pfile:
|
||||
_writeFileHeader(pfile, ppath)
|
||||
print >> pfile, _package
|
||||
@ -207,7 +207,7 @@ class _ToVHDLConvertor(object):
|
||||
self._cleanup(siglist)
|
||||
|
||||
return h.top
|
||||
|
||||
|
||||
def _cleanup(self, siglist):
|
||||
# clean up signal names
|
||||
for sig in siglist:
|
||||
@ -215,7 +215,7 @@ class _ToVHDLConvertor(object):
|
||||
# sig._name = None
|
||||
# sig._driven = False
|
||||
# sig._read = False
|
||||
|
||||
|
||||
# clean up attributes
|
||||
self.name = None
|
||||
self.component_declarations = None
|
||||
@ -224,13 +224,13 @@ class _ToVHDLConvertor(object):
|
||||
self.no_myhdl_package = False
|
||||
self.architecture = "MyHDL"
|
||||
self.numeric_ports = True
|
||||
|
||||
|
||||
|
||||
|
||||
def _convert_filter(self, h, intf, siglist, memlist, genlist):
|
||||
# intended to be a entry point for other uses:
|
||||
# intended to be a entry point for other uses:
|
||||
# code checking, optimizations, etc
|
||||
pass
|
||||
|
||||
|
||||
|
||||
toVHDL = _ToVHDLConvertor()
|
||||
|
||||
@ -241,7 +241,7 @@ myhdl_header = """\
|
||||
"""
|
||||
|
||||
def _writeFileHeader(f, fn):
|
||||
vars = dict(filename=fn,
|
||||
vars = dict(filename=fn,
|
||||
version=myhdl.__version__,
|
||||
date=datetime.today().ctime()
|
||||
)
|
||||
@ -404,8 +404,8 @@ def _writeCompDecls(f, compDecls):
|
||||
print >> f, compDecls
|
||||
|
||||
def _writeModuleFooter(f, arch):
|
||||
print >> f, "end architecture %s;" % arch
|
||||
|
||||
print >> f, "end architecture %s;" % arch
|
||||
|
||||
def _getRangeString(s):
|
||||
if isinstance(s._val, EnumItemType):
|
||||
return ''
|
||||
@ -416,7 +416,7 @@ def _getRangeString(s):
|
||||
if ls:
|
||||
msb = ls + '-1'
|
||||
else:
|
||||
msb = s._nrbits-1
|
||||
msb = s._nrbits-1
|
||||
return "(%s downto 0)" % msb
|
||||
else:
|
||||
raise AssertionError
|
||||
@ -513,10 +513,10 @@ opmap = {
|
||||
ast.And : 'and',
|
||||
ast.Or : 'or',
|
||||
}
|
||||
|
||||
|
||||
|
||||
class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
|
||||
|
||||
def __init__(self, tree, buf):
|
||||
self.tree = tree
|
||||
self.buf = buf
|
||||
@ -526,30 +526,30 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.isLhs = False
|
||||
self.labelStack = []
|
||||
self.context = None
|
||||
|
||||
|
||||
def write(self, arg):
|
||||
self.buf.write("%s" % arg)
|
||||
|
||||
def writeline(self, nr=1):
|
||||
for i in range(nr):
|
||||
self.buf.write("\n%s" % self.ind)
|
||||
|
||||
|
||||
def writeDoc(self, node):
|
||||
assert hasattr(node, 'doc')
|
||||
doc = _makeDoc(node.doc, self.ind)
|
||||
self.write(doc)
|
||||
self.writeline()
|
||||
|
||||
def IntRepr(self, obj):
|
||||
self.writeline()
|
||||
|
||||
def IntRepr(self, obj):
|
||||
if obj >= 0:
|
||||
s = "%s" % int(obj)
|
||||
else:
|
||||
s = "(- %s)" % abs(int(obj))
|
||||
return s
|
||||
|
||||
|
||||
def BitRepr(self, item, var):
|
||||
return '"%s"' % bin(item, len(var))
|
||||
|
||||
|
||||
def inferCast(self, vhd, ori):
|
||||
pre, suf = "", ""
|
||||
if isinstance(vhd, vhd_int):
|
||||
@ -584,13 +584,13 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
pre, suf = "bool(", ")"
|
||||
elif isinstance(vhd, vhd_std_logic):
|
||||
if not isinstance(ori, vhd_std_logic):
|
||||
pre, suf = "stdl(", ")"
|
||||
pre, suf = "stdl(", ")"
|
||||
elif isinstance(vhd, vhd_string):
|
||||
if isinstance(ori, vhd_enum):
|
||||
pre, suf = "%s'image(" % ori._type._name, ")"
|
||||
|
||||
|
||||
return pre, suf
|
||||
|
||||
|
||||
def writeIntSize(self, n):
|
||||
# write size for large integers (beyond 32 bits signed)
|
||||
# with some safety margin
|
||||
@ -615,7 +615,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
if kind: kind += " "
|
||||
if dir: dir += " "
|
||||
self.write("%s%s: %s%s%s" % (kind, name, dir, tipe, endchar))
|
||||
|
||||
|
||||
def writeDeclarations(self):
|
||||
if self.tree.hasPrint:
|
||||
self.writeline()
|
||||
@ -625,7 +625,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
continue # hack for loop vars
|
||||
self.writeline()
|
||||
self.writeDeclaration(obj, name, kind="variable")
|
||||
|
||||
|
||||
def indent(self):
|
||||
self.ind += ' ' * 4
|
||||
|
||||
@ -643,7 +643,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.visit(node.right)
|
||||
else:
|
||||
self.BinOp(node)
|
||||
|
||||
|
||||
def inferBinaryOpCast(self, node, left, right, op):
|
||||
ns, os = node.vhd.size, node.vhdOri.size
|
||||
ds = ns - os
|
||||
@ -671,7 +671,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
if isinstance(op, (ast.Add, ast.Sub, ast.Mod, ast.FloorDiv)):
|
||||
left.vhd.size = ns
|
||||
node.vhdOri.size = ns
|
||||
elif isinstance(op, ast.Mult):
|
||||
elif isinstance(op, ast.Mult):
|
||||
left.vhd.size += ds
|
||||
node.vhdOri.size = 2 * left.vhd.size
|
||||
else:
|
||||
@ -681,14 +681,14 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
right.vhd.size = ns
|
||||
node.vhdOri.size = ns
|
||||
elif isinstance(op, ast.Mult):
|
||||
node.vhdOri.size = 2 * right.vhd.size
|
||||
node.vhdOri.size = 2 * right.vhd.size
|
||||
else:
|
||||
raise AssertionError("unexpected op %s" % op)
|
||||
pre, suf = self.inferCast(node.vhd, node.vhdOri)
|
||||
if pre == "":
|
||||
pre, suf = "(", ")"
|
||||
return pre, suf
|
||||
|
||||
|
||||
def BinOp(self, node):
|
||||
pre, suf = self.inferBinaryOpCast(node, node.left, node.right, node.op)
|
||||
self.write(pre)
|
||||
@ -696,7 +696,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.write(" %s " % opmap[type(node.op)])
|
||||
self.visit(node.right)
|
||||
self.write(suf)
|
||||
|
||||
|
||||
def inferShiftOpCast(self, node, left, right, op):
|
||||
ns, os = node.vhd.size, node.vhdOri.size
|
||||
ds = ns - os
|
||||
@ -706,7 +706,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
node.vhdOri.size = ns
|
||||
pre, suf = self.inferCast(node.vhd, node.vhdOri)
|
||||
return pre, suf
|
||||
|
||||
|
||||
def shiftOp(self, node):
|
||||
pre, suf = self.inferShiftOpCast(node, node.left, node.right, node.op)
|
||||
self.write(pre)
|
||||
@ -716,7 +716,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.visit(node.right)
|
||||
self.write(")")
|
||||
self.write(suf)
|
||||
|
||||
|
||||
def BitOp(self, node):
|
||||
pre, suf = self.inferCast(node.vhd, node.vhdOri)
|
||||
self.write(pre)
|
||||
@ -726,7 +726,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.visit(node.right)
|
||||
self.write(")")
|
||||
self.write(suf)
|
||||
|
||||
|
||||
def visit_BoolOp(self, node):
|
||||
if isinstance(node.vhd, vhd_std_logic):
|
||||
self.write("stdl")
|
||||
@ -736,7 +736,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.write(" %s " % opmap[type(node.op)])
|
||||
self.visit(n)
|
||||
self.write(")")
|
||||
|
||||
|
||||
def visit_UnaryOp(self, node):
|
||||
pre, suf = self.inferCast(node.vhd, node.vhdOri)
|
||||
self.write(pre)
|
||||
@ -745,7 +745,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.visit(node.operand)
|
||||
self.write(")")
|
||||
self.write(suf)
|
||||
|
||||
|
||||
def visit_Attribute(self, node):
|
||||
if isinstance(node.ctx, ast.Store):
|
||||
self.setAttr(node)
|
||||
@ -893,7 +893,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.write(")")
|
||||
self.write(suf)
|
||||
self.write(";")
|
||||
|
||||
|
||||
def visit_Break(self, node):
|
||||
self.write("exit;")
|
||||
|
||||
@ -1012,12 +1012,12 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
# self.write('"%s"' % bin(n, node.vhd.size))
|
||||
elif isinstance(node.vhd, vhd_unsigned):
|
||||
if abs(n) < 2**31:
|
||||
self.write("to_unsigned(%s, %s)" % (n, node.vhd.size))
|
||||
self.write("to_unsigned(%s, %s)" % (n, node.vhd.size))
|
||||
else:
|
||||
self.write('unsigned\'("%s")' % bin(n, node.vhd.size))
|
||||
elif isinstance(node.vhd, vhd_signed):
|
||||
if abs(n) < 2**31:
|
||||
self.write("to_signed(%s, %s)" % (n, node.vhd.size))
|
||||
self.write("to_signed(%s, %s)" % (n, node.vhd.size))
|
||||
else:
|
||||
self.write('signed\'("%s")' % bin(n, node.vhd.size))
|
||||
else:
|
||||
@ -1026,7 +1026,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.write(n)
|
||||
if n < 0:
|
||||
self.write(")")
|
||||
|
||||
|
||||
def visit_Str(self, node):
|
||||
typemark = 'string'
|
||||
if isinstance(node.vhd, vhd_unsigned):
|
||||
@ -1050,7 +1050,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
# ugly hack to detect an orphan "task" call
|
||||
if isinstance(expr, ast.Call) and hasattr(expr, 'tree'):
|
||||
self.write(';')
|
||||
|
||||
|
||||
def visit_IfExp(self, node):
|
||||
pre, suf = self.inferCast(node.vhd, node.body.vhdOri)
|
||||
self.write(pre)
|
||||
@ -1123,7 +1123,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
## self.write("end")
|
||||
self.labelStack.pop()
|
||||
self.labelStack.pop()
|
||||
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
raise AssertionError("To be implemented in subclass")
|
||||
|
||||
@ -1155,7 +1155,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
if (i == len(node.tests)-1) and not node.else_:
|
||||
self.write("when others")
|
||||
comment = " -- %s" % itemRepr
|
||||
else:
|
||||
else:
|
||||
self.write("when ")
|
||||
self.write(itemRepr)
|
||||
self.write(" =>%s" % comment)
|
||||
@ -1202,13 +1202,13 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.dedent()
|
||||
self.writeline()
|
||||
self.write("end if;")
|
||||
|
||||
|
||||
def visit_ListComp(self, node):
|
||||
pass # do nothing
|
||||
|
||||
def visit_Module(self, node):
|
||||
for stmt in node.body:
|
||||
self.visit(stmt)
|
||||
self.visit(stmt)
|
||||
|
||||
def visit_Name(self, node):
|
||||
if isinstance(node.ctx, ast.Store):
|
||||
@ -1239,7 +1239,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
ori = inferVhdlObj(obj)
|
||||
pre, suf = self.inferCast(node.vhd, ori)
|
||||
s = "%s%s%s" % (pre, s, suf)
|
||||
|
||||
|
||||
elif n in self.tree.argnames:
|
||||
assert n in self.tree.symdict
|
||||
obj = self.tree.symdict[n]
|
||||
@ -1262,9 +1262,9 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
elif isinstance(node.vhd, vhd_std_logic):
|
||||
s = "stdl(%s)" % n
|
||||
elif isinstance(node.vhd, vhd_unsigned):
|
||||
s = "to_unsigned(%s, %s)" % (n, node.vhd.size)
|
||||
s = "to_unsigned(%s, %s)" % (n, node.vhd.size)
|
||||
elif isinstance(node.vhd, vhd_signed):
|
||||
s = "to_signed(%s, %s)" % (n, node.vhd.size)
|
||||
s = "to_signed(%s, %s)" % (n, node.vhd.size)
|
||||
else:
|
||||
if isinstance(node.vhd, vhd_int):
|
||||
s = self.IntRepr(obj)
|
||||
@ -1272,12 +1272,12 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
s = "'%s'" % int(obj)
|
||||
elif isinstance(node.vhd, vhd_unsigned):
|
||||
if abs(obj) < 2** 31:
|
||||
s = "to_unsigned(%s, %s)" % (n, node.vhd.size)
|
||||
s = "to_unsigned(%s, %s)" % (n, node.vhd.size)
|
||||
else:
|
||||
s = 'unsigned\'("%s")' % bin(obj, node.vhd.size)
|
||||
elif isinstance(node.vhd, vhd_signed):
|
||||
if abs(obj) < 2** 31:
|
||||
s = "to_signed(%s, %s)" % (n, node.vhd.size)
|
||||
s = "to_signed(%s, %s)" % (n, node.vhd.size)
|
||||
else:
|
||||
s = 'signed\'("%s")' % bin(obj, node.vhd.size)
|
||||
elif isinstance(obj, _Signal):
|
||||
@ -1308,7 +1308,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
|
||||
def visit_Pass(self, node):
|
||||
self.write("null;")
|
||||
|
||||
|
||||
def visit_Print(self, node):
|
||||
argnr = 0
|
||||
for s in node.format:
|
||||
@ -1341,7 +1341,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
|
||||
def visit_Raise(self, node):
|
||||
self.write('assert False report "End of Simulation" severity Failure;')
|
||||
|
||||
|
||||
def visit_Return(self, node):
|
||||
pass
|
||||
|
||||
@ -1489,9 +1489,9 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
senslist = [s.sig for s in senslist]
|
||||
return senslist
|
||||
|
||||
|
||||
|
||||
class _ConvertAlwaysVisitor(_ConvertVisitor):
|
||||
|
||||
|
||||
def __init__(self, tree, blockBuf, funcBuf):
|
||||
_ConvertVisitor.__init__(self, tree, blockBuf)
|
||||
self.funcBuf = funcBuf
|
||||
@ -1538,9 +1538,9 @@ class _ConvertAlwaysVisitor(_ConvertVisitor):
|
||||
self.write("end process %s;" % self.tree.name)
|
||||
self.writeline(2)
|
||||
|
||||
|
||||
|
||||
class _ConvertInitialVisitor(_ConvertVisitor):
|
||||
|
||||
|
||||
def __init__(self, tree, blockBuf, funcBuf):
|
||||
_ConvertVisitor.__init__(self, tree, blockBuf)
|
||||
self.funcBuf = funcBuf
|
||||
@ -1564,7 +1564,7 @@ class _ConvertInitialVisitor(_ConvertVisitor):
|
||||
|
||||
|
||||
class _ConvertAlwaysCombVisitor(_ConvertVisitor):
|
||||
|
||||
|
||||
def __init__(self, tree, blockBuf, funcBuf):
|
||||
_ConvertVisitor.__init__(self, tree, blockBuf)
|
||||
self.funcBuf = funcBuf
|
||||
@ -1590,9 +1590,9 @@ class _ConvertAlwaysCombVisitor(_ConvertVisitor):
|
||||
self.write("end process %s;" % self.tree.name)
|
||||
self.writeline(2)
|
||||
|
||||
|
||||
|
||||
class _ConvertSimpleAlwaysCombVisitor(_ConvertVisitor):
|
||||
|
||||
|
||||
def __init__(self, tree, blockBuf, funcBuf):
|
||||
_ConvertVisitor.__init__(self, tree, blockBuf)
|
||||
self.funcBuf = funcBuf
|
||||
@ -1614,7 +1614,7 @@ class _ConvertSimpleAlwaysCombVisitor(_ConvertVisitor):
|
||||
|
||||
|
||||
class _ConvertAlwaysDecoVisitor(_ConvertVisitor):
|
||||
|
||||
|
||||
def __init__(self, tree, blockBuf, funcBuf):
|
||||
_ConvertVisitor.__init__(self, tree, blockBuf)
|
||||
self.funcBuf = funcBuf
|
||||
@ -1653,8 +1653,8 @@ class _ConvertAlwaysDecoVisitor(_ConvertVisitor):
|
||||
self.writeline()
|
||||
self.write("end process %s;" % self.tree.name)
|
||||
self.writeline(2)
|
||||
|
||||
|
||||
|
||||
|
||||
def _convertInitVal(reg, init):
|
||||
pre, suf = '', ''
|
||||
if isinstance(reg, _Signal):
|
||||
@ -1678,10 +1678,10 @@ def _convertInitVal(reg, init):
|
||||
assert isinstance(init, EnumItemType)
|
||||
v = init._toVHDL()
|
||||
return v
|
||||
|
||||
|
||||
|
||||
|
||||
class _ConvertAlwaysSeqVisitor(_ConvertVisitor):
|
||||
|
||||
|
||||
def __init__(self, tree, blockBuf, funcBuf):
|
||||
_ConvertVisitor.__init__(self, tree, blockBuf)
|
||||
self.funcBuf = funcBuf
|
||||
@ -1743,9 +1743,9 @@ class _ConvertAlwaysSeqVisitor(_ConvertVisitor):
|
||||
self.write("end process %s;" % self.tree.name)
|
||||
self.writeline(2)
|
||||
|
||||
|
||||
|
||||
class _ConvertFunctionVisitor(_ConvertVisitor):
|
||||
|
||||
|
||||
def __init__(self, tree, funcBuf):
|
||||
_ConvertVisitor.__init__(self, tree, funcBuf)
|
||||
self.returnObj = tree.returnObj
|
||||
@ -1762,7 +1762,7 @@ class _ConvertFunctionVisitor(_ConvertVisitor):
|
||||
obj = self.tree.symdict[name]
|
||||
self.writeline()
|
||||
self.writeDeclaration(obj, name, dir="in", constr=False, endchar="")
|
||||
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
self.write("function %s(" % self.tree.name)
|
||||
self.indent()
|
||||
@ -1787,9 +1787,9 @@ class _ConvertFunctionVisitor(_ConvertVisitor):
|
||||
self.visit(node.value)
|
||||
self.write(";")
|
||||
|
||||
|
||||
|
||||
class _ConvertTaskVisitor(_ConvertVisitor):
|
||||
|
||||
|
||||
def __init__(self, tree, funcBuf):
|
||||
_ConvertVisitor.__init__(self, tree, funcBuf)
|
||||
self.returnLabel = _Label("RETURN")
|
||||
@ -1806,7 +1806,7 @@ class _ConvertTaskVisitor(_ConvertVisitor):
|
||||
dir = (inout and "inout") or (output and "out") or "in"
|
||||
self.writeline()
|
||||
self.writeDeclaration(obj, name, dir=dir, constr=False, endchar="")
|
||||
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
self.write("procedure %s" % self.tree.name)
|
||||
if self.tree.argnames:
|
||||
@ -1844,14 +1844,14 @@ class vhd_string(vhd_type):
|
||||
class vhd_enum(vhd_type):
|
||||
def __init__(self, tipe):
|
||||
self._type = tipe
|
||||
|
||||
|
||||
class vhd_std_logic(vhd_type):
|
||||
def __init__(self, size=0):
|
||||
vhd_type.__init__(self)
|
||||
self.size = 1
|
||||
def toStr(self, constr=True):
|
||||
return 'std_logic'
|
||||
|
||||
|
||||
class vhd_boolean(vhd_type):
|
||||
def __init__(self, size=0):
|
||||
vhd_type.__init__(self)
|
||||
@ -1863,7 +1863,7 @@ class vhd_vector(vhd_type):
|
||||
def __init__(self, size=0, lenStr=False):
|
||||
vhd_type.__init__(self, size)
|
||||
self.lenStr = lenStr
|
||||
|
||||
|
||||
class vhd_unsigned(vhd_vector):
|
||||
def toStr(self, constr=True):
|
||||
if constr:
|
||||
@ -1874,7 +1874,7 @@ class vhd_unsigned(vhd_vector):
|
||||
return "unsigned(%s downto 0)" % (self.size-1)
|
||||
else:
|
||||
return "unsigned"
|
||||
|
||||
|
||||
class vhd_signed(vhd_vector):
|
||||
def toStr(self, constr=True):
|
||||
if constr:
|
||||
@ -1885,7 +1885,7 @@ class vhd_signed(vhd_vector):
|
||||
return "signed(%s downto 0)" % (self.size-1)
|
||||
else:
|
||||
return "signed"
|
||||
|
||||
|
||||
class vhd_int(vhd_type):
|
||||
def toStr(self, constr=True):
|
||||
return "integer"
|
||||
@ -1893,7 +1893,7 @@ class vhd_int(vhd_type):
|
||||
class vhd_nat(vhd_int):
|
||||
def toStr(self, constr=True):
|
||||
return "natural"
|
||||
|
||||
|
||||
|
||||
class _loopInt(int):
|
||||
pass
|
||||
@ -1915,7 +1915,7 @@ def maxType(o1, o2):
|
||||
return vhd_int()
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def inferVhdlObj(obj):
|
||||
vhd = None
|
||||
if (isinstance(obj, _Signal) and obj._type is intbv) or \
|
||||
@ -1934,7 +1934,7 @@ def inferVhdlObj(obj):
|
||||
tipe = obj._val._type
|
||||
else:
|
||||
tipe = obj._type
|
||||
vhd = vhd_enum(tipe)
|
||||
vhd = vhd_enum(tipe)
|
||||
elif isinstance(obj, (int, long)):
|
||||
if obj >= 0:
|
||||
vhd = vhd_nat()
|
||||
@ -1949,7 +1949,7 @@ def maybeNegative(vhd):
|
||||
if isinstance(vhd, vhd_int) and not isinstance(vhd, vhd_nat):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
|
||||
def __init__(self, tree):
|
||||
@ -1976,7 +1976,7 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
node.value.vhd = copy(node.target.vhd)
|
||||
node.vhdOri = copy(node.target.vhd)
|
||||
elif isinstance(node.op, (ast.RShift, ast.LShift)):
|
||||
node.value.vhd = vhd_int()
|
||||
node.value.vhd = vhd_int()
|
||||
node.vhdOri = copy(node.target.vhd)
|
||||
else:
|
||||
node.left, node.right = node.target, node.value
|
||||
@ -2044,7 +2044,7 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
# make it possible to detect loop variable
|
||||
self.tree.vardict[var] = _loopInt(-1)
|
||||
self.generic_visit(node)
|
||||
|
||||
|
||||
def visit_Name(self, node):
|
||||
if node.id in self.tree.vardict:
|
||||
node.obj = self.tree.vardict[node.id]
|
||||
@ -2083,7 +2083,7 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
if isinstance(left.vhd, vhd_unsigned) and maybeNegative(right.vhd):
|
||||
left.vhd = vhd_signed(left.vhd.size + 1)
|
||||
l, r = left.vhd, right.vhd
|
||||
ls, rs = l.size, r.size
|
||||
ls, rs = l.size, r.size
|
||||
if isinstance(r, vhd_vector) and isinstance(l, vhd_vector):
|
||||
if isinstance(op, (ast.Add, ast.Sub)):
|
||||
s = max(ls, rs)
|
||||
@ -2132,7 +2132,7 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.generic_visit(node)
|
||||
for test, suite in node.tests:
|
||||
test.vhd = vhd_boolean()
|
||||
|
||||
|
||||
def visit_IfExp(self, node):
|
||||
self.generic_visit(node)
|
||||
node.test.vhd = vhd_boolean()
|
||||
@ -2196,7 +2196,7 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
elif isinstance(node.vhd, vhd_nat):
|
||||
node.vhd = vhd_int()
|
||||
node.vhdOri = copy(node.vhd)
|
||||
|
||||
|
||||
def visit_While(self, node):
|
||||
self.generic_visit(node)
|
||||
node.test.vhd = vhd_boolean()
|
||||
@ -2211,7 +2211,7 @@ def _annotateTypes(genlist):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -40,12 +40,12 @@ from myhdl._extractHierarchy import (_HierExtr, _isMem, _getMemInfo,
|
||||
_UserVerilogCode, _userCodeMap)
|
||||
|
||||
from myhdl._instance import _Instantiator
|
||||
from myhdl.conversion._misc import (_error, _kind, _context,
|
||||
from myhdl.conversion._misc import (_error, _kind, _context,
|
||||
_ConversionMixin, _Label, _genUniqueSuffix, _isConstant)
|
||||
from myhdl.conversion._analyze import (_analyzeSigs, _analyzeGens, _analyzeTopFunc,
|
||||
from myhdl.conversion._analyze import (_analyzeSigs, _analyzeGens, _analyzeTopFunc,
|
||||
_Ram, _Rom)
|
||||
from myhdl._Signal import _Signal
|
||||
|
||||
|
||||
_converting = 0
|
||||
_profileFunc = None
|
||||
|
||||
@ -53,7 +53,7 @@ def _checkArgs(arglist):
|
||||
for arg in arglist:
|
||||
if not isinstance(arg, (GeneratorType, _Instantiator, _UserVerilogCode)):
|
||||
raise ToVerilogError(_error.ArgType, arg)
|
||||
|
||||
|
||||
def _flatten(*args):
|
||||
arglist = []
|
||||
for arg in args:
|
||||
@ -79,10 +79,10 @@ def _makeDoc(doc, indent=''):
|
||||
|
||||
class _ToVerilogConvertor(object):
|
||||
|
||||
__slots__ = ("name",
|
||||
"timescale",
|
||||
__slots__ = ("name",
|
||||
"timescale",
|
||||
"standard",
|
||||
"prefer_blocking_assignments",
|
||||
"prefer_blocking_assignments",
|
||||
"radix",
|
||||
"header",
|
||||
"no_myhdl_header",
|
||||
@ -124,20 +124,19 @@ class _ToVerilogConvertor(object):
|
||||
|
||||
vpath = name + ".v"
|
||||
vfile = open(vpath, 'w')
|
||||
|
||||
|
||||
### initialize properly ###
|
||||
_genUniqueSuffix.reset()
|
||||
|
||||
siglist, memlist = _analyzeSigs(h.hierarchy)
|
||||
arglist = _flatten(h.top)
|
||||
# print h.top
|
||||
_checkArgs(arglist)
|
||||
genlist = _analyzeGens(arglist, h.absnames)
|
||||
siglist, memlist = _analyzeSigs(h.hierarchy)
|
||||
_annotateTypes(genlist)
|
||||
intf = _analyzeTopFunc(func, *args, **kwargs)
|
||||
intf.name = name
|
||||
doc = _makeDoc(inspect.getdoc(func))
|
||||
|
||||
|
||||
self._convert_filter(h, intf, siglist, memlist, genlist)
|
||||
|
||||
_writeFileHeader(vfile, vpath, self.timescale)
|
||||
@ -157,9 +156,9 @@ class _ToVerilogConvertor(object):
|
||||
|
||||
### clean-up properly ###
|
||||
self._cleanup(siglist)
|
||||
|
||||
|
||||
return h.top
|
||||
|
||||
|
||||
def _cleanup(self, siglist):
|
||||
# clean up signal names
|
||||
for sig in siglist:
|
||||
@ -167,7 +166,7 @@ class _ToVerilogConvertor(object):
|
||||
# sig._name = None
|
||||
# sig._driven = False
|
||||
# sig._read = False
|
||||
|
||||
|
||||
# clean up attributes
|
||||
self.name = None
|
||||
self.standard = '2001'
|
||||
@ -176,13 +175,13 @@ class _ToVerilogConvertor(object):
|
||||
self.header = ""
|
||||
self.no_myhdl_header = False
|
||||
self.no_testbench = False
|
||||
|
||||
|
||||
|
||||
|
||||
def _convert_filter(self, h, intf, siglist, memlist, genlist):
|
||||
# intended to be a entry point for other uses:
|
||||
# intended to be a entry point for other uses:
|
||||
# code checking, optimizations, etc
|
||||
pass
|
||||
|
||||
|
||||
|
||||
toVerilog = _ToVerilogConvertor()
|
||||
|
||||
@ -193,7 +192,7 @@ myhdl_header = """\
|
||||
"""
|
||||
|
||||
def _writeFileHeader(f, fn, ts):
|
||||
vars = dict(filename=fn,
|
||||
vars = dict(filename=fn,
|
||||
version=myhdl.__version__,
|
||||
date=datetime.today().ctime()
|
||||
)
|
||||
@ -290,7 +289,7 @@ def _writeSigDecls(f, intf, siglist, memlist):
|
||||
p = _getSignString(m.elObj)
|
||||
k = 'wire'
|
||||
if m._driven:
|
||||
k = m._driven
|
||||
k = m._driven
|
||||
print >> f, "%s %s%s%s [0:%s-1];" % (k, p, r, m.name, m.depth)
|
||||
print >> f
|
||||
for s in constwires:
|
||||
@ -309,7 +308,7 @@ def _writeSigDecls(f, intf, siglist, memlist):
|
||||
|
||||
def _writeModuleFooter(f):
|
||||
print >> f, "endmodule"
|
||||
|
||||
|
||||
|
||||
def _writeTestBench(f, intf):
|
||||
print >> f, "module tb_%s;" % intf.name
|
||||
@ -336,7 +335,7 @@ def _writeTestBench(f, intf):
|
||||
if to.getvalue():
|
||||
print >> f, " $to_myhdl("
|
||||
print >> f, to.getvalue()[:-2]
|
||||
print >> f, " );"
|
||||
print >> f, " );"
|
||||
print >> f, "end"
|
||||
print >> f
|
||||
print >> f, "%s dut(" % intf.name
|
||||
@ -378,7 +377,7 @@ def _convertGens(genlist, vfile):
|
||||
elif tree.kind == _kind.ALWAYS_DECO:
|
||||
Visitor = _ConvertAlwaysDecoVisitor
|
||||
elif tree.kind == _kind.ALWAYS_SEQ:
|
||||
Visitor = _ConvertAlwaysSeqVisitor
|
||||
Visitor = _ConvertAlwaysSeqVisitor
|
||||
else: # ALWAYS_COMB
|
||||
Visitor = _ConvertAlwaysCombVisitor
|
||||
v = Visitor(tree, blockBuf, funcBuf)
|
||||
@ -417,7 +416,7 @@ opmap = {
|
||||
|
||||
|
||||
class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
|
||||
|
||||
def __init__(self, tree, buf):
|
||||
self.tree = tree
|
||||
self.buf = buf
|
||||
@ -440,13 +439,13 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
def writeline(self, nr=1):
|
||||
for i in range(nr):
|
||||
self.buf.write("\n%s" % self.ind)
|
||||
|
||||
|
||||
def writeDoc(self, node):
|
||||
assert hasattr(node, 'doc')
|
||||
doc = _makeDoc(node.doc, self.ind)
|
||||
self.write(doc)
|
||||
self.writeline()
|
||||
|
||||
|
||||
def indent(self):
|
||||
self.ind += ' ' * 4
|
||||
|
||||
@ -502,7 +501,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.write(" = %s;" % inival)
|
||||
else:
|
||||
self.write(";")
|
||||
|
||||
|
||||
def writeDeclarations(self):
|
||||
for name, obj in self.tree.vardict.items():
|
||||
self.writeline()
|
||||
@ -566,7 +565,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.write(" %s " % opmap[type(node.op)])
|
||||
self.visit(n)
|
||||
self.write(")")
|
||||
|
||||
|
||||
def visit_UnaryOp(self, node):
|
||||
self.write("(%s" % opmap[type(node.op)])
|
||||
self.visit(node.operand)
|
||||
@ -793,7 +792,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
# ugly hack to detect an orphan "task" call
|
||||
if isinstance(expr, ast.Call) and hasattr(expr, 'tree'):
|
||||
self.write(';')
|
||||
|
||||
|
||||
def visit_IfExp(self, node):
|
||||
self.visit(node.test)
|
||||
self.write(' ? ')
|
||||
@ -912,7 +911,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.dedent()
|
||||
self.writeline()
|
||||
self.write("endcase")
|
||||
|
||||
|
||||
def mapToIf(self, node, *args):
|
||||
first = True
|
||||
for test, suite in node.tests:
|
||||
@ -945,7 +944,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
def visit_Module(self, node, *args):
|
||||
for stmt in node.body:
|
||||
self.visit(stmt)
|
||||
|
||||
|
||||
def visit_ListComp(self, node):
|
||||
pass # do nothing
|
||||
|
||||
@ -1000,7 +999,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.write("$signed({1'b0, ")
|
||||
self.write(s)
|
||||
if addSignBit:
|
||||
self.write("})")
|
||||
self.write("})")
|
||||
|
||||
def visit_Pass(self, node):
|
||||
self.write("// pass")
|
||||
@ -1054,7 +1053,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
|
||||
def visit_Raise(self, node):
|
||||
self.write("$finish;")
|
||||
|
||||
|
||||
def visit_Return(self, node):
|
||||
self.write("disable %s;" % self.returnLabel)
|
||||
|
||||
@ -1163,9 +1162,9 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.writeSensitivityList(senslist)
|
||||
self.write(";")
|
||||
|
||||
|
||||
|
||||
class _ConvertAlwaysVisitor(_ConvertVisitor):
|
||||
|
||||
|
||||
def __init__(self, tree, blockBuf, funcBuf):
|
||||
_ConvertVisitor.__init__(self, tree, blockBuf)
|
||||
self.funcBuf = funcBuf
|
||||
@ -1190,14 +1189,14 @@ class _ConvertAlwaysVisitor(_ConvertVisitor):
|
||||
|
||||
|
||||
class _ConvertInitialVisitor(_ConvertVisitor):
|
||||
|
||||
|
||||
def __init__(self, tree, blockBuf, funcBuf):
|
||||
_ConvertVisitor.__init__(self, tree, blockBuf)
|
||||
self.funcBuf = funcBuf
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
self.writeDoc(node)
|
||||
self.write("initial begin: %s" % self.tree.name)
|
||||
self.write("initial begin: %s" % self.tree.name)
|
||||
self.indent()
|
||||
self.writeDeclarations()
|
||||
self.visit_stmt(node.body)
|
||||
@ -1209,7 +1208,7 @@ class _ConvertInitialVisitor(_ConvertVisitor):
|
||||
|
||||
|
||||
class _ConvertAlwaysCombVisitor(_ConvertVisitor):
|
||||
|
||||
|
||||
def __init__(self, tree, blockBuf, funcBuf):
|
||||
_ConvertVisitor.__init__(self, tree, blockBuf)
|
||||
if toVerilog.prefer_blocking_assignments:
|
||||
@ -1227,9 +1226,9 @@ class _ConvertAlwaysCombVisitor(_ConvertVisitor):
|
||||
self.writeline(2)
|
||||
|
||||
|
||||
|
||||
|
||||
class _ConvertSimpleAlwaysCombVisitor(_ConvertVisitor):
|
||||
|
||||
|
||||
def __init__(self, tree, blockBuf, funcBuf):
|
||||
_ConvertVisitor.__init__(self, tree, blockBuf)
|
||||
self.funcBuf = funcBuf
|
||||
@ -1245,9 +1244,9 @@ class _ConvertSimpleAlwaysCombVisitor(_ConvertVisitor):
|
||||
self.visit_stmt(node.body)
|
||||
self.writeline(2)
|
||||
|
||||
|
||||
|
||||
class _ConvertAlwaysDecoVisitor(_ConvertVisitor):
|
||||
|
||||
|
||||
def __init__(self, tree, blockBuf, funcBuf):
|
||||
_ConvertVisitor.__init__(self, tree, blockBuf)
|
||||
self.funcBuf = funcBuf
|
||||
@ -1277,10 +1276,10 @@ def _convertInitVal(reg, init):
|
||||
assert isinstance(init, EnumItemType)
|
||||
v = init._toVerilog()
|
||||
return v
|
||||
|
||||
|
||||
|
||||
class _ConvertAlwaysSeqVisitor(_ConvertVisitor):
|
||||
|
||||
|
||||
def __init__(self, tree, blockBuf, funcBuf):
|
||||
_ConvertVisitor.__init__(self, tree, blockBuf)
|
||||
self.funcBuf = funcBuf
|
||||
@ -1319,9 +1318,9 @@ class _ConvertAlwaysSeqVisitor(_ConvertVisitor):
|
||||
self.write("end")
|
||||
self.writeline(2)
|
||||
|
||||
|
||||
|
||||
class _ConvertFunctionVisitor(_ConvertVisitor):
|
||||
|
||||
|
||||
def __init__(self, tree, funcBuf):
|
||||
_ConvertVisitor.__init__(self, tree, funcBuf)
|
||||
self.returnObj = tree.returnObj
|
||||
@ -1336,7 +1335,7 @@ class _ConvertFunctionVisitor(_ConvertVisitor):
|
||||
obj = self.tree.symdict[name]
|
||||
self.writeline()
|
||||
self.writeDeclaration(obj, name, "input")
|
||||
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
self.write("function ")
|
||||
self.writeOutputDeclaration()
|
||||
@ -1364,9 +1363,9 @@ class _ConvertFunctionVisitor(_ConvertVisitor):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class _ConvertTaskVisitor(_ConvertVisitor):
|
||||
|
||||
|
||||
def __init__(self, tree, funcBuf):
|
||||
_ConvertVisitor.__init__(self, tree, funcBuf)
|
||||
self.returnLabel = _Label("RETURN")
|
||||
@ -1380,7 +1379,7 @@ class _ConvertTaskVisitor(_ConvertVisitor):
|
||||
dir = (inout and "inout") or (output and "output") or "input"
|
||||
self.writeline()
|
||||
self.writeDeclaration(obj, name, dir)
|
||||
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
self.write("task %s;" % self.tree.name)
|
||||
self.indent()
|
||||
@ -1410,17 +1409,17 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
|
||||
def __init__(self, tree):
|
||||
self.tree = tree
|
||||
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
# don't visit arguments and decorators
|
||||
for stmt in node.body:
|
||||
self.visit(stmt)
|
||||
|
||||
self.visit(stmt)
|
||||
|
||||
def visit_BinOp(self, node):
|
||||
self.visit(node.left)
|
||||
self.visit(node.right)
|
||||
node.signed = node.left.signed or node.right.signed
|
||||
|
||||
|
||||
def visit_BoolOp(self, node):
|
||||
for n in node.values:
|
||||
self.visit(n)
|
||||
@ -1433,20 +1432,20 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
node.obj = int(-1)
|
||||
if isinstance(node.operand, ast.Num):
|
||||
node.signed = True
|
||||
|
||||
|
||||
def visit_Attribute(self, node):
|
||||
if isinstance(node.ctx, ast.Store):
|
||||
self.setAttr(node)
|
||||
else:
|
||||
self.getAttr(node)
|
||||
|
||||
|
||||
def setAttr(self, node):
|
||||
self.visit(node.value)
|
||||
|
||||
def getAttr(self, node):
|
||||
node.signed = False
|
||||
self.visit(node.value)
|
||||
|
||||
|
||||
def visit_Call(self, node):
|
||||
self.generic_visit(node)
|
||||
f = self.getObj(node.func)
|
||||
@ -1457,7 +1456,7 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
elif hasattr(node, 'tree'):
|
||||
v = _AnnotateTypesVisitor(node.tree)
|
||||
v.visit(node.tree)
|
||||
node.signed = _maybeNegative(node.tree.returnObj)
|
||||
node.signed = _maybeNegative(node.tree.returnObj)
|
||||
|
||||
def visit_Compare(self, node):
|
||||
node.signed = False
|
||||
@ -1466,7 +1465,7 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.visit(n)
|
||||
if n.signed:
|
||||
node.signed = True
|
||||
|
||||
|
||||
def visit_If(self, node):
|
||||
if node.ignore:
|
||||
return
|
||||
@ -1509,13 +1508,13 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
node.signed = False
|
||||
self.generic_visit(node)
|
||||
|
||||
|
||||
|
||||
def _annotateTypes(genlist):
|
||||
for tree in genlist:
|
||||
if isinstance(tree, _UserVerilogCode):
|
||||
continue
|
||||
v = _AnnotateTypesVisitor(tree)
|
||||
v.visit(tree)
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user