def slice_to_SLICE(sliceVals, width): """convert python slice to value of SLICE hdl type""" if sliceVals.step is not None: raise NotImplementedError() start = sliceVals.start stop = sliceVals.stop if sliceVals.start is None: start = INT.fromPy(width) else: start = toHVal(sliceVals.start) if sliceVals.stop is None: stop = INT.fromPy(0) else: stop = toHVal(sliceVals.stop) startIsVal = isinstance(start, Value) stopIsVal = isinstance(stop, Value) indexesAreValues = startIsVal and stopIsVal if indexesAreValues: updateTime = max(start.updateTime, stop.updateTime) else: updateTime = -1 return Slice.getValueCls()((start, stop), SLICE, 1, updateTime)
def __getitem__(self, key): iamVal = isinstance(self, HValue) key = toHVal(key) isSLICE = isinstance(key, Slice.getValueCls()) if isSLICE: raise NotImplementedError() elif isinstance(key, (HValue, RtlSignalBase)): pass else: raise NotImplementedError( f"Index operation not implemented for index {key}") if iamVal and isinstance(key, HValue): return self._getitem__val(key) return Operator.withRes(AllOps.INDEX, [self, key], self._dtype.element_t)
def __getitem__(self, key): iamVal = isinstance(self, Value) key = toHVal(key) isSLICE = isinstance(key, Slice.getValueCls()) if isSLICE: raise NotImplementedError() elif isinstance(key, RtlSignalBase): key = key._auto_cast(INT) elif isinstance(key, Value): pass else: raise NotImplementedError( "Index operation not implemented for index %r" % (key)) if iamVal and isinstance(key, Value): return self._getitem__val(key) return Operator.withRes(AllOps.INDEX, [self, key], self._dtype.elmType)
""" Definitions of most common types """ from hwt.hdl.types.bits import Bits from hwt.hdl.types.slice import Slice from hwt.hdl.types.string import String from hwt.hdl.types.float import HFloat BOOL = Bits(bit_length=1, name="bool") INT = Bits(bit_length=32, signed=True, name="int", strict_sign=False, strict_width=False) BIT = Bits(bit_length=1) BIT_N = Bits(bit_length=1, negated=True) STR = String() SLICE = Slice() FLOAT64 = HFloat(11, 52, name="float64")
def __getitem__(self, key): """ [] operator :attention: Table below is for litle endian bit order (MSB:LSB) which is default. This is **reversed** as it is in pure python where it is [0, len(self)]. :attention: slice on slice f signal is automatically reduced to single slice +-----------------------------+----------------------------------------------------------------------------------+ | a[up:low] | items low through up; a[16:8] selects upper byte from 16b vector a | +-----------------------------+----------------------------------------------------------------------------------+ | a[up:] | low is automatically substituted with 0; a[8:] will select lower 8 bits | +-----------------------------+----------------------------------------------------------------------------------+ | a[:end] | up is automatically substituted; a[:8] will select upper byte from 16b vector a | +-----------------------------+----------------------------------------------------------------------------------+ | a[:], a[-1], a[-2:], a[:-2] | raises NotImplementedError (not implemented due to complicated support in hdl) | +-----------+----------------------------------------------------------------------------------------------------+ """ st = self._dtype length = st.bit_length() if length == 1 and not st.force_vector: # assert not indexing on single bit raise TypeError("indexing on single bit") if isinstance(key, slice): key = slice_to_SLICE(key, length) isSLICE = True else: isSLICE = isinstance(key, Slice.getValueCls()) if isSLICE: # :note: downto notation start = key.val.start stop = key.val.stop if key.val.step != -1: raise NotImplementedError() startIsVal = isinstance(start, HValue) stopIsVal = isinstance(stop, HValue) indexesareHValues = startIsVal and stopIsVal else: key = toHVal(key, INT) iamVal = isinstance(self, HValue) iAmResultOfIndexing = (not iamVal and len(self.drivers) == 1 and isinstance(self.origin, Operator) and self.origin.operator == AllOps.INDEX) Bits = self._dtype.__class__ if isSLICE: if indexesareHValues and start.val == length and stop.val == 0: # selecting all bits no conversion needed return self if iAmResultOfIndexing: # try reduce self and parent slice to one original, parentIndex = self.origin.operands if isinstance(parentIndex._dtype, Slice): parentLower = parentIndex.val.stop start = start + parentLower stop = stop + parentLower return original[start:stop] # check start boundaries if startIsVal: _start = int(start) if _start < 0 or _start > length: raise IndexError(_start, length) # check end boundaries if stopIsVal: _stop = int(stop) if _stop < 0 or _stop > length: raise IndexError(_stop, length) # check width of selected range if startIsVal and stopIsVal and _start - _stop <= 0: raise IndexError(_start, _stop) if iamVal: if isinstance(key, SLICE.getValueCls()): key = key.val v = Bits3val.__getitem__(self, key) if v._dtype.bit_length() == 1 and not v._dtype.force_vector: assert v._dtype is not self._dtype v._dtype.force_vector = True return v else: key = SLICE.from_py(slice(start, stop, -1)) _resWidth = start - stop resT = Bits(bit_length=_resWidth, force_vector=True, signed=st.signed, negated=st.negated) elif isinstance(key, Bits.getValueCls()): if key._is_full_valid(): # check index range _v = int(key) if _v < 0 or _v > length - 1: raise IndexError(_v) if iAmResultOfIndexing: original, parentIndex = self.origin.operands if isinstance(parentIndex._dtype, Slice): parentLower = parentIndex.val.stop return original[parentLower + _v] if iamVal: return Bits3val.__getitem__(self, key) resT = BIT elif isinstance(key, RtlSignalBase): t = key._dtype if isinstance(t, Slice): resT = Bits(bit_length=key.staticEval()._size(), force_vector=True, signed=st.signed, negated=st.negated) elif isinstance(t, Bits): resT = BIT else: raise TypeError("Index operation not implemented" " for index of type %r" % (t)) else: raise TypeError("Index operation not implemented for index %r" % (key)) if st.negated and resT is BIT: resT = BIT_N return Operator.withRes(AllOps.INDEX, [self, key], resT)