Esempio n. 1
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])
Esempio n. 2
0
class ToHdlAstHwt(ToHdlAstHwt_value, ToHdlAstHwt_ops, ToHdlAstHwt_types,
                  ToHdlAst):
    """
    Serializer which converts Hwt objects back to Hwt code
    for debugging purposes/code ports

    :ivar ~._valueWidthRequired: flag which tells if the values are required to have
        the width specified
    """
    _keywords_dict = {kw: LanguageKeyword() for kw in HWT_KEYWORDS}

    def __init__(self, name_scope: Optional[NameScope] = None):
        super(ToHdlAstHwt, self).__init__(name_scope=name_scope)
        self._valueWidthRequired = False
        self.currentUnit = None
        self.debug = False

    def has_to_be_process(self, proc):
        return True

    def can_pop_process_wrap(self, statements, hasToBeVhdlProcess):
        return False

    def _as_hdl_HdlModuleDef(self, new_m: HdlModuleDef) -> HdlModuleDef:
        return ToHdlAstSimModel._as_hdl_HdlModuleDef(self, new_m)

    def sensitivityListItem(self, item, anyIsEventDependnt):
        if isinstance(item, Operator):
            op = item.operator
            assert op in (AllOps.RISING_EDGE, AllOps.FALLING_EDGE), item
            assert not item.operands[0].hidden, item
            return self.as_hdl_Operator(item)
        else:
            return HdlValueId(item.name, obj=item)
Esempio n. 3
0
class ToHdlAstHwt_ops():
    CONCAT = HdlValueId("Concat", obj=LanguageKeyword())
    op_transl_dict = ToHdlAstSimModel_value.op_transl_dict
    _cast_ops = ToHdlAstSimModel_value._cast_ops

    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.as_hdl(cond)
                with ValueWidthRequirementScope(self, True):
                    op0 = self.as_hdl(op0)
                    op1 = self.as_hdl(op1)
                return hdl_call(hdl_getattr(cond, "_ternary"), [op0, op1])
            else:
                o = self.op_transl_dict[o]
                return HdlOp(o, [self.as_hdl(o2) for o2 in ops])
Esempio n. 4
0
class ToHdlAstVhdl2008_types():
    BOOLEAN = HdlValueId("BOOLEAN", obj=LanguageKeyword())
    INTEGER = HdlValueId("INTEGER", obj=LanguageKeyword())
    STRING = HdlValueId("STRING", obj=LanguageKeyword())
    STD_LOGIC_VECTOR = HdlValueId("STD_LOGIC_VECTOR", obj=LanguageKeyword())
    STD_LOGIC = HdlValueId("STD_LOGIC", obj=LanguageKeyword())
    SIGNED = HdlValueId("SIGNED", obj=LanguageKeyword())
    UNSIGNED = HdlValueId("UNSIGNED", obj=LanguageKeyword())

    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()
        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)])
        ])

    def as_hdl_HdlType_array(self, typ: HArray, declaration=False):
        if declaration:
            v = HdlIdDef()
            name = getattr(typ, "name", None)
            if name is None:
                name = "arr_t_"
            v.name = self.name_scope.checked_name(name, typ)
            v.type = HdlTypeType
            v.origin = typ
            size = hdl_downto(self.as_hdl_int(int(typ.size) - 1),
                              self.as_hdl_int(0))
            if self.does_type_requires_extra_def(typ.element_t, ()):
                raise NotImplementedError(typ.element_t)
            e_t = self.as_hdl_HdlType(typ.element_t, declaration=False)
            v.value = hdl_index(e_t, size)
            return v
        else:
            return super(ToHdlAstVhdl2008_types,
                         self).as_hdl_HdlType_array(typ, declaration)
