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)
def _sig( self, name: str, dtype: HdlType = BIT, def_val: Union[int, None, dict, list] = None, nop_val: Union[int, None, dict, list, "NOT_SPECIFIED"] = NOT_SPECIFIED ) -> RtlSignal: """ Create signal in this unit :see: :func:`hwt.synthesizer.rtlLevel.netlist.RtlNetlist.sig` """ if isinstance(dtype, HStruct): if def_val is not None: raise NotImplementedError() if nop_val is not NOT_SPECIFIED: raise NotImplementedError() container = dtype.from_py(None) for f in dtype.fields: if f.name is not None: r = self._sig(f"{name:s}_{f.name:s}", f.dtype) setattr(container, f.name, r) return container return self._ctx.sig(name, dtype=dtype, def_val=def_val, nop_val=nop_val)
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) if self.bit_length() != toType.bit_length(): if self.strict_width: raise TypeConversionErr(self, toType) val = toType.from_py(val.val, val.vld_mask & toType.all_mask()) 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)
def HdlValue_unpack(t: HdlType, data: List[Union[HValue, RtlSignalBase, int]], getDataFn=None, dataWidth=None): """ Parse raw Bits array to a value of specified HdlType """ if getDataFn is None: assert dataWidth is not None def _getDataFn(x): return toHVal(x)._auto_cast(Bits(dataWidth)) getDataFn = _getDataFn val = t.from_py(None) fData = iter(data) # actual is storage variable for items from frameData actualOffset = 0 actual = None for v in walkFlattenFields(val, skipPadding=False): # walk flatten fields and take values from fData and parse them to # field required = v._dtype.bit_length() if actual is None: actualOffset = 0 try: actual = getDataFn(next(fData)) except StopIteration: raise ValueError("Input data too short") if dataWidth is None: dataWidth = actual._dtype.bit_length() actuallyHave = dataWidth else: actuallyHave = actual._dtype.bit_length() - actualOffset while actuallyHave < required: # collect data for this field try: d = getDataFn(next(fData)) except StopIteration: raise ValueError("Input data too short") actual = d._concat(actual) actuallyHave += dataWidth if actuallyHave >= required: # parse value of actual to field # skip padding _v = actual[(required + actualOffset):actualOffset] _v = _v._auto_cast(v._dtype) v.val = _v.val v.vld_mask = _v.vld_mask # update slice out what was taken actuallyHave -= required actualOffset += required if actuallyHave == 0: actual = None if actual is not None: assert actual._dtype.bit_length() - actualOffset < dataWidth, ( "It should be just a padding at the end of frame") return val