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 bitsArithOp(self, other, op): other = toHVal(other, self._dtype) assert isinstance(other._dtype, Bits), other._dtype if areValues(self, other): return bitsArithOp__val(self, other, op._evalFn) else: if self._dtype.signed is None: self = self._unsigned() resT = self._dtype if isinstance(other._dtype, Bits): t0 = self._dtype t1 = other._dtype if t0.bit_length() != t1.bit_length(): if not t1.strict_width: # resize to type of this other = other._auto_cast(t1) t1 = other._dtype pass elif not t0.strict_width: # resize self to type of result self = self._auto_cast(t0) t0 = self._dtype pass else: raise TypeError("%r %r %r" % (self, op, other)) if t1.signed != resT.signed: other = other._convSign(t0.signed) else: raise TypeError("%r %r %r" % (self, op, other)) o = Operator.withRes(op, [self, other], self._dtype) return o._auto_cast(resT)
def _concat(self, other): """ Concatenate this with other to one wider value/signal """ w = self._dtype.bit_length() try: other._dtype.bit_length except AttributeError: raise TypeError("Can not concat Bits and", other._dtype) 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 Bits = self._dtype.__class__ resT = Bits(resWidth, signed=self._dtype.signed) # 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._auto_cast(BIT) else: raise TypeError(other._dtype) if self._dtype.signed is not None: self = self._vec() return Operator.withRes(AllOps.CONCAT, [self, other], resT)\ ._auto_cast(Bits(resWidth, signed=self._dtype.signed))
def cast_integer(self, sigOrVal, toType): isVal = isinstance(sigOrVal, Value) if toType == BOOL: if isVal: v = int(bool(sigOrVal.val)) return HBoolVal(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 default_auto_cast_fn(self, sigOrVal, toType)
def __floordiv__(self, other) -> "Bits3val": other = toHVal(other) if isinstance(self, Value) and isinstance(other, Value): return Bits3val.__floordiv__(self, other) else: return Operator.withRes(AllOps.MUL, [self, other], self._dtype.__copy__())
def __mul__(self, other): Bits = self._dtype.__class__ other = toHVal(other) if not isinstance(other._dtype, Bits): raise TypeError(other) if areValues(self, other): return self._mul__val(other) else: myT = self._dtype if self._dtype.signed is None: self = self._unsigned() if isinstance(other._dtype, Bits): s = other._dtype.signed if s is None: other = other._unsigned() else: raise TypeError("%r %r %r" % (self, AllOps.MUL, other)) if other._dtype == INT: res_w = myT.bit_length() * 2 res_sign = self._dtype.signed else: res_w = myT.bit_length() + other._dtype.bit_length() res_sign = self._dtype.signed or other._dtype.signed subResT = Bits(res_w, signed=res_sign) o = Operator.withRes(AllOps.MUL, [self, other], subResT) resT = Bits(res_w, signed=myT.signed) return o._auto_cast(resT)
def _eq(self, other): assert self._dtype is other._dtype if areHValues(self, other): return self._eq__val(other) else: return Operator.withRes(AllOps.EQ, [self, other], BOOL)
def _convSign(self, signed): """ Convert signum, no bit manipulation just data are represented differently :param signed: if True value will be signed, if False value will be unsigned, if None value will be vector without any sign specification """ if isinstance(self, HValue): return self._convSign__val(signed) else: if self._dtype.signed == signed: return self t = copy(self._dtype) t.signed = signed if t.signed is not None: t.force_vector = True if signed is None: cnv = AllOps.BitsAsVec elif signed: cnv = AllOps.BitsAsSigned else: cnv = AllOps.BitsAsUnsigned return Operator.withRes(cnv, [self], t)
def bitsBitOp(self, other, op, getVldFn, reduceCheckFn): """ :attention: If other is Bool signal, convert this to bool (not ideal, due VHDL event operator) """ other = toHVal(other) iamVal = isinstance(self, Value) otherIsVal = isinstance(other, Value) if iamVal and otherIsVal: other = other._auto_cast(self._dtype) return bitsBitOp__val(self, other, op, getVldFn) else: if other._dtype == BOOL: self = self._auto_cast(BOOL) return op._evalFn(self, other) elif self._dtype == other._dtype: pass else: raise TypeError("Can not apply operator %r (%r, %r)" % (op, self._dtype, other._dtype)) if otherIsVal: r = reduceCheckFn(self, other) if r is not None: return r elif iamVal: r = reduceCheckFn(other, self) if r is not None: return r return Operator.withRes(op, [self, other], self._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._auto_cast(BOOL)], 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 __floordiv__(self, other) -> "Bits3val": other = toHVal(other, suggestedType=self._dtype) if isinstance(self, HValue) and isinstance(other, HValue): return Bits3val.__floordiv__(self, other) else: if not isinstance(other._dtype, self._dtype.__class__): raise TypeError() return Operator.withRes(AllOps.DIV, [self, other], self._dtype.__copy__())
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 _ternary(self, a, b): if isinstance(self, HValue): if self: return a else: return b else: a = toHVal(a) b = toHVal(b) return Operator.withRes(AllOps.TERNARY, [self, a, b], a._dtype.__copy__())
def __neg__(self): if isinstance(self, HValue): return Bits3val.__neg__(self) else: if not self._dtype.signed: self = self._signed() resT = self._dtype o = Operator.withRes(AllOps.MINUS_UNARY, [self], self._dtype) return o._auto_cast(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.operands[0] except (MultipleDriversErr, NoDriverErr): pass return Operator.withRes(AllOps.NOT, [self], self._dtype)
def __invert__(self): if isinstance(self, HValue): return Bits3val.__invert__(self) else: try: # double negation d = self.singleDriver() if isinstance(d, Operator) and d.operator == AllOps.NOT: return d.operands[0] except SignalDriverErr: pass return Operator.withRes(AllOps.NOT, [self], self._dtype)
def _operand(cls, operand: Operator, operator: OpDefinition, ctx: SerializerCtx): s = cls.asHdl(operand, ctx) if isinstance(operand, RtlSignalBase): try: o = operand.singleDriver() if o.operator != operator and\ cls.opPrecedence[o.operator] <= cls.opPrecedence[operator]: return "(%s)" % s except Exception: pass return s
def __mul__(self, other): Bits = self._dtype.__class__ other = toHVal(other) if not isinstance(other._dtype, Bits): raise TypeError(other) self_is_val = isinstance(self, HValue) other_is_val = isinstance(other, HValue) if self_is_val and other_is_val: return Bits3val.__mul__(self, other) else: # reduce *1 and *0 if self_is_val and self._is_full_valid(): _s = int(self) if _s == 0: return self._dtype.from_py(0) elif _s: return other._auto_cast(self._dtype) if other_is_val and other._is_full_valid(): _o = int(other) if _o == 0: return self._dtype.from_py(0) elif _o == 1: return self myT = self._dtype if self._dtype.signed is None: self = self._unsigned() if isinstance(other._dtype, Bits): s = other._dtype.signed if s is None: other = other._unsigned() else: raise TypeError("%r %r %r" % (self, AllOps.MUL, other)) if other._dtype == INT: res_w = myT.bit_length() res_sign = self._dtype.signed subResT = resT = myT else: res_w = max(myT.bit_length(), other._dtype.bit_length()) res_sign = self._dtype.signed or other._dtype.signed subResT = Bits(res_w, signed=res_sign) resT = Bits(res_w, signed=myT.signed) o = Operator.withRes(AllOps.MUL, [self, other], subResT) return o._auto_cast(resT)
def bitsBitOp(self, other, op, getVldFn, reduceCheckFn): """ :attention: If other is Bool signal, convert this to bool (not ideal, due VHDL event operator) """ other = toHVal(other, self._dtype) iamVal = isinstance(self, HValue) otherIsVal = isinstance(other, HValue) if iamVal and otherIsVal: other = other._auto_cast(self._dtype) return bitsBitOp__val(self, other, op._evalFn, getVldFn) else: s_t = self._dtype o_t = other._dtype if not isinstance(o_t, s_t.__class__): raise TypeError(o_t) if s_t == o_t: pass elif o_t == BOOL and s_t != BOOL: self = self._auto_cast(BOOL) return op._evalFn(self, other) elif o_t != BOOL and s_t == BOOL: other = other._auto_cast(BOOL) return op._evalFn(self, other) elif s_t.bit_length() == 1 and o_t.bit_length() == 1\ and s_t.signed is o_t.signed \ and s_t.force_vector != o_t.force_vector: if s_t.force_vector: self = self[0] else: other = other[0] else: raise TypeError("Can not apply operator %r (%r, %r)" % (op, self._dtype, other._dtype)) if otherIsVal: r = reduceCheckFn(self, other) if r is not None: return r elif iamVal: r = reduceCheckFn(other, self) if r is not None: return r return Operator.withRes(op, [self, other], self._dtype)
def _ternary(self, a, b): if isinstance(self, HValue): if self: return a else: return b else: a = toHVal(a) b = toHVal(b) try: if a == b: return a except ValidityError: pass return Operator.withRes(AllOps.TERNARY, [self, a, b], a._dtype.__copy__())
def convertBits(self, sigOrVal, toType): """ Cast signed-unsigned, to int or bool """ if isinstance(sigOrVal, Value): return convertBits__val(self, sigOrVal, toType) elif isinstance(toType, HBool): if self.bit_length() == 1: v = 0 if sigOrVal._dtype.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: return Operator.withRes(AllOps.BitsToInt, [sigOrVal], toType) return default_auto_cast_fn(self, sigOrVal, toType)
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)
def boolLogOp(self, other, op, getVldFn, reduceCheckFn): other = toHVal(other) iamVal = isinstance(self, Value) otherIsVal = isinstance(other, Value) if iamVal and otherIsVal: return boolLogOp__val(self, other, op, getVldFn) else: if otherIsVal: r = reduceCheckFn(self, other) if r is not None: return r elif iamVal: r = reduceCheckFn(other, self) if r is not None: return r return Operator.withRes(op, [self, other._auto_cast(BOOL)], BOOL)
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): assert other._dtype.bit_length() == resT.bit_length( ), (op, other._dtype.bit_length(), resT.bit_length()) other = other._convSign(self._dtype.signed) elif isinstance(other._dtype, Integer): pass else: raise TypeError("%r %r %r" % (self, op, other)) o = Operator.withRes(op, [self, other], self._dtype) return o._auto_cast(resT)
def bitsCmp(self, other, op, evalFn=None): """ :attention: If other is Bool signal convert this to bool (not ideal, due VHDL event operator) """ other = toHVal(other) t = self._dtype ot = other._dtype iamVal = isinstance(self, Value) otherIsVal = isinstance(other, Value) if evalFn is None: evalFn = op._evalFn if iamVal and otherIsVal: if ot == BOOL: self = self._auto_cast(BOOL) elif t == ot: pass elif isinstance(ot, Integer): other = other._auto_cast(t) else: raise TypeError("Values of types (%r, %r) are not comparable" % ( self._dtype, other._dtype)) return bitsCmp__val(self, other, op, evalFn) else: if ot == BOOL: self = self._auto_cast(BOOL) elif t == ot: pass elif isinstance(ot, Integer): other = other._auto_cast(self._dtype) else: raise TypeError("Values of types (%r, %r) are not comparable" % ( self._dtype, other._dtype)) return Operator.withRes(op, [self, other], BOOL)
def HdlType_bits(cls, typ, ctx, declaration=False): disableRange = False bitLength = typ.bit_length() w = typ.width isVector = typ.forceVector or bitLength > 1 if typ.signed is None: if isVector: name = 'STD_LOGIC_VECTOR' else: return 'STD_LOGIC' elif typ.signed: name = "SIGNED" else: name = 'UNSIGNED' if disableRange: constr = "" elif isinstance(w, int): constr = "(%d DOWNTO 0)" % (w - 1) else: o = Operator(AllOps.SUB, (w, hInt(1))) constr = "(%s DOWNTO 0)" % cls.Operator(o, ctx) return name + constr
def __neg__(self): if isinstance(self, Value): return self._neg__val() else: return Operator.withRes(AllOps.UN_MINUS, [self], INT)
def _downto(self, other): other = toHVal(other)._auto_cast(INT) if areValues(self, other): return self._downto__val(other) else: return Operator.withRes(AllOps.DOWNTO, [self, other], SLICE)