Esempio n. 5
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)
Esempio n. 6
0
class ToHdlAstVhdl2008(ToHdlAstVhdl2008_Value, ToHdlAstVhdl2008_ops,
                       ToHdlAstVhdl2008_types, ToHdlAstVhdl2008_statements,
                       ToHdlAst):
    """
    :ivar ~.name_scope: name scope used to generate a unique names for tmp variables
        (all object should be registered in namescope before serialization)
    """
    _keywords_dict = {kw: LanguageKeyword() for kw in VHLD2008_KEYWORDS}

    DEFAULT_IMPORTS = [
        HdlLibrary("IEEE"),
        HdlImport([IEEE, std_logic_1164, HdlAll]),
        HdlImport([IEEE, numeric_std, HdlAll]),
    ]

    @classmethod
    def getBaseNameScope(cls):
        s = VhdlNameScope.make_top(True)
        s.update(cls._keywords_dict)
        return s

    def as_hdl_HdlModuleDef(self, o: HdlModuleDef):
        """
        Translate hwt types and expressions to HDL AST and add explicit components
        """
        _o = super(ToHdlAstVhdl2008, self).as_hdl_HdlModuleDef(o)
        component_insts = []
        for c in _o.objs:
            if isinstance(c, HdlCompInst):
                component_insts.append(c)

        # select comonent instances whith an unique module_name
        components = [
            x[1][0]
            for x in groupedby(component_insts, lambda c: c.module_name)
        ]
        components.sort(key=lambda c: c.module_name)
        components = [self.as_hdl_HldComponent(c) for c in components]
        if components:
            _o.objs = components + _o.objs

        res = HdlContext()
        res.objs.extend(self.DEFAULT_IMPORTS)
        res.objs.append(_o)
        return res

    def as_hdl_HldComponent(self, o: HdlCompInst):
        c = self.as_hdl_HdlModuleDec(o.origin._ctx.ent)
        return c
Esempio n. 7
0
def BitsT(width, is_signed=False, bits_cls_name="Bits3t"):
    """
    Create an AST expression of Bits type constructor
    (reg/std_logic_vector equivalent for BasicHdlSimModel)

    :type width: iHdlExpr
    """
    width = verilog_slice_to_width(width)

    if isinstance(width, int):
        width = HdlValueInt(width, None, None)

    c = HdlOp(HdlOpType.CALL, [
        HdlValueId(bits_cls_name, obj=LanguageKeyword()), width,
        NONE if is_signed is None else HdlValueInt(int(is_signed), None, None)
    ])
    return c
Esempio n. 8
0
class ToHdlAstSimModel_types():
    """
    part of ToHdlAstSimModel responsible for type serialization
    """
    SELF = HdlValueId("self", obj=LanguageKeyword())
    BITS3T = HdlValueId("Bits3t", obj=Bits3t)
    SLICE = HdlValueId("slice", obj=slice)

    def as_hdl_HdlType_bits(self, typ: Bits, declaration=False):
        assert not declaration
        w = typ.bit_length()
        if isinstance(w, int):
            pass
        else:
            w = int(w)

        return hdl_call(self.BITS3T, [
            HdlValueInt(w, None, None),
            HdlValueInt(int(bool(typ.signed)), None, None)
        ])

    def as_hdl_HdlType_slice(self, typ: Slice, declaration=False):
        if declaration:
            raise NotImplementedError()
        else:
            return self.SLICE

    def as_hdl_HdlType_array(self, typ, declaration=False):
        if declaration:
            return super(ToHdlAstSimModel_types,
                         self).as_hdl_HdlType_array(typ,
                                                    declaration=declaration)
        else:
            t_name = self.name_scope.get_object_name(typ)
            return hdl_getattr(self.SELF, t_name)

    def as_hdl_HdlType_enum(self, typ, declaration=False):
        if declaration:
            return super(ToHdlAstSimModel_types,
                         self).as_hdl_HdlType_enum(typ, declaration=True)
        else:
            t_name = self.name_scope.get_object_name(typ)
            return hdl_getattr(self.SELF, t_name)
