Source code for hwt.hdl.types.bitsCast

from typing import Union

from hwt.doc_markers import internal
from hwt.hdl.operator import Operator
from hwt.hdl.operatorDefs import AllOps
from hwt.hdl.types.array import HArray
from hwt.hdl.types.bits import Bits
from hwt.hdl.types.defs import INT, BOOL
from hwt.hdl.types.hdlType import default_auto_cast_fn, HdlType
from hwt.hdl.types.struct import HStruct
from hwt.hdl.types.union import HUnion
from hwt.hdl.value import HValue
from hwt.interfaces.structIntf import HdlType_to_Interface
from hwt.synthesizer.exceptions import TypeConversionErr
from hwt.synthesizer.hObjList import HObjList
from hwt.synthesizer.interfaceLevel.mainBases import InterfaceBase
from hwt.synthesizer.rtlLevel.rtlSignal import RtlSignal
from hwt.synthesizer.rtlLevel.signalUtils.exceptions import SignalDriverErr
from hwt.synthesizer.vectorUtils import iterBits, fitTo_t
from pyMathBitPrecise.bit_utils import set_bit_range, mask


[docs]@internal def convertBits__val(self: Bits, val: "BitVal", toType: HdlType): if toType == BOOL: return val != self.getValueCls().from_py(self, 0) elif isinstance(toType, Bits): if self.signed != toType.signed: if self.strict_sign and bool(self.signed) != bool(toType.signed): raise TypeConversionErr(self, toType) val = val._convSign__val(toType.signed) w_from, w_to = self.bit_length(), toType.bit_length() if w_from != w_to: if self.strict_width: raise TypeConversionErr(self, toType) if w_from > w_to: # cut off some bits from value new_m = val.vld_mask & toType.all_mask() else: # w_from < w_to, extend the value to some bit length extra_mask_bits = mask(w_to - w_from) new_m = set_bit_range(val.vld_mask, w_from, w_to - w_from, extra_mask_bits) val = toType.from_py(val.val, new_m) if val._dtype != toType: # sign and width checked, only name, strict_* flags can be different val = toType.from_py(val.val, val.vld_mask) return val elif toType == INT: return INT.getValueCls()(INT, val.val, int(val._is_full_valid())) return default_auto_cast_fn(self, val, toType)
[docs]@internal def convertBits(self: Bits, sigOrVal, toType: HdlType): """ Cast Bit subtypes, (integers, bool, ...) """ if isinstance(sigOrVal, HValue): return convertBits__val(self, sigOrVal, toType) elif toType == BOOL: if self.bit_length() == 1: v = 0 if sigOrVal._dtype.negated else 1 if isinstance(sigOrVal, RtlSignal): sigOrVal: RtlSignal try: d = sigOrVal.singleDriver() except SignalDriverErr: d = None if d is not None and isinstance(d, Operator) and d.operator == AllOps.NOT: # signal itself is negated, ~a = 1 to a = 0 v = int(not bool(v)) sigOrVal = d.operands[0] return sigOrVal._eq(self.getValueCls().from_py(self, v)) elif isinstance(toType, Bits): if self.bit_length() == toType.bit_length(): #if self.force_vector != toType.force_vector: # raise NotImplementedError(self, toType) if self.const == toType.const: return sigOrVal._convSign(toType.signed) return default_auto_cast_fn(self, sigOrVal, toType)
[docs]@internal def reinterpret_bits_to_hstruct__val(val: HValue, hStructT: HStruct): """ Reinterpret signal of type Bits to signal of type HStruct """ container = hStructT.from_py(None) hStructT.vld_mask = int(val._is_full_valid()) offset = 0 for f in hStructT.fields: t = f.dtype width = t.bit_length() if f.name is not None: v = val[(width + offset):offset] v = v._reinterpret_cast(t) setattr(container, f.name, v) offset += width return container
[docs]@internal def transfer_signals(src: InterfaceBase, dst: InterfaceBase): if src._interfaces: assert len(src._interfaces) == len(dst._interfaces), (src, dst) for si, di in zip(src._interfaces, dst._interfaces): transfer_signals(si, di) else: dst._sig = src._sig dst._sigInside = src._sigInside
[docs]@internal def reinterpret_bits_to_hstruct(val: Union[RtlSignal, HValue], hStructT: HStruct): """ Reinterpret signal of type Bits to signal of type HStruct """ container = HdlType_to_Interface().apply(hStructT) container._loadDeclarations() offset = 0 for f in hStructT.fields: t = f.dtype width = t.bit_length() if f.name is not None: v = val[(width + offset):offset] v = v._reinterpret_cast(t) current = getattr(container, f.name) if isinstance(v, InterfaceBase): transfer_signals(v, current) elif isinstance(v, HObjList): raise NotImplementedError() elif isinstance(v, (RtlSignal, HValue)): current._sig = v else: raise NotImplementedError() offset += width return container
[docs]@internal def reinterpret_bits_to_harray(sigOrVal: Union[RtlSignal, HValue], hArrayT: HArray): elmT = hArrayT.element_t elmWidth = elmT.bit_length() if isinstance(sigOrVal, HValue): a = hArrayT.from_py(None) a.vld_mask = int(sigOrVal._is_full_valid()) else: a = HObjList([None for _ in range(hArrayT.size)]) for i, item in enumerate(iterBits(sigOrVal, bitsInOne=elmWidth, skipPadding=False)): item = item._reinterpret_cast(elmT) a[i] = item return a
[docs]@internal def reinterpretBits__val(self: Bits, val: HValue, toType: HdlType): if isinstance(toType, Bits): if self.signed != toType.signed: val = val._convSign__val(toType.signed) return fitTo_t(val, toType) elif isinstance(toType, HStruct): return reinterpret_bits_to_hstruct__val(val, toType) elif isinstance(toType, HUnion): raise NotImplementedError() elif isinstance(toType, HArray): return reinterpret_bits_to_harray(val, toType) return default_auto_cast_fn(self, val, toType)
[docs]@internal def reinterpretBits(self: Bits, sigOrVal: Union[RtlSignal, HValue], toType: HdlType): """ Cast object of same bit size between to other type (f.e. bits to struct, union or array) """ if isinstance(sigOrVal, HValue): return reinterpretBits__val(self, sigOrVal, toType) elif isinstance(toType, Bits): if self.signed != toType.signed: sigOrVal = sigOrVal._convSign(toType.signed) return fitTo_t(sigOrVal, toType) elif sigOrVal._dtype.bit_length() == toType.bit_length(): if isinstance(toType, HStruct): return reinterpret_bits_to_hstruct(sigOrVal, toType) elif isinstance(toType, HUnion): raise NotImplementedError() elif isinstance(toType, HArray): return reinterpret_bits_to_harray(sigOrVal, toType) return default_auto_cast_fn(self, sigOrVal, toType)