def bitsCmp(self, other, op, evalFn=None): """ :attention: If other is Bool signal convert this to boolean (not ideal, due VHDL event operator) """ other = toHVal(other) iamVal = isinstance(self, Value) otherIsVal = isinstance(other, Value) if evalFn is None: evalFn = op._evalFn if iamVal and otherIsVal: return bitsCmp__val(self, other, op, evalFn) else: if other._dtype == BOOL: self = self._convert(BOOL) elif self._dtype == other._dtype: pass elif isinstance(other._dtype, Integer): other = other._convert(self._dtype) else: raise TypeError("Values of types (%s, %s) are not comparable" % (repr(self._dtype), repr(other._dtype))) return Operator.withRes(op, [self, other], BOOL)
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 convertBits(self, sigOrVal, toType): isVal = isinstance(sigOrVal, Value) if isinstance(toType, Boolean): if isVal: return sigOrVal._eq(self.getValueCls().fromPy(1, self)) elif self.bit_length() == 1: v = 0 if sigOrVal.negated else 1 return sigOrVal._eq(self.getValueCls().fromPy(v, self)) elif isinstance(toType, Bits): if self.bit_length() == toType.bit_length(): return sigOrVal._convSign(toType.signed) elif toType == INT: if isVal: if self.signed: raise NotImplementedError() else: fullMask = mask(self.bit_length()) return INT.getValueCls()(sigOrVal.val, INT, sigOrVal.vldMask == fullMask, sigOrVal.updateTime) else: return Operator.withRes(AllOps.BitsToInt, [sigOrVal], toType) return HdlType.defaultConvert(self, sigOrVal, toType)
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 _ternary(self, ifTrue, ifFalse): ifTrue = toHVal(ifTrue) ifFalse = toHVal(ifFalse) if isinstance(self, Value): return self._ternary__val(ifTrue, ifFalse) else: return Operator.withRes(AllOps.TERNARY, [self, ifTrue, ifFalse], ifTrue._dtype)
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 __invert__(self): if isinstance(self, Value): return self._invert__val() else: try: # double negation d = self.singleDriver() if isinstance(d, Operator) and d.operator == AllOps.NOT: return d.ops[0] except MultipleDriversExc: pass return Operator.withRes(AllOps.NOT, [self], self._dtype)
def SwitchContainer(cls, sw, indent, enclosure=None): switchOn = sw.switchOn mkCond = lambda c: {Operator(AllOps.EQ, [switchOn, c])} elIfs = [] for key, statements in sw.cases: elIfs.append((mkCond(key), statements)) ifFalse = sw.default topCond = mkCond(sw.cases[0][0]) topIf = IfContainer(topCond, sw.cases[0][1], ifFalse, elIfs) return cls.IfContainer(topIf, indent, enclosure)
def boolLogOp(self, other, op, getVldFn, whenOneIsVal): other = toHVal(other) if isinstance(self, Value): if isinstance(other, Value): return boolLogOp__val(self, other, op, getVldFn) return whenOneIsVal(self, other) else: if isinstance(other, Value): return whenOneIsVal(other, self) return Operator.withRes(op, [self, other._convert(BOOL)], BOOL)
def _convSign(self, signed): if isinstance(self, Value): return self._convSign__val(signed) else: if self._dtype.signed == signed: return self t = copy(self._dtype) t.signed = signed if signed is None: cnv = AllOps.BitsAsVec elif signed: cnv = AllOps.BitsAsSigned else: cnv = AllOps.BitsAsUnsigned return Operator.withRes(cnv, [self], t)
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 __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._convert(INT) elif isinstance(key, Value): pass else: raise NotImplementedError( "Index operation not implemented for index %s" % (repr(key))) if iamVal and isinstance(key, Value): return self._getitem__val(key) return Operator.withRes(AllOps.INDEX, [self, key], self._dtype.elmType)
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 bitsBitOp(self, other, op, getVldFn): """ :attention: If other is Bool signal, convert this to boolean (not ideal, due VHDL event operator) """ other = toHVal(other) iamVal = isinstance(self, Value) otherIsVal = isinstance(other, Value) if iamVal and otherIsVal: return bitsBitOp__val(self, other, op, getVldFn) else: if other._dtype == BOOL: self = self._convert(BOOL) return op._evalFn(self, other) elif self._dtype == other._dtype: pass else: raise TypeError("Types are not comparable (%s, %s)" % (repr(self._dtype), repr(other._dtype))) return Operator.withRes(op, [self, other], self._dtype)
def convertInteger(self, sigOrVal, toType): isVal = isinstance(sigOrVal, Value) if isinstance(toType, Integer): if isVal: v = sigOrVal.clone() if toType.min is not None: assert v.val >= toType.min if toType.max is not None: assert v.val <= toType.max v._dtype = toType return v else: return sigOrVal # [TODO] use convertor op elif toType == BOOL: if isVal: v = sigOrVal.val assert v == 0 or v == 1 return BooleanVal(v, BOOL, sigOrVal.vldMask, sigOrVal.updateTime) elif isinstance(toType, Bits): if isVal: _v = sigOrVal.val w = toType.bit_length() assert _v.bit_length() <= w, "%d can not fit into %d bits" % (_v, w) v = toType.fromPy(_v) v.updateTime = sigOrVal.updateTime v._dtype = toType if not sigOrVal.vldMask: v.vldMask = 0 return v else: return Operator.withRes(AllOps.IntToBits, [sigOrVal], toType) return HdlType.defaultConvert(self, sigOrVal, toType)
def _hasEvent(self, now): if isinstance(self, Value): return self._hasEvent__val(now) else: return Operator.withRes(AllOps.EVENT, [self], BOOL)
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 _onFallingEdge(self, now): if isinstance(self, Value): return self._onFallingEdge__val(now) else: return Operator.withRes(AllOps.FALLIGN_EDGE, [self], BOOL)
def _onRisingEdge(self, now): if isinstance(self, Value): return self._onRisingEdge__val(now) else: return Operator.withRes(AllOps.RISING_EDGE, [self], BOOL)
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)
def __neg__(self): if isinstance(self, Value): return self._neg__val() else: return Operator.withRes(AllOps.UN_MINUS, [self], INT)