Esempio n. 9
0
def BitsT(width, is_signed=False, bits_cls_name="Bits3t"):
    """
    Create an AST expression of Bits type constructor
    (reg/std_logic_vector equivalent for BasicHdlSimModel)

    :type width: iHdlExpr
    """
    if isinstance(width, HdlOp):
        if width.fn == HdlOpType.DOWNTO:
            high, low = width.ops
            assert int(low) == 0
            width = int(high) + 1
        else:
            raise NotImplementedError(width)
    c = HdlOp(HdlOpType.CALL, [
        HdlValueId(bits_cls_name, obj=LanguageKeyword()),
        HdlValueInt(width, None, None),
        NONE if is_signed is None else HdlValueInt(int(is_signed), None, None)
    ])
    return c
Esempio n. 10
0
def BitsT(width, is_signed=False, bits_cls_name="Bits"):
    """
    Create an AST expression of Bits type constructor
    (reg/std_logic_vector equivalent for hwt)

    :type width: iHdlExpr
    """
    width = verilog_slice_to_width(width)

    if isinstance(width, int):
        width = HdlValueInt(width, None, None)

    args = [
        HdlValueId(bits_cls_name, obj=LanguageKeyword()),
        width,
    ]
    if is_signed is not None:
        args.append(HdlValueInt(int(is_signed), None, None))

    return HdlOp(HdlOpType.CALL, args)
Esempio n. 11
0
    def check_file(self, name, to_hdl_cls):
        """
        Load AST from json and convert it to target language
        and compare it with reference file
        """
        json_suffix, ref_file_suffix = self.FILE_SUFFIX[to_hdl_cls]
        d = parse_hdlConvertor_json_file(os.path.join(ROOT,
                                                      name + json_suffix))

        buff = StringIO()
        ser = to_hdl_cls(buff)
        if to_hdl_cls is ToBasicHdlSimModel:
            # it is required to know outputs of each process
            stm_outputs = discover_stm_outputs_context(d)
            stm_outputs = rm_ToBasicHdlSimModel_io_prefix_and_tmp_vars_from_outputs(
                stm_outputs)
            ser.visit_HdlContext(d, stm_outputs)
        else:
            if to_hdl_cls is ToHwt:
                # it is required to know the direction of port connections
                link_module_dec_def(d)
                name_scope = NameScope.make_top(False)
                for kw in HWT_KEYWORDS:
                    name_scope.register_name(kw, LanguageKeyword())
                DiscoverDeclarations(name_scope).visit_HdlContext(d)
                ResolveNames(name_scope).visit_HdlContext(d)

            ser.visit_HdlContext(d)

        res_str = buff.getvalue()

        ref_file = os.path.join(ROOT, "ref", name + ref_file_suffix)
        # with open(ref_file, "w", encoding="utf-8") as f:
        #     f.write(res_str)

        with open(ref_file, encoding="utf-8") as f:
            ref = f.read()

        self.assertEqual(ref, res_str)
Esempio n. 12
0
class ToHdlAstHwt_ops():
    CONCAT = HdlValueId("Concat", obj=LanguageKeyword())
    op_transl_dict = {
        **HWT_TO_HDLCONVEROTR_OPS,
        AllOps.INDEX: HdlOpType.INDEX,
    }
    _cast_ops = {
        AllOps.BitsAsSigned,
        AllOps.BitsAsUnsigned,
        AllOps.BitsAsVec,
    }

    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])
Esempio n. 13
0
class ToHdlAstVerilog_ops():
    SIGNED = HdlValueId("$signed", obj=LanguageKeyword())
    UNSIGNED = HdlValueId("$unsigned", obj=LanguageKeyword())
    op_transl_dict = {
        **HWT_TO_HDLCONVEROTR_OPS,
        AllOps.INDEX: HdlOpType.INDEX,
    }

    def _operandIsAnotherOperand(self, operand):
        if isinstance(operand, RtlSignal) and operand.hidden\
                and isinstance(operand.origin, Operator):
            return True

    def as_hdl_operand(self, operand: Union[RtlSignal, Value], 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.createTmpVarFn("tmp_concat_", operand._dtype)
            tmpVar.def_val = operand
            # Assignment(tmpVar, operand, virtual_only=True)
            operand = tmpVar

        oper = operator.operator
        width = None
        if 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:
            return HdlOp(HdlOpType.APOSTROPHE,
                         [self.as_hdl_int(width), hdl_op])
        else:
            return hdl_op

    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)])
