def __init__(self, func, deco, srcfile, srcline, *args, **kwargs): calls = deco.calls self.func = func self.args = args self.kwargs = kwargs self.__doc__ = func.__doc__ callinfo = _getCallInfo() self.callinfo = callinfo self.modctxt = callinfo.modctxt self.callername = callinfo.name self.symdict = None self.sigdict = {} self.memdict = {} self.name = self.__name__ = func.__name__ + '_' + str(calls) # flatten, but keep BlockInstance objects self.subs = _flatten(func(*args, **kwargs)) self._verifySubs() self._updateNamespaces() self.verilog_code = self.vhdl_code = None self.sim = None if hasattr(deco, 'verilog_code'): self.verilog_code = _UserVerilogCode(deco.verilog_code, self.symdict, func.__name__, func, srcfile, srcline) if hasattr(deco, 'vhdl_code'): self.vhdl_code = _UserVhdlCode(deco.vhdl_code, self.symdict, func.__name__, func, srcfile, srcline) self._config_sim = {'trace': False}
def __init__(self, func, deco, srcfile, srcline, *args, **kwargs): calls = deco.calls self.func = func self.args = args self.kwargs = kwargs self.__doc__ = func.__doc__ callinfo = _getCallInfo() self.callinfo = callinfo self.modctxt = callinfo.modctxt self.callername = callinfo.name self.symdict = None self.sigdict = {} self.memdict = {} self.name = self.__name__ = func.__name__ + '_' + str(calls - 1) # flatten, but keep BlockInstance objects self.subs = _flatten(func(*args, **kwargs)) self._verifySubs() self._updateNamespaces() self.verilog_code = self.vhdl_code = None self.sim = None if hasattr(deco, 'verilog_code'): self.verilog_code = _UserVerilogCode(deco.verilog_code, self.symdict, func.__name__, func, srcfile, srcline) if hasattr(deco, 'vhdl_code'): self.vhdl_code = _UserVhdlCode(deco.vhdl_code, self.symdict, func.__name__, func, srcfile, srcline) self._config_sim = {'trace': False}
def _getCellVars(symdict, arg): gens = _flatten(arg) data = Data() data.symdict = symdict v = _GetCellVars(data) for gen in gens: v.visit(gen.ast) return list(data.objset)
def _resolveRefs(symdict, arg): gens = _flatten(arg) data = Data() data.symdict = symdict v = _AttrRefTransformer(data) for gen in gens: v.visit(gen.ast) return data.objlist
def _resolveRefs(symdict, arg): gens = _flatten(arg) data = Data() data.symdict = symdict v = _AttrRefTransformer(data) for gen in gens: func = _genfunc(gen) tree = _makeAST(func) v.visit(tree) return data.objlist
def __init__(self, *args): """ Construct a simulation object. *args -- list of arguments. Each argument is a generator or a nested sequence of generators. """ _simulator._time = 0 arglist = _flatten(*args) self._waiters, self._cosim = _makeWaiters(arglist) if not self._cosim and _simulator._cosim: warn("Cosimulation not registered as Simulation argument") self._finished = False del _futureEvents[:] del _siglist[:]
def visit_FunctionDef(self, node): nodes = _flatten(node.body, node.args) for n in nodes: self.visit(n) return node
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 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 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 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 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": trace.push(False, '_HierExtr: 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 = {} # collections.OrderedDict() #{} 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 = {} # collections.OrderedDict() #{} memdict = {} # collections.OrderedDict() #{} argdict = {} # collections.OrderedDict() #{} if func: arglist = inspect.getargspec(func).args else: arglist = [] 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) # TODO: must re-work this to let 'interfaces' work # as before objlist = _resolveRefs(symdict, local_gens) cellvars.extend(objlist) # the last one passing by is the top module ... # for n, v in nsymdict.items(): 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): trace.print( 'level {} Signal {} {}, used: {}, driven: {}, read: {}' .format(self.level, n, repr(v), v._used, v.driven, v._read)) sigdict[n] = v if n in cellvars: v._markUsed() elif isinstance(v, list): trace.print('level {} list {} {}'.format( self.level, n, v)) if len(v) > 0: levels, sizes, totalelements, element = m1Dinfo( v) if isinstance(element, (_Signal, Array, StructType)): m = _makeMemInfo(v, levels, sizes, totalelements, element) memdict[n] = m if n in cellvars: m._used = True if isinstance(element, (Array)): if isinstance(v[0], list): raise ValueError( 'don\'t handle nested lists', repr(v)) else: # instantiate every element separately for i, a in enumerate(v): m = _makeMemInfo( a, len(a.shape), a.shape, a.size, element) m.name = n + '({})'.format( str(i)) memdict[m.name] = m trace.print('\t', m.name, m) # for item in m.mem: # trace.print('\t', m.driven) if m.name in cellvars: m._used = True # else: # trace.print(repr(element)) elif isinstance(v, Array): trace.print('level {} Array {} {} {} {}'.format( self.level, n, repr(v), v.driven, v._read)) # only enter 'top' Arrays, i.e. not Arrays that are # a member of StructType(s) if '.' not in n: # we have all information handy in the Array # object m = _makeMemInfo(v, v.levels, v.shape, v.size, v.element) memdict[n] = m if n in cellvars: m._used = True m._driven = v.driven elif isinstance(v, StructType): trace.print('_HierExtr {} StructType {} {}'.format( self.level, n, v)) # only enter 'top' StructTypes, i.e. not the nested # StructType(s) if '.' not in n: # should also be entered in the memdict m = _makeMemInfo(v, 1, 1, 1, v) memdict[n] = m if n in cellvars: m._used = True m._driven = v.driven # 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, funcname) self.hierarchy.append(inst) self.level -= 1 if funcname in self.skipNames: self.skip -= 1 trace.pop()