Source code for hwt.hdl.types.streamConst
from hwt.doc_markers import internal
from hwt.hdl.const import HConst
from hwt.hdl.types.bits import HBits
from hwt.hdl.types.defs import BIT, INT
from hwt.hdl.types.slice import HSlice
from hwt.hdl.types.typeCast import toHVal
from hwt.mainBases import RtlSignalBase
[docs]
class HStreamConst(HConst):
"""
Class for values of HStream HDL type
"""
[docs]
@classmethod
def from_py(cls, typeObj, val, vld_mask=None):
"""
:param typeObj: HStream instance
:param val: None or iterrable of values
:param vld_mask: if is None validity is resolved from val
if is 0 value is invalidated
if is 1 value has to be valid
"""
min_len = typeObj.len_min
if vld_mask == 0:
val = None
element_t = typeObj.element_t
if val is None:
elements = [element_t.from_py(None) for _ in range(min_len)]
else:
elements = []
for v in val:
if isinstance(v, RtlSignalBase): # is signal
assert v._dtype == typeObj.element_t
e = v
else:
e = typeObj.element_t.from_py(v)
elements.append(e)
cur_len = len(elements)
assert cur_len >= min_len and cur_len <= typeObj.len_max
_mask = int(bool(val))
if vld_mask is None:
vld_mask = _mask
else:
assert (vld_mask == _mask)
return cls(typeObj, elements, vld_mask)
[docs]
def to_py(self) -> list:
if not self._is_full_valid():
raise ValueError(f"Value of {self} is not fully defined")
return [v.to_py() for v in self.val]
@internal
def __hash__(self):
return hash((self._dtype, self.val, self.vld_mask))
[docs]
def _is_full_valid(self):
return self.vld_mask == 1
[docs]
@internal
def _getitem__const(self, key):
"""
:attention: this will clone item from array, iterate over .val
if you need to modify items
"""
kv = key.val
if not key._is_full_valid():
raise KeyError()
return self.val[kv].__copy__()
def __getitem__(self, key):
key = toHVal(key)
isSLICE = isinstance(key, HSlice.getConstCls())
if isSLICE:
raise NotImplementedError()
elif isinstance(key, (HConst, RtlSignalBase)):
pass
else:
raise NotImplementedError(
f"Index operation not implemented for index {key}")
kv = key.val
if not key._is_full_valid():
raise KeyError()
return self.val[kv].__copy__()
def __setitem__(self, index, value):
"""
Only syntax sugar for user, not used inside HWT
* In HW design is not used (__getitem__ returns "reference"
and it is used)
"""
if isinstance(index, int):
index = INT.from_py(index)
else:
assert isinstance(index._dtype, HBits), index._dtype
if not isinstance(value, HConst):
value = self._dtype.element_t.from_py(value)
else:
assert value._dtype == self._dtype.element_t, (
value._dtype, self._dtype.element_t)
if index._is_full_valid():
self.val[index.val] = value.__copy__()
else:
self.val = {}
return self
def __iter__(self):
return iter(self.val)
def __len__(self):
return len(self.val)
[docs]
def _eq(self, other):
assert isinstance(other, HStreamConst)
assert self._dtype.element_t == other._dtype.element_t
eq = True
vld = 1
if (len(self.val) == len(other.val)):
for a, b in zip(self.val, other.val):
eq = eq and bool(a) == bool(b)
if not eq:
break
vld = vld & a.vld_mask & b.vld_mask
else:
eq = False
vld = 0
return BIT.getConstCls()(BIT, int(eq), vld)