Esempio n. 14
0
class ToHdlAstVerilog(ToHdlAstVerilog_types, ToHdlAstVerilog_Value,
                      ToHdlAstVerilog_statements, ToHdlAstVerilog_ops,
                      ToHdlAst):
    _keywords_dict = {kw: LanguageKeyword() for kw in IEEE1800_2017_KEYWORDS}

    def __init__(self, name_scope: Optional[NameScope] = None):
        ToHdlAst.__init__(self, name_scope=name_scope)
        self.signalType = SIGNAL_TYPE.PORT_WIRE

    def as_hdl_HdlModuleDef_variable(self, v, types, hdl_types, hdl_variables,
                                     processes, component_insts):
        new_v = copy(v)
        with SignalTypeSwap(self, verilogTypeOfSig(v.origin)):
            t = v.type
            # if type requires extra definition
            if self.does_type_requires_extra_def(t, types):
                _t = self.as_hdl_HdlType(t, declaration=True)
                hdl_types.append(_t)
                types.add(t)
            new_v.type = self.as_hdl_HdlType(t, declaration=False)
            # this is a array variable which requires value intialization in init
            # process
            if isinstance(t, HArray):
                if v.value.vld_mask:
                    rom = v.origin
                    p = HdlStmProcess()
                    label = self.name_scope.checked_name(
                        rom.name + "_rom_init", p)
                    p.labels.append(label)
                    p.body = HdlStmBlock()
                    body = p.body.body
                    for i, _v in enumerate(rom.def_val.val):
                        a = HdlStmAssign(self.as_hdl_int(int(_v)),
                                         self.as_hdl(rom[i]))
                        a.is_blocking = True
                        body.append(a)
                    w = HdlStmWait()
                    w.val = []  # initial process
                    body.append(w)
                    processes.append(p)
                # because we would not be able to initialize const/localparam variable later
                new_v.is_const = False
                new_v.value = None
            elif new_v.value is not None:
                new_v.value = self.as_hdl_Value(new_v.value)
            return new_v

    def as_hdl_GenericItem(self, g: HdlIdDef):
        with SignalTypeSwap(self, SIGNAL_TYPE.PORT_WIRE):
            new_v = copy(g)
            v = g.value
            if v._dtype == STR or v._dtype == INT or v._dtype == BOOL:
                t = HdlTypeAuto
            else:
                t = self.as_hdl_HdlType(v._dtype)
            new_v.type = t
            assert new_v.value is not None, g
            new_v.value = self.as_hdl_Value(v)
            return new_v

    def as_hdl_HdlPortItem(self, pi: HdlPortItem):
        with SignalTypeSwap(self, verilogTypeOfSig(pi)):
            v = super(ToHdlAstVerilog, self).as_hdl_HdlPortItem(pi)
            v.is_latched = self.signalType == SIGNAL_TYPE.PORT_REG
        return v
Esempio n. 15
0
File: ops.py Progetto: klopstock/hwt
 def apply_cast(self, t_name, op):
     return hdl_call(HdlValueId(t_name, obj=LanguageKeyword()),
                     [op, ])
