Example #1
0
File: ops.py Project: arnabd88/hwt
    def as_hdl_Operator(self, op: Operator):
        ops = op.operands
        o = op.operator

        if o == AllOps.TERNARY:
            zero, one = BIT.from_py(0), BIT.from_py(1)
            if ops[1] == one and ops[2] == zero:
                # ignore redundant x ? 1 : 0
                return self.as_hdl_cond(ops[0], True)
            else:
                op0 = self.as_hdl_cond(ops[0], True)
                op1 = self.as_hdl_operand(ops[1], 1, op)
                op2 = self.as_hdl_operand(ops[2], 2, op)
                return HdlOp(HdlOpType.TERNARY, [op0, op1, op2])
        elif o == AllOps.RISING_EDGE or o == AllOps.FALLING_EDGE:
            raise UnsupportedEventOpErr()
        elif o in [AllOps.BitsAsUnsigned, AllOps.BitsAsVec, AllOps.BitsAsSigned]:
            op0, = ops
            do_cast = bool(op0._dtype.signed) != bool(op.result._dtype.signed)

            op_hdl = self.as_hdl_operand(op0, 0, op)
            if do_cast:
                if bool(op0._dtype.signed):
                    cast = self.SIGNED
                else:
                    cast = self.UNSIGNED
                return hdl_call(cast, [op_hdl, ])
            else:
                return op_hdl
        else:
            _o = self.op_transl_dict[o]
            return HdlOp(_o, [self.as_hdl_operand(o2, i, op)
                              for i, o2 in enumerate(ops)])
Example #2
0
    def as_hdl_HdlType_bits(self, typ: Bits, declaration=False):
        if declaration:
            raise NotImplementedError()
        if typ == BOOL:
            return self.BOOLEAN
        if typ == INT:
            return self.INTEGER

        bitLength = typ.bit_length()
        w = typ.bit_length()
        isVector = typ.force_vector or bitLength > 1

        if typ.signed is None:
            if isVector:
                name = self.STD_LOGIC_VECTOR
            else:
                return self.STD_LOGIC
        elif typ.signed:
            name = self.SIGNED
        else:
            name = self.UNSIGNED

        return HdlOp(HdlOpType.CALL, [
            name,
            HdlOp(HdlOpType.DOWNTO, [
                self.as_hdl(w - 1),
                self.as_hdl_int(0)
            ])])
Example #3
0
    def as_hdl_Operator(self, op: Operator):
        ops = op.operands
        o = op.operator

        with ValueWidthRequirementScope(self, o == AllOps.CONCAT):
            if o in self._cast_ops:
                op0 = hdl_getattr(self.as_hdl(ops[0]), "_reinterpret_cast")
                op1 = self.as_hdl_HdlType(op.result._dtype)
                return hdl_call(op0, [
                    op1,
                ])
            elif o == AllOps.EQ:
                return hdl_call(hdl_getattr(self.as_hdl(ops[0]), "_eq"),
                                [self.as_hdl(ops[1])])
            elif o == AllOps.CONCAT:
                return hdl_call(self.CONCAT, [self.as_hdl(o2) for o2 in ops])
            elif o == AllOps.TERNARY:
                cond, op0, op1 = ops
                cond = self.visit_iHdlObj(cond)
                with ValueWidthRequirementScope(self, True):
                    op0 = self.as_hdl(op0)
                    op1 = self.as_hdl(op1)
                return HdlOp(o, [cond, op0, op1])
            else:
                o = self.op_transl_dict[o]
                return HdlOp(o, [self.as_hdl(o2) for o2 in ops])
