from hwt.hdl.value import Value, areValues from hwt.hdl.types.defs import BOOL, INT, SLICE from hwt.hdl.operator import Operator from hwt.hdl.operatorDefs import AllOps from hwt.hdl.types.typeCast import toHVal from hwt.hdl.types.integer import Integer from operator import pow, eq BoolVal = BOOL.getValueCls() SliceVal = SLICE.getValueCls() def intOp__val(self, other, resT, evalFn): v = evalFn(self.val, other.val) vldMask = int(self.vldMask and other.vldMask) updateTime = max(self.updateTime, other.updateTime) return resT.getValueCls()(v, resT, vldMask, updateTime) def intOp(self, other, op, resT, evalFn=None): if evalFn is None: evalFn = op._evalFn other = toHVal(other)._auto_cast(INT) if areValues(self, other): return intOp__val(self, other, resT, evalFn) else: return Operator.withRes(op, [self, other], resT) def intAritmeticOp(self, other, op):
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)