Source code for hwt.hdl.const
from typing import TypeVar, Generic, Self, Set
from hwt.doc_markers import internal
from hwt.hdl.sensitivityCtx import SensitivityCtx
from hwt.mainBases import RtlSignalBase
T = TypeVar("T", bound="HdlType")
[docs]
class HConst(Generic[T]):
"""
Wrap around hdl value with overloaded operators
operators are overloaded in every type separately
"""
__slots__ = ["_dtype", "val", "vld_mask"]
[docs]
def __init__(self, dtype: "HdlType", val, vld_mask):
"""
:param val: pythonic value representing this value
:param dtype: data type object from which this value was derived from
:param vld_mask: validity mask for value
"""
self._dtype = dtype
self.val = val
self.vld_mask = vld_mask
[docs]
def _is_full_valid(self):
return self.vld_mask == self._dtype.all_mask()
[docs]
def _is_partially_valid(self) -> bool:
return self.vld_mask != 0
[docs]
def _auto_cast(self, toType: "HdlType"):
"""
Cast value or signal of this type to another compatible type.
:param toType: instance of HdlType to cast into
"""
return self._dtype.auto_cast_HConst(self, toType)
[docs]
def _explicit_cast(self, toType: "HdlType"):
"""
Cast value or signal of this type to another friendly type.
:param toType: instance of HdlType to cast into
"""
return self._dtype.explicit_cast_HConst(self, toType)
[docs]
def _reinterpret_cast(self, toType: "HdlType"):
"""
Cast value or signal of this type to another type of same size.
:param toType: instance of HdlType to cast into
"""
return self._dtype.reinterpret_cast_HConst(self, toType)
[docs]
def staticEval(self) -> Self:
return self.__copy__()
def __copy__(self) -> Self:
return self.__class__(self._dtype, self.val, self.vld_mask)
@internal
def __hash__(self) -> int:
return hash((self._dtype, self.val, self.vld_mask))
def __repr__(self) -> str:
if self._is_full_valid():
vld_mask = ""
else:
vld_mask = ", mask {0:x}".format(self.vld_mask)
return "<{0:s} {1:s}{2:s}>".format(
self.__class__.__name__, repr(self.val), vld_mask)
[docs]
@classmethod
def _from_py(cls, typeObj, val, vld_mask) -> Self:
"""
from_py without value normalization and type checking
"""
return cls(typeObj, val, vld_mask)
[docs]
@classmethod
def from_py(cls, typeObj, val, vld_mask=None) -> Self:
raise NotImplementedError(
"from_py method is not implemented for", cls)
[docs]
def to_py(self):
"""
Cast HConst back to pythonic value like int/float/list[int] etc.
"""
raise NotImplementedError(
"to_py method is not implemented for", self.__class__)
def __eq__(self, other):
if isinstance(other, HConst):
return self._dtype == other._dtype and \
self.vld_mask == other.vld_mask and\
self.val == other.val
else:
return super().__eq__(other)
[docs]
def _eq(self, other):
"""
:see: :meth:`SignalOps._eq`
"""
raise TypeError()
def __ne__(self, other):
eq = self._eq(other)
eq.val = not eq.val
return eq
[docs]
def _walk_sensitivity(self, casualSensitivity: Set[RtlSignalBase], seen: Set[RtlSignalBase], ctx: SensitivityCtx):
"""
:see: :meth:`hwt.synthesizer.rtlLevel.rtlSignal.RtlSignal._walk_sensitivity`
"""
seen.add(self)
[docs]
def areHConsts(*items) -> bool:
"""
:return: True if all arguments are instances of HConst class else False
"""
for i in items:
if not isinstance(i, HConst):
return False
return True