Esempio n. 16
0
class ToHdlAstSimModel_value(ToHdlAst_Value):
    Bits3val = HdlValueId("Bits3val", obj=Bits3val)
    Bits3t = HdlValueId("Bits3t", obj=Bits3t)
    SELF = HdlValueId("self", obj=LanguageKeyword())
    Array3val = HdlValueId("Array3val", obj=Array3val)
    SLICE = HdlValueId("slice", obj=slice)
    TRUE = HdlValueId("True", obj=True)
    FALSE = HdlValueId("False", obj=False)
    Bits3val = HdlValueId("Bits3val", obj=Bits3val)
    ABits3t = HdlValueId("Bits3t", obj=Bits3t)
    SELF_IO = hdl_getattr(HdlValueId("self", obj=LanguageKeyword()), "io")
    CONCAT = HdlValueId("Concat", obj=Concat)
    op_transl_dict = {
        **HWT_TO_HDLCONVEROTR_OPS,
        AllOps.INDEX: HdlOpType.INDEX,
    }
    _cast_ops = {
        AllOps.BitsAsSigned,
        AllOps.BitsAsUnsigned,
        AllOps.BitsAsVec,
    }

    def is_suitable_for_const_extract(self, val: HValue):
        return not isinstance(val._dtype, HEnum) or val.vld_mask == 0

    def as_hdl_SignalItem(self,
                          si: Union[SignalItem, HdlIdDef],
                          declaration=False):
        if not declaration and not si.hidden:
            if si._const:
                return hdl_getattr(self.SELF, si.name)
            else:
                return hdl_getattr(hdl_getattr(self.SELF_IO, si.name), "val")
        else:
            return super(ToHdlAstSimModel_value,
                         self).as_hdl_SignalItem(si, declaration=declaration)

    def as_hdl_BitsVal(self, val: BitsVal):
        dtype = val._dtype
        as_hdl_int = self.as_hdl_int
        t = hdl_call(self.Bits3t, [
            as_hdl_int(dtype.bit_length()),
            as_hdl_int(int(bool(dtype.signed)))
        ])
        return hdl_call(self.Bits3val,
                        [t, as_hdl_int(val.val),
                         as_hdl_int(val.vld_mask)])

    def as_hdl_DictVal(self, val):
        return {
            self.as_hdl_int(int(k)): self.as_hdl_Value(v)
            for k, v in val.items()
        }

    def as_hdl_HArrayVal(self, val):
        return hdl_call(self.Array3val, [
            self.as_hdl_HdlType(val._dtype),
            self.as_hdl_DictVal(val.val),
            self.as_hdl_int(val.vld_mask)
        ])

    def as_hdl_SliceVal(self, val):
        args = (val.val.start, val.val.stop, val.val.step)
        return hdl_call(self.SLICE, [self.as_hdl_int(int(a)) for a in args])

    def as_hdl_HEnumVal(self, val: HEnumVal):
        t_name = self.name_scope.get_object_name(val._dtype)
        if val.vld_mask:
            name = self.name_scope.get_object_name(val)
            return hdl_getattr(hdl_getattr(self.SELF, t_name), name)
        else:
            return hdl_call(
                hdl_getattr(hdl_getattr(self.SELF, t_name), "from_py"), [
                    None,
                ])

    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:
            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 self._cast_ops:
            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(op.result._dtype.signed):
                    sign = self.TRUE
                else:
                    sign = self.FALSE
                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])
Esempio n. 17
0
class ToHdlAstSystemC_expr(ToHdlAst_Value):
    static_cast = HdlValueId("static_cast", obj=LanguageKeyword())
    op_transl_dict = ToHdlAstVerilog_ops.op_transl_dict

    def as_hdl_Value(self, v):
        if isinstance(v, tuple):
            return tuple((self.as_hdl(o2) for o2 in v))
        return super(ToHdlAstSystemC_expr, self).as_hdl_Value(v)

    def as_hdl_operand(self, operand: Union[RtlSignal, HValue], i: int,
                       operator: Operator):
        return self.as_hdl(operand)

    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)

    def as_hdl_SignalItem(self, si: SignalItem, declaration=False):
        if declaration:
            sigType = systemCTypeOfSig(si)
            with SignalTypeSwap(self, sigType):
                return ToHdlAst_Value.as_hdl_SignalItem(self, si, declaration=True)
        else:
            if si.hidden and si.origin is not None:
                return self.as_hdl(si.origin)
            else:
                sigType = systemCTypeOfSig(si)
                _si = HdlValueId(si.name, obj=si)
                if self._in_sensitivity_list or self._is_target or sigType is SIGNAL_TYPE.REG:
                    return _si
                else:
                    return hdl_call(hdl_getattr(_si, "read"), [])

    def as_hdl_BitsVal(self, val):
        t = val._dtype
        w = t.bit_length()
        _v = bit_string(val.val, w, val.vld_mask)
        t = self.as_hdl_HdlType_bits(Bits(w, signed=t.signed))
        return hdl_call(t, [_v, ])

    def as_hdl_HEnumVal(self, val: HEnumVal):
        i = val._dtype._allValues.index(val.val)
        assert i >= 0
        return self.as_hdl_int(i)

    def as_hdl_HArrayVal(self, val):
        return [self.as_hdl_Value(v) for v in val]