Example #4
0
    def as_hdl_IfContainer(self, ifc: IfContainer) -> HdlStmIf:
        """
        .. code-block:: python

            if cond:
                ...
            else:
                ...

        will become

        .. code-block:: python

            c, cVld = sim_eval_cond(cond)
            if not cVld:
                # ivalidate outputs
            elif c:
                ... # original if true branch
            else:
                ... # original if else brach
        """
        invalidate_block = self.as_hdl_IfContainer_out_invalidate_section(
            ifc._outputs, ifc)
        c, cVld, cond_eval = self.as_hdl_IfContainer_cond_eval(ifc.cond)
        _if = HdlStmIf()
        res = HdlStmBlock()
        res.body = [cond_eval, _if]

        _if.cond = HdlOp(HdlOpType.NEG_LOG, [
            cVld,
        ])
        _if.if_true = invalidate_block

        if_true = self.as_hdl_statements(ifc.ifTrue)
        _if.elifs.append((c, if_true))
        elifs = iter(ifc.elIfs)
        for eif_c, eif_stms in elifs:
            c, cVld, cond_eval = self.as_hdl_IfContainer_cond_eval(eif_c)
            newIf = HdlStmIf()
            newIf.cond = HdlOp(HdlOpType.NEG_LOG, [
                cVld,
            ])
            newIf.if_true = invalidate_block

            if_true = self.as_hdl_statements(eif_stms)
            newIf.elifs.append((c, if_true))

            _if.if_false = HdlStmBlock()
            _if.if_false.body = [cond_eval, newIf]
            _if = newIf

        _if.if_false = self.as_hdl_statements(ifc.ifFalse)

        return res
Example #5
0
    def sensitivityListItem(self, item, anyIsEventDependent):
        if isinstance(item, Operator):
            return HdlOp(HWT_TO_HDLCONVEROTR_OPS[item.operator], [
                self.as_hdl(item.operands[0]),
            ])
        elif anyIsEventDependent:
            if item._dtype.negated:
                op = HdlOpType.FALLING
            else:
                op = HdlOpType.RISING
            return HdlOp(op, [
                self.as_hdl(item),
            ])

        return self.as_hdl(item)
Example #6
0
File: ops.py Project: klopstock/hwt
    def as_hdl_Operator(self, op: Operator):
        ops = op.operands
        o = op.operator

        if o == AllOps.INDEX:
            op0, op1 = ops
            if isinstance(op0, RtlSignalBase) and isResultOfTypeConversion(op0):
                op0 = self.createTmpVarFn("tmpTypeConv_", op0._dtype)
                op0.def_val = ops[0]

            # if the op0 is not signal or other index index operator it is extracted
            # as tmp variable
            op0 = self.as_hdl_operand(op0)
            _op1 = self.as_hdl_operand(ops[1])

            if isinstance(op1._dtype, Bits) and op1._dtype != INT:
                sig = op1._dtype.signed
                if sig is None:
                    _op1 = self.apply_cast("UNSIGNED", _op1)
                _op1 = self.apply_cast("TO_INTEGER", _op1)

            return HdlOp(HdlOpType.INDEX, [op0, _op1])
        elif o == AllOps.TERNARY:
            op0 = self.as_hdl_cond(ops[0], True)
            op1 = self.as_hdl_operand(ops[1])
            op2 = self.as_hdl_operand(ops[2])
            return HdlOp(HdlOpType.TERNARY, [op0, op1, op2])
        else:
            _o = self._cast_ops.get(o, None)
            if _o is not None:
                op0 = ops[0]
                op0 = self._as_Bits_vec(op0)
                if isinstance(op0, RtlSignalBase) and op0.hidden:
                    op0 = self.createTmpVarFn("tmpTypeConv_", op0._dtype)
                    op0.def_val = ops[0]
                return self.apply_cast(_o, self.as_hdl_operand(op0))
            o = self.op_transl_dict[o]
            if len(ops) == 2:
                res_t = op.result._dtype
                op0, op1 = ops
                if isinstance(res_t, Bits) and res_t != BOOL:
                    op0 = self._as_Bits(op0)
                    op1 = self._as_Bits(op1)
                op0 = self.as_hdl_operand(op0)
                op1 = self.as_hdl_operand(op1)
                return HdlOp(o, [op0, op1])
            return HdlOp(o, [self.as_hdl_operand(o2)
                             for o2 in ops])
