def __init__(self, func, symdict): self.symdict = symdict s = inspect.getsource(func) s = _dedent(s) tree = ast.parse(s) # print ast.dump(tree) v = _AttrRefTransformer(self) v.visit(tree) v = _SigNameVisitor(self.symdict) v.visit(tree) self.inputs = v.results["input"] self.outputs = v.results["output"] inouts = v.results["inout"] | self.inputs.intersection(self.outputs) if inouts: raise AlwaysCombError(_error.SignalAsInout % inouts) if v.results["embedded_func"]: raise AlwaysCombError(_error.EmbeddedFunction) senslist = [] for n in self.inputs: s = self.symdict[n] if isinstance(s, _Signal): senslist.append(s) elif _isListOfSigs(s): senslist.extend(s) self.senslist = tuple(senslist) if len(self.senslist) == 0: raise AlwaysCombError(_error.EmptySensitivityList) super(_AlwaysComb, self).__init__(func, senslist)
def extractor(self, frame, event, arg): if event == "call": func_name = frame.f_code.co_name if func_name in self.skipNames: self.skip = 1 if not self.skip: self.level += 1 elif event == "return": if not self.skip: isGenSeq = _isGenSeq(arg) if isGenSeq: for hdl in _userCodeMap: key = "__%s__" % hdl if key in frame.f_locals: code = frame.f_locals[key] namespace = frame.f_globals.copy() namespace.update(frame.f_locals) sourcefile = inspect.getsourcefile(frame) funcname = frame.f_code.co_name sourceline = inspect.getsourcelines(frame)[1] _addUserCode(hdl, arg, code, namespace, sourcefile, funcname, sourceline) # building hierarchy only makes sense if there are generators if isGenSeq and arg: sigdict = {} memdict = {} 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 ## if not n in cellvars: ## continue if isinstance(v, Signal): sigdict[n] = v if n in cellvars: v._used = True if _isListOfSigs(v): m = _makeMemInfo(v) memdict[n] = m if n in cellvars: m._used = True 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) self.hierarchy.append(inst) self.level -= 1 func_name = frame.f_code.co_name if func_name in self.skipNames: self.skip = 0
def _updateNamespaces(self): # dicts to keep track of objects used in Instantiator objects usedsigdict = {} usedlosdict = {} for inst in self.subs: # the symdict of a block instance is defined by # the call context of its instantiations if isinstance(inst, Cosimulation): continue # ignore if self.symdict is None: self.symdict = inst.callinfo.symdict if isinstance(inst, _Instantiator): usedsigdict.update(inst.sigdict) usedlosdict.update(inst.losdict) if self.symdict is None: self.symdict = {} # Special case: due to attribute reference transformation, the # sigdict and losdict from Instantiator objects may contain new # references. Therefore, update the symdict with them. # To be revisited. self.symdict.update(usedsigdict) self.symdict.update(usedlosdict) # Infer sigdict and memdict, with compatibility patches from _extractHierarchy for n, v in self.symdict.items(): if isinstance(v, _Signal): self.sigdict[n] = v if n in usedsigdict: v._markUsed() if _isListOfSigs(v): m = _makeMemInfo(v) self.memdict[n] = m if n in usedlosdict: m._used = True
def __init__(self, func): senslist = [] super(_AlwaysComb, self).__init__(func, senslist) s = inspect.getsource(func) s = _dedent(s) tree = ast.parse(s) # print ast.dump(tree) v = _AttrRefTransformer(self) v.visit(tree) v = _SigNameVisitor(self.symdict) v.visit(tree) self.inputs = v.results['input'] self.outputs = v.results['output'] inouts = v.results['inout'] | self.inputs.intersection(self.outputs) if inouts: raise AlwaysCombError(_error.SignalAsInout % inouts) if v.results['embedded_func']: raise AlwaysCombError(_error.EmbeddedFunction) for n in self.inputs: s = self.symdict[n] if isinstance(s, _Signal): senslist.append(s) elif _isListOfSigs(s): senslist.extend(s) self.senslist = tuple(senslist) if len(self.senslist) == 0: raise AlwaysCombError(_error.EmptySensitivityList)
def visit_Name(self, node): id = node.id if id not in self.symdict: return s = self.symdict[id] if isinstance(s, (_Signal, intbv)) or _isListOfSigs(s): if self.context in ('input', 'output', 'inout'): self.results[self.context].add(id) else: print(self.context) raise AssertionError("bug in always_comb")
def visit_Name(self, node): n = node.id if n not in self.symdict: return s = self.symdict[n] if isinstance(s, (_Signal, intbv)) or _isListOfSigs(s): if self.context == 'input': self.inputs.add(n) elif self.context == 'output': self.outputs.add(n) elif self.context == 'inout': self.inouts.add(n) elif self.context == 'pass': pass else: print(self.context) raise AssertionError("bug in _SigNameVisitor") if isinstance(s, _Signal): self.sigdict[n] = s elif _isListOfSigs(s): self.losdict[n] = s
def visitName(self, node, access=INPUT): if node.name not in self.symdict: return s = self.symdict[node.name] if isinstance(s, Signal) or _isListOfSigs(s): if access == INPUT: self.inputs.add(node.name) elif access == OUTPUT: self.outputs.add(node.name) elif access == INOUT: raise AlwaysCombError(_error.SignalAsInout) else: raise AlwaysCombError
def visit_Name(self, node): id = node.id if id not in self.symdict: return s = self.symdict[id] if isinstance(s, _Signal) or _isListOfSigs(s): if self.context == INPUT: self.inputs.add(id) elif self.context == OUTPUT: self.outputs.add(id) elif self.context == INOUT: raise AlwaysCombError(_error.SignalAsInout % id) else: raise AssertionError("bug in always_comb")
def visit_Name(self, node): id = node.id if id not in self.symdict: return s = self.symdict[id] if isinstance(s, (_Signal, intbv)) or _isListOfSigs(s): if self.context == INPUT: self.inputs.add(id) elif self.context == OUTPUT: self.outputs.add(id) elif self.context == INOUT: raise AlwaysSeqError(_error.SigAugAssign, id) else: raise AssertionError("bug in always_seq")
def visit_Name(self, node): id = node.id if id not in self.symdict: return s = self.symdict[id] if isinstance(s, (_Signal, intbv)) or _isListOfSigs(s): if self.context == 'input': self.inputs.add(id) elif self.context == 'output': self.outputs.add(id) elif self.context == 'inout': self.inouts.add(id) else: print(self.context) raise AssertionError("bug in _SigNameVisitor")
def visit_Name(self, node): id = node.id if id not in self.symdict: # print('visit_Name, lost {}'.format(id)) return s = self.symdict[id] if isinstance(s, (_Signal, intbv)) or _isListOfSigs(s) or isinstance( s, (Array, StructType)): # print(repr(s), self.context) # print(repr(s), self.context) if self.context in ('input', 'output', 'inout'): self.results[self.context].add(id) else: # print(self.context) raise AssertionError("bug in always_comb")
def __init__(self, func, callinfo): senslist = [] super(_AlwaysComb, self).__init__(func, senslist, callinfo=callinfo) if self.embedded_func: raise AlwaysCombError(_error.EmbeddedFunction) for n in self.inputs: s = self.symdict[n] if isinstance(s, _Signal): senslist.append(s) elif _isListOfSigs(s): senslist.extend(s) self.senslist = tuple(senslist) if len(self.senslist) == 0: raise AlwaysCombError(_error.EmptySensitivityList)
def __init__(self, func): senslist = [] super(_AlwaysComb, self).__init__(func, senslist) inouts = self.inouts | self.inputs.intersection(self.outputs) if inouts: raise AlwaysCombError(_error.SignalAsInout % inouts) if self.embedded_func: raise AlwaysCombError(_error.EmbeddedFunction) for n in self.inputs: s = self.symdict[n] if isinstance(s, _Signal): senslist.append(s) elif _isListOfSigs(s): senslist.extend(s) self.senslist = tuple(senslist) if len(self.senslist) == 0: raise AlwaysCombError(_error.EmptySensitivityList)
def __init__(self, func, edge, reset, callinfo, sigdict): senslist = [edge] self.reset = reset if reset is not None: self.genfunc = self.genfunc_reset active = self.reset.active isasync = self.reset.isasync if isasync: if active: senslist.append(reset.posedge) else: senslist.append(reset.negedge) else: self.genfunc = self.genfunc_no_reset super(_AlwaysSeq, self).__init__(func, senslist, callinfo=callinfo, sigdict=sigdict) if self.inouts: raise AlwaysSeqError(_error.SigAugAssign, self.inouts) if self.embedded_func: raise AlwaysSeqError(_error.EmbeddedFunction) sigregs = self.sigregs = [] varregs = self.varregs = [] for n in self.outputs: reg = self.symdict[n] if isinstance(reg, _Signal): sigregs.append(reg) elif isinstance(reg, intbv): varregs.append((n, reg, int(reg))) else: assert _isListOfSigs(reg) for e in reg: sigregs.append(e)
def __init__(self, func, edge, reset, callinfo, sigdict): senslist = [edge] self.reset = reset if reset is not None: self.genfunc = self.genfunc_reset active = self.reset.active isasync = self.reset.isasync if isasync: if active: senslist.append(reset.posedge) else: senslist.append(reset.negedge) else: self.genfunc = self.genfunc_no_reset super(_AlwaysSeq, self).__init__( func, senslist, callinfo=callinfo, sigdict=sigdict) if self.inouts: raise AlwaysSeqError(_error.SigAugAssign, self.inouts) if self.embedded_func: raise AlwaysSeqError(_error.EmbeddedFunction) sigregs = self.sigregs = [] varregs = self.varregs = [] for n in self.outputs: reg = self.symdict[n] if isinstance(reg, _Signal): sigregs.append(reg) elif isinstance(reg, intbv): varregs.append((n, reg, int(reg))) else: assert _isListOfSigs(reg) for e in reg: sigregs.append(e)
tree = ast.parse(s) # print ast.dump(tree) v = _AttrRefTransformer(self) v.visit(tree) v = _SigNameVisitor(self.symdict) v.visit(tree) sigregs = self.sigregs = [] varregs = self.varregs = [] for n in v.outputs: reg = self.symdict[n] if isinstance(reg, _Signal): sigregs.append(reg) elif isinstance(reg, intbv): varregs.append((n, reg, int(reg))) else: assert _isListOfSigs(reg) for e in reg: sigregs.append(e) def reset_sigs(self): for s in self.sigregs: s.next = s._init def reset_vars(self): for v in self.varregs: # only intbv's for now n, reg, init = v reg._val = init def genfunc(self):
if v.results['inout']: raise AlwaysSeqError(_error.SigAugAssign, v.results['inout']) if v.results['embedded_func']: raise AlwaysSeqError(_error.EmbeddedFunction) sigregs = self.sigregs = [] varregs = self.varregs = [] for n in v.results['output']: reg = self.symdict[n] if isinstance(reg, _Signal): sigregs.append(reg) elif isinstance(reg, intbv): varregs.append((n, reg, int(reg))) else: assert _isListOfSigs(reg) for e in reg: sigregs.append(e) def reset_sigs(self): for s in self.sigregs: s.next = s._init def reset_vars(self): for v in self.varregs: # only intbv's for now n, reg, init = v reg._val = init def genfunc_reset(self): senslist = self.senslist
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) 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) if not self.skip: isGenSeq = _isGenSeq(arg) if isGenSeq: specs = {} for hdl in _userCodeMap: spec = "__%s__" % hdl if spec in frame.f_locals and frame.f_locals[spec]: specs[spec] = frame.f_locals[spec] spec = "%s_code" % hdl if func and hasattr(func, spec) and getattr( func, spec): specs[spec] = getattr(func, spec) spec = "%s_instance" % hdl if func and hasattr(func, spec) and getattr( func, spec): specs[spec] = getattr(func, spec) if specs: _addUserCode(specs, arg, funcname, func, frame) # building hierarchy only makes sense if there are generators if isGenSeq and arg: sigdict = {} memdict = {} symdict = frame.f_globals.copy() symdict.update(frame.f_locals) cellvars = [] # All nested functions will be in co_consts if func: local_gens = [] consts = func.__code__.co_consts for item in _flatten(arg): genfunc = _genfunc(item) if genfunc.__code__ in consts: local_gens.append(item) if local_gens: cellvarlist = _getCellVars(symdict, local_gens) cellvars.extend(cellvarlist) objlist = _resolveRefs(symdict, local_gens) 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 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) self.hierarchy.append(inst) self.level -= 1 if funcname in self.skipNames: self.skip -= 1
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) 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) if not self.skip: isGenSeq = _isGenSeq(arg) if isGenSeq: specs = {} for hdl in _userCodeMap: spec = "__%s__" % hdl if spec in frame.f_locals and frame.f_locals[spec]: specs[spec] = frame.f_locals[spec] spec = "%s_code" % hdl if func and hasattr(func, spec) and getattr(func, spec): specs[spec] = getattr(func, spec) spec = "%s_instance" % hdl if func and hasattr(func, spec) and getattr(func, spec): specs[spec] = getattr(func, spec) if specs: _addUserCode(specs, arg, funcname, func, frame) # building hierarchy only makes sense if there are generators if isGenSeq and arg: sigdict = {} memdict = {} argdict = {} if func: arglist = inspect.getargspec(func).args else: arglist = [] symdict = frame.f_globals.copy() symdict.update(frame.f_locals) cellvars = [] cellvars.extend(frame.f_code.co_cellvars) #All nested functions will be in co_consts if func: local_gens = [] consts = func.__code__.co_consts for item in _flatten(arg): genfunc = _genfunc(item) if genfunc.__code__ in consts: local_gens.append(item) if local_gens: objlist = _resolveRefs(symdict, local_gens) 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 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 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) 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) if not self.skip: isGenSeq = _isGenSeq(arg) if isGenSeq: specs = {} for hdl in _userCodeMap: spec = "__%s__" % hdl if spec in frame.f_locals and frame.f_locals[spec]: specs[spec] = frame.f_locals[spec] spec = "%s_code" % hdl if func and hasattr(func, spec) and getattr( func, spec): specs[spec] = getattr(func, spec) spec = "%s_instance" % hdl if func and hasattr(func, spec) and getattr( func, spec): specs[spec] = getattr(func, spec) if specs: _addUserCode(specs, arg, funcname, func, frame) # building hierarchy only makes sense if there are generators if isGenSeq and arg: sigdict = {} memdict = {} # **** KH added code argdict = {} if func: arglist = 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 ## 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 # **** KH added code: 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)) # **** KH modified code: add "func" and "argdict" 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
varregs = self.varregs = [] for n in v.results['output']: reg = self.symdict[n] if isinstance(reg, _Signal): sigregs.append(reg) elif isinstance(reg, intbv): varregs.append((n, reg, int(reg))) elif isinstance(reg, Array): for e in reg: sigregs.append(e) elif isinstance(reg, StructType): srcvars = vars(reg) for var in srcvars: if isinstance(var, (_Signal, Array, StructType)): sigregs.append(var) elif _isListOfSigs(reg): for e in reg: sigregs.append(e) else: raise ValueError('Unhandled output type') def reset_sigs(self): for s in self.sigregs: s.next = s._init def reset_vars(self): for v in self.varregs: # only intbv's for now n, reg, init = v reg._val = init