Example #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])
Example #2
0
 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
Example #3
0
    def create_HdlModuleDef(self, target_platform: DummyPlatform,
                            store_manager: "StoreManager"):
        """
        Generate a module body (architecture) for this module

        * Resolve name collisions
        * Convert netlist representation to HdlProcesses
        * Remove unconnected
        * Mark visibility of signals
        """
        removeUnconnectedSignals(self)
        markVisibilityOfSignalsAndCheckDrivers(self.signals, self.interfaces)

        for proc in target_platform.beforeHdlArchGeneration:
            proc(self)

        ns = store_manager.name_scope
        mdef = HdlModuleDef()
        mdef.dec = self.ent
        mdef.module_name = HdlValueId(self.ent.name, obj=self.ent)
        mdef.name = "rtl"

        processes = sorted(self.statements, key=HdlStatement_sort_key)
        processes = sorted(statements_to_HdlStatementBlocks(processes),
                           key=HdlStatement_sort_key)

        # add signals, variables etc. in architecture
        for s in sorted((s for s in self.signals
                         if not s.hidden and s not in self.interfaces.keys()),
                        key=RtlSignal_sort_key):
            v = HdlIdDef()
            v.origin = s
            s.name = v.name = ns.checked_name(s.name, s)
            v.type = s._dtype
            v.value = s.def_val
            v.is_const = s._const
            mdef.objs.append(v)

        for p in processes:
            p.name = ns.checked_name(p.name, p)
        mdef.objs.extend(processes)
        # instantiate subUnits in architecture
        for u in self.subUnits:
            ci = HdlCompInst()
            ci.origin = u
            ci.module_name = HdlValueId(u._ctx.ent.name, obj=u._ctx.ent)
            ci.name = HdlValueId(ns.checked_name(u._name + "_inst", ci), obj=u)
            e = u._ctx.ent

            ci.param_map.extend(e.params)
            ci.port_map.extend(e.ports)

            mdef.objs.append(ci)

        self.arch = mdef
        return mdef
Example #4
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 #5
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 #6
0
 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
Example #7
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])
Example #8
0
class ToHdlAstHwt_types():
    """
    part of ToHdlAstSimModel responsible for type serialization
    """
    BOOL = HdlValueId("BOOL", obj=BOOL)
    INT = HdlValueId("INT", obj=INT)
    BITS = HdlValueId("Bits", obj=Bits)

    def does_type_requires_extra_def(self, t, other_types):
        try:
            return t._as_hdl_requires_def(self, other_types)
        except MethodNotOverloaded:
            pass
        return isinstance(t, HEnum) and t not in other_types

    def as_hdl_HdlType_array(self, typ: HArray, declaration=False):
        assert not declaration, "declaration should not be required"
        t = self.as_hdl_HdlType(typ.element_t, declaration=declaration)
        return hdl_index(t, HdlValueInt(int(typ.size), None, None))

    def as_hdl_HdlType_bits(self, typ: Bits, declaration=False):
        if declaration:
            raise NotImplementedError()
        elif typ == BOOL:
            return self.BOOL
        elif typ == INT:
            return self.INT

        w = typ.bit_length()
        assert isinstance(w, int), w

        def add_kw(name, val):
            kw = hdl_map_asoc(HdlValueId(name), HdlValueInt(val, None, None))
            args.append(kw)

        args = [HdlValueInt(w, None, None)]
        if typ.signed is not BITS_DEFAUTL_SIGNED:
            add_kw("signed", typ.signed)
        if typ.force_vector is not BITS_DEFAUTL_FORCEVECTOR and w <= 1:
            add_kw("force_vector", typ.force_vector)
        if typ.negated is not BITS_DEFAUTL_NEGATED:
            add_kw("negated", typ.negated)

        return hdl_call(self.BITS, args)

    def as_hdl_HdlType_float(self, typ: HFloat, declaration=False):
        return hdl_call(HdlValueId("HFloat"), typ.exponent_w, typ.mantisa_w)
Example #9
0
 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)
