def __init__(self, sim: "BasicRtlSimulator", name="Ram_dp"): BasicRtlSimModel.__init__(self, sim, name=name) # ports self.io.a_addr = BasicRtlSimProxy(sim, self, "a_addr", Bits3t(8, 0), None) self.io.a_clk = BasicRtlSimProxy(sim, self, "a_clk", Bits3t(1, 0), None) self.io.a_din = BasicRtlSimProxy(sim, self, "a_din", Bits3t(64, 0), None) self.io.a_dout = BasicRtlSimProxy(sim, self, "a_dout", Bits3t(64, 0), None) self.io.a_en = BasicRtlSimProxy(sim, self, "a_en", Bits3t(1, 0), None) self.io.a_we = BasicRtlSimProxy(sim, self, "a_we", Bits3t(1, 0), None) self.io.b_addr = BasicRtlSimProxy(sim, self, "b_addr", Bits3t(8, 0), None) self.io.b_clk = BasicRtlSimProxy(sim, self, "b_clk", Bits3t(1, 0), None) self.io.b_din = BasicRtlSimProxy(sim, self, "b_din", Bits3t(64, 0), None) self.io.b_dout = BasicRtlSimProxy(sim, self, "b_dout", Bits3t(64, 0), None) self.io.b_en = BasicRtlSimProxy(sim, self, "b_en", Bits3t(1, 0), None) self.io.b_we = BasicRtlSimProxy(sim, self, "b_we", Bits3t(1, 0), None) # internal signals self.io.ram_memory = BasicRtlSimProxy(sim, self, "ram_memory", self.arr_t_0, None) self.const_0 = Array3val(self.arr_t_0, {}, 0) self.const_0_0 = Bits3val(Bits3t(64, 0), 0, 0) self.const_1_0 = Bits3val(Bits3t(1, 0), 1, 1)
def __setitem__(self, index, value): """ this []= operator can not be called in desing description, it can be only used to update HValues """ if not isinstance(self, HValue): raise TypeError( "To assign a member of hdl arrray/vector/list/... use a[index](val) instead of a[index] = val" ) # convert index to hSlice or hInt if isinstance(index, HValue): index = index elif isinstance(index, slice): length = self._dtype.bit_length() index = slice_to_SLICE(index, length) if not index._is_full_valid(): raise ValueError("invalid index", index) else: index = hInt(index) # convert value to bits of length specified by index if index._dtype == SLICE: Bits = self._dtype.__class__ itemT = Bits(index._size()) else: itemT = BIT if isinstance(value, HValue): value = value._auto_cast(itemT) else: value = itemT.from_py(value) return Bits3val.__setitem__(self, index, value)
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 __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 __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, 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 __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 __setitem__(self, index, value): """ this can not be called in desing description on non static values, only simulator can resolve this (in design use self[index] ** value instead of self[index] = value) """ # convert index to hSlice or hInt indexConst = True if not isinstance(index, Value): if isinstance(index, RtlSignalBase): if index._const: index = index.staticEval() else: indexConst = False elif isinstance(index, slice): length = self._dtype.bit_length() index = slice_to_SLICE(index, length) else: index = hInt(index) if indexConst and not index._is_full_valid(): indexConst = False # convert value to bits of length specified by index if indexConst: if index._dtype == SLICE: Bits = self._dtype.__class__ itemT = Bits(index._size()) else: itemT = BIT if not isinstance(value, Value): if isinstance(value, RtlSignalBase): if value._const: value = value.staticEval()._auto_cast(itemT) valueConst = True else: valueConst = False else: value = itemT.from_py(value) valueConst = True else: valueConst = True value = value._auto_cast(itemT) if indexConst and valueConst and isinstance(self, Value): return Bits3val.__setitem__(self, index, value) raise TypeError( "Only simulator can resolve []= for signals or invalid index")
def _concat__val(self, other): return Bits3val._concat(self, other)
def _convSign__val(self, signed): v = Bits3val.cast_sign(self, signed) if signed is not None: assert v._dtype is not self._dtype, "can modify shared type instance" v._dtype.force_vector = True return v
def __hash__(self): if isinstance(self, RtlSignalBase): return hash(id(self)) else: return Bits3val.__hash__(self)
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)
def _convSign__val(self, signed): return Bits3val.cast_sign(self, signed)
def __init__(self, sim: "BasicRtlSimulator", name="Showcase0"): BasicRtlSimModel.__init__(self, sim, name=name) # ports self.io.a = BasicRtlSimProxy(sim, self, "a", Bits3t(32, 0), None) self.io.b = BasicRtlSimProxy(sim, self, "b", Bits3t(32, 1), None) self.io.c = BasicRtlSimProxy(sim, self, "c", Bits3t(32, 0), None) self.io.clk = BasicRtlSimProxy(sim, self, "clk", Bits3t(1, 0), None) self.io.cmp_0 = BasicRtlSimProxy(sim, self, "cmp_0", Bits3t(1, 0), None) self.io.cmp_1 = BasicRtlSimProxy(sim, self, "cmp_1", Bits3t(1, 0), None) self.io.cmp_2 = BasicRtlSimProxy(sim, self, "cmp_2", Bits3t(1, 0), None) self.io.cmp_3 = BasicRtlSimProxy(sim, self, "cmp_3", Bits3t(1, 0), None) self.io.cmp_4 = BasicRtlSimProxy(sim, self, "cmp_4", Bits3t(1, 0), None) self.io.cmp_5 = BasicRtlSimProxy(sim, self, "cmp_5", Bits3t(1, 0), None) self.io.contOut = BasicRtlSimProxy(sim, self, "contOut", Bits3t(32, 0), None) self.io.d = BasicRtlSimProxy(sim, self, "d", Bits3t(32, 0), None) self.io.e = BasicRtlSimProxy(sim, self, "e", Bits3t(1, 0), None) self.io.f = BasicRtlSimProxy(sim, self, "f", Bits3t(1, 0), None) self.io.fitted = BasicRtlSimProxy(sim, self, "fitted", Bits3t(16, 0), None) self.io.g = BasicRtlSimProxy(sim, self, "g", Bits3t(8, 0), None) self.io.h = BasicRtlSimProxy(sim, self, "h", Bits3t(8, 0), None) self.io.i = BasicRtlSimProxy(sim, self, "i", Bits3t(2, 0), None) self.io.j = BasicRtlSimProxy(sim, self, "j", Bits3t(8, 0), None) self.io.k = BasicRtlSimProxy(sim, self, "k", Bits3t(32, 0), None) self.io.out = BasicRtlSimProxy(sim, self, "out", Bits3t(1, 0), None) self.io.output = BasicRtlSimProxy(sim, self, "output", Bits3t(1, 0), None) self.io.rst_n = BasicRtlSimProxy(sim, self, "rst_n", Bits3t(1, 0), None) self.io.sc_signal = BasicRtlSimProxy(sim, self, "sc_signal", Bits3t(8, 0), None) # internal signals self.const_private_signal = Bits3val(Bits3t(32, 0), 123, 4294967295) self.io.fallingEdgeRam = BasicRtlSimProxy(sim, self, "fallingEdgeRam", self.arr_t_0, None) self.io.r = BasicRtlSimProxy(sim, self, "r", Bits3t(1, 0), Bits3val(Bits3t(1, 0), 0, 1)) self.io.r_0 = BasicRtlSimProxy(sim, self, "r_0", Bits3t(2, 0), Bits3val(Bits3t(2, 0), 0, 3)) self.io.r_1 = BasicRtlSimProxy(sim, self, "r_1", Bits3t(2, 0), Bits3val(Bits3t(2, 0), 0, 3)) self.io.r_next = BasicRtlSimProxy(sim, self, "r_next", Bits3t(1, 0), None) self.io.r_next_0 = BasicRtlSimProxy(sim, self, "r_next_0", Bits3t(2, 0), None) self.io.r_next_1 = BasicRtlSimProxy(sim, self, "r_next_1", Bits3t(2, 0), None) self.rom = Array3val( self.arr_t_1, { 0: Bits3val(Bits3t(8, 0), 0, 255), 1: Bits3val(Bits3t(8, 0), 1, 255), 2: Bits3val(Bits3t(8, 0), 2, 255), 3: Bits3val(Bits3t(8, 0), 3, 255) }, 1) self.const_4_0 = Bits3val(Bits3t(32, 0), 4, 4294967295) self.const_4_1 = Bits3val(Bits3t(32, 1), 4, 4294967295) self.const_0 = Array3val(self.arr_t_0, {}, 0) self.const_0_0 = Bits3val(Bits3t(32, 0), 0, 0) self.const_1 = slice(8, 0, -1) self.const_0_1 = Bits3val(Bits3t(24, 0), 0, 16777215) self.const_2 = slice(16, 0, -1) self.const_1_0 = Bits3val(Bits3t(32, 1), 1, 4294967295) self.const_0_2 = Bits3val(Bits3t(32, 1), 0, 4294967295) self.const_3 = slice(6, 0, -1) self.const_0_3 = Bits3val(Bits3t(8, 0), 0, 0) self.const_2_0 = Bits3val(Bits3t(32, 1), 2, 4294967295) self.const_1_1 = Bits3val(Bits3t(1, 0), 1, 1) self.const_0_4 = Bits3val(Bits3t(8, 0), 0, 255) self.const_1_2 = Bits3val(Bits3t(8, 0), 1, 255) self.const_2_1 = Bits3val(Bits3t(8, 0), 2, 255) self.const_0_5 = Bits3val(Bits3t(1, 0), 0, 1) self.const_0_6 = Bits3val(Bits3t(1, 0), 0, 0) self.const_0_7 = Bits3val(Bits3t(2, 0), 0, 0) self.const_0_8 = Bits3val(Bits3t(2, 0), 0, 3) self.const_1_3 = Bits3val(Bits3t(32, 0), 1, 4294967295) self.const_2_2 = Bits3val(Bits3t(32, 0), 2, 4294967295) self.const_3_0 = Bits3val(Bits3t(32, 0), 3, 4294967295) self.const_3_1 = Bits3val(Bits3t(8, 0), 3, 255) self.const_4_2 = Bits3val(Bits3t(8, 0), 4, 255)