def is_non_const_stream(t: HdlType): if isinstance(t, HStream): try: t.bit_length() except TypeError: return True return False
def _loadFromBits(self, dtype: HdlType, bitAddr: int): """ Parse Bits type to this transaction template instance :return: address of it's end """ return bitAddr + dtype.bit_length()
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 to_primitive_stream_t(t: HdlType): """ Convert type to a HStream of Bits With proper frame len, offset etc. """ if isinstance(t, HStruct) and len(t.fields) == 1: return to_primitive_stream_t(t.fields[0].dtype) frame_len = (1, 1) start_offsets = [0, ] if isinstance(t, HStream): e_t = t.element_t if isinstance(e_t, Bits): return t else: frame_len = t.frame_len start_offsets = t.start_offsets t = e_t try: bit_len = t.bit_length() except TypeError: bit_len = None if bit_len is not None: return HStream(Bits(bit_len), frame_len=frame_len, start_offsets=start_offsets) else: raise NotImplementedError(t)
def getTypeWidth(self, dtype: HdlType, do_eval=False)\ -> Tuple[int, Union[int, RtlSignal], bool]: """ :see: doc of method on parent class """ width = dtype.bit_length() widthStr = str(width) return width, widthStr, False
def _loadFromUnion(self, dtype: HdlType, bitAddr: int) -> int: """ Parse HUnion type to this transaction template instance :return: address of it's end """ for field in dtype.fields.values(): ch = TransTmpl(field.dtype, 0, parent=self, origin=field) self.children.append(ch) return bitAddr + dtype.bit_length()
def get_trace_formatter(self, t: HdlType)\ -> Tuple[str, int, Callable[[RtlSignalBase, HValue], str]]: """ :return: (vcd type name, vcd width, formatter fn) """ if isinstance(t, (Bits3t, Bits)): return (VCD_SIG_TYPE.WIRE, t.bit_length(), JsonBitsFormatter()) elif isinstance(t, (Enum3t, HEnum)): return (VCD_SIG_TYPE.ENUM, 1, JsonEnumFormatter()) elif isinstance(t, (HArray, Array3t)): dimensions = [] while isinstance(t, (HArray, Array3t)): dimensions.append(t.size) t = t.element_t _, _, elm_format = self.get_trace_formatter(t) return (VCD_SIG_TYPE.ARRAY, dimensions + [ t.bit_length(), ], JsonArrayFormatter(dimensions, elm_format)) else: raise ValueError(t)
def hstruct_reinterpret_to_bits(self, sigOrVal, toType: HdlType): assert toType.bit_length() == self.bit_length() parts = [] for f in self.fields: if f.name is None: width = f.bit_length() part = vec(None, width) else: part = getattr(sigOrVal, f.name) if not isinstance(part, (Value, RtlSignalBase)): part = f.dtype.from_py(part) parts.append(part) return Concat(*reversed(parts))
def convertBits(self: Bits, sigOrVal, toType: HdlType): """ Cast Bit subtypes, (integers, bool, ...) """ if isinstance(sigOrVal, Value): return convertBits__val(self, sigOrVal, toType) elif toType == BOOL: if self.bit_length() == 1: v = 0 if sigOrVal._dtype.negated else 1 return sigOrVal._eq(self.getValueCls().from_py(self, v)) elif isinstance(toType, Bits): if self.bit_length() == toType.bit_length(): return sigOrVal._convSign(toType.signed) return default_auto_cast_fn(self, sigOrVal, toType)
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)
def fitTo_t(what: Union[RtlSignalBase, HValue], where_t: HdlType, extend: bool = True, shrink: bool = True): """ Slice signal "what" to fit in "where" or arithmetically (for signed by MSB / unsigned, vector with 0) extend "what" to same width as "where" little-endian impl. :param extend: allow increasing of the signal width :param shrink: allow shrinking of the signal width """ whatWidth = what._dtype.bit_length() toWidth = where_t.bit_length() if toWidth == whatWidth: return what elif toWidth < whatWidth: # slice if not shrink: raise BitWidthErr() return what[toWidth:] else: if not extend: raise BitWidthErr() w = toWidth - whatWidth if what._dtype.signed: # signed extension msb = what[whatWidth - 1] ext = reduce(lambda a, b: a._concat(b), [msb for _ in range(w)]) else: # 0 extend ext = Bits(w).from_py(0) return ext._concat(what)
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)