Example #7
0
def hdl_getattr(o, prop_name):
    """
    :type o: iHdlExpr
    :type prop_name: str
    :return: HdlOp
    """
    return HdlOp(HdlOpType.DOT, [o, HdlValueId(prop_name)])
Example #8
0
 def as_hdl_HdlType_array(self, typ: HArray, declaration=False):
     if declaration:
         raise NotImplementedError()
     else:
         _int = self.as_hdl_int
         size = HdlOp(HdlOpType.DOWNTO, [_int(0), _int(int(typ.size) - 1)])
         return hdl_index(self.as_hdl_HdlType(typ.element_t), size)
Example #9
0
    def as_hdl_Operator(self, op: Operator):
        ops = op.operands
        o = op.operator

        if o == AllOps.INDEX:
            assert len(ops) == 2
            o0, o1 = ops
            if o1._dtype == SLICE:
                # index to .range(x, y)
                o0_hdl = self.as_hdl_operand(o0, 0, op)
                o0_hdl = hdl_getattr(o0_hdl, "range")
                return hdl_call(o0_hdl, [self.as_hdl_Value(o1.val.start),
                                         self.as_hdl_Value(o1.val.stop)])
            else:
                return ToHdlAstVerilog_ops.as_hdl_Operator(self, op)
        elif o in ToHdlAstHwt_ops._cast_ops:
            assert len(ops) == 1, ops
            t = self.as_hdl_HdlType(op.result._dtype)
            return hdl_call(
                HdlOp(HdlOpType.PARAMETRIZATION, [self.static_cast, t]),
                [self.as_hdl_Value(ops[0]), ])
        elif o == AllOps.CONCAT:
            isNew, o = self.tmpVars.create_var_cached("tmpConcat_",
                                                      op.result._dtype,
                                                      postponed_init=True,
                                                      extra_args=(AllOps.CONCAT, op.result))
            if isNew:
                o.drivers.append(Assignment(op, o, virtual_only=True))
                self.tmpVars.finish_var_init(o)

            return self.as_hdl(o)
        else:
            return ToHdlAstVerilog_ops.as_hdl_Operator(self, op)
Example #10
0
    def as_hdl_HdlPortItem(self, o: HdlPortItem):
        i = o.getInternSig()._interface
        d = o.direction
        if isinstance(i, Clk):
            assert i._dtype.bit_length() == 1, i
            if d == DIRECTION.IN:
                t = self.sc_in_clk
            elif d == DIRECTION.OUT:
                t = self.sc_out_clk
            elif d == DIRECTION.INOUT:
                t = self.sc_inout_clk
            else:
                raise ValueError(d)
        else:
            if d == DIRECTION.IN:
                pt = self.sc_in
            elif d == DIRECTION.OUT:
                pt = self.sc_out
            elif d == DIRECTION.INOUT:
                pt = self.sc_inout
            else:
                raise ValueError(d)
            t = self.as_hdl_HdlType(o._dtype)
            t = HdlOp(HdlOpType.PARAMETRIZATION, [pt, t])

        var = HdlIdDef()
        var.direction = HWT_TO_HDLCONVEROTR_DIRECTION[o.direction]
        s = o.getInternSig()
        var.name = s.name
        var.origin = o
        var.type = t
        return var
