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 __init__(self, exponent_w, mantisa_w, name=None, const=False): """ :param negated: if true the value is in negated form """ HdlType.__init__(self, const=const) assert exponent_w > 0, exponent_w assert mantisa_w > 0, mantisa_w Floatt.__init__(self, exponent_w, mantisa_w, name=name)
def is_non_const_stream(t: HdlType): if isinstance(t, HStream): try: t.bit_length() except TypeError: return True return False
def __init__(self, bit_length, signed=BITS_DEFAUTL_SIGNED, force_vector=BITS_DEFAUTL_FORCEVECTOR, negated=BITS_DEFAUTL_NEGATED, name=None, const=False, strict_sign=True, strict_width=True): """ :param negated: if true the value is in negated form """ self.negated = negated HdlType.__init__(self, const=const) bit_length = int(bit_length) assert bit_length > 0, bit_length Bits3t.__init__(self, bit_length, signed, name=name, force_vector=force_vector, strict_sign=strict_sign, strict_width=strict_width)
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 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 _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 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 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 as_hdl_HdlType(self, typ: HdlType, declaration=False): try: return typ._as_hdl(self, declaration) except MethodNotOverloaded: pass if typ == STR: sFn = self.as_hdl_HdlType_str elif isinstance(typ, Bits): sFn = self.as_hdl_HdlType_bits elif isinstance(typ, HEnum): sFn = self.as_hdl_HdlType_enum elif isinstance(typ, HArray): sFn = self.as_hdl_HdlType_array elif isinstance(typ, Slice): sFn = self.as_hdl_HdlType_slice else: # [todo] better error msg raise NotImplementedError("type declaration is not implemented" " for type %s" % (HdlType.__repr__(typ))) return sFn(typ, declaration=declaration)
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 does_type_requires_extra_def(self, t: HdlType, other_types: list): try: return t._as_hdl_requires_def(self, other_types) except MethodNotOverloaded: pass return False
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
def does_type_requires_extra_def(self, t: HdlType, other_types: list): try: return t._as_hdl_requires_def(self, other_types) except MethodNotOverloaded: pass return isinstance(t, (HEnum, HArray)) and t not in other_types