Beispiel #1
0
    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}
Beispiel #2
0
    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}
Beispiel #3
0
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 _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)
Beispiel #5
0
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
Beispiel #6
0
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
Beispiel #7
0
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
Beispiel #8
0
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
Beispiel #9
0
    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[:]
Beispiel #10
0
    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[:]
Beispiel #11
0
 def visit_FunctionDef(self, node):
     nodes = _flatten(node.body, node.args)
     for n in nodes:
         self.visit(n)
     return node
Beispiel #12
0
 def visit_FunctionDef(self, node):
     nodes = _flatten(node.body, node.args)
     for n in nodes:
         self.visit(n)
     return node
Beispiel #13
0
    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
Beispiel #14
0
    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)
Beispiel #15
0
    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
Beispiel #16
0
    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)
Beispiel #17
0
    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()