Example #11
0
    def as_hdl_HdlType_bits(self, typ: Bits, declaration=False):
        isVector = typ.force_vector or typ.bit_length() > 1
        sigType = self.signalType

        if typ == INT:
            t = HdlValueId("int", obj=int)
        elif sigType is SIGNAL_TYPE.PORT_WIRE:
            t = HdlTypeAuto
        elif sigType is SIGNAL_TYPE.REG or sigType is SIGNAL_TYPE.PORT_REG:
            t = HdlValueId("reg", obj=LanguageKeyword())
        elif sigType is SIGNAL_TYPE.WIRE:
            t = HdlValueId("wire", obj=LanguageKeyword())
        else:
            raise ValueError(sigType)

        if typ.signed is None:
            is_signed = None
        else:
            is_signed = self.as_hdl_int(int(typ.signed))

        if isVector:
            w = typ.bit_length()
            assert isinstance(w, int) or (isinstance(w, RtlSignal)
                                          and w._const), w
            w = hdl_downto(self.as_hdl(w - 1), self.as_hdl_int(0))
        else:
            w = None

        return HdlOp(HdlOpType.PARAMETRIZATION, [t, w, is_signed])
Example #12
0
def hdl_index(o, i):
    """
    :type o: iHdlExpr
    :type args: List[iHdlExpr]
    :return: HdlOp
    """
    return HdlOp(HdlOpType.INDEX, [o, i])
Example #13
0
def hdl_map_asoc(o1, o2):
    """
    :type o1: iHdlExpr
    :type o2: iHdlExpr
    :return: HdlOp
    """
    return HdlOp(HdlOpType.MAP_ASSOCIATION, [o1, o2])
Example #14
0
    def as_hdl_Operator(self, op: Operator):
        ops = op.operands
        o = op.operator

        if o == AllOps.EQ:
            op0 = self.as_hdl_Value(ops[0])
            op1 = self.as_hdl_Value(ops[1])
            return hdl_call(hdl_getattr(op0, "_eq"), [
                op1,
            ])
        elif o == AllOps.TERNARY:
            zero, one = BIT.from_py(0), BIT.from_py(1)
            if ops[1] == one and ops[2] == zero:
                # ignore redundant x ? 1 : 0
                return self.as_hdl_cond(ops[0], True)
            else:
                op0 = self.as_hdl_cond(ops[0], True)
                op1 = self.as_hdl_Value(ops[1])
                op2 = self.as_hdl_Value(ops[2])
                return hdl_call(hdl_getattr(op0, "_ternary"), [op1, op2])
        elif o == AllOps.RISING_EDGE or o == AllOps.FALLING_EDGE:
            if o == AllOps.RISING_EDGE:
                fn = "_onRisingEdge"
            else:
                fn = "_onFallingEdge"
            op0 = self.as_hdl_Value(ops[0])
            # pop .val
            op0 = op0.ops[0]
            return hdl_call(hdl_getattr(op0, fn), [])
        elif o in [
                AllOps.BitsAsUnsigned, AllOps.BitsAsVec, AllOps.BitsAsSigned
        ]:
            op0, = ops
            do_cast = bool(op0._dtype.signed) != bool(op.result._dtype.signed)

            op_hdl = self.as_hdl_Value(op0)
            if do_cast:
                if bool(op0._dtype.signed):
                    sign = self.TRUE
                else:
                    sign = self.FALSE
                    # cast_sign()
                return hdl_call(hdl_getattr(op_hdl, "cast_sign"), [
                    sign,
                ])
            else:
                return op_hdl
        elif o == AllOps.CONCAT:
            return hdl_call(hdl_getattr(self.as_hdl_Value(ops[0]), "_concat"),
                            [
                                self.as_hdl_Value(ops[1]),
                            ])
        elif o == AllOps.EQ:
            return hdl_call(hdl_getattr(self.as_hdl_Value(ops[0]), "_eq"), [
                self.as_hdl_Value(ops[1]),
            ])
        else:
            o = self.op_transl_dict[o]
            return HdlOp(o, [self.as_hdl_Value(o2) for o2 in ops])
Example #15
0
def hdl_name_prefix(prefix_name, o):
    """
    :type o: HdlValueId
    :type prefix_name: iHdlExpr
    :return: HdlOp
    """
    assert isinstance(o, HdlValueId), o
    return HdlOp(HdlOpType.DOT, [prefix_name, o])