Example #10
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)
def rm_ToBasicHdlSimModel_io_prefix_and_tmp_vars_from_outputs(stm_outputs):
    C = HdlValueId("c")
    CVLD = HdlValueId("cVld")
    SELF = HdlValueId("self")
    IO = HdlValueId("io")
    VAL_NEXT = HdlValueId("val_next")
    res = {}
    for stm, outputs in stm_outputs.items():
        new_outputs = []
        for o in outputs:
            if o in (C, CVLD):
                continue
            assert o[0] == SELF, o
            assert o[1] == IO, o
            assert o[-1] == VAL_NEXT
            new_o = o[2:-1]
            if len(new_o) == 1:
                new_o = new_o[0]
            new_outputs.append(new_o)
        res[stm] = new_outputs
    return res
Example #12
0
    def as_hdl_HEnumVal(self, val: HEnumVal):
        try:
            t_name = self.name_scope.get_object_name(val._dtype)
        except ObjectForNameNotFound:
            if self.debug:
                t_name = val._dtype.name
            else:
                raise

        if val.vld_mask:
            try:
                name = self.name_scope.get_object_name(val)
            except ObjectForNameNotFound:
                if self.debug:
                    name = val.val
                else:
                    raise

            return hdl_getattr(HdlValueId(t_name, obj=val._dtype), name)
        else:
            return hdl_call(hdl_getattr(HdlValueId(t_name, obj=val._dtype), "from_py"),
                            [None, ])
Example #13
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 #14
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 #15
0
 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"), [])
Example #16
0
 def as_hdl_SignalItem(self, si: Union[SignalItem, HdlIdDef], declaration=False):
     if declaration:
         if isinstance(si, HdlIdDef):
             new_si = copy(si)
             new_si.type = self.as_hdl_HdlType(si.type)
             if si.value is not None:
                 new_si.value = self.as_hdl_Value(si.value)
             return new_si
         else:
             raise NotImplementedError()
     else:
         # if isinstance(si, SignalItem) and si._const:
         #    # to allow const cache to extract constants
         #    return self.as_hdl_Value(si._val)
         if si.hidden and si.origin is not None:
             return self.as_hdl(si.origin)
         else:
             return HdlValueId(si.name, obj=si)
Example #17
0
 def visit_HdlOp(self, o):
     """
     :type o: HdlOp
     """
     op = o.fn
     if op == HdlOpType.EQ:
         # HdlOpType.EQ: '%s._eq(%s)',
         to_property_call(o, "_eq")
     elif op == HdlOpType.CONCAT:
         to_property_call(o, "_concat")
     elif op == HdlOpType.TERNARY:
         to_property_call(o, "_ternary__val")
     elif op == HdlOpType.DOWNTO:
         # HdlOpType.DOWNTO: "slice(%s, %s)",
         o.fn = HdlOpType.CALL
         o.ops = [
             HdlValueId("slice"),
         ] + o.ops
     elif op == HdlOpType.TO:
         raise NotImplementedError(o)
     elif op == HdlOpType.CALL:
         raise NotImplementedError("inline", o)
Example #18
0
def link_module_dec_def(context):
    """
    :type context: HdlContext
    """
    objs = []
    last = None
    for o in context.objs:
        if isinstance(o, HdlModuleDef) and o.dec is None:
            assert isinstance(last, HdlModuleDec) \
                and o.module_name == HdlValueId(last.name), (
                "Module body has to be behind the module header", last, o)
            o.dec = last
            objs.append(o)
            last = None
        else:
            if last is not None:
                objs.append(last)
            last = o
    if last is not None:
        objs.append(last)

    context.objs = objs
