Source code for hwt.hdl.types.structValBase
from hwt.hdl.value import HValue, areHValues
from hwt.serializer.generic.indent import getIndent
from hwt.synthesizer.rtlLevel.mainBases import RtlSignalBase
[docs]class StructValBase(HValue):
"""
Base class for values for structure types.
Every structure type has it's own value class derived from this.
"""
__slots__ = []
[docs] def __init__(self, typeObj, val, skipCheck=False):
"""
:param val: None or dict {field name: field value}
:param typeObj: instance of HString HdlType
:param skipCheck: flag to skip field name consistency in val
"""
self._dtype = typeObj
if not skipCheck and val is not None:
assert set(self.__slots__).issuperset(set(val.keys())), \
("struct value specifies undefined members",
set(val.keys()).difference(set(self.__slots__)))
for f in self._dtype.fields:
if f.name is None:
continue
if val is None:
v = None
else:
v = val.get(f.name, None)
if not isinstance(v, (HValue, RtlSignalBase)):
v = f.dtype.from_py(v)
setattr(self, f.name, v)
def __copy__(self):
d = {}
for f in self._dtype.fields:
if f.name is None:
continue
v = getattr(self, f.name)
if not isinstance(v, RtlSignalBase):
v = v.__copy__()
d[f.name] = v
return self.__class__(self._dtype, d, skipCheck=True)
[docs] @classmethod
def from_py(cls, typeObj, val, vld_mask=None):
"""
:param val: None or dict {field name: field value}
:param typeObj: instance of HString HdlType
: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
"""
if vld_mask == 0:
val = None
return cls(typeObj, val)
[docs] def _is_full_valid(self):
for f in self._dtype.fields:
if f.name is not None:
val = getattr(self, f.name, None)
if val is None or not val._is_full_valid():
return False
return True
[docs] def to_py(self):
if not self._is_full_valid():
raise ValueError(f"Value of {self} is not fully defined")
d = {}
for f in self._dtype.fields:
if f.name is not None:
val = getattr(self, f.name).to_py()
d[f.name] = val
return d
def __ne__(self, other):
if areHValues(self, other):
if self._dtype == other._dtype:
for f in self._dtype.fields:
isPadding = f.name is None
if not isPadding:
sf = getattr(self, f.name)
of = getattr(other, f.name)
if (sf != of):
return True
return False
else:
return True
else:
return super(HValue, self).__ne__(other)
[docs] def _eq(self, other):
return self.__eq__(other)
def __eq__(self, other):
if areHValues(self, other):
if self._dtype == other._dtype:
for f in self._dtype.fields:
isPadding = f.name is None
if not isPadding:
sf = getattr(self, f.name)
of = getattr(other, f.name)
if not (sf == of):
return False
return True
else:
return False
else:
return super(HValue, self).__eq__(other)
def __repr__(self, indent=0):
buff = ["{"]
indentOfFields = getIndent(indent + 1)
for f in self._dtype.fields:
if f.name is not None:
val = getattr(self, f.name)
try:
v = val.__repr__(indent=indent + 1)
except TypeError:
v = repr(val)
buff.append(f"{indentOfFields:s}{f.name:s}: {v:s}")
buff.append(getIndent(indent) + "}")
return ("\n").join(buff)