Esempio n. 18
0
from hwt.serializer.generic.to_hdl_ast import ToHdlAst
from hwt.serializer.vhdl.ops import ToHdlAstVhdl2008_ops
from hwt.serializer.vhdl.statements import ToHdlAstVhdl2008_statements
from hwt.serializer.vhdl.types import ToHdlAstVhdl2008_types
from hwt.serializer.vhdl.value import ToHdlAstVhdl2008_Value


class VhdlNameScope(NameScope):
    RE_MANY_UNDERSCORES = re.compile(r"(_{2,})")

    def checked_name(self, actualName, actualObj):
        actualName = self.RE_MANY_UNDERSCORES.sub(r"_", actualName)
        return NameScope.checked_name(self, actualName, actualObj)


IEEE = HdlValueId("IEEE", obj=LanguageKeyword())
std_logic_1164 = HdlValueId("std_logic_1164", obj=LanguageKeyword())
numeric_std = HdlValueId("numeric_std", obj=LanguageKeyword())


class ToHdlAstVhdl2008(ToHdlAstVhdl2008_Value, ToHdlAstVhdl2008_ops,
                       ToHdlAstVhdl2008_types, ToHdlAstVhdl2008_statements,
                       ToHdlAst):
    """
    :ivar ~.name_scope: name scope used to generate a unique names for tmp variables
        (all object should be registered in namescope before serialization)
    """
    _keywords_dict = {kw: LanguageKeyword() for kw in VHLD2008_KEYWORDS}

    DEFAULT_IMPORTS = [
        HdlLibrary("IEEE"),
Esempio n. 19
0
class ToHdlAstSimModel(ToHdlAstSimModel_value, ToHdlAstSimModel_types,
                       ToHdlAst):
    """
    Serializer which converts Unit instances to simulator code
    """
    _keywords_dict = {kw: LanguageKeyword() for kw in SIMMODEL_KEYWORDS}
    SIM_EVAL_COND = HdlValueId("sim_eval_cond", obj=sim_eval_cond)
    C = HdlValueId("c", obj=LanguageKeyword())
    CVLD = HdlValueId("cVld", obj=LanguageKeyword())

    def __init__(self, name_scope: Optional[NameScope] = None):
        super(ToHdlAstSimModel, self).__init__(name_scope)
        self.currentUnit = None
        self.stm_outputs = {}

    def as_hdl_HdlModuleDec(self, o: HdlModuleDec):
        # convert types, exprs
        # delete params because they should not be used in expressions and thus
        # are useless
        new_o = copy(o)
        new_o.params = []
        new_o.ports = [self.as_hdl_HdlPortItem(p) for p in o.ports]
        return new_o

    def as_hdl_PortConnection(self, o: HdlPortItem):
        assert isinstance(o, HdlPortItem), o
        intern, outer = o.getInternSig(), o.getOuterSig()
        assert not intern.hidden, intern
        assert not outer.hidden, outer
        intern_hdl = HdlValueId(intern.name, obj=intern)
        outer_hdl = HdlValueId(outer.name, obj=outer)
        pm = hdl_map_asoc(intern_hdl, outer_hdl)
        return pm

    def as_hdl_Assignment(self, a: Assignment):
        dst, dst_indexes, src = self._as_hdl_Assignment_auto_conversions(a)
        ev = HdlValueInt(int(a._event_dependent_from_branch == 0), None, None)
        if dst_indexes is not None:
            src = (src, dst_indexes, ev)
        else:
            src = (src, ev)
        hdl_dst = hdl_getattr(hdl_getattr(self.SELF_IO, dst.name), "val_next")
        hdl_a = HdlStmAssign(src, hdl_dst)
        hdl_a.is_blocking = dst.virtual_only
        return hdl_a

    def as_hdl_IfContainer_out_invalidate_section(self,
                                                  outputs: List[RtlSignalBase],
                                                  parent: IfContainer):
        outputInvalidateStms = []
        for o in outputs:
            # [TODO] look up indexes
            indexes = None
            v = o._dtype.from_py(None)
            oa = Assignment(v,
                            o,
                            indexes,
                            virtual_only=True,
                            parentStm=parent,
                            event_dependent_from_branch=parent.
                            _event_dependent_from_branch)
            outputInvalidateStms.append(self.as_hdl_Assignment(oa))

        if len(outputInvalidateStms) == 1:
            return outputInvalidateStms[0]
        else:
            b = HdlStmBlock()
            b.body = outputInvalidateStms
            return b

    def as_hdl_IfContainer_cond_eval(self, cond):
        """
        constructs condition evaluation statement
        c, cVld = sim_eval_cond(cond)
        """
        c, cVld = self.C, self.CVLD
        cond = self.as_hdl_cond(cond, True)
        cond_eval = hdl_call(self.SIM_EVAL_COND, [cond])
        cond_eval = HdlStmAssign(cond_eval, (c, cVld))
        cond_eval.is_blocking = True
        return c, cVld, cond_eval

    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

    def as_hdl_SwitchContainer(self, sw: SwitchContainer) -> HdlStmIf:
        "switch -> if"
        switchOn = sw.switchOn

        def mkCond(c):
            return switchOn._eq(c)

        elIfs = []

        for key, statements in sw.cases[1:]:
            elIfs.append((mkCond(key), statements))
        ifFalse = sw.default

        topCond = mkCond(sw.cases[0][0])
        topIf = IfContainer(topCond,
                            ifTrue=sw.cases[0][1],
                            ifFalse=ifFalse,
                            elIfs=elIfs)

        topIf._sensitivity = sw._sensitivity
        topIf._inputs = sw._inputs
        topIf._outputs = sw._outputs

        return self.as_hdl_IfContainer(topIf)

    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)

    def has_to_be_process(self, proc):
        return True

    def can_pop_process_wrap(self, statements, hasToBeVhdlProcess):
        return False

    def as_hdl_HdlStatementBlock(self,
                                 proc: HdlStatementBlock) -> HdlStmProcess:
        p = ToHdlAst.as_hdl_HdlStatementBlock(self, proc)
        self.stm_outputs[p] = sorted(
            [HdlValueId(i.name, obj=i) for i in proc._outputs])
        return p

    def as_hdl_extraVarsInit(self, extraVars):
        return []

    def _as_hdl_HdlModuleDef_body(self, *args) -> HdlModuleDef:
        orig_const_cache = self.constCache
        try:
            self.constCache = ConstantCache(self.createTmpVarFn)
            return ToHdlAst._as_hdl_HdlModuleDef_body(self, *args)
        finally:
            self.constCache = orig_const_cache