Example #19
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])
Example #20
0
    def visit_HdlOp(self, o):
        """
        :type o: HdlOp
        """
        fn = o.ops[0]
        if fn == HdlValueId("assert"):
            self.visit_assert(o.ops[1:])
            return
        elif fn == HdlValueId("report"):
            self.visit_report(o.ops[1:])
            return

        w = self.out.write
        op = o.fn
        if op == HdlOpType.RISING:
            w("RISING_EDGE(")
            self.visit_iHdlExpr(o.ops[0])
            w(")")
        elif op == HdlOpType.FALLING:
            w("FALLING_EDGE(")
            self.visit_iHdlExpr(o.ops[0])
            w(")")
        elif op == HdlOpType.INDEX or op == HdlOpType.CALL:
            self._visit_operand(o.ops[0], 0, o, False, False)
            w("(")
            for isLast, (o_i, _o) in iter_with_last(enumerate(o.ops[1:])):
                self._visit_operand(_o, o_i + 1, o, False, True)
                if not isLast:
                    w(", ")
            w(")")
        elif op == HdlOpType.TERNARY:
            has_3_ops = len(o.ops) == 3
            if has_3_ops:
                cond, o0, o1 = o.ops
            else:
                cond, o0 = o.ops

            self._visit_operand(o0, 1, o, True, False)
            w(" WHEN ")
            self._visit_operand(cond, 0, o, True, False)
            if has_3_ops:
                if isinstance(o1, HdlOp) and o1.fn == HdlOpType.TERNARY:
                    w(" ELSE\n")
                    self.visit_iHdlExpr(o1)  # must not have parenthesis
                else:
                    w(" ELSE ")
                    self._visit_operand(o1, 2, o, False, False)
        elif op == HdlOpType.APOSTROPHE:
            self._visit_operand(o.ops[0], 0, o, True, False)
            w("'")
            args = o.ops[1]
            if isinstance(args, list):
                self.visit_iHdlExpr(args)
            elif isinstance(args, HdlValueId):
                # normal attribute
                self.visit_iHdlExpr(args)
            else:
                w("(")
                self._visit_operand(args, 0, o, False, True)
                w(")")
        elif op == HdlOpType.ABS:
            w("ABS(")
            self.visit_iHdlExpr(o.ops[0])
            w(")")
        elif op == HdlOpType.DEFINE_RESOLVER:
            assert self.in_typedef
            self.visit_iHdlExpr(o.ops[0])
            w(" ")
            self.visit_iHdlExpr(o.ops[1])
        else:
            return ToHdlCommon.visit_HdlOp(self, o)
Example #21
0
File: ops.py Project: klopstock/hwt
 def apply_cast(self, t_name, op):
     return hdl_call(HdlValueId(t_name, obj=LanguageKeyword()),
                     [op, ])
Example #22
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])
Example #23
0
class ToHdlAstHwt_value(ToHdlAst_Value):
    NONE = HdlValueId("None")
    SLICE = HdlValueId("SLICE", obj=SLICE)

    def is_suitable_for_const_extract(self, val: Value):
        # full valid values can be represented as int and do not have any
        # constructor overhead, entirely invalid values can be represented by None
        return not val._is_full_valid() and not isinstance(val._dtype, HEnum)

    def as_hdl_BitsVal(self, val: BitsVal):
        isFullVld = val._is_full_valid()
        if not self._valueWidthRequired:
            if isFullVld:
                return HdlValueInt(val.val, None, 16)
            elif val.vld_mask == 0:
                return self.NONE

        t = self.as_hdl_HdlType_bits(val._dtype, declaration=False)
        c = hdl_getattr(t, "from_py")
        args = [
            HdlValueInt(val.val, None, 16),
        ]
        if not isFullVld:
            args.append(HdlValueInt(val.vld_mask, None, 16))

        return hdl_call(c, args)

    def as_hdl_SignalItem(self,
                          si: Union[SignalItem, HdlIdDef],
                          declaration=False):
        if declaration:
            if isinstance(si, HdlIdDef):
                new_si = copy(si)
                new_si.type = self.as_hdl_HdlType(si.type)
                if si.value is not None:
                    new_si.value = self.as_hdl_Value(si.value)
                return new_si
            else:
                raise NotImplementedError()
        else:
            # if isinstance(si, SignalItem) and si._const:
            #    # to allow const cache to extract constants
            #    return self.as_hdl_Value(si._val)
            if si.hidden and hasattr(si, "origin"):
                return self.as_hdl(si.origin)
            else:
                return HdlValueId(si.name, obj=si)

    def as_hdl_DictVal(self, val):
        return ToHdlAstSimModel_value.as_hdl_DictVal(self, val)

    def as_hdl_HArrayVal(self, val: HArrayVal):
        if not val.vld_mask:
            return self.NONE
        # else:
        #    if len(val.val) == val._dtype.size:
        #        allValuesSame = True
        #        values = iter(val.val.values())
        #        reference = next(values)
        #         for v in values:
        #             if allValuesSame:
        #                 allValuesSame = isSameHVal(reference, v)
        #             else:
        #                 break
        #        if allValuesSame:
        #            # all values of items in array are same, use generator
        #            # exression
        #            raise NotImplementedError()
        #            return "[%s for _ in range(%d)]" % (self.Value(reference))

        # if value can not be simplified it is required to serialize it item
        # by item
        return self.as_hdl_DictVal(val.val)

    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)

    def as_hdl_HEnumVal(self, val: HEnumVal):
        try:
            t_name = self.name_scope.get_object_name(val._dtype)
        except ObjectForNameNotFound:
            if self.debug:
                t_name = val._dtype.name
            else:
                raise

        if val.vld_mask:
            try:
                name = self.name_scope.get_object_name(val)
            except ObjectForNameNotFound:
                if self.debug:
                    name = val.val
                else:
                    raise

            return hdl_getattr(HdlValueId(t_name, obj=val._dtype), name)
        else:
            return hdl_call(
                hdl_getattr(HdlValueId(t_name, obj=val._dtype), "from_py"), [
                    None,
                ])