Example #16
0
class ToHdlAstSystemC_type():
    sc_int = HdlValueId("sc_int", obj=LanguageKeyword())
    sc_uint = HdlValueId("sc_uint", obj=LanguageKeyword())
    sc_bigint = HdlValueId("sc_bigint", obj=LanguageKeyword())
    sc_biguint = HdlValueId("sc_biguint", obj=LanguageKeyword())
    sc_signal = HdlValueId("sc_signal", obj=LanguageKeyword())
    STRING = HdlOp(HdlOpType.DOUBLE_COLON,
                   HdlValueId("string", obj=LanguageKeyword()))

    def does_type_requires_extra_def(self, t, other_types):
        try:
            return t._as_hdl_requires_def(self, other_types)
        except MethodNotOverloaded:
            pass
        return False

    def as_hdl_HdlType_str(self, typ, declaration=False):
        assert not declaration
        return self.STRING

    def as_hdl_HdlType_bits(self, typ: Bits, declaration=False):
        if declaration:
            raise NotImplementedError()

        w = typ.bit_length()

        if w <= 64:
            if typ.signed:
                typeBaseName = self.sc_int
            else:
                typeBaseName = self.sc_uint
        else:
            if typ.signed:
                typeBaseName = self.sc_bigint
            else:
                typeBaseName = self.sc_biguint

        t = HdlOp(HdlOpType.PARAMETRIZATION,
                  [typeBaseName, self.as_hdl_int(w)])
        if self.signalType == SIGNAL_TYPE.WIRE:
            t = HdlOp(HdlOpType.PARAMETRIZATION, [self.sc_signal, t])
        return t

    def as_hdl_HdlType_array(self, typ: HArray, declaration=False):
        if declaration:
            return super(ToHdlAstSystemC_type,
                         self).as_hdl_HdlType_array(self,
                                                    typ,
                                                    declaration=declaration)
        else:
            _int = self.as_hdl_int
            size = _int(int(typ.size))
            return hdl_index(self.as_hdl_HdlType(typ.element_t), size)

    def as_hdl_HdlType_enum(self, typ: HEnum, declaration=False):
        return ToHdlAstVerilog_types.as_hdl_HdlType_enum(
            self, typ, declaration=declaration)
Example #17
0
def hdl_call(o, args):
    """
    :type o: iHdlExpr
    :type args: List[iHdlExpr]
    :return: HdlOp
    """
    return HdlOp(HdlOpType.CALL, [
        o,
    ] + args)
Example #18
0
def hdl_or(*args):
    first = True
    res = None
    for o in args:
        if first:
            res = o
            first = False
        else:
            res = HdlOp(HdlOpType.OR, [res, o])
    assert res is not None
    return res
Example #19
0
 def as_hdl_SliceVal(self, val: SliceVal):
     if val._is_full_valid():
         return HdlOp(HdlOpType.DOWNTO, [
             HdlValueInt(int(val.val.start), None, None),
             HdlValueInt(int(val.val.stop), None, None)
         ])
     else:
         raise NotImplementedError()
         return "SliceVal(slice(%s, %s, %s), SLICE, %d)" % (
             self.as_hdl_Value(val.val.start),
             self.as_hdl_Value(val.val.stop), self.as_hdl_Value(
                 val.val.step), val.vld_mask)
Example #20
0
    def sensitivityListItem(self, item, anyEventDependent):
        if isinstance(item, Operator):
            op = item.operator
            if op == AllOps.RISING_EDGE:
                sens = HdlOpType.RISING
            elif op == AllOps.FALLING_EDGE:
                sens = HdlOpType.FALLING
            else:
                raise TypeError("This is not an event sensitivity", op)

            return HdlOp(sens, [HdlValueId(item.operands[0].name)])
        else:
            return HdlValueId(item.name)