Esempio n. 20
0
class ToHdlAstSystemC(ToHdlAstSystemC_expr, ToHdlAstSystemC_type,
                      ToHdlAstSystemC_statements, ToHdlAst):
    """
    Serialized used to convert HWT design to SystemC code
    """
    _keywords_dict = {kw: LanguageKeyword() for kw in SYSTEMC_KEYWORDS}
    sc_in_clk = HdlValueId("sc_in_clk", obj=LanguageKeyword())
    sc_out_clk = HdlValueId("sc_out_clk", obj=LanguageKeyword())
    sc_inout_clk = HdlValueId("sc_inout_clk", obj=LanguageKeyword())
    sc_in = HdlValueId("sc_in", obj=LanguageKeyword())
    sc_out = HdlValueId("sc_out", obj=LanguageKeyword())
    sc_inout = HdlValueId("sc_inout", obj=LanguageKeyword())

    def __init__(self, name_scope: Optional[NameScope] = None):
        ToHdlAst.__init__(self, name_scope=name_scope)
        self._is_target = False
        self._in_sensitivity_list = False
        self.signalType = None

    def as_hdl_HdlModuleDec(self, o: HdlModuleDec):
        return ToHdlAstSimModel.as_hdl_HdlModuleDec(self, o)

    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

    def as_hdl_HdlCompInst(self, o: HdlCompInst) -> HdlCompInst:
        new_o = copy(o)
        new_o.param_map = []

        orig_is_target = self._is_target
        try:
            self._is_target = True
            port_map = []
            for pi in o.port_map:
                pm = self.as_hdl_PortConnection(pi)
                port_map.append(pm)
            new_o.port_map = port_map
        finally:
            self._is_target = orig_is_target

        return new_o
