def visit_FunctionDef(self, node): self.name = node.name argnames = [arg.id for arg in node.args.args] if isboundmethod(self.func): if not argnames[0] == 'self': self.raiseError(node, _error.NotSupported, "first method argument name other than 'self'") # skip self argnames = argnames[1:] i=-1 for i, arg in enumerate(self.args): n = argnames[i] if isinstance(arg, _Signal): self.argdict[n] = arg if _isMem(arg): self.raiseError(node, _error.ListAsPort, n) for n in argnames[i+1:]: if n in self.kwargs: arg = self.kwargs[n] if isinstance(arg, _Signal): self.argdict[n] = arg if _isMem(arg): self.raiseError(node, _error.ListAsPort, n) self.argnames = [n for n in argnames if n in self.argdict]
def visit_FunctionDef(self, node): self.name = node.name self.argnames = _get_argnames(node) if isboundmethod(self.func): if not self.argnames[0] == 'self': self.raiseError(node, _error.NotSupported, "first method argument name other than 'self'") # skip self self.argnames = self.argnames[1:] i = -1 for i, arg in enumerate(self.args): n = self.argnames[i] self.fullargdict[n] = arg if isinstance(arg, _Signal): self.argdict[n] = arg if _isMem(arg): self.raiseError(node, _error.ListAsPort, n) for n in self.argnames[i + 1:]: if n in self.kwargs: arg = self.kwargs[n] self.fullargdict[n] = arg if isinstance(arg, _Signal): self.argdict[n] = arg if _isMem(arg): self.raiseError(node, _error.ListAsPort, n) self.argnames = [n for n in self.argnames if n in self.argdict]
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 accessIndex(self, node): self.visit(node.value) self.access = _access.INPUT self.visit(node.slice.value) if isinstance(node.value.obj, _Ram): if isinstance(node.ctx, ast.Store): self.raiseError(node, _error.ListElementAssign) else: node.obj = node.value.obj.elObj elif _isMem(node.value.obj): node.obj = node.value.obj[0] elif isinstance(node.value.obj, _Rom): node.obj = int(-1) elif isinstance(node.value.obj, intbv): node.obj = bool() else: node.obj = bool() # XXX default
def visit_Yield(self, node, *args): self.tree.hasYield += 1 n = node.value self.visit(n) senslist = [] if isinstance(n, ast.Tuple): for n in n.elts: if not isinstance(n.obj, (_Signal, _WaiterList)): self.raiseError(node, _error.UnsupportedYield) senslist.append(n.obj) elif isinstance(n.obj, (_Signal, _WaiterList, delay)): senslist = [n.obj] elif _isMem(n.obj): senslist = n.obj else: self.raiseError(node, _error.UnsupportedYield) node.senslist = senslist
def getName(self, node): addSignBit = False isMixedExpr = (not node.signed) and (self.context == _context.SIGNED) n = node.id if n == 'False': s = "1'b0" elif n == 'True': s = "1'b1" elif n == 'None': s = "'bz" elif n in self.tree.vardict: addSignBit = isMixedExpr s = n elif n in self.tree.argnames: assert n in self.tree.symdict addSignBit = isMixedExpr s = n elif n in self.tree.symdict: obj = self.tree.symdict[n] if isinstance(obj, bool): s = "%s" % int(obj) elif isinstance(obj, (int, long)): s = self.IntRepr(obj) elif isinstance(obj, _Signal): addSignBit = isMixedExpr s = str(obj) elif _isMem(obj): m = _getMemInfo(obj) assert m.name s = m.name elif isinstance(obj, EnumItemType): s = obj._toVerilog() elif type(obj) in (ClassType, TypeType) and issubclass( obj, Exception): s = n else: self.raiseError(node, _error.UnsupportedType, "%s, %s" % (n, type(obj))) else: raise AssertionError("name ref: %s" % n) if addSignBit: self.write("$signed({1'b0, ") self.write(s) if addSignBit: self.write("})")
def visitSubscript(self, node, access=_access.INPUT, *args): self.visit(node.expr, access) assert len(node.subs) == 1 self.visit(node.subs[0], _access.INPUT) if isinstance(node.expr.obj, _Ram): if node.flags == 'OP_ASSIGN': self.raiseError(node, _error.ListElementAssign) else: node.obj = node.expr.obj.elObj elif _isMem(node.expr.obj): node.obj = node.expr.obj[0] elif isinstance(node.expr.obj, _Rom): node.obj = int(-1) elif isinstance(node.expr.obj, intbv): node.obj = bool() else: node.obj = bool() # XXX default node.signed = _maybeNegative(node.obj)
def getName(self, node): addSignBit = False isMixedExpr = (not node.signed) and (self.context == _context.SIGNED) n = node.id if n == 'False': s = "1'b0" elif n == 'True': s = "1'b1" elif n == 'None': s = "'bz" elif n in self.tree.vardict: addSignBit = isMixedExpr s = n elif n in self.tree.argnames: assert n in self.tree.symdict addSignBit = isMixedExpr s = n elif n in self.tree.symdict: obj = self.tree.symdict[n] if isinstance(obj, bool): s = "%s" % int(obj) elif isinstance(obj, (int, long)): s = self.IntRepr(obj) elif isinstance(obj, _Signal): addSignBit = isMixedExpr s = str(obj) elif _isMem(obj): m = _getMemInfo(obj) assert m.name s = m.name elif isinstance(obj, EnumItemType): s = obj._toVerilog() elif type(obj) in (ClassType, TypeType) and issubclass(obj, Exception): s = n else: self.raiseError(node, _error.UnsupportedType, "%s, %s" % (n, type(obj))) else: raise AssertionError("name ref: %s" % n) if addSignBit: self.write("$signed({1'b0, ") self.write(s) if addSignBit: self.write("})")
def getName(self, node): n = node.id if PY2 and n in ('True', 'False', 'None'): self.visit_NameConstant(node) return addSignBit = False isMixedExpr = (not node.signed) and (self.context == _context.SIGNED) if n in self.tree.vardict: addSignBit = isMixedExpr s = n elif n in self.tree.argnames: assert n in self.tree.symdict addSignBit = isMixedExpr s = n elif n in self.tree.symdict: obj = self.tree.symdict[n] if isinstance(obj, bool): s = "1'b%s" % int(obj) elif isinstance(obj, integer_types): s = self.IntRepr(obj) elif isinstance(obj, _Signal): addSignBit = isMixedExpr s = str(obj) elif _isMem(obj): m = _getMemInfo(obj) assert m.name s = m.name elif isinstance(obj, EnumItemType): s = obj._toVerilog() elif (type(obj) in class_types) and issubclass(obj, Exception): s = n else: self.raiseError(node, _error.UnsupportedType, "%s, %s" % (n, type(obj))) else: raise AssertionError("name ref: %s" % n) if addSignBit: self.write("$signed({1'b0, ") self.write(s) if addSignBit: self.write("})")
def accessIndex(self, node): self.visit(node.value) self.access = _access.INPUT if sys.version_info >= (3, 9, 0): # Python 3.9+: no ast.Index wrapper self.visit(node.slice) else: self.visit(node.slice.value) if isinstance(node.value.obj, _Ram): if isinstance(node.ctx, ast.Store): self.raiseError(node, _error.ListElementAssign) else: node.obj = node.value.obj.elObj elif _isMem(node.value.obj): node.obj = node.value.obj[0] elif isinstance(node.value.obj, _Rom): node.obj = int(-1) elif isinstance(node.value.obj, intbv): node.obj = bool() else: node.obj = bool() # XXX default
def getName(self, node): n = node.id node.obj = None if n not in self.refStack: if (n in self.tree.vardict) and (n not in self.tree.nonlocaldict): self.raiseError(node, _error.UnboundLocal, n) self.globalRefs.add(n) if n in self.tree.sigdict: node.obj = sig = self.tree.sigdict[n] # mark shadow signal as driven only when they are seen somewhere if isinstance(sig, _ShadowSignal): sig._driven = 'wire' # mark tristate signal as driven if its driver is seen somewhere if isinstance(sig, _TristateDriver): sig._sig._driven = 'wire' if not isinstance(sig, _Signal): # print "not a signal: %s" % n pass else: if sig._type is bool: node.edge = sig.posedge if self.access == _access.INPUT: self.tree.inputs.add(n) elif self.access == _access.OUTPUT: self.tree.kind = _kind.TASK if n in self.tree.outputs: node.kind = _kind.REG self.tree.outputs.add(n) elif self.access == _access.UNKNOWN: pass else: self.raiseError(node, _error.NotSupported, "Augmented signal assignment") if n in self.tree.vardict: obj = self.tree.vardict[n] if self.access == _access.INOUT: # probably dead code # upgrade bool to int for augmented assignments if isinstance(obj, bool): obj = int(-1) self.tree.vardict[n] = obj node.obj = obj elif n in self.tree.symdict: node.obj = self.tree.symdict[n] if _isTupleOfInts(node.obj): node.obj = _Rom(node.obj) self.tree.hasRom = True elif _isMem(node.obj): m = _getMemInfo(node.obj) if self.access == _access.INPUT: m._read = True elif self.access == _access.OUTPUT: m._driven = 'reg' self.tree.outmems.add(n) elif self.access == _access.UNKNOWN: pass else: assert False, "unexpected mem access %s %s" % (n, self.access) self.tree.hasLos = True elif isinstance(node.obj, int): node.value = node.obj if n in self.tree.nonlocaldict: # hack: put nonlocal intbv's in the vardict self.tree.vardict[n] = v = node.obj elif n in builtins.__dict__: node.obj = builtins.__dict__[n] else: self.raiseError(node, _error.UnboundLocal, n)
def getName(self, node): n = node.id node.obj = None if n not in self.refStack: if (n in self.tree.vardict) and (n not in self.tree.nonlocaldict): self.raiseError(node, _error.UnboundLocal, n) self.globalRefs.add(n) if n in self.tree.sigdict: node.obj = sig = self.tree.sigdict[n] # mark shadow signal as driven only when they are seen somewhere if isinstance(sig, _ShadowSignal): sig._driven = 'wire' if not isinstance(sig, _Signal): # print "not a signal: %s" % n pass else: if sig._type is bool: node.edge = sig.posedge ws = getattr(sig._val, 'lenStr', False) ext = getattr(sig._val, 'external', False) if ws and ws in self.tree.symdict: _constDict[ws] = self.tree.symdict[ws] if ext: _extConstDict[ws] = self.tree.symdict[ws] if self.access == _access.INPUT: self.tree.inputs.add(n) elif self.access == _access.OUTPUT: self.tree.kind = _kind.TASK if n in self.tree.outputs: node.kind = _kind.REG self.tree.outputs.add(n) elif self.access == _access.UNKNOWN: pass else: self.raiseError(node, _error.NotSupported, "Augmented signal assignment") if n in self.tree.vardict: obj = self.tree.vardict[n] if self.access == _access.INOUT: # probably dead code # upgrade bool to int for augmented assignments if isinstance(obj, bool): obj = int(-1) self.tree.vardict[n] = obj node.obj = obj elif n in self.tree.symdict: node.obj = self.tree.symdict[n] if _isTupleOfInts(node.obj): node.obj = _Rom(node.obj) self.tree.hasRom = True elif _isMem(node.obj): m = _getMemInfo(node.obj) if self.access == _access.INPUT: m._read = True elif self.access == _access.OUTPUT: m._driven = 'reg' self.tree.outmems.add(n) elif self.access == _access.UNKNOWN: pass else: assert False, "unexpected mem access %s %s" % (n, self.access) self.tree.hasLos = True ws = getattr(m.elObj._val, 'lenStr', False) ext = getattr(m.elObj._val, 'external', False) if ws and ws in self.tree.symdict: _constDict[ws] = self.tree.symdict[ws] if ext: _extConstDict[ws] = self.tree.symdict[ws] elif isinstance(node.obj, int): node.value = node.obj # put VHDL compliant integer constants in global dict if n not in _constDict and abs(node.obj) < 2**31: _constDict[n] = node.obj if n in self.tree.nonlocaldict: # hack: put nonlocal intbv's in the vardict self.tree.vardict[n] = v = node.obj # typedef string for nonlocal intbv's ws = getattr(v, 'lenStr', False) ext = getattr(v, 'external', False) if ws and ws in self.tree.symdict: _constDict[ws] = self.tree.symdict[ws] if ext: _extConstDict[ws] = self.tree.symdict[ws] elif n in __builtin__.__dict__: node.obj = __builtin__.__dict__[n] else: self.raiseError(node, _error.UnboundLocal, n)