Example #21
0
    def as_hdl_HdlType_bits(self, typ: Bits, declaration=False):
        if declaration:
            raise NotImplementedError()

        w = typ.bit_length()

        if w <= 64:
            if typ.signed:
                typeBaseName = self.sc_int
            else:
                typeBaseName = self.sc_uint
        else:
            if typ.signed:
                typeBaseName = self.sc_bigint
            else:
                typeBaseName = self.sc_biguint

        t = HdlOp(HdlOpType.PARAMETRIZATION,
                  [typeBaseName, self.as_hdl_int(w)])
        if self.signalType == SIGNAL_TYPE.WIRE:
            t = HdlOp(HdlOpType.PARAMETRIZATION, [self.sc_signal, t])
        return t
Example #22
0
    def array1d_t_to_vhdl(to_hdl: ToHdlAstVhdl2008, declaration=False):
        if not isinstance(to_hdl, ToHdlAstVhdl2008):
            raise NotImplementedError()

        if declaration:
            raise ValueError(
                "_as_hdl_requires_def specifies that this should not be required"
            )
        # "mem(0 to %d)(%d downto 0)" % (t.size, t.element_t.bit_length() - 1)
        _int = to_hdl.as_hdl_int
        size = HdlOp(HdlOpType.TO, [_int(0), _int(int(array1d_t.size))])
        e_width = hdl_downto(_int(array1d_t.element_t.bit_length() - 1),
                             _int(0))
        return hdl_index(hdl_index(HdlValueId("mem"), size), e_width)
Example #23
0
    def as_hdl_operand(self, operand: Union[RtlSignal, HValue], i: int,
                       operator: Operator):

        # [TODO] if operand is concatenation and parent operator
        #        is not concatenation operand should be extracted
        #        as tmp variable
        #        * maybe flatten the concatenations
        if operator.operator != AllOps.CONCAT\
                and self._operandIsAnotherOperand(operand)\
                and operand.origin.operator == AllOps.CONCAT:
            _, tmpVar = self.tmpVars.create_var_cached("tmp_concat_",
                                                       operand._dtype,
                                                       def_val=operand)
            # Assignment(tmpVar, operand, virtual_only=True)
            operand = tmpVar

        oper = operator.operator
        width = None
        if not isinstance(operand, RtlSignal) and operand._dtype == INT and\
           oper not in [AllOps.BitsAsUnsigned,
                        AllOps.BitsAsVec,
                        AllOps.BitsAsSigned,
                        AllOps.INDEX] and\
                operator.result is not None and\
                not operator.result._dtype == INT:
            # have to lock the width
            for o in operator.operands:
                try:
                    bl = o._dtype.bit_length
                except AttributeError:
                    bl = None
                if bl is not None:
                    width = bl()
                    break

            assert width is not None, (operator, operand)
        hdl_op = self.as_hdl_Value(operand)
        if width is not None:
            if isinstance(hdl_op, HdlValueInt):
                assert isinstance(width, int), width
                hdl_op.bits = width
            else:
                return HdlOp(HdlOpType.APOSTROPHE,
                             [self.as_hdl_int(width), hdl_op])
        return hdl_op
Example #24
0
def hdl_add_int(a, b):
    """
    :type a: iHdlExpr
    :type b: int
    :return: iHdlExpr
    """
    if b == 0:
        return a
    elif isinstance(a, HdlValueInt):
        return HdlValueInt(int(a.val) + b, a.val, a.base)
    elif isinstance(a, HdlOp) and a.fn == HdlOpType.ADD:
        o0, o1 = a.ops
        if isinstance(o1, HdlValueInt):
            return hdl_add_int(o0, int(o1) + b)
    elif isinstance(a, HdlOp) and a.fn == HdlOpType.SUB:
        o0, o1 = a.ops
        if isinstance(o1, HdlValueInt):
            return hdl_sub_int(o0, int(o1) - b)

    return HdlOp(HdlOpType.ADD, [a, HdlValueInt(b, None, None)])
Example #25
0
def hdl_downto(msb, lsb):
    return HdlOp(HdlOpType.DOWNTO, [msb, lsb])