Esempio n. 21
0
class ToHdlAstVhdl2008_Value(ToHdlAst_Value):

    TRUE = HdlValueId("TRUE", obj=LanguageKeyword())
    FALSE = HdlValueId("FALSE", obj=LanguageKeyword())
    #TO_UNSIGNED = HdlValueId("TO_UNSIGNED", obj=LanguageKeyword())
    #TO_SIGNED = HdlValueId("TO_SIGNED", obj=LanguageKeyword())

    def as_hdl_cond(self, c, forceBool):
        assert isinstance(c, (RtlSignalBase, HValue)), c
        if not forceBool or c._dtype == BOOL:
            return self.as_hdl(c)
        elif c._dtype == BIT:
            return self.as_hdl(c._eq(1))
        elif isinstance(c._dtype, Bits):
            return self.as_hdl(c != 0)
        else:
            raise NotImplementedError()

    def as_hdl_HEnumVal(self, val: HEnumVal):
        name = self.name_scope.get_object_name(val)
        return HdlValueId(name, obj=val)

    def as_hdl_HArrayVal(self, val):
        return [self.as_hdl_Value(v) for v in val]

    def sensitivityListItem(self, item, anyIsEventDependnt):
        if isinstance(item, Operator):
            item = item.operands[0]
        return self.as_hdl(item)

    def as_hdl_BitString(self, v, width: int,
                         force_vector: bool, vld_mask: int, signed):
        is_bit = not force_vector and width == 1
        #if vld_mask != mask(width) or width >= 32 or is_bit:
        v = bit_string(v, width, vld_mask)
        if is_bit:
            v.base = 256
            return v
        if signed is None:
            return v
        elif signed:
            cast = self.SIGNED
        else:
            cast = self.UNSIGNED
        return HdlOp(HdlOpType.APOSTROPHE, [cast, v])

        #else:
        #    v = HdlValueInt(v, None, None)
        #
        #    if signed is None:
        #        return v
        #    elif signed:
        #        cast_fn = self.TO_SIGNED
        #    else:
        #        cast_fn = self.TO_UNSIGNED
        #    return hdl_call(cast_fn, [v, HdlValueInt(width, None, None)])

    def as_hdl_BoolVal(self, val: BitsVal):
        if val.val:
            return self.TRUE
        else:
            return self.FALSE

    def as_hdl_BitsVal(self, val: BitsVal):
        t = val._dtype
        v = super(ToHdlAstVhdl2008_Value, self).as_hdl_BitsVal(val)
        # handle '1' vs "1" difference (bit literal vs vector)
        if not t.force_vector and t.bit_length() == 1 and t != BOOL:
            if isinstance(v, HdlValueInt):
                v.base = 256
            else:
                # assert is cast
                assert isinstance(v, HdlOp) and v.fn == HdlOpType.CALL, v
                _v = v.ops[1]
                if isinstance(_v, HdlValueInt):
                    _v.base = 256
                else:
                    raise NotImplementedError()
        return v

    def as_hdl_SliceVal(self, val: SliceVal):
        upper = val.val.start
        if int(val.val.step) == -1:
            if isinstance(upper, HValue):
                upper = HdlValueInt(int(upper) - 1, None, None)
            else:
                upper = HdlOp(HdlOpType.SUB, [self.as_hdl_Value(upper),
                                                   HdlValueInt(1, None, None)])
        else:
            raise NotImplementedError(val.val.step)

        return HdlOp(HdlOpType.DOWNTO, [upper, self.as_hdl(val.val.stop)])