Example #1
0
    def visit_Compare(self, node):
        left = self.visit(node.left)
        methods = [getMethodName(op) for op in node.ops]
        ops = [getVeriloggenOp(op) for op in node.ops]
        comparators = [self.visit(comp) for comp in node.comparators]

        rslts = []
        for i, (method, op) in enumerate(zip(methods, ops)):
            if i == 0:
                try:
                    rslts.append(applyMethod(left, method, comparators[i]))
                except NotImplementedError:
                    rslts.append(op(left, comparators[i]))
            else:
                try:
                    rslts.append(
                        applyMethod(comparators[i - 1], method,
                                    comparators[i]))
                except NotImplementedError:
                    rslts.append(op(comparators[i - 1], comparators[i]))

        if len(rslts) == 1:
            return rslts[0]

        ret = None
        for r in rslts:
            if ret:
                ret = vtypes.Land(ret, r)
            else:
                ret = r
        return ret
Example #2
0
    def visit_Compare(self, node):
        left = self.visit(node.left)
        methods = [getMethodName(op) for op in node.ops]
        ops = [getVeriloggenOp(op) for op in node.ops]
        comparators = [self.visit(comp) for comp in node.comparators]

        rslts = []
        for i, (method, op) in enumerate(zip(methods, ops)):
            if i == 0:
                if (not isinstance(left, fxd._FixedBase)
                        and isinstance(comparators[i], fxd._FixedBase)):
                    raise TypeError(
                        "type mismatch of operator arguments: '%s' and '%s'" %
                        (str(type(left)), str(type(comparators[i]))))

                try:
                    rslts.append(applyMethod(left, method, comparators[i]))
                except NotImplementedError:
                    rslts.append(op(left, comparators[i]))
            else:
                if (not isinstance(comparators[i - 1], fxd._FixedBase)
                        and isinstance(comparators[i], fxd._FixedBase)):
                    raise TypeError(
                        "type mismatch of operator arguments: '%s' and '%s'" %
                        (str(type(
                            comparators[i - 1])), str(type(comparators[i]))))

                try:
                    rslts.append(
                        applyMethod(comparators[i - 1], method,
                                    comparators[i]))
                except NotImplementedError:
                    rslts.append(op(comparators[i - 1], comparators[i]))

        if len(rslts) == 1:
            return rslts[0]

        ret = None
        for r in rslts:
            if ret:
                ret = vtypes.Land(ret, r)
            else:
                ret = r
        return ret
Example #3
0
 def visit_Compare(self, node):
     left = self.visit(node.left)
     ops = [getVeriloggenOp(op) for op in node.ops]
     comparators = [self.visit(comp) for comp in node.comparators]
     rslts = []
     for i, op in enumerate(ops):
         if i == 0:
             rslts.append(op(left, comparators[i]))
         else:
             rslts.append(op(comparators[i - 1], comparators[i]))
     if len(rslts) == 1:
         return rslts[0]
     ret = None
     for r in rslts:
         if ret:
             ret = vtypes.Land(ret, r)
         else:
             ret = r
     return ret
Example #4
0
    def reset(self, fsm, tid):
        """ reset the FSM counter to the initial state """

        for thread in self.threads:
            if thread.end_state is None:
                raise ValueError('thread %d not started' % thread.tid)

        for thread in self.threads:
            reset_flag = vtypes.Land((fsm.state == fsm.current),
                                     (tid == thread.tid))

            thread.fsm._set_index(thread.end_state)

            if thread.called is not None:
                thread.fsm.If(reset_flag)(thread.called(0))

            thread.fsm.goto_from(thread.end_state, thread.start_state,
                                 reset_flag)
            thread._set_index(thread.start_state)

        return 0
Example #5
0
 def visit_Land(self, node):
     left = self.visit(node.left)
     right = self.visit(node.right)
     return vtypes.Land(left, right)
