Source code for hwt.hdl.types.hdlType

from enum import Enum
from typing import Union, Type, Self, Optional

from hwt.doc_markers import internal
from hwt.synthesizer.exceptions import TypeConversionErr


[docs] class MethodNotOverloaded(NotImplementedError): """ Method is missing overload of abstract parent method. """ pass
[docs] class HdlType(): """ Base class for all hardware related types. :ivar const: if True the type has const specifier which means that the value should not be modified after initialization and is read only :note: Cast functions are linked trough HldType class because Python lacks forward declarations. :cvar ~._PRECOMPUTE_CONSTANT_SIGNALS: if true a constant expressions made from this type have value pre-computed. :note: Each implementation of HdlType also defines is HConst and RtlSignal class. These classes then implement operators and methods for constants/expressions. """ _PRECOMPUTE_CONSTANT_SIGNALS = True
[docs] def __init__(self, const=False): self.const = const
[docs] def _from_py(self, v, vld_mask) -> "HConst": """ same as from_py just without type checks """ return self.getConstCls()._from_py(self, v, vld_mask)
[docs] def from_py(self, v, vld_mask=None) -> "HConst": """ Construct value of this type. Delegated on value class for this type """ if isinstance(v, Enum): v = v.value return self.getConstCls().from_py(self, v, vld_mask=vld_mask)
[docs] def auto_cast_HConst(self, v: "HConst", toType: Self) -> "HConst": """ Cast constant of this type to another compatible type. :note: auto cast may change bitwidth if type implements it in auto cast :param v: constant to cast :param toType: instance of HdlType to cast into """ if v._dtype == toType: return v try: castFn = self._auto_cast_HConst_fn except AttributeError: castFn = self.get_auto_cast_HConst_fn() self._auto_cast_HConst_fn = castFn castErr = None try: return castFn(self, v, toType) except TypeConversionErr as e: castErr = e try: return toType._reverse_auto_cast_HConst(v, self) except TypeConversionErr: pass raise castErr from castErr # raise original exception from non-reverse cast
[docs] def auto_cast_RtlSignal(self, v: "RtlSignal", toType: Self) -> "RtlSignal": """ Equivalent of :meth:`~.auto_cast_HConst` for :class:`RtlSignal` instances """ if v._dtype == toType: return v try: castFn = self._auto_cast_RtlSignal_fn except AttributeError: castFn = self.get_auto_cast_RtlSignal_fn() self._auto_cast_RtlSignal_fn = castFn castErr = None try: return castFn(self, v, toType) except TypeConversionErr as e: castErr = e try: return toType._reverse_auto_cast_RtlSignal(v, self) except TypeConversionErr: pass raise castErr from castErr # raise original exception from non-reverse cast
[docs] def explicit_cast_HConst(self, v: "HConst", toType: Self) -> "HConst": """ Cast constant of this type to another friendly type. :param v: constant to cast :param toType: instance of HdlType to cast into """ if v._dtype == toType: return v try: castFn = self._explicit_cast_HConst_fn except AttributeError: castFn = self.get_explicit_cast_HConst_fn() self._explicit_cast_HConst_fn = castFn castErr = None try: return castFn(self, v, toType) except TypeConversionErr as e: castErr = e try: return toType._reverse_explicit_cast_HConst(v, self) except TypeConversionErr: pass raise castErr from castErr # raise original exception from non-reverse cast
[docs] def explicit_cast_RtlSignal(self, v: "RtlSignal", toType: Self) -> "RtlSignal": """ Cast value or signal of this type to another type of same size. :param v: signal to cast :param toType: instance of HdlType to cast into """ if v._dtype == toType: return v try: castFn = self._explicit_cast_RtlSignal_fn except AttributeError: castFn = self.get_explicit_cast_RtlSignal_fn() self._explicit_cast_RtlSignal_fn = castFn castErr = None try: return castFn(self, v, toType) except TypeConversionErr as e: castErr = e try: return toType._reverse_explicit_cast_RtlSignal(v, self) except TypeConversionErr: pass raise castErr from castErr # raise original exception from non-reverse cast
[docs] def reinterpret_cast_HConst(self, v: "HConst", toType: Self) -> "HConst": """ Cast constant of this type to another type of same size. :param v: constant to cast :param toType: instance of HdlType to cast into """ if v._dtype == toType: return v try: castFn = self._reinterpret_cast_HConst_fn except AttributeError: castFn = self.get_reinterpret_cast_HConst_fn() self._reinterpret_cast_HConst_fn = castFn castErr = None try: return castFn(self, v, toType) except TypeConversionErr as e: castErr = e try: return toType._reverse_reinterpret_cast_HConst(v, self) except TypeConversionErr: pass raise castErr from castErr # raise original exception from non-reverse cast
[docs] def reinterpret_cast_RtlSignal(self, v: "RtlSignal", toType: Self) -> "RtlSignal": """ Cast value or signal of this type to another type of same size. :param v: signal to cast :param toType: instance of HdlType to cast into """ if v._dtype == toType: return v try: castFn = self._reinterpret_cast_RtlSignal_fn except AttributeError: castFn = self.get_reinterpret_cast_RtlSignal_fn() self._reinterpret_cast_RtlSignal_fn = castFn castErr = None try: # call _reinterpret_cast_RtlSignal_fn to cast this type to toType return castFn(self, v, toType) except TypeConversionErr as e: castErr = e pass try: return toType._reverse_reinterpret_cast_RtlSignal(v, self) except TypeConversionErr: pass raise castErr from castErr # raise original exception from non-reverse cast
# reverse casts which are doing the same thing but cast methods are implemented on dst type # :note: this is there to allow casting old types(self) to a new types(toType) # when old type does not know anything about new type
[docs] def _reverse_auto_cast_HConst(self, v: "HConst", fromType: Self) -> "HConst": try: castFn = self._reverse_auto_cast_HConst_fn except AttributeError: castFn = self.get_reverse_auto_cast_HConst_fn() self._reverse_auto_cast_HConst_fn = castFn return castFn(self, v, fromType)
[docs] def _reverse_auto_cast_RtlSignal(self, v: "RtlSignal", fromType: Self) -> "RtlSignal": try: castFn = self._reverse_auto_cast_RtlSignal_fn except AttributeError: castFn = self.get_reverse_auto_cast_RtlSignal_fn() self._reverse_auto_cast_RtlSignal_fn = castFn return castFn(self, v, fromType)
[docs] def _reverse_explicit_cast_HConst(self, v: "HConst", fromType: Self) -> "HConst": try: castFn = self._reverse_explicit_cast_HConst_fn except AttributeError: castFn = self.get_reverse_explicit_cast_HConst_fn() self._reverse_explicit_cast_HConst_fn = castFn return castFn(self, v, fromType)
[docs] def _reverse_explicit_cast_RtlSignal(self, v: "RtlSignal", fromType: Self) -> "RtlSignal": try: castFn = self._reverse_explicit_cast_RtlSignal_fn except AttributeError: castFn = self.get_reverse_explicit_cast_RtlSignal_fn() self._reverse_explicit_cast_RtlSignal_fn = castFn return castFn(self, v, fromType)
[docs] def _reverse_reinterpret_cast_HConst(self, v: "HConst", fromType: Self) -> "HConst": try: castFn = self._reverse_reinterpret_cast_HConst_fn except AttributeError: castFn = self.get_reverse_reinterpret_cast_HConst_fn() self._reverse_reinterpret_cast_HConst_fn = castFn return castFn(self, v, fromType)
[docs] def _reverse_reinterpret_cast_RtlSignal(self, v: "RtlSignal", fromType: Self) -> "RtlSignal": try: castFn = self._reverse_reinterpret_cast_RtlSignal_fn except AttributeError: castFn = self.get_reverse_reinterpret_cast_RtlSignal_fn() self._reverse_reinterpret_cast_RtlSignal_fn = castFn return castFn(self, v, fromType)
# methods for getting cast function which cast value of one type to another # for more details :see: methods for casting of this class # auto_cast
[docs] @internal @classmethod def get_auto_cast_HConst_fn(cls): return default_auto_cast_fn
[docs] @internal @classmethod def get_auto_cast_RtlSignal_fn(cls): return default_auto_cast_fn
[docs] @internal @classmethod def get_reverse_auto_cast_RtlSignal_fn(cls): return default_reverse_auto_cast_fn
[docs] @internal @classmethod def get_reverse_auto_cast_HConst_fn(cls): return default_reverse_auto_cast_fn
# explicit_cast
[docs] @internal @classmethod def get_explicit_cast_HConst_fn(cls): return default_explicit_cast_fn
[docs] @internal @classmethod def get_explicit_cast_RtlSignal_fn(cls): return default_explicit_cast_fn
[docs] @internal @classmethod def get_reverse_explicit_cast_RtlSignal_fn(cls): return default_reverse_explicit_cast_fn
[docs] @internal @classmethod def get_reverse_explicit_cast_HConst_fn(cls): return default_reverse_explicit_cast_fn
# reinterpret_cast
[docs] @internal @classmethod def get_reinterpret_cast_HConst_fn(cls): return default_reinterpret_cast_fn
[docs] @internal @classmethod def get_reverse_reinterpret_cast_HConst_fn(cls): return default_reverse_reinterpret_cast_fn
[docs] @internal @classmethod def get_reinterpret_cast_RtlSignal_fn(cls): return default_reinterpret_cast_fn
[docs] @internal @classmethod def get_reverse_reinterpret_cast_RtlSignal_fn(cls): return default_reverse_reinterpret_cast_fn
[docs] @internal @classmethod def getConstCls(cls) -> Type["HConst"]: """ :attention: Overrode in implementation of concrete HdlType. :return: class for value derived from this type """ raise NotImplementedError(cls)
[docs] @internal @classmethod def getRtlSignalCls(cls) -> Type["RtlSignal"]: """ :attention: Overrode in implementation of concrete HdlType. :return: class for value derived from this type """ raise NotImplementedError(cls)
[docs] def _as_hdl(self, to_Hdl: "ToHdlAst", declaration:bool): raise MethodNotOverloaded()
[docs] def _as_hdl_requires_def(self, to_Hdl: "ToHdlAst", other_types: list): raise MethodNotOverloaded()
[docs] def isScalar(self): return True
def __getitem__(self, key): """ [] operator to create an array of this type. """ assert int(key) > 0, key # array has to have some items from hwt.hdl.types.array import HArray return HArray(self, key) def __repr__(self, indent:int=0, withAddr:Optional[int]=None, expandStructs=False): """ :param indent: number of indentation :param withAddr: if is not None, it is used as a additional information about on which address this type is stored (used only by HStruct) :param expandStructs: expand HStructTypes (used by HStruct and Array) """ name = getattr(self, "name", "") if name is None: name = "" return f"<{self.__class__.__name__:s} {name:s}>"
# auto_cast
[docs] @internal def default_auto_cast_fn(typeFrom: HdlType, sigOrConst: Union["RtlSignal", "HConst"], toType: HdlType): raise TypeConversionErr("auto_cast", typeFrom, "->", toType, "is not implemented")
[docs] @internal def default_reverse_auto_cast_fn(toType: HdlType, sigOrConst: Union["RtlSignal", "HConst"], fromType: HdlType): raise TypeConversionErr("auto_cast", fromType, "->", toType, "is not implemented")
# explicit_cast
[docs] @internal def default_explicit_cast_fn(typeFrom: HdlType, sigOrConst: Union["RtlSignal", "HConst"], toType: HdlType): raise TypeConversionErr("explicit_cast", typeFrom, "->", toType, "is not implemented")
[docs] @internal def default_reverse_explicit_cast_fn(toType: HdlType, sigOrConst: Union["RtlSignal", "HConst"], fromType: HdlType): raise TypeConversionErr("explicit_cast", fromType, "->", toType, "is not implemented")
# reinterpret_cast
[docs] @internal def default_reinterpret_cast_fn(fromType: HdlType, sigOrConst: Union["RtlSignal", "HConst"], toType: HdlType): raise TypeConversionErr("reinterpret_cast", fromType, "->", toType, "is not implemented")
[docs] @internal def default_reverse_reinterpret_cast_fn(toType: HdlType, sigOrConst: Union["RtlSignal", "HConst"], fromType: HdlType): raise TypeConversionErr("reinterpret_cast", fromType, "->", toType, "is not implemented")