def _concat(self, other): w = self._dtype.bit_length() other_w = other._dtype.bit_length() resWidth = w + other_w resT = vecT(resWidth) if areValues(self, other): return self._concat__val(other) else: w = self._dtype.bit_length() other_w = other._dtype.bit_length() resWidth = w + other_w resT = vecT(resWidth) # is instance of signal if isinstance(other, InterfaceBase): other = other._sig if isinstance(other._dtype, Bits): if other._dtype.signed is not None: other = other._vec() elif other._dtype == BOOL: other = other._convert(BIT) else: raise TypeError(other._dtype) if self._dtype.signed is not None: self = self._vec() return Operator.withRes(AllOps.CONCAT, [self, other], resT)\ ._convert(vecT(resWidth, signed=self._dtype.signed))
def __ne__(self, other): assert self._dtype is other._dtype if areValues(self, other): return self._ne__val(other) else: return Operator.withRes(AllOps.NEQ, [self, other], BOOL)
def boolCmpOp(self, other, op, evalFn=None): other = toHVal(other) if evalFn is None: evalFn = op._evalFn if areValues(self, other): return boolCmpOp__val(self, other, op, evalFn) else: return Operator.withRes(op, [self, other._convert(BOOL)], BOOL)
def intOp(self, other, op, resT, evalFn=None): if evalFn is None: evalFn = op._evalFn other = toHVal(other)._convert(INT) if areValues(self, other): return intOp__val(self, other, op, resT, evalFn) else: return Operator.withRes(op, [self, other], resT)
def bitsArithOp(self, other, op): other = toHVal(other) assert isinstance(other._dtype, (Integer, Bits)) if areValues(self, other): return bitsArithOp__val(self, other, op) else: resT = self._dtype if self._dtype.signed is None: self = self._unsigned() if isinstance(other._dtype, Bits): other = other._convSign(self._dtype.signed) elif isinstance(other._dtype, Integer): pass else: raise TypeError("%s %s %s" % (repr(self), repr(op), repr(other))) o = Operator.withRes(op, [self, other], self._dtype) return o._convert(resT)
def __mul__(self, other): other = toHVal(other) assert isinstance(other._dtype, (Integer, Bits)) if areValues(self, other): return self._mul__val(other) else: resT = getMulResT(self._dtype, other._dtype) if self._dtype.signed is None: self = self._unsigned() if isinstance(other._dtype, Bits) and other._dtype.signed is None: other = other._unsigned() elif isinstance(other._dtype, Integer): pass else: raise TypeError("%s %s %s" % (repr(self), repr(AllOps.MUL), repr(other))) subResT = vecT(resT.bit_length(), self._dtype.signed) o = Operator.withRes(AllOps.MUL, [self, other], subResT) return o._convert(resT)
def __getitem__(self, key): iamVal = isinstance(self, Value) st = self._dtype l = st.bit_length() if l == 1: assert st.forceVector # assert not indexing on single bit isSlice = isinstance(key, slice) isSLICE = isinstance(key, Slice.getValueCls()) if areValues(self, key): return self._getitem__val(key) elif isSlice or isSLICE: if isSlice: if key.step is not None: raise NotImplementedError() start = key.start stop = key.stop if key.start is None: start = boundryFromType(self, 0) + 1 else: start = toHVal(key.start) if key.stop is None: stop = boundryFromType(self, 1) else: stop = toHVal(key.stop) else: start = key.val[0] stop = key.val[1] indexesAreValues = isinstance(start, Value) and isinstance(stop, Value) if indexesAreValues and start.val == l and stop.val == 0: # selecting all bits no conversion needed return self if iamVal and indexesAreValues: raise NotImplementedError("[TODO] bit select on value") else: key = (start - INT.fromPy(1))._downto(stop) # [TODO] type can be wrong, but we need to get rid off widthConstr and use only width _resWidth = (start - 1 - stop)._downto(0) resT = Bits(widthConstr=_resWidth, forceVector=True, signed=st.signed) elif isinstance(key, (int, IntegerVal)): key = toHVal(key) resT = BIT elif isinstance(key, RtlSignalBase): t = key._dtype if isinstance(t, Integer): resT = BIT elif isinstance(t, Slice): resT = Bits(widthConstr=key, forceVector=st.forceVector, signed=st.signed) elif isinstance(t, Bits): resT = BIT key = key._convert(INT) else: raise TypeError("Index operation not implemented for index of type %s" % (repr(t))) else: raise TypeError("Index operation not implemented for index %s" % (repr(key))) # [TODO] boundary check return Operator.withRes(AllOps.INDEX, [self, key], resT)
def _downto(self, other): other = toHVal(other)._convert(INT) if areValues(self, other): return self._downto__val(other) else: return Operator.withRes(AllOps.DOWNTO, [self, other], SLICE)