def _analyzeGens(top, absnames): genlist = [] for g in top: if isinstance(g, _UserCode): tree = g elif isinstance(g, (_AlwaysComb, _AlwaysSeq, _Always)): f = g.func 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() tree.callstack = [] # handle free variables tree.nonlocaldict = {} 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 = _FirstPassVisitor(tree) v.visit(tree) if isinstance(g, _AlwaysComb): v = _AnalyzeAlwaysCombVisitor(tree, g.senslist) elif isinstance(g, _AlwaysSeq): v = _AnalyzeAlwaysSeqVisitor(tree, g.senslist, g.reset, g.sigregs, g.varregs) else: v = _AnalyzeAlwaysDecoVisitor(tree, g.senslist) v.visit(tree) else: # @instance f = g.gen.gi_frame 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() tree.symdict.update(f.f_locals) tree.nonlocaldict = {} tree.callstack = [] tree.name = absnames.get(id(g), str(_Label("BLOCK"))).upper() v = _FirstPassVisitor(tree) v.visit(tree) v = _AnalyzeBlockVisitor(tree) v.visit(tree) genlist.append(tree) return genlist
def _analyzeGens(top, absnames): genlist = [] for g in top: if isinstance(g, _UserCode): ast = g elif isinstance(g, (_AlwaysComb, _Always)): f = g.func s = inspect.getsource(f) # remove decorators s = re.sub(r"@.*", "", s) s = s.lstrip() ast = compiler.parse(s) # print ast ast.sourcefile = inspect.getsourcefile(f) ast.lineoffset = inspect.getsourcelines(f)[1]-1 ast.symdict = f.func_globals.copy() ast.callstack = [] # handle free variables 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): # print type(obj) assert isinstance(obj, (int, long, Signal)) or \ _isMem(obj) or _isTupleOfInts(obj) ast.symdict[n] = obj ast.name = absnames.get(id(g), str(_Label("BLOCK"))).upper() v = _NotSupportedVisitor(ast) compiler.walk(ast, v) if isinstance(g, _AlwaysComb): v = _AnalyzeAlwaysCombVisitor(ast, g.senslist) else: v = _AnalyzeAlwaysDecoVisitor(ast, g.senslist) compiler.walk(ast, v) else: # @instance f = g.gen.gi_frame s = inspect.getsource(f) # remove decorators s = re.sub(r"@.*", "", s) s = s.lstrip() ast = compiler.parse(s) # print ast ast.sourcefile = inspect.getsourcefile(f) ast.lineoffset = inspect.getsourcelines(f)[1]-1 ast.symdict = f.f_globals.copy() ast.symdict.update(f.f_locals) ast.callstack = [] ast.name = absnames.get(id(g), str(_Label("BLOCK"))).upper() v = _NotSupportedVisitor(ast) compiler.walk(ast, v) v = _AnalyzeBlockVisitor(ast) compiler.walk(ast, v) genlist.append(ast) return genlist
def _analyzeGens(top, absnames): genlist = [] for g in top: if isinstance(g, _UserCode): tree = g elif isinstance(g, (_AlwaysComb, _AlwaysSeq, _Always)): f = g.func tree = g.ast tree.symdict = f.__globals__.copy() tree.callstack = [] # handle free variables tree.nonlocaldict = {} if f.__code__.co_freevars: for n, c in zip(f.__code__.co_freevars, f.__closure__): obj = c.cell_contents 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): v = _AnalyzeAlwaysCombVisitor(tree, g.senslist) elif isinstance(g, _AlwaysSeq): v = _AnalyzeAlwaysSeqVisitor(tree, g.senslist, g.reset, g.sigregs, g.varregs) else: v = _AnalyzeAlwaysDecoVisitor(tree, g.senslist) v.visit(tree) else: # @instance f = g.gen.gi_frame tree = g.ast tree.symdict = f.f_globals.copy() tree.symdict.update(f.f_locals) 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) v.visit(tree) genlist.append(tree) return genlist
def visitWhile(self, node, *args): node.breakLabel = _Label("BREAK") node.loopLabel = _Label("LOOP") self.labelStack.append(node.breakLabel) self.labelStack.append(node.loopLabel) self.visit(node.test, *args) self.refStack.push() self.visit(node.body, *args) self.refStack.pop() y = node.body.nodes[0] if isinstance(y, astNode.Discard): y = y.expr if node.test.obj == True and \ isinstance(y, astNode.Yield) and \ not self.ast.hasYield > 1 and \ not isinstance(self.getObj(y.value), delay): node.kind = _kind.ALWAYS self.ast.senslist = y.senslist self.require(node, node.else_ is None, "while-else not supported") self.labelStack.pop() self.labelStack.pop()
def visitFor(self, node, *args): node.breakLabel = _Label("BREAK") node.loopLabel = _Label("LOOP") self.labelStack.append(node.breakLabel) self.labelStack.append(node.loopLabel) self.refStack.push() self.visit(node.assign) var = node.assign.name self.ast.vardict[var] = int(-1) cf = node.list self.visit(cf) self.require(node, isinstance(cf, astNode.CallFunc), "Expected (down)range call") f = self.getObj(cf.node) self.require(node, f in (range, downrange), "Expected (down)range call") self.visit(node.body, *args) self.refStack.pop() self.require(node, node.else_ is None, "for-else not supported") self.labelStack.pop() self.labelStack.pop()
def visit_For(self, node): node.breakLabel = _Label("BREAK") node.loopLabel = _Label("LOOP") self.labelStack.append(node.breakLabel) self.labelStack.append(node.loopLabel) self.refStack.push() 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_While(self, node): node.breakLabel = _Label("BREAK") node.loopLabel = _Label("LOOP") self.labelStack.append(node.breakLabel) self.labelStack.append(node.loopLabel) self.visit(node.test) self.refStack.push() for n in node.body: self.visit(n) self.refStack.pop() y = node.body[0] if isinstance(y, ast.Expr): y = y.value if node.test.obj == True and \ isinstance(y, ast.Yield) and \ not self.tree.hasYield > 1 and \ not isinstance(self.getObj(y.value), delay): node.kind = _kind.ALWAYS self.tree.senslist = y.senslist self.require(node, not node.orelse, "while-else not supported") self.labelStack.pop() self.labelStack.pop()
def visit_Call(self, node): self.visit(node.func) self.access = _access.UNKNOWN for arg in node.args: self.visit(arg) for kw in node.keywords: self.visit(kw) self.access = _access.INPUT argsAreInputs = True f = self.getObj(node.func) node.obj = None if type(f) is type and issubclass(f, intbv): node.obj = self.getVal(node) elif f is concat: node.obj = self.getVal(node) elif f is len: self.access = _access.UNKNOWN node.obj = int(0) # XXX elif f is bool: node.obj = bool() elif f in (int, long, ord): node.obj = int(-1) ## elif f in (posedge , negedge): ## node.obj = _EdgeDetector() elif f is delay: node.obj = delay(0) ### suprize: identity comparison on unbound methods doesn't work in python 2.5?? elif f == intbv.signed: node.obj = int(-1) elif f in myhdlObjects: pass elif f in builtinObjects: pass elif type(f) is FunctionType: argsAreInputs = False s = inspect.getsource(f) s = _dedent(s) tree = ast.parse(s) # print ast.dump(tree) # print tree fname = f.__name__ tree.name = _Label(fname) tree.sourcefile = inspect.getsourcefile(f) tree.lineoffset = inspect.getsourcelines(f)[1]-1 tree.symdict = f.func_globals.copy() tree.nonlocaldict = {} if fname in self.tree.callstack: self.raiseError(node, _error.NotSupported, "Recursive call") tree.callstack = self.tree.callstack[:] tree.callstack.append(fname) # handle free variables if f.func_code.co_freevars: for n, c in zip(f.func_code.co_freevars, f.func_closure): obj = _cell_deref(c) if not isinstance(obj, (int, long, _Signal)): self.raiseError(node, _error.FreeVarTypeError, n) tree.symdict[n] = obj v = _FirstPassVisitor(tree) v.visit(tree) v = _AnalyzeFuncVisitor(tree, node.args, node.keywords) v.visit(tree) node.obj = tree.returnObj node.tree = tree tree.argnames = argnames = [arg.id for arg in tree.body[0].args.args] # extend argument list with keyword arguments on the correct position node.args.extend([None]*len(node.keywords)) for kw in node.keywords: node.args[argnames.index(kw.arg)] = kw.value for n, arg in zip(argnames, node.args): if n in tree.outputs: self.access = _access.OUTPUT self.visit(arg) self.access = _access.INPUT if n in tree.inputs: self.visit(arg) elif type(f) is MethodType: self.raiseError(node,_error.NotSupported, "method call: '%s'" % f.__name__) else: debug_info = [e for e in ast.iter_fields(node.func)] raise AssertionError("Unexpected callable %s" % str(debug_info)) if argsAreInputs: for arg in node.args: self.visit(arg)
def visit_Call(self, node): self.visit(node.func) f = self.getObj(node.func) node.obj = None if f is print: self.visit_Print(node) return self.access = _access.UNKNOWN for arg in node.args: self.visit(arg) for kw in node.keywords: self.visit(kw) self.access = _access.INPUT argsAreInputs = True if type(f) is type and issubclass(f, intbv): node.obj = self.getVal(node) elif f is concat: node.obj = self.getVal(node) elif f is len: self.access = _access.UNKNOWN node.obj = int(0) # XXX elif f is bool: node.obj = bool() elif f in _flatten(integer_types): node.obj = int(-1) # elif f in (posedge , negedge): ## node.obj = _EdgeDetector() elif f is ord: node.obj = int(-1) if not (isinstance(node.args[0], ast.Str) and (len(node.args[0].s) == 1)): self.raiseError(node, _error.NotSupported, "ord: expect string argument with length 1") elif f is delay: node.obj = delay(0) # suprize: identity comparison on unbound methods doesn't work in python 2.5?? elif f == intbv.signed: obj = node.func.value.obj if len(obj): M = 2 ** (len(obj) - 1) node.obj = intbv(-1, min=-M, max=M) else: node.obj = intbv(-1) elif f in myhdlObjects: pass elif f in builtinObjects: pass elif type(f) is FunctionType: argsAreInputs = False tree = _makeAST(f) fname = f.__name__ tree.name = _Label(fname) tree.symdict = f.__globals__.copy() tree.nonlocaldict = {} if fname in self.tree.callstack: self.raiseError(node, _error.NotSupported, "Recursive call") tree.callstack = self.tree.callstack[:] tree.callstack.append(fname) # handle free variables if f.__code__.co_freevars: for n, c in zip(f.__code__.co_freevars, f.__closure__): obj = c.cell_contents if not isinstance(obj, (integer_types, _Signal)): self.raiseError(node, _error.FreeVarTypeError, n) tree.symdict[n] = obj v = _FirstPassVisitor(tree) v.visit(tree) v = _AnalyzeFuncVisitor(tree, node.args, node.keywords) v.visit(tree) node.obj = tree.returnObj node.tree = tree tree.argnames = argnames = _get_argnames(tree.body[0]) # extend argument list with keyword arguments on the correct position node.args.extend([None] * len(node.keywords)) for kw in node.keywords: node.args[argnames.index(kw.arg)] = kw.value for n, arg in zip(argnames, node.args): if n in tree.outputs: self.access = _access.OUTPUT self.visit(arg) self.access = _access.INPUT if n in tree.inputs: self.visit(arg) elif type(f) is MethodType: self.raiseError(node, _error.NotSupported, "method call: '%s'" % f.__name__) else: debug_info = [e for e in ast.iter_fields(node.func)] raise AssertionError("Unexpected callable %s" % str(debug_info)) if argsAreInputs: for arg in node.args: self.visit(arg)
def __init__(self, ast, funcBuf): _ConvertVisitor.__init__(self, ast, funcBuf) self.returnObj = ast.returnObj self.returnLabel = _Label("RETURN")
def __init__(self, tree, funcBuf): _ConvertVisitor.__init__(self, tree, funcBuf) self.returnLabel = _Label("RETURN")
def visitCallFunc(self, node, *args): self.visit(node.node) for arg in node.args: self.visit(arg, _access.UNKNOWN) argsAreInputs = True f = self.getObj(node.node) node.obj = None node.signed = False if type(f) is type and issubclass(f, intbv): node.obj = self.getVal(node) elif f is concat: node.obj = self.getVal(node) elif f is len: node.obj = int(0) # XXX elif f is bool: node.obj = bool() elif f in (int, long, ord): node.obj = int(-1) ## elif f in (posedge , negedge): ## node.obj = _EdgeDetector() elif f is delay: node.obj = delay(0) ### 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: pass elif type(f) is FunctionType: argsAreInputs = False s = inspect.getsource(f) s = s.lstrip() ast = compiler.parse(s) # print ast fname = f.__name__ ast.name = _Label(fname) ast.sourcefile = inspect.getsourcefile(f) ast.lineoffset = inspect.getsourcelines(f)[1]-1 ast.symdict = f.func_globals.copy() if fname in self.ast.callstack: self.raiseError(node, _error.NotSupported, "Recursive call") ast.callstack = self.ast.callstack[:] ast.callstack.append(fname) # handle free variables if f.func_code.co_freevars: for n, c in zip(f.func_code.co_freevars, f.func_closure): obj = _cell_deref(c) if not isinstance(obj, (int, long, Signal)): self.raiseError(node, _error.FreeVarTypeError, n) ast.symdict[n] = obj v = _NotSupportedVisitor(ast) compiler.walk(ast, v) v = _AnalyzeFuncVisitor(ast, node.args) compiler.walk(ast, v) node.obj = ast.returnObj node.ast = ast for i, arg in enumerate(node.args): if isinstance(arg, astNode.Keyword): n = arg.name else: # Name n = ast.argnames[i] if n in ast.outputs: self.visit(arg, _access.OUTPUT) if n in ast.inputs: self.visit(arg, _access.INPUT) elif type(f) is MethodType: self.raiseError(node,_error.NotSupported, "method call: '%s'" % f.__name__) else: raise AssertionError("Unexpected callable") if argsAreInputs: for arg in node.args: self.visit(arg, _access.INPUT)
def visit_Call(self, node): self.visit(node.func) f = self.getObj(node.func) node.obj = None if f is print: self.visit_Print(node) return self.access = _access.UNKNOWN for arg in node.args: self.visit(arg) for kw in node.keywords: self.visit(kw) self.access = _access.INPUT argsAreInputs = True if type(f) is type and issubclass(f, intbv): node.obj = self.getVal(node) elif f is concat: node.obj = self.getVal(node) elif f is len: self.access = _access.UNKNOWN node.obj = int(0) # XXX elif f is bool: node.obj = bool() elif f in _flatten(integer_types): node.obj = int(-1) # elif f in (posedge , negedge): # # node.obj = _EdgeDetector() elif f is ord: node.obj = int(-1) if not (isinstance(node.args[0], ast.Str) and (len(node.args[0].s) == 1)): self.raiseError(node, _error.NotSupported, "ord: expect string argument with length 1") elif f is delay: node.obj = delay(0) # suprize: identity comparison on unbound methods doesn't work in python 2.5?? elif f == intbv.signed: obj = node.func.value.obj if len(obj): M = 2**(len(obj) - 1) node.obj = intbv(-1, min=-M, max=M) else: node.obj = intbv(-1) elif f in myhdlObjects: pass elif f in builtinObjects: pass elif type(f) is FunctionType: argsAreInputs = False tree = _makeAST(f) fname = f.__name__ tree.name = _Label(fname) tree.symdict = f.__globals__.copy() tree.nonlocaldict = {} if fname in self.tree.callstack: self.raiseError(node, _error.NotSupported, "Recursive call") tree.callstack = self.tree.callstack[:] tree.callstack.append(fname) # handle free variables if f.__code__.co_freevars: for n, c in zip(f.__code__.co_freevars, f.__closure__): obj = c.cell_contents if not isinstance(obj, (integer_types, _Signal)): self.raiseError(node, _error.FreeVarTypeError, n) tree.symdict[n] = obj v = _FirstPassVisitor(tree) v.visit(tree) v = _AnalyzeFuncVisitor(tree, node.args, node.keywords) v.visit(tree) node.obj = tree.returnObj node.tree = tree tree.argnames = argnames = _get_argnames(tree.body[0]) # extend argument list with keyword arguments on the correct position node.args.extend([None] * len(node.keywords)) for kw in node.keywords: node.args[argnames.index(kw.arg)] = kw.value for n, arg in zip(argnames, node.args): if n in tree.outputs: self.access = _access.OUTPUT self.visit(arg) self.access = _access.INPUT if n in tree.inputs: self.visit(arg) elif type(f) is MethodType: self.raiseError(node, _error.NotSupported, "method call: '%s'" % f.__name__) else: debug_info = [e for e in ast.iter_fields(node.func)] raise AssertionError("Unexpected callable %s" % str(debug_info)) if argsAreInputs: for arg in node.args: self.visit(arg)