mirror of
https://github.com/myhdl/myhdl.git
synced 2025-01-24 21:52:56 +08:00
UNSTABLE - replace compiler by ast for conversion
Tests in conversion/general for Verilog work.
This commit is contained in:
parent
c962b8542e
commit
e6ba8d4ec1
@ -139,7 +139,6 @@ def _analyzeGens(top, absnames):
|
||||
s = inspect.getsource(f)
|
||||
s = _dedent(s)
|
||||
tree = ast.parse(s)
|
||||
#print ast.dump(tree)
|
||||
tree.sourcefile = inspect.getsourcefile(f)
|
||||
tree.lineoffset = inspect.getsourcelines(f)[1]-1
|
||||
tree.symdict = f.func_globals.copy()
|
||||
@ -166,7 +165,6 @@ def _analyzeGens(top, absnames):
|
||||
s = inspect.getsource(f)
|
||||
s = _dedent(s)
|
||||
tree = ast.parse(s)
|
||||
# print ast.dump(tree)
|
||||
tree.sourcefile = inspect.getsourcefile(f)
|
||||
tree.lineoffset = inspect.getsourcelines(f)[1]-1
|
||||
tree.symdict = f.f_globals.copy()
|
||||
@ -279,7 +277,8 @@ class _FirstPassVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.raiseError(node, _error.NotSupported, "embedded function definition")
|
||||
self.toplevel = False
|
||||
node.argnames = [arg.id for arg in node.args.args]
|
||||
self.generic_visit(node)
|
||||
# don't visit decorator lists - they can support more than other calls
|
||||
self.visitList(node.body)
|
||||
|
||||
def flattenIf(self, node, tests):
|
||||
""" Flatten if-then-else as in compiler package."""
|
||||
@ -485,7 +484,7 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
node.signed = node.operand.signed
|
||||
if isinstance(op, ast.Not):
|
||||
node.obj = bool()
|
||||
elif isintance(op, ast.UAdd):
|
||||
elif isinstance(op, ast.UAdd):
|
||||
node.obj = int(-1)
|
||||
elif isinstance(op, ast.USub):
|
||||
node.obj = int(-1)
|
||||
@ -545,16 +544,16 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
if node.attr != 'next':
|
||||
self.raiseError(node, _error.NotSupported, "attribute assignment")
|
||||
self.tree.kind = _kind.TASK
|
||||
self.access = _access.OUTPUT
|
||||
# self.access = _access.OUTPUT
|
||||
self.visit(node.value)
|
||||
self.access = _access.INPUT
|
||||
# self.access = _access.INPUT
|
||||
|
||||
def getAttr(self, node):
|
||||
self.visit(node.value)
|
||||
node.obj = None
|
||||
node.signed = False
|
||||
if isinstance(node.value, astNode.Name):
|
||||
n = node.value.name
|
||||
if isinstance(node.value, ast.Name):
|
||||
n = node.value.id
|
||||
if (n not in self.tree.vardict) and (n not in self.tree.symdict):
|
||||
raise AssertionError("attribute target: %s" % n)
|
||||
obj = node.value.obj
|
||||
@ -869,11 +868,12 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
def visit_Compare(self, node):
|
||||
node.obj = bool()
|
||||
node.signed = False
|
||||
for n in ast.iter_field_nodes(node):
|
||||
#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 = ops[0], compartors[0]
|
||||
op, arg = node.ops[0], node.comparators[0]
|
||||
## node.expr.target = self.getObj(arg)
|
||||
## arg.target = self.getObj(node.expr)
|
||||
# detect specialized case for the test
|
||||
@ -1029,11 +1029,11 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
for test, suite in node.tests:
|
||||
self.visit(test)
|
||||
self.refStack.push()
|
||||
self.visit(suite)
|
||||
self.visitList(suite)
|
||||
self.refStack.pop()
|
||||
if node.else_:
|
||||
self.refStack.push()
|
||||
self.visit(node.else_)
|
||||
self.visitList(node.else_)
|
||||
self.refStack.pop()
|
||||
# check whether the if can be mapped to a (parallel) case
|
||||
node.isCase = node.isFullCase = False
|
||||
@ -1164,14 +1164,28 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.getName(node)
|
||||
|
||||
def setName(self, node):
|
||||
# XXX INOUT access in Store context, unlike with compiler
|
||||
# XXX check whether ast context is correct
|
||||
n = node.id
|
||||
if n in ("__verilog__", "__vhdl__"):
|
||||
self.raiseError(node, _error.NotSupported,
|
||||
"%s in generator function" % n)
|
||||
# XXX ?
|
||||
if n in self.globalRefs:
|
||||
self.raiseError(node, _error.UnboundLocal, n)
|
||||
self.refStack.add(n)
|
||||
if self.access == _access.INOUT: # augmented assign
|
||||
if n in self.tree.sigdict:
|
||||
sig = self.tree.sigdict[n]
|
||||
if isinstance(sig, Signal):
|
||||
self.raiseError(node, _error.NotSupported, "Augmented signal assignment")
|
||||
if n in self.tree.vardict:
|
||||
obj = self.tree.vardict[n]
|
||||
# upgrade bool to int for augmented assignments
|
||||
if isinstance(obj, bool):
|
||||
obj = int(0)
|
||||
self.tree.vardict[n] = obj
|
||||
node.obj = obj
|
||||
else:
|
||||
if n in ("__verilog__", "__vhdl__"):
|
||||
self.raiseError(node, _error.NotSupported,
|
||||
"%s in generator function" % n)
|
||||
if n in self.globalRefs:
|
||||
self.raiseError(node, _error.UnboundLocal, n)
|
||||
self.refStack.add(n)
|
||||
|
||||
def getName(self, node):
|
||||
n = node.id
|
||||
@ -1201,7 +1215,7 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.raiseError(node, _error.NotSupported, "Augmented signal assignment")
|
||||
if n in self.tree.vardict:
|
||||
obj = self.tree.vardict[n]
|
||||
if self.access == _access.INOUT:
|
||||
if self.access == _access.INOUT: # probably dead code
|
||||
# upgrade bool to int for augmented assignments
|
||||
if isinstance(obj, bool):
|
||||
obj = int(0)
|
||||
@ -1302,7 +1316,7 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
a.extend(n.right.elts)
|
||||
else:
|
||||
a.append(n.right)
|
||||
s = n.left.value
|
||||
s = n.left.s
|
||||
while s:
|
||||
if not s:
|
||||
break
|
||||
@ -1417,7 +1431,7 @@ class _AnalyzeVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.access = _access.INPUT
|
||||
self.visit(node.slice.value)
|
||||
if isinstance(node.value.obj, _Ram):
|
||||
if node.flags == 'OP_ASSIGN':
|
||||
if isinstance(node.ctx, ast.Store):
|
||||
self.raiseError(node, _error.ListElementAssign)
|
||||
else:
|
||||
node.obj = node.value.obj.elObj
|
||||
|
@ -333,6 +333,12 @@ opmap = {
|
||||
ast.Not : '!',
|
||||
ast.UAdd : '+',
|
||||
ast.USub : '-',
|
||||
ast.Eq : '==',
|
||||
ast.Gt : '>',
|
||||
ast.GtE : '>=',
|
||||
ast.Lt : '<',
|
||||
ast.LtE : '<=',
|
||||
ast.NotEq : '!=',
|
||||
}
|
||||
|
||||
|
||||
@ -528,7 +534,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.write("(")
|
||||
self.visit(node.values[0])
|
||||
for n in node.nodes[1:]:
|
||||
self.write(" %s " % opmap[node.op])
|
||||
self.write(" %s " % opmap[type(node.op)])
|
||||
self.visit(n)
|
||||
self.write(")")
|
||||
|
||||
@ -551,7 +557,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
|
||||
|
||||
def visit_UnaryOp(self, node):
|
||||
self.write("(%s" % opmap[node.op])
|
||||
self.write("(%s" % opmap[type(node.op)])
|
||||
self.visit(node.operand)
|
||||
self.write(")")
|
||||
|
||||
@ -562,12 +568,71 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
# self.isSigAss = True
|
||||
# self.visit(node.expr)
|
||||
|
||||
# def visitGetattr(self, node, *args):
|
||||
# assert isinstance(node.expr, astNode.Name)
|
||||
# n = node.expr.name
|
||||
# if n in self.tree.symdict:
|
||||
# obj = self.tree.symdict[n]
|
||||
# elif n in self.tree.vardict:
|
||||
# obj = self.tree.vardict[n]
|
||||
# else:
|
||||
# raise AssertionError("object not found")
|
||||
# if isinstance(obj, Signal):
|
||||
# if node.attrname == 'next':
|
||||
# self.isSigAss = True
|
||||
# self.visit(node.expr)
|
||||
# elif node.attrname in ('posedge', 'negedge'):
|
||||
# self.write(node.attrname)
|
||||
# self.write(' ')
|
||||
# self.visit(node.expr)
|
||||
# elif node.attrname == 'val':
|
||||
# self.visit(node.expr)
|
||||
# if isinstance(obj, (Signal, intbv)):
|
||||
# if node.attrname in ('min', 'max'):
|
||||
# self.write("%s" % node.obj)
|
||||
# if isinstance(obj, EnumType):
|
||||
# assert hasattr(obj, node.attrname)
|
||||
# e = getattr(obj, node.attrname)
|
||||
# self.write(e._toVerilog())
|
||||
|
||||
|
||||
def visit_Attribute(self, node):
|
||||
if isinstance(node.ctx, ast.Store):
|
||||
assert node.attr == 'next'
|
||||
self.isSigAss = True
|
||||
self.visit(node.value)
|
||||
self.setAttr(node)
|
||||
else:
|
||||
self.getAttr(node)
|
||||
|
||||
def setAttr(self, node):
|
||||
assert node.attr == 'next'
|
||||
self.isSigAss = True
|
||||
self.visit(node.value)
|
||||
|
||||
def getAttr(self, node):
|
||||
assert isinstance(node.value, ast.Name)
|
||||
n = node.value.id
|
||||
if n in self.tree.symdict:
|
||||
obj = self.tree.symdict[n]
|
||||
elif n in self.tree.vardict:
|
||||
obj = self.tree.vardict[n]
|
||||
else:
|
||||
raise AssertionError("object not found")
|
||||
if isinstance(obj, Signal):
|
||||
if node.attr == 'next':
|
||||
self.isSigAss = True
|
||||
self.visit(node.value)
|
||||
elif node.attr in ('posedge', 'negedge'):
|
||||
self.write(node.attr)
|
||||
self.write(' ')
|
||||
self.visit(node.value)
|
||||
elif node.attr == 'val':
|
||||
self.visit(node.value)
|
||||
if isinstance(obj, (Signal, intbv)):
|
||||
if node.attr in ('min', 'max'):
|
||||
self.write("%s" % node.obj)
|
||||
if isinstance(obj, EnumType):
|
||||
assert hasattr(obj, node.attr)
|
||||
e = getattr(obj, node.attr)
|
||||
self.write(e._toVerilog())
|
||||
|
||||
|
||||
# def visitAssert(self, node, *args):
|
||||
@ -803,6 +868,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
|
||||
|
||||
def visit_Call(self, node):
|
||||
self.context = None
|
||||
fn = node.func
|
||||
# assert isinstance(fn, astNode.Name)
|
||||
f = self.getObj(fn)
|
||||
@ -839,10 +905,10 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
elif f == intbv.signed: # note equality comparison
|
||||
# comes from a getattr
|
||||
opening, closing = '', ''
|
||||
if not fn.expr.signed:
|
||||
if not fn.value.signed:
|
||||
opening, closing = "$signed(", ")"
|
||||
self.write(opening)
|
||||
self.visit(fn.expr)
|
||||
self.visit(fn.value)
|
||||
self.write(closing)
|
||||
elif type(f) in (ClassType, TypeType) and issubclass(f, Exception):
|
||||
self.write(f.__name__)
|
||||
@ -874,16 +940,27 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
v.visit(node.tree)
|
||||
|
||||
|
||||
def visitCompare(self, node, *args):
|
||||
context = None
|
||||
# def visitCompare(self, node, *args):
|
||||
# context = None
|
||||
# if node.signed:
|
||||
# context = _context.SIGNED
|
||||
# self.write("(")
|
||||
# self.visit(node.expr, context)
|
||||
# op, code = node.ops[0]
|
||||
# self.write(" %s " % op)
|
||||
# self.visit(code, context)
|
||||
# self.write(")")
|
||||
|
||||
def visit_Compare(self, node):
|
||||
self.context = None
|
||||
if node.signed:
|
||||
context = _context.SIGNED
|
||||
self.context = _context.SIGNED
|
||||
self.write("(")
|
||||
self.visit(node.expr, context)
|
||||
op, code = node.ops[0]
|
||||
self.write(" %s " % op)
|
||||
self.visit(code, context)
|
||||
self.visit(node.left)
|
||||
self.write(" %s " % opmap[type(node.ops[0])])
|
||||
self.visit(node.comparators[0])
|
||||
self.write(")")
|
||||
self.context = None
|
||||
|
||||
|
||||
|
||||
@ -1072,33 +1149,6 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
|
||||
|
||||
|
||||
def visitGetattr(self, node, *args):
|
||||
assert isinstance(node.expr, astNode.Name)
|
||||
n = node.expr.name
|
||||
if n in self.tree.symdict:
|
||||
obj = self.tree.symdict[n]
|
||||
elif n in self.tree.vardict:
|
||||
obj = self.tree.vardict[n]
|
||||
else:
|
||||
raise AssertionError("object not found")
|
||||
if isinstance(obj, Signal):
|
||||
if node.attrname == 'next':
|
||||
self.isSigAss = True
|
||||
self.visit(node.expr)
|
||||
elif node.attrname in ('posedge', 'negedge'):
|
||||
self.write(node.attrname)
|
||||
self.write(' ')
|
||||
self.visit(node.expr)
|
||||
elif node.attrname == 'val':
|
||||
self.visit(node.expr)
|
||||
if isinstance(obj, (Signal, intbv)):
|
||||
if node.attrname in ('min', 'max'):
|
||||
self.write("%s" % node.obj)
|
||||
if isinstance(obj, EnumType):
|
||||
assert hasattr(obj, node.attrname)
|
||||
e = getattr(obj, node.attrname)
|
||||
self.write(e._toVerilog())
|
||||
|
||||
|
||||
|
||||
# def visitIf(self, node, *args):
|
||||
@ -1133,7 +1183,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.write(item._toVerilog(dontcare=True))
|
||||
self.write(": begin")
|
||||
self.indent()
|
||||
self.visit(suite)
|
||||
self.visit_stmt(suite)
|
||||
self.dedent()
|
||||
self.writeline()
|
||||
self.write("end")
|
||||
@ -1141,7 +1191,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.writeline()
|
||||
self.write("default: begin")
|
||||
self.indent()
|
||||
self.visit(node.else_)
|
||||
self.visit_stmt(node.else_)
|
||||
self.dedent()
|
||||
self.writeline()
|
||||
self.write("end")
|
||||
@ -1162,7 +1212,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.visit(test)
|
||||
self.write(") begin")
|
||||
self.indent()
|
||||
self.visit(suite)
|
||||
self.visit_stmt(suite)
|
||||
self.dedent()
|
||||
self.writeline()
|
||||
self.write("end")
|
||||
@ -1170,7 +1220,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
self.writeline()
|
||||
self.write("else begin")
|
||||
self.indent()
|
||||
self.visit(node.else_)
|
||||
self.visit_stmt(node.else_)
|
||||
self.dedent()
|
||||
self.writeline()
|
||||
self.write("end")
|
||||
@ -1364,7 +1414,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
if isinstance(s, str):
|
||||
self.write('$write("%s");' % s)
|
||||
else:
|
||||
a = node.values[argnr]
|
||||
a = node.args[argnr]
|
||||
argnr += 1
|
||||
obj = a.obj
|
||||
fs = "%0d"
|
||||
@ -1549,7 +1599,7 @@ class _ConvertVisitor(ast.NodeVisitor, _ConversionMixin):
|
||||
# self.visit(elt)
|
||||
|
||||
|
||||
def visitTuple(self, node):
|
||||
def visit_Tuple(self, node):
|
||||
assert self.context != None
|
||||
sep = ", "
|
||||
tpl = node.elts
|
||||
@ -1747,7 +1797,7 @@ class _ConvertSimpleAlwaysCombVisitor(_ConvertVisitor):
|
||||
# self.visit(node.expr)
|
||||
|
||||
def visit_Attribute(self, node):
|
||||
if isintance(node.ctx, ast.Store):
|
||||
if isinstance(node.ctx, ast.Store):
|
||||
self.write("assign ")
|
||||
self.visit(node.value)
|
||||
else:
|
||||
@ -1758,8 +1808,7 @@ class _ConvertSimpleAlwaysCombVisitor(_ConvertVisitor):
|
||||
# self.writeline(2)
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
for stmt in node.body:
|
||||
self.visit(node.body)
|
||||
self.visit_stmt(node.body)
|
||||
self.writeline(2)
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user