Example #24
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]
Example #25
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
Example #26
0
 def add_kw(name, val):
     kw = hdl_map_asoc(HdlValueId(name), HdlValueInt(val, None, None))
     args.append(kw)
Example #27
0
 def as_hdl_HdlType_float(self, typ: HFloat, declaration=False):
     return hdl_call(HdlValueId("HFloat"), typ.exponent_w, typ.mantisa_w)
Example #28
0
    def as_hdl_SignalItem(self,
                          si: Union[SignalItem, HdlIdDef],
                          declaration=False):
        if declaration:
            if isinstance(si, HdlIdDef):
                var = copy(si)
                si = si.origin
            else:
                var = HdlIdDef()
                var.name = si.name
                var.origin = si
                var.value = si._val
                var.type = si._dtype
                var.is_const = si._const
            v = var.value
            if isinstance(si, RtlSignalBase):
                if si.virtual_only:
                    var.is_latched = True
                elif si.drivers or var.direction != HdlDirection.UNKNOWN:
                    # has drivers or is port/param
                    pass
                elif si.endpoints:
                    if not v.vld_mask:
                        raise SerializerException(
                            "Signal %s is constant and has undefined value" %
                            si.name)
                    var.is_const = True
                else:
                    raise SerializerException(
                        "Signal %s should be declared but it is not used" %
                        si.name)

            if v is None:
                pass
            elif isinstance(v, RtlSignalBase):
                if v._const:
                    var.value = self.as_hdl(v)
                else:
                    # default value has to be set by reset,
                    # because it is not resolvable in compile time
                    var.value = None
                    pass
            elif isinstance(v, Value):
                if v.vld_mask or var.is_const:
                    orig_const_cache = self.constCache
                    try:
                        self.constCache = None
                        var.value = self.as_hdl_Value(v)
                    finally:
                        self.constCache = orig_const_cache
                else:
                    # remove value if it is entirely undefined
                    var.value = None
            else:
                raise NotImplementedError(v)
            var.type = self.as_hdl_HdlType(var.type)
            return var
        else:
            if si.hidden and hasattr(si, "origin"):
                # hidden signal, render it's driver instead
                return self.as_hdl(si.origin)
            return HdlValueId(si.name, obj=si)
Example #29
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)])
Example #30
0
 def as_hdl_HdlType_float(self, typ: HFloat, declaration=False):
     if typ == FLOAT64:
         return HdlValueId("real")
     else:
         raise NotImplementedError(typ)