Example #6
0
    def _synthesize_run_fsm(self, parent_fsm, args, kwargs, cond=None):
        start_flag = (parent_fsm.state == parent_fsm.current)

        if self.called is None:
            self.called = self.m.Reg('_'.join(['', self.name, 'called']),
                                     initval=0)

        if cond is not None:
            self.fsm.If(cond)

        self.fsm.If(start_flag)(self.called(1))

        functions = self._get_functions()

        cvisitor = compiler.CompileVisitor(self.m,
                                           self.name,
                                           self.clk,
                                           self.rst,
                                           self.fsm,
                                           functions,
                                           self.intrinsic_functions,
                                           self.intrinsic_methods,
                                           self.start_frame,
                                           datawidth=self.datawidth)

        text = textwrap.dedent(inspect.getsource(self.targ))
        tree = ast.parse(text).body[0]

        # stack a new scope frame
        cvisitor.pushScope(ftype='call')

        used_args = []

        # args
        args_code = []
        for pos, arginfo in enumerate(tree.args.args):
            argname = (
                arginfo.id if isinstance(arginfo, ast.Name)  # python 2
                else arginfo.arg)  # python 3

            # actual values can be assigned later in default value section
            args_code.append(argname)

            # regular args
            if pos < len(args):
                arg = args[pos]
                used_args.append(argname)

                if isinstance(arg, vtypes.numerical_types):  # pass by value
                    if argname not in self.args_dict:
                        name = compiler._tmp_name('_'.join(
                            ['', self.name, argname]))
                        v = self.m.Reg(name,
                                       self.datawidth,
                                       initval=0,
                                       signed=True)
                        cvisitor.scope.addVariable(argname, v)
                        self.args_dict[argname] = v
                    else:
                        v = self.args_dict[argname]

                    # binding
                    if cond is not None:
                        self.fsm.If(cond)

                    self.fsm.If(start_flag)(v(arg))

                else:  # pass by reference
                    if argname not in self.args_dict:
                        cvisitor.scope.addVariable(argname, arg)
                        self.args_dict[argname] = arg
                    elif id(self.args_dict[argname]) == id(arg):
                        pass
                    else:
                        raise ValueError(
                            'same object must be passed for non-numeric argument'
                        )

        # variable length args
        if tree.args.vararg is None and len(args) > len(tree.args.args):
            raise TypeError('takes %d positional arguments but %d were given' %
                            (len(tree.args.args), len(args)))

        if tree.args.vararg is not None and not self.vararg_set:
            baseobj = tree.args.vararg
            varargname = (
                baseobj.id if isinstance(baseobj, ast.Name)  # python 2
                else baseobj.arg)  # python 3
            cvisitor.scope.addVariable(varargname, self.vararg_regs)

        if len(args) > len(tree.args.args):
            used_args.append(varargname)
            raise ValueError(
                'variable length argument is not supported in dynamic thread execution'
            )

            #num_vararg_vars = len(args) - len(tree.args.args)
            # if num_vararg_vars > len(self.vararg_regs):
            #    for i in range(num_vararg_vars - len(self.vararg_regs)):
            #        name = compiler._tmp_name('_'.join(['', self.name, varargname]))
            #        v = self.m.Reg(name, self.datawidth, initval=0, signed=True)
            #        self.vararg_regs.append(v)
            #        args_code.append(varargname)
            # for i, arg in enumerate(args[-num_vararg_vars:]):
            #    if not isinstance(arg, vtypes.numerical_types):
            #        raise TypeError('variable length argument support no non-numeric values')
            #    v = self.vararg_regs[i]
            #    # binding
            #    if cond is not None:
            #        self.fsm.If(cond)
            #    self.fsm.If(start_flag)(
            #        v(arg)
            #    )

        # kwargs
        kwargs_code = []
        for argname, arg in sorted(kwargs.items(), key=lambda x: x[0]):
            if argname in used_args:
                raise TypeError("got multiple values for argument '%s'" %
                                argname)

            used_args.append(argname)

            if isinstance(arg, vtypes.numerical_types):  # pass by value
                if argname not in self.args_dict:
                    name = compiler._tmp_name('_'.join(
                        ['', self.name, argname]))
                    v = self.m.Reg(name,
                                   self.datawidth,
                                   initval=0,
                                   signed=True)
                    cvisitor.scope.addVariable(argname, v)
                    self.args_dict[argname] = v
                else:
                    v = self.args_dict[argname]

                # binding
                if cond is not None:
                    self.fsm.If(cond)

                self.fsm.If(start_flag)(v(arg))

            else:  # pass by reference
                if argname not in self.args_dict:
                    cvisitor.scope.addVariable(argname, arg)
                    self.args_dict[argname] = arg
                elif id(self.args_dict[argname]) == id(arg):
                    pass
                else:
                    raise ValueError(
                        'same object must be passed for non-numeric argument')

            kwargs_code.append('{}={}'.format(key, key))

        # defaults
        defaults_size = len(tree.args.defaults)
        if defaults_size > 0:
            for arg, val in zip(tree.args.args[-defaults_size:],
                                tree.args.defaults):
                argname = (
                    arg.id if isinstance(arg, ast.Name)  # python 2
                    else arg.arg)  # python 3

                if argname not in self.args_dict:
                    name = compiler._tmp_name('_'.join(
                        ['', self.name, argname]))
                    v = self.m.Reg(name,
                                   self.datawidth,
                                   initval=0,
                                   signed=True)
                    cvisitor.scope.addVariable(argname, v)
                    self.args_dict[argname] = v
                else:
                    v = self.args_dict[argname]

                if argname not in used_args:
                    right = cvisitor.visit(val)

                    # binding
                    if cond is not None:
                        self.fsm.If(cond)

                    self.fsm.If(start_flag)(v(right))

        c = start_flag
        if cond is not None:
            c = vtypes.Land(c, cond)

        self.fsm.goto_from(self.start_state, self.start_state + 1, c)
        self.fsm._set_index(self.start_state + 1)

        parent_fsm.goto_next()

        # if already synthesized
        if self.end_state is not None:
            return self.return_value

        # call AST
        args_text = ', '.join(args_code + kwargs_code)
        call_code = ''.join([self.targ.__name__, '(', args_text, ')'])
        _call_ast = ast.parse(call_code)

        # start visit
        self.return_value = cvisitor.visit(_call_ast.body[0].value)

        # clean-up jump conditions
        cvisitor.clearBreak()
        cvisitor.clearContinue()
        cvisitor.clearReturn()
        cvisitor.clearReturnVariable()

        # return to the previous scope frame
        cvisitor.popScope()

        return self.return_value