from hwt.hdl.sensitivityCtx import SensitivityCtx
from hwt.doc_markers import internal
from typing import TypeVar, Generic
T = TypeVar("T", bound="HdlType")
[docs]class HValue(Generic[T]):
"""
Wrap around hdl value with overloaded operators
http://www.rafekettler.com/magicmethods.html
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 _auto_cast(self, toT):
"type cast to compatible type"
return self._dtype.auto_cast(self, toT)
[docs] def _reinterpret_cast(self, toT):
"type cast to type of same size"
return self._dtype.reinterpret_cast(self, toT)
[docs] def staticEval(self):
return self.__copy__()
def __copy__(self):
return self.__class__(self._dtype, self.val, self.vld_mask)
@internal
def __hash__(self):
return hash((self._dtype, self.val, self.vld_mask))
def __repr__(self):
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):
"""
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):
raise NotImplementedError(
f"from_py fn is not implemented for {cls}")
def __int__(self):
if isinstance(self, HValue) or self._const:
if self._is_full_valid():
return int(self.val)
else:
raise ValueError(f"HValue of {self} is not fully defined")
raise ValueError(
f"HValue of {self} is not constant it can be statically solved")
def __bool__(self):
if isinstance(self, HValue) or self._const:
if self._is_full_valid():
return bool(self.val)
else:
raise ValueError(f"HValue of {self} is not fully defined")
raise ValueError(
f"HValue of {self} is not constant it can be statically solved")
def __eq__(self, other):
if areHValues(self, other):
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):
raise TypeError()
def __ne__(self, other):
eq = self._eq(other)
eq.val = not eq.val
return eq
[docs] def _walk_sensitivity(self, casualSensitivity: set, seen: set, ctx: SensitivityCtx):
"""
:see: :meth:`hwt.synthesizer.rtlLevel.rtlSignal.RtlSignal._walk_sensitivity`
"""
seen.add(self)
# def __pos__(self):
# raise TypeError()
#
# def __neg__(self):
# raise TypeError()
#
# def __abs__(self):
# raise TypeError()
#
# def __invert__(self):
# raise TypeError()
#
# def __round__(self, n):
# raise TypeError()
#
# def __floor__(self):
# raise TypeError()
#
# def __ceil__(self):
# raise TypeError()
#
# def __add__(self, other):
# raise TypeError()
#
# def __sub__(self, other):
# raise TypeError()
#
# def __mul__(self, other):
# raise TypeError()
#
# def __floordiv__(self, other):
# raise TypeError()
#
# def __div__(self, other):
# raise TypeError()
#
# def __truediv__(self, other):
# raise TypeError()
#
# def __mod__(self, other):
# raise TypeError()
#
# def __divmod__(self, other):
# raise TypeError()
#
# def __pow__(self, other):
# raise TypeError()
#
# def __lshift__(self, other):
# raise TypeError()
#
# def __rshift__(self, other):
# raise TypeError()
#
# def __and__(self, other):
# raise TypeError()
#
# def __or__(self, other):
# raise TypeError()
#
# def __xor__(self, other):
# raise TypeError()
#
# def _concat(self, other):
# raise TypeError()
#
# def __lt__(self, other):
# raise TypeError()
#
# def __le__(self, other):
# raise TypeError()
#
# def __gt__(self, other):
# raise TypeError()
#
# def __ge__(self, other):
# raise TypeError()
#
# def _onRisingEdge(self):
# raise TypeError()
#
# def _onFallingEdge(self):
# raise TypeError()
[docs]def areHValues(*items):
"""
:return: True if all arguments are instances of HValue class else False
"""
for i in items:
if not isinstance(i, HValue):
return False
return True