mirror of
https://github.com/myhdl/myhdl.git
synced 2025-01-24 21:52:56 +08:00
Major refactoring of type inference for toVerilog
Put the code in _toVerilog instead of _analyze --HG-- branch : 0.8-dev
This commit is contained in:
parent
951d0d53ae
commit
1006dbe564
@ -25,23 +25,19 @@
|
||||
import inspect
|
||||
# import compiler
|
||||
# from compiler import ast as astNode
|
||||
from types import GeneratorType, FunctionType, ClassType, MethodType
|
||||
from cStringIO import StringIO
|
||||
from types import FunctionType, MethodType
|
||||
import re
|
||||
import warnings
|
||||
import ast
|
||||
import __builtin__
|
||||
|
||||
import myhdl
|
||||
from myhdl import *
|
||||
from myhdl import ConversionError
|
||||
from myhdl._unparse import _unparse
|
||||
from myhdl._cell_deref import _cell_deref
|
||||
from myhdl._always_comb import _AlwaysComb
|
||||
from myhdl._always_seq import _AlwaysSeq
|
||||
from myhdl._always import _Always
|
||||
from myhdl._delay import delay
|
||||
from myhdl.conversion._misc import (_error, _access, _kind, _context,
|
||||
from myhdl.conversion._misc import (_error, _access, _kind,
|
||||
_ConversionMixin, _Label, _genUniqueSuffix)
|
||||
from myhdl._extractHierarchy import _isMem, _getMemInfo, _UserCode
|
||||
from myhdl._Signal import _Signal, _WaiterList
|
||||
@ -376,14 +372,6 @@ class _Rom(object):
|
||||
def __init__(self, rom):
|
||||
self.rom = rom
|
||||
|
||||
|
||||
def _maybeNegative(obj):
|
||||
if hasattr(obj, '_min') and (obj._min is not None) and (obj._min < 0):
|
||||
return True
|
||||
if isinstance(obj, (int, long)) and obj < 0:
|
||||
return True
|
||||
return False
|
||||
|
||||
re_str = re.compile(r"[^%]+")
|
||||
re_ConvSpec = re.compile(r"%(?P<justified>[-]?)(?P<width>[0-9]*)(?P<conv>[sd])")
|
||||
|
||||
@ -435,13 +423,10 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.access = _access.INPUT
|
||||
self.kind = _kind.NORMAL
|
||||
|
||||
|
||||
def visit_BinOp(self, node):
|
||||
self.visit(node.left)
|
||||
self.visit(node.right)
|
||||
node.obj = int(-1)
|
||||
node.signed = node.left.signed or node.right.signed
|
||||
|
||||
|
||||
def visit_BoolOp(self, node):
|
||||
for n in node.values:
|
||||
@ -450,23 +435,17 @@ 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()
|
||||
node.signed = False
|
||||
|
||||
|
||||
def visit_UnaryOp(self, node):
|
||||
self.visit(node.operand)
|
||||
op = node.op
|
||||
node.obj = node.operand.obj
|
||||
node.signed = node.operand.signed
|
||||
if isinstance(op, ast.Not):
|
||||
node.obj = bool()
|
||||
elif isinstance(op, ast.UAdd):
|
||||
node.obj = int(-1)
|
||||
elif isinstance(op, ast.USub):
|
||||
node.obj = int(-1)
|
||||
if isinstance(node.operand, ast.Num):
|
||||
node.signed = True
|
||||
|
||||
|
||||
def visit_Attribute(self, node):
|
||||
if isinstance(node.ctx, ast.Store):
|
||||
@ -481,7 +460,6 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
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")
|
||||
@ -493,7 +471,6 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
def getAttr(self, node):
|
||||
self.visit(node.value)
|
||||
node.obj = None
|
||||
node.signed = False
|
||||
if isinstance(node.value, ast.Name):
|
||||
n = node.value.id
|
||||
if (n not in self.tree.vardict) and (n not in self.tree.symdict):
|
||||
@ -523,8 +500,6 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
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
|
||||
@ -544,8 +519,6 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
if isinstance(obj, intbv):
|
||||
if len(obj) == 0:
|
||||
self.raiseError(node, _error.IntbvBitWidth, n)
|
||||
if obj._min < 0:
|
||||
_signed = True
|
||||
if isinstance(obj, modbv):
|
||||
if not obj._hasFullRange():
|
||||
self.raiseError(node, _error.ModbvRange, n)
|
||||
@ -564,23 +537,15 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
else:
|
||||
self.visit(value)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def visit_AugAssign(self, node):
|
||||
self.access = _access.INOUT
|
||||
self.visit(node.target)
|
||||
self.access = _access.INPUT
|
||||
self.visit(node.value)
|
||||
|
||||
|
||||
|
||||
def visit_Break(self, node):
|
||||
self.labelStack[-2].isActive = True
|
||||
|
||||
|
||||
|
||||
def visit_Call(self, node):
|
||||
self.visit(node.func)
|
||||
self.access = _access.UNKNOWN
|
||||
@ -592,7 +557,6 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
argsAreInputs = True
|
||||
f = self.getObj(node.func)
|
||||
node.obj = None
|
||||
node.signed = False
|
||||
if type(f) is type and issubclass(f, intbv):
|
||||
node.obj = self.getVal(node)
|
||||
elif f is concat:
|
||||
@ -610,7 +574,6 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
### suprize: identity comparison on unbound methods doesn't work in python 2.5??
|
||||
elif f == intbv.signed:
|
||||
node.obj = int(-1)
|
||||
node.signed = True
|
||||
elif f in myhdlObjects:
|
||||
pass
|
||||
elif f in builtinObjects:
|
||||
@ -665,17 +628,10 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
for arg in node.args:
|
||||
self.visit(arg)
|
||||
|
||||
|
||||
|
||||
|
||||
def visit_Compare(self, node):
|
||||
node.obj = bool()
|
||||
node.signed = False
|
||||
#for n in ast.iter_child_nodes(node):
|
||||
for n in [node.left] + node.comparators:
|
||||
self.visit(n)
|
||||
if n.signed:
|
||||
node.signed = True
|
||||
op, arg = node.ops[0], node.comparators[0]
|
||||
## node.expr.target = self.getObj(arg)
|
||||
## arg.target = self.getObj(node.expr)
|
||||
@ -698,10 +654,7 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
elif v == 1:
|
||||
node.edge = sig.posedge
|
||||
|
||||
|
||||
|
||||
def visit_Num(self, node):
|
||||
node.signed = False
|
||||
n = node.n
|
||||
# assign to value attribute for backwards compatibility
|
||||
node.value = n
|
||||
@ -713,15 +666,11 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
node.obj = None
|
||||
|
||||
def visit_Str(self, node):
|
||||
node.signed = False
|
||||
node.obj = node.s
|
||||
|
||||
|
||||
def visit_Continue(self, node):
|
||||
self.labelStack[-1].isActive = True
|
||||
|
||||
|
||||
|
||||
def visit_For(self, node):
|
||||
node.breakLabel = _Label("BREAK")
|
||||
node.loopLabel = _Label("LOOP")
|
||||
@ -745,11 +694,9 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.labelStack.pop()
|
||||
self.labelStack.pop()
|
||||
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
raise AssertionError("subclass must implement this")
|
||||
|
||||
|
||||
def visit_If(self, node):
|
||||
if node.ignore:
|
||||
return
|
||||
@ -789,8 +736,6 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
if (len(choices) == _getNritems(var1.obj)) or node.else_:
|
||||
node.isFullCase = True
|
||||
|
||||
|
||||
|
||||
def visit_ListComp(self, node):
|
||||
mem = node.obj = _Ram()
|
||||
self.kind = _kind.DECLARATION
|
||||
@ -808,8 +753,6 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.raiseError(node, _error.UnsupportedListComp)
|
||||
mem.depth = cf.args[0].obj
|
||||
|
||||
|
||||
|
||||
def visit_Name(self, node):
|
||||
if isinstance(node.ctx, ast.Store):
|
||||
self.setName(node)
|
||||
@ -843,7 +786,6 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
def getName(self, node):
|
||||
n = node.id
|
||||
node.obj = None
|
||||
|
||||
if n not in self.refStack:
|
||||
if n in self.tree.vardict:
|
||||
self.raiseError(node, _error.UnboundLocal, n)
|
||||
@ -901,19 +843,10 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
node.obj = __builtin__.__dict__[n]
|
||||
else:
|
||||
pass
|
||||
node.signed = _maybeNegative(node.obj)
|
||||
## node.target = node.obj
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def visit_Return(self, node):
|
||||
self.raiseError(node, _error.NotSupported, "return statement")
|
||||
|
||||
|
||||
|
||||
def visit_Print(self, node):
|
||||
self.tree.hasPrint = True
|
||||
f = []
|
||||
@ -969,8 +902,6 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
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)
|
||||
@ -978,7 +909,6 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.accessIndex(node)
|
||||
|
||||
def accessSlice(self, node):
|
||||
node.signed = False
|
||||
self.visit(node.value)
|
||||
node.obj = self.getObj(node.value)
|
||||
self.access = _access.INPUT
|
||||
@ -1014,15 +944,10 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
node.obj = bool()
|
||||
else:
|
||||
node.obj = bool() # XXX default
|
||||
node.signed = _maybeNegative(node.obj)
|
||||
|
||||
|
||||
def visit_Tuple(self, node):
|
||||
node.signed = False
|
||||
self.generic_visit(node)
|
||||
|
||||
|
||||
|
||||
def visit_While(self, node):
|
||||
node.breakLabel = _Label("BREAK")
|
||||
node.loopLabel = _Label("LOOP")
|
||||
@ -1046,7 +971,6 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.labelStack.pop()
|
||||
self.labelStack.pop()
|
||||
|
||||
|
||||
def visit_Yield(self, node, *args):
|
||||
self.tree.hasYield += 1
|
||||
n = node.value
|
||||
@ -1066,8 +990,6 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
node.senslist = senslist
|
||||
|
||||
|
||||
|
||||
|
||||
class _AnalyzeBlockVisitor(_AnalyzeVisitor):
|
||||
|
||||
def __init__(self, tree):
|
||||
|
@ -1,7 +1,7 @@
|
||||
# This file is part of the myhdl library, a Python package for using
|
||||
# Python as a Hardware Description Language.
|
||||
#
|
||||
# Copyright (C) 2003-2009 Jan Decaluwe
|
||||
# Copyright (C) 2003-2012 Jan Decaluwe
|
||||
#
|
||||
# The myhdl library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License as
|
||||
@ -86,8 +86,6 @@ def _makeDoc(doc, indent=''):
|
||||
return doc
|
||||
|
||||
|
||||
|
||||
|
||||
class _ToVHDLConvertor(object):
|
||||
|
||||
__slots__ = ("name",
|
||||
@ -220,7 +218,6 @@ def _writeFileHeader(f, fn):
|
||||
print >> f
|
||||
|
||||
|
||||
|
||||
def _writeCustomPackage(f, intf):
|
||||
print >> f
|
||||
print >> f, "package pck_%s is" % intf.name
|
||||
@ -343,10 +340,6 @@ def _writeCompDecls(f, compDecls):
|
||||
|
||||
def _writeModuleFooter(f, arch):
|
||||
print >> f, "end architecture %s;" % arch
|
||||
|
||||
|
||||
|
||||
|
||||
def _getRangeString(s):
|
||||
if isinstance(s._val, EnumItemType):
|
||||
return ''
|
||||
@ -358,7 +351,6 @@ def _getRangeString(s):
|
||||
else:
|
||||
raise AssertionError
|
||||
|
||||
|
||||
def _getTypeString(s):
|
||||
if isinstance(s._val, EnumItemType):
|
||||
return s._val._type._name
|
||||
@ -369,7 +361,6 @@ def _getTypeString(s):
|
||||
else:
|
||||
return 'unsigned'
|
||||
|
||||
|
||||
def _convertGens(genlist, siglist, memlist, vfile):
|
||||
blockBuf = StringIO()
|
||||
funcBuf = StringIO()
|
||||
@ -463,7 +454,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.labelStack = []
|
||||
self.context = None
|
||||
|
||||
|
||||
def write(self, arg):
|
||||
self.buf.write("%s" % arg)
|
||||
|
||||
@ -487,7 +477,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
def BitRepr(self, item, var):
|
||||
return '"%s"' % bin(item, len(var))
|
||||
|
||||
|
||||
def inferCast(self, vhd, ori):
|
||||
pre, suf = "", ""
|
||||
if isinstance(vhd, vhd_int):
|
||||
@ -529,7 +518,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
|
||||
return pre, suf
|
||||
|
||||
|
||||
def writeIntSize(self, n):
|
||||
# write size for large integers (beyond 32 bits signed)
|
||||
# with some safety margin
|
||||
@ -555,7 +543,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
if dir: dir += " "
|
||||
self.write("%s%s: %s%s%s" % (kind, name, dir, tipe, endchar))
|
||||
|
||||
|
||||
def writeDeclarations(self):
|
||||
if self.tree.hasPrint:
|
||||
self.writeline()
|
||||
@ -572,7 +559,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
def dedent(self):
|
||||
self.ind = self.ind[:-4]
|
||||
|
||||
|
||||
def visit_BinOp(self, node):
|
||||
if isinstance(node.op, (ast.LShift, ast.RShift)):
|
||||
self.shiftOp(node)
|
||||
@ -585,8 +571,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
else:
|
||||
self.BinOp(node)
|
||||
|
||||
|
||||
|
||||
def inferBinaryOpCast(self, node, left, right, op):
|
||||
ns, os = node.vhd.size, node.vhdOri.size
|
||||
ds = ns - os
|
||||
@ -628,7 +612,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
pre, suf = "(", ")"
|
||||
return pre, suf
|
||||
|
||||
|
||||
def BinOp(self, node):
|
||||
pre, suf = self.inferBinaryOpCast(node, node.left, node.right, node.op)
|
||||
self.write(pre)
|
||||
@ -637,7 +620,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
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
|
||||
@ -648,7 +630,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
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)
|
||||
@ -659,8 +640,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.write(")")
|
||||
self.write(suf)
|
||||
|
||||
|
||||
|
||||
def BitOp(self, node):
|
||||
pre, suf = self.inferCast(node.vhd, node.vhdOri)
|
||||
self.write(pre)
|
||||
@ -671,7 +650,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.write(")")
|
||||
self.write(suf)
|
||||
|
||||
|
||||
def visit_BoolOp(self, node):
|
||||
if isinstance(node.vhd, vhd_std_logic):
|
||||
self.write("stdl")
|
||||
@ -682,7 +660,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.visit(n)
|
||||
self.write(")")
|
||||
|
||||
|
||||
def visit_UnaryOp(self, node):
|
||||
pre, suf = self.inferCast(node.vhd, node.vhdOri)
|
||||
self.write(pre)
|
||||
@ -692,21 +669,18 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.write(")")
|
||||
self.write(suf)
|
||||
|
||||
|
||||
def visit_Attribute(self, node):
|
||||
if isinstance(node.ctx, ast.Store):
|
||||
self.setAttr(node)
|
||||
else:
|
||||
self.getAttr(node)
|
||||
|
||||
|
||||
def setAttr(self, node):
|
||||
assert node.attr == 'next'
|
||||
self.isSigAss = True
|
||||
self.visit(node.value)
|
||||
node.obj = self.getObj(node.value)
|
||||
|
||||
|
||||
def getAttr(self, node):
|
||||
assert isinstance(node.value, ast.Name), node.value
|
||||
n = node.value.id
|
||||
@ -741,7 +715,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
e = getattr(obj, node.attr)
|
||||
self.write(e._toVHDL())
|
||||
|
||||
|
||||
def visit_Assert(self, node):
|
||||
# XXX
|
||||
self.write("assert ")
|
||||
@ -753,7 +726,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.write("severity error;")
|
||||
self.dedent()
|
||||
|
||||
|
||||
def visit_Assign(self, node):
|
||||
lhs = node.targets[0]
|
||||
rhs = node.value
|
||||
@ -808,9 +780,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.write(convClose)
|
||||
self.write(';')
|
||||
|
||||
|
||||
def visit_AugAssign(self, node):
|
||||
op = opmap[type(node.op)]
|
||||
# XXX apparently no signed context required for augmented assigns
|
||||
left, op, right = node.target, node.op, node.value
|
||||
isFunc = False
|
||||
@ -836,12 +806,9 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.write(suf)
|
||||
self.write(";")
|
||||
|
||||
|
||||
|
||||
def visit_Break(self, node):
|
||||
self.write("exit;")
|
||||
|
||||
|
||||
def visit_Call(self, node):
|
||||
fn = node.func
|
||||
# assert isinstance(fn, astNode.Name)
|
||||
@ -930,8 +897,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
v = Visitor(node.tree, self.funcBuf)
|
||||
v.visit(node.tree)
|
||||
|
||||
|
||||
|
||||
def visit_Compare(self, node):
|
||||
n = node.vhd
|
||||
ns = node.vhd.size
|
||||
@ -949,7 +914,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.visit(right)
|
||||
self.write(suf)
|
||||
|
||||
|
||||
def visit_Num(self, node):
|
||||
n = node.n
|
||||
if isinstance(node.vhd, vhd_std_logic):
|
||||
@ -968,11 +932,9 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
def visit_Str(self, node):
|
||||
self.write("string'(\"%s\")" % node.s)
|
||||
|
||||
|
||||
def visit_Continue(self, node, *args):
|
||||
self.write("next;")
|
||||
|
||||
|
||||
def visit_Expr(self, node):
|
||||
expr = node.value
|
||||
# docstrings on unofficial places
|
||||
@ -988,7 +950,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
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)
|
||||
@ -1063,11 +1024,9 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.labelStack.pop()
|
||||
self.labelStack.pop()
|
||||
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
raise AssertionError("To be implemented in subclass")
|
||||
|
||||
|
||||
def visit_If(self, node):
|
||||
if node.ignore:
|
||||
return
|
||||
@ -1077,7 +1036,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
else:
|
||||
self.mapToIf(node)
|
||||
|
||||
|
||||
def mapToCase(self, node):
|
||||
var = node.caseVar
|
||||
obj = self.getObj(var)
|
||||
@ -1114,7 +1072,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.writeline()
|
||||
self.write("end case;")
|
||||
|
||||
|
||||
def mapToIf(self, node):
|
||||
first = True
|
||||
for test, suite in node.tests:
|
||||
@ -1146,16 +1103,13 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
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)
|
||||
|
||||
|
||||
def visit_Name(self, node):
|
||||
if isinstance(node.ctx, ast.Store):
|
||||
self.setName(node)
|
||||
@ -1226,12 +1180,9 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
raise AssertionError("name ref: %s" % n)
|
||||
self.write(s)
|
||||
|
||||
|
||||
|
||||
def visit_Pass(self, node):
|
||||
self.write("null;")
|
||||
|
||||
|
||||
def visit_Print(self, node):
|
||||
argnr = 0
|
||||
for s in node.format:
|
||||
@ -1262,13 +1213,9 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.writeline()
|
||||
self.write("writeline(output, L);")
|
||||
|
||||
|
||||
def visit_Raise(self, node):
|
||||
self.write('assert False report "End of Simulation" severity Failure;')
|
||||
|
||||
# def visitReturn(self, node, *args):
|
||||
# self.write("disable %s;" % self.returnLabel)
|
||||
|
||||
def visit_Return(self, node):
|
||||
pass
|
||||
|
||||
@ -1278,7 +1225,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
else:
|
||||
self.accessIndex(node)
|
||||
|
||||
|
||||
def accessSlice(self, node):
|
||||
if isinstance(node.value, ast.Call) and \
|
||||
node.value.func.obj is intbv and \
|
||||
@ -1335,7 +1281,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.write(")")
|
||||
self.write(suf)
|
||||
|
||||
|
||||
def visit_stmt(self, body):
|
||||
for stmt in body:
|
||||
self.writeline()
|
||||
@ -1344,7 +1289,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
if isinstance(stmt, ast.Call) and hasattr(stmt, 'tree'):
|
||||
self.write(';')
|
||||
|
||||
|
||||
def visit_Tuple(self, node):
|
||||
assert self.context != None
|
||||
sep = ", "
|
||||
@ -1354,7 +1298,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.write(sep)
|
||||
self.visit(elt)
|
||||
|
||||
|
||||
def visit_While(self, node):
|
||||
self.labelStack.append(node.breakLabel)
|
||||
self.labelStack.append(node.loopLabel)
|
||||
@ -1370,7 +1313,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.labelStack.pop()
|
||||
self.labelStack.pop()
|
||||
|
||||
|
||||
def visit_Yield(self, node):
|
||||
self.write("wait ")
|
||||
yieldObj = self.getObj(node.value)
|
||||
@ -1385,8 +1327,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.context = _context.UNKNOWN
|
||||
self.write(";")
|
||||
|
||||
|
||||
|
||||
def manageEdges(self, ifnode, senslist):
|
||||
""" Helper method to convert MyHDL style template into VHDL style"""
|
||||
first = senslist[0]
|
||||
@ -1424,14 +1364,12 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
return senslist
|
||||
|
||||
|
||||
|
||||
class _ConvertAlwaysVisitor(_ConvertVisitor):
|
||||
|
||||
def __init__(self, tree, blockBuf, funcBuf):
|
||||
_ConvertVisitor.__init__(self, tree, blockBuf)
|
||||
self.funcBuf = funcBuf
|
||||
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
self.writeDoc(node)
|
||||
w = node.body[-1]
|
||||
@ -1475,15 +1413,12 @@ class _ConvertAlwaysVisitor(_ConvertVisitor):
|
||||
self.writeline(2)
|
||||
|
||||
|
||||
|
||||
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("%s: process is" % self.tree.name)
|
||||
@ -1502,8 +1437,6 @@ class _ConvertInitialVisitor(_ConvertVisitor):
|
||||
self.writeline(2)
|
||||
|
||||
|
||||
|
||||
|
||||
class _ConvertAlwaysCombVisitor(_ConvertVisitor):
|
||||
|
||||
def __init__(self, tree, blockBuf, funcBuf):
|
||||
@ -1532,7 +1465,6 @@ class _ConvertAlwaysCombVisitor(_ConvertVisitor):
|
||||
self.writeline(2)
|
||||
|
||||
|
||||
|
||||
class _ConvertSimpleAlwaysCombVisitor(_ConvertVisitor):
|
||||
|
||||
def __init__(self, tree, blockBuf, funcBuf):
|
||||
@ -1668,8 +1600,6 @@ class _ConvertAlwaysSeqVisitor(_ConvertVisitor):
|
||||
self.writeline(2)
|
||||
|
||||
|
||||
|
||||
|
||||
class _ConvertFunctionVisitor(_ConvertVisitor):
|
||||
|
||||
def __init__(self, tree, funcBuf):
|
||||
@ -1689,7 +1619,6 @@ class _ConvertFunctionVisitor(_ConvertVisitor):
|
||||
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()
|
||||
@ -1709,16 +1638,12 @@ class _ConvertFunctionVisitor(_ConvertVisitor):
|
||||
self.write("end function %s;" % self.tree.name)
|
||||
self.writeline(2)
|
||||
|
||||
|
||||
|
||||
def visit_Return(self, node):
|
||||
self.write("return ")
|
||||
self.visit(node.value)
|
||||
self.write(";")
|
||||
|
||||
|
||||
|
||||
|
||||
class _ConvertTaskVisitor(_ConvertVisitor):
|
||||
|
||||
def __init__(self, tree, funcBuf):
|
||||
@ -1738,8 +1663,6 @@ class _ConvertTaskVisitor(_ConvertVisitor):
|
||||
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:
|
||||
@ -1764,6 +1687,7 @@ class _ConvertTaskVisitor(_ConvertVisitor):
|
||||
|
||||
# type inference
|
||||
|
||||
|
||||
class vhd_type(object):
|
||||
def __init__(self, size=0):
|
||||
self.size = size
|
||||
@ -1871,7 +1795,6 @@ def maybeNegative(vhd):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
|
||||
def __init__(self, tree):
|
||||
@ -1882,19 +1805,15 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
for stmt in node.body:
|
||||
self.visit(stmt)
|
||||
|
||||
|
||||
|
||||
def visit_Attribute(self, node):
|
||||
self.generic_visit(node)
|
||||
node.vhd = copy(node.value.vhd)
|
||||
node.vhdOri = copy(node.vhd)
|
||||
|
||||
|
||||
def visit_Assert(self, node):
|
||||
self.visit(node.test)
|
||||
node.test.vhd = vhd_boolean()
|
||||
|
||||
|
||||
def visit_AugAssign(self, node):
|
||||
self.visit(node.target)
|
||||
self.visit(node.value)
|
||||
@ -1909,7 +1828,6 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.inferBinOpType(node)
|
||||
node.vhd = copy(node.target.vhd)
|
||||
|
||||
|
||||
def visit_Call(self, node):
|
||||
fn = node.func
|
||||
# assert isinstance(fn, astNode.Name)
|
||||
@ -1941,8 +1859,6 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
node.vhd = node.tree.vhd = inferVhdlObj(node.tree.returnObj)
|
||||
node.vhdOri = copy(node.vhd)
|
||||
|
||||
|
||||
|
||||
def visit_Compare(self, node):
|
||||
node.vhd = vhd_boolean()
|
||||
self.generic_visit(node)
|
||||
@ -1955,7 +1871,6 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
right.vhd = vhd_signed(right.vhd.size + 1)
|
||||
node.vhdOri = copy(node.vhd)
|
||||
|
||||
|
||||
def visit_Str(self, node):
|
||||
node.vhd = vhd_string()
|
||||
node.vhdOri = copy(node.vhd)
|
||||
@ -1967,21 +1882,18 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
node.vhd = vhd_nat()
|
||||
node.vhdOri = copy(node.vhd)
|
||||
|
||||
|
||||
def visit_For(self, node):
|
||||
var = node.target.id
|
||||
# make it possible to detect loop variable
|
||||
self.tree.vardict[var] = _loopInt(-1)
|
||||
self.generic_visit(node)
|
||||
|
||||
|
||||
def visit_Name(self, node):
|
||||
if isinstance(node.ctx, ast.Store):
|
||||
node.obj = self.tree.vardict[node.id]
|
||||
node.vhd = inferVhdlObj(node.obj)
|
||||
node.vhdOri = copy(node.vhd)
|
||||
|
||||
|
||||
def visit_BinOp(self, node):
|
||||
self.generic_visit(node)
|
||||
if isinstance(node.op, (ast.LShift, ast.RShift)):
|
||||
@ -1998,7 +1910,6 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
node.right.vhd = vhd_nat()
|
||||
node.vhdOri = copy(node.vhd)
|
||||
|
||||
|
||||
def inferBitOpType(self, node):
|
||||
obj = maxType(node.left.vhd, node.right.vhd)
|
||||
node.vhd = node.left.vhd = node.right.vhd = obj
|
||||
@ -2051,7 +1962,6 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
node.vhd = vhd_int()
|
||||
node.vhdOri = copy(node.vhd)
|
||||
|
||||
|
||||
def visit_BoolOp(self, node):
|
||||
self.generic_visit(node)
|
||||
for n in node.values:
|
||||
@ -2059,7 +1969,6 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
node.vhd = vhd_boolean()
|
||||
node.vhdOri = copy(node.vhd)
|
||||
|
||||
|
||||
def visit_If(self, node):
|
||||
if node.ignore:
|
||||
return
|
||||
@ -2071,18 +1980,15 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.generic_visit(node)
|
||||
node.test.vhd = vhd_boolean()
|
||||
|
||||
|
||||
def visit_ListComp(self, node):
|
||||
pass # do nothing
|
||||
|
||||
|
||||
def visit_Subscript(self, node):
|
||||
if isinstance(node.slice, ast.Slice):
|
||||
self.accessSlice(node)
|
||||
else:
|
||||
self.accessIndex(node)
|
||||
|
||||
|
||||
def accessSlice(self, node):
|
||||
self.generic_visit(node)
|
||||
lower = node.value.vhd.size
|
||||
@ -2101,7 +2007,6 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
node.vhd = vhd_unsigned(lower-upper)
|
||||
node.vhdOri = copy(node.vhd)
|
||||
|
||||
|
||||
def accessIndex(self, node):
|
||||
self.generic_visit(node)
|
||||
node.vhd = vhd_std_logic() # XXX default
|
||||
@ -2118,8 +2023,6 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
node.vhd = vhd_std_logic()
|
||||
node.vhdOri = copy(node.vhd)
|
||||
|
||||
|
||||
|
||||
def visit_UnaryOp(self, node):
|
||||
self.visit(node.operand)
|
||||
node.vhd = copy(node.operand.vhd)
|
||||
@ -2137,14 +2040,11 @@ class _AnnotateTypesVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
node.vhd = vhd_int()
|
||||
node.vhdOri = copy(node.vhd)
|
||||
|
||||
|
||||
def visit_While(self, node):
|
||||
self.generic_visit(node)
|
||||
node.test.vhd = vhd_boolean()
|
||||
|
||||
|
||||
|
||||
|
||||
def _annotateTypes(genlist):
|
||||
for tree in genlist:
|
||||
if isinstance(tree, _UserVhdlCode):
|
||||
|
@ -1,7 +1,7 @@
|
||||
# This file is part of the myhdl library, a Python package for using
|
||||
# Python as a Hardware Description Language.
|
||||
#
|
||||
# Copyright (C) 2003-2008 Jan Decaluwe
|
||||
# Copyright (C) 2003-2012 Jan Decaluwe
|
||||
#
|
||||
# The myhdl library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License as
|
||||
@ -23,19 +23,14 @@
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
import math
|
||||
import traceback
|
||||
import inspect
|
||||
from datetime import datetime
|
||||
import compiler
|
||||
# from compiler import ast as astNode
|
||||
import ast
|
||||
import string
|
||||
|
||||
from types import GeneratorType, FunctionType, ClassType, TypeType, StringType
|
||||
from types import GeneratorType, ClassType, TypeType
|
||||
from cStringIO import StringIO
|
||||
import __builtin__
|
||||
import warnings
|
||||
|
||||
import myhdl
|
||||
@ -45,12 +40,11 @@ from myhdl._extractHierarchy import (_HierExtr, _isMem, _getMemInfo,
|
||||
_UserVerilogCode, _userCodeMap)
|
||||
|
||||
from myhdl._instance import _Instantiator
|
||||
from myhdl.conversion._misc import (_error, _access, _kind, _context,
|
||||
from myhdl.conversion._misc import (_error, _kind, _context,
|
||||
_ConversionMixin, _Label, _genUniqueSuffix, _isConstant)
|
||||
from myhdl.conversion._analyze import (_analyzeSigs, _analyzeGens, _analyzeTopFunc,
|
||||
_Ram, _Rom)
|
||||
from myhdl._Signal import _Signal
|
||||
from myhdl._ShadowSignal import _SliceSignal
|
||||
|
||||
_converting = 0
|
||||
_profileFunc = None
|
||||
@ -139,6 +133,7 @@ class _ToVerilogConvertor(object):
|
||||
# print h.top
|
||||
_checkArgs(arglist)
|
||||
genlist = _analyzeGens(arglist, h.absnames)
|
||||
_annotateTypes(genlist)
|
||||
intf = _analyzeTopFunc(func, *args, **kwargs)
|
||||
intf.name = name
|
||||
doc = _makeDoc(inspect.getdoc(func))
|
||||
@ -496,7 +491,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
else:
|
||||
self.write(";")
|
||||
|
||||
|
||||
def writeDeclarations(self):
|
||||
for name, obj in self.tree.vardict.items():
|
||||
self.writeline()
|
||||
@ -521,8 +515,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.write(senslist[-1]._toVerilog())
|
||||
self.write(")")
|
||||
|
||||
|
||||
|
||||
def visit_BinOp(self, node):
|
||||
if isinstance(node.op, ast.Mod) and self.context == _context.PRINT:
|
||||
self.visit(node.left)
|
||||
@ -546,9 +538,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.write(")")
|
||||
self.context = None
|
||||
|
||||
|
||||
|
||||
|
||||
def checkOpWithNegIntbv(self, node, op):
|
||||
if op in ("+", "-", "*", "~", "&&", "||", "!"):
|
||||
return
|
||||
@ -558,9 +547,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.raiseError(node, _error.NotSupported,
|
||||
"negative intbv with operator %s" % op)
|
||||
|
||||
|
||||
|
||||
|
||||
def visit_BoolOp(self, node):
|
||||
self.write("(")
|
||||
self.visit(node.values[0])
|
||||
@ -569,14 +555,11 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.visit(n)
|
||||
self.write(")")
|
||||
|
||||
|
||||
def visit_UnaryOp(self, node):
|
||||
self.write("(%s" % opmap[type(node.op)])
|
||||
self.visit(node.operand)
|
||||
self.write(")")
|
||||
|
||||
|
||||
|
||||
def visit_Attribute(self, node):
|
||||
if isinstance(node.ctx, ast.Store):
|
||||
self.setAttr(node)
|
||||
@ -615,8 +598,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
e = getattr(obj, node.attr)
|
||||
self.write(e._toVerilog())
|
||||
|
||||
|
||||
|
||||
def visit_Assert(self, node):
|
||||
self.write("if (")
|
||||
self.visit(node.test)
|
||||
@ -630,8 +611,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.writeline()
|
||||
self.write("end")
|
||||
|
||||
|
||||
|
||||
def visit_Assign(self, node):
|
||||
# shortcut for expansion of ROM in case statement
|
||||
if isinstance(node.value, ast.Subscript) and \
|
||||
@ -675,8 +654,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.visit(node.value)
|
||||
self.write(';')
|
||||
|
||||
|
||||
|
||||
def visit_AugAssign(self, node, *args):
|
||||
# XXX apparently no signed context required for augmented assigns
|
||||
self.visit(node.target)
|
||||
@ -686,12 +663,9 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.visit(node.value)
|
||||
self.write(";")
|
||||
|
||||
|
||||
|
||||
def visit_Break(self, node,):
|
||||
self.write("disable %s;" % self.labelStack[-2])
|
||||
|
||||
|
||||
def visit_Call(self, node):
|
||||
self.context = None
|
||||
fn = node.func
|
||||
@ -764,7 +738,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
v = Visitor(node.tree, self.funcBuf)
|
||||
v.visit(node.tree)
|
||||
|
||||
|
||||
def visit_Compare(self, node):
|
||||
self.context = None
|
||||
if node.signed:
|
||||
@ -776,8 +749,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.write(")")
|
||||
self.context = None
|
||||
|
||||
|
||||
|
||||
def visit_Num(self, node):
|
||||
if self.context == _context.PRINT:
|
||||
self.write('"%s"' % node.n)
|
||||
@ -793,12 +764,9 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
else:
|
||||
self.write(s)
|
||||
|
||||
|
||||
|
||||
def visit_Continue(self, node):
|
||||
self.write("disable %s;" % self.labelStack[-1])
|
||||
|
||||
|
||||
def visit_Expr(self, node):
|
||||
expr = node.value
|
||||
# docstrings on unofficial places
|
||||
@ -814,7 +782,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
if isinstance(expr, ast.Call) and hasattr(expr, 'tree'):
|
||||
self.write(';')
|
||||
|
||||
|
||||
def visit_IfExp(self, node):
|
||||
self.visit(node.test)
|
||||
self.write(' ? ')
|
||||
@ -822,7 +789,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.write(' : ')
|
||||
self.visit(node.orelse)
|
||||
|
||||
|
||||
def visit_For(self, node):
|
||||
self.labelStack.append(node.breakLabel)
|
||||
self.labelStack.append(node.loopLabel)
|
||||
@ -885,11 +851,9 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.labelStack.pop()
|
||||
self.labelStack.pop()
|
||||
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
raise AssertionError("To be implemented in subclass")
|
||||
|
||||
|
||||
def visit_If(self, node):
|
||||
if node.ignore:
|
||||
return
|
||||
@ -963,7 +927,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.writeline()
|
||||
self.write("end")
|
||||
|
||||
|
||||
def visitKeyword(self, node, *args):
|
||||
self.visit(node.expr)
|
||||
|
||||
@ -1027,11 +990,9 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
if addSignBit:
|
||||
self.write("})")
|
||||
|
||||
|
||||
def visit_Pass(self, node):
|
||||
self.write("// pass")
|
||||
|
||||
|
||||
def visit_Print(self, node):
|
||||
argnr = 0
|
||||
for s in node.format:
|
||||
@ -1079,16 +1040,12 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.writeline()
|
||||
self.write('$write("\\n");')
|
||||
|
||||
|
||||
|
||||
def visit_Raise(self, node):
|
||||
self.write("$finish;")
|
||||
|
||||
|
||||
def visit_Return(self, node):
|
||||
self.write("disable %s;" % self.returnLabel)
|
||||
|
||||
|
||||
def visit_Subscript(self, node):
|
||||
if isinstance(node.slice, ast.Slice):
|
||||
self.accessSlice(node)
|
||||
@ -1126,7 +1083,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
if addSignBit:
|
||||
self.write("})")
|
||||
|
||||
|
||||
def accessIndex(self, node):
|
||||
addSignBit = isinstance(node.ctx, ast.Load) and \
|
||||
(not node.signed) and \
|
||||
@ -1142,7 +1098,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
if addSignBit:
|
||||
self.write("})")
|
||||
|
||||
|
||||
def visit_stmt(self, body):
|
||||
for stmt in body:
|
||||
self.writeline()
|
||||
@ -1151,7 +1106,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
if isinstance(stmt, ast.Call) and hasattr(stmt, 'tree'):
|
||||
self.write(';')
|
||||
|
||||
|
||||
def visit_Tuple(self, node):
|
||||
assert self.context != None
|
||||
sep = ", "
|
||||
@ -1161,8 +1115,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.write(sep)
|
||||
self.visit(elt)
|
||||
|
||||
|
||||
|
||||
def visit_While(self, node):
|
||||
self.labelStack.append(node.breakLabel)
|
||||
self.labelStack.append(node.loopLabel)
|
||||
@ -1185,8 +1137,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.labelStack.pop()
|
||||
self.labelStack.pop()
|
||||
|
||||
|
||||
|
||||
def visit_Yield(self, node):
|
||||
yieldObj = self.getObj(node.value)
|
||||
assert node.senslist
|
||||
@ -1202,10 +1152,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.write(";")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class _ConvertAlwaysVisitor(_ConvertVisitor):
|
||||
|
||||
def __init__(self, tree, blockBuf, funcBuf):
|
||||
@ -1250,7 +1196,6 @@ class _ConvertInitialVisitor(_ConvertVisitor):
|
||||
|
||||
|
||||
|
||||
|
||||
class _ConvertAlwaysCombVisitor(_ConvertVisitor):
|
||||
|
||||
def __init__(self, tree, blockBuf, funcBuf):
|
||||
@ -1259,7 +1204,6 @@ class _ConvertAlwaysCombVisitor(_ConvertVisitor):
|
||||
self.okSigAss = False
|
||||
self.funcBuf = funcBuf
|
||||
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
self.writeDoc(node)
|
||||
self.writeAlwaysHeader()
|
||||
@ -1272,14 +1216,11 @@ class _ConvertAlwaysCombVisitor(_ConvertVisitor):
|
||||
|
||||
|
||||
|
||||
|
||||
class _ConvertSimpleAlwaysCombVisitor(_ConvertVisitor):
|
||||
|
||||
def __init__(self, tree, blockBuf, funcBuf):
|
||||
_ConvertVisitor.__init__(self, tree, blockBuf)
|
||||
self.funcBuf = funcBuf
|
||||
|
||||
|
||||
def visit_Attribute(self, node):
|
||||
if isinstance(node.ctx, ast.Store):
|
||||
self.write("assign ")
|
||||
@ -1287,7 +1228,6 @@ class _ConvertSimpleAlwaysCombVisitor(_ConvertVisitor):
|
||||
else:
|
||||
self.getAttr(node)
|
||||
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
self.writeDoc(node)
|
||||
self.visit_stmt(node.body)
|
||||
@ -1300,7 +1240,6 @@ class _ConvertAlwaysDecoVisitor(_ConvertVisitor):
|
||||
_ConvertVisitor.__init__(self, tree, blockBuf)
|
||||
self.funcBuf = funcBuf
|
||||
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
self.writeDoc(node)
|
||||
self.writeAlwaysHeader()
|
||||
@ -1360,8 +1299,6 @@ class _ConvertAlwaysSeqVisitor(_ConvertVisitor):
|
||||
self.writeline(2)
|
||||
|
||||
|
||||
|
||||
|
||||
class _ConvertFunctionVisitor(_ConvertVisitor):
|
||||
|
||||
def __init__(self, tree, funcBuf):
|
||||
@ -1379,7 +1316,6 @@ class _ConvertFunctionVisitor(_ConvertVisitor):
|
||||
self.writeline()
|
||||
self.writeDeclaration(obj, name, "input")
|
||||
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
self.write("function ")
|
||||
self.writeOutputDeclaration()
|
||||
@ -1398,7 +1334,6 @@ class _ConvertFunctionVisitor(_ConvertVisitor):
|
||||
self.write("endfunction")
|
||||
self.writeline(2)
|
||||
|
||||
|
||||
def visit_Return(self, node):
|
||||
self.write("%s = " % self.tree.name)
|
||||
self.visit(node.value)
|
||||
@ -1425,7 +1360,6 @@ class _ConvertTaskVisitor(_ConvertVisitor):
|
||||
self.writeline()
|
||||
self.writeDeclaration(obj, name, dir)
|
||||
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
self.write("task %s;" % self.tree.name)
|
||||
self.indent()
|
||||
@ -1442,3 +1376,125 @@ class _ConvertTaskVisitor(_ConvertVisitor):
|
||||
self.writeline()
|
||||
self.write("endtask")
|
||||
self.writeline(2)
|
||||
|
||||
|
||||
def _maybeNegative(obj):
|
||||
if hasattr(obj, '_min') and (obj._min is not None) and (obj._min < 0):
|
||||
return True
|
||||
if isinstance(obj, (int, long)) and obj < 0:
|
||||
return True
|
||||
return False
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
node.signed = False
|
||||
|
||||
def visit_UnaryOp(self, node):
|
||||
self.visit(node.operand)
|
||||
node.signed = node.operand.signed
|
||||
if isinstance(node.op, ast.USub):
|
||||
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)
|
||||
node.signed = False
|
||||
### suprize: identity comparison on unbound methods doesn't work in python 2.5??
|
||||
if f == intbv.signed:
|
||||
node.signed = True
|
||||
elif hasattr(node, 'tree'):
|
||||
v = _AnnotateTypesVisitor(node.tree)
|
||||
v.visit(node.tree)
|
||||
node.signed = _maybeNegative(node.tree.returnObj)
|
||||
|
||||
def visit_Compare(self, node):
|
||||
node.signed = False
|
||||
#for n in ast.iter_child_nodes(node):
|
||||
for n in [node.left] + node.comparators:
|
||||
self.visit(n)
|
||||
if n.signed:
|
||||
node.signed = True
|
||||
|
||||
def visit_If(self, node):
|
||||
if node.ignore:
|
||||
return
|
||||
self.generic_visit(node)
|
||||
|
||||
|
||||
def visit_Num(self, node):
|
||||
node.signed = False
|
||||
|
||||
def visit_Str(self, node):
|
||||
node.signed = False
|
||||
|
||||
def visit_Name(self, node):
|
||||
if isinstance(node.ctx, ast.Store):
|
||||
self.setName(node)
|
||||
else:
|
||||
self.getName(node)
|
||||
|
||||
def setName(self, node):
|
||||
pass
|
||||
|
||||
def getName(self, node):
|
||||
node.signed = _maybeNegative(node.obj)
|
||||
|
||||
def visit_Subscript(self, node):
|
||||
if isinstance(node.slice, ast.Slice):
|
||||
self.accessSlice(node)
|
||||
else:
|
||||
self.accessIndex(node)
|
||||
|
||||
def accessSlice(self, node):
|
||||
node.signed = False
|
||||
self.generic_visit(node)
|
||||
|
||||
def accessIndex(self, node):
|
||||
node.signed = _maybeNegative(node.obj)
|
||||
self.generic_visit(node)
|
||||
|
||||
def visit_Tuple(self, node):
|
||||
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