def _write_single_word(self, data: HValue, strb: int, word_i: int): if strb == 0: return if strb != self.allMask: cur = self.data.get(word_i, None) if cur is None: cur_val = 0 cur_mask = 0 elif isinstance(cur, int): cur_val = cur cur_mask = self.allMask else: cur_val = cur.val cur_mask = cur.vld_mask for i in range(self.cellSize): if get_bit(strb, i): cur_val = set_bit_range( cur_val, i * 8, 8, get_bit_range(data.val, i * 8, 8)) cur_mask = set_bit_range( cur_mask, i * 8, 8, get_bit_range(data.vld_mask, i * 8, 8)) if cur_mask == self.allMask: data = cur_val else: data = self.word_t.from_py(cur_val, cur_mask) # print(f"data[{word_i:d}] = {data}") self.data[word_i] = data
def convertBits__val(self: Bits, val: "BitVal", toType: HdlType): if toType == BOOL: return val != self.getValueCls().from_py(self, 0) elif isinstance(toType, Bits): if self.signed != toType.signed: if self.strict_sign and bool(self.signed) != bool(toType.signed): raise TypeConversionErr(self, toType) val = val._convSign__val(toType.signed) w_from, w_to = self.bit_length(), toType.bit_length() if w_from != w_to: if self.strict_width: raise TypeConversionErr(self, toType) if w_from > w_to: # cut off some bits from value new_m = val.vld_mask & toType.all_mask() else: # w_from < w_to, extend the value to some bit length extra_mask_bits = mask(w_to - w_from) new_m = set_bit_range(val.vld_mask, w_from, w_to - w_from, extra_mask_bits) val = toType.from_py(val.val, new_m) if val._dtype != toType: # sign and width checked, only name, strict_* flags can be different val = toType.from_py(val.val, val.vld_mask) return val elif toType == INT: return INT.getValueCls()(INT, val.val, int(val._is_full_valid())) return default_auto_cast_fn(self, val, toType)
def test_mergable2(self, N=10, ADDRESSES=[ 0, ], randomized=False): """ same as test_mergable just the inner cycle is reversed """ u = self.u mem = AxiSimRam(u.m) expected = {} for i in range(N): offset = i * N for a in ADDRESSES: B_i = (i % 4) _i = ((offset + i) % 0xff) d = _i << (B_i * 8) m = 1 << B_i u.w._ag.data.append((a, d, m)) v = expected.get(a, 0) v = set_bit_range(v, B_i * 8, 8, _i) expected[a] = v if randomized: self.randomize_all() self.runSim((N * len(ADDRESSES) + 10) * 3 * u.BUS_WORDS_IN_CACHE_LINE * CLK_PERIOD) for a in ADDRESSES: self.assertValEqual(mem.data[a], expected[a], "%d: 0x%08x" % (a, expected[a]))
def test_mergable(self, N=10, ADDRESSES=[ 0, ], randomized=False): u = self.u mem = AxiSimRam(u.m) expected = {} for a in ADDRESSES: for i in range(N): B_i = i % (u.CACHE_LINE_SIZE) d = i << (B_i * 8) m = 1 << B_i u.w._ag.data.append((a, d, m)) v = expected.get(a, 0) v = set_bit_range(v, B_i * 8, 8, i) expected[a] = v t = (N * len(ADDRESSES) + 10) * 3 * \ u.BUS_WORDS_IN_CACHE_LINE * CLK_PERIOD if randomized: #t *= 2 self.randomize_all() self.runSim(t) data = mem.getArray(0, u.CACHE_LINE_SIZE, max(ADDRESSES) + 1) for a in ADDRESSES: self.assertValEqual( data[a], expected[a], "%d: expected 0x%08x got 0x%08x, 0x%08x" % (a, expected[a], data[a].val, data[a].vld_mask))
def __setitem__(self, index: Union[slice, int, "Bits3val"], value: Union["Bits3val", int]): "An item assignment operator self[index] = value." if isinstance(index, slice): firstBitNo, size = normalize_slice(index, self._dtype.bit_length()) if isinstance(value, Bits3val): v = value.val m = value.vld_mask else: v = value m = mask(size) self.val = set_bit_range(self.val, firstBitNo, size, v) self.vld_mask = set_bit_range(self.vld_mask, firstBitNo, size, m) else: if index is None: raise TypeError(index) try: _i = int(index) except ValidityError: _i = None if _i is None: self.val = 0 self.vld_mask = 0 else: if value is None: v = 0 m = 0 elif isinstance(value, Bits3val): v = value.val m = value.vld_mask else: v = value m = 0b1 try: index = int(index) except ValidityError: index = None if index is None: self.val = 0 self.vld_mask = 0 else: self.val = bit_set_to(self.val, index, v) self.vld_mask = bit_set_to(self.vld_mask, index, m)
def is_footer_mask_set_values(self, LOOK_AHEAD, regs): D_W = self.DATA_WIDTH BYTE_CNT = D_W // 8 FOOTER_WIDTH = self.FOOTER_WIDTH din = self.dataIn if self.USE_KEEP: in_mask = din.keep elif self.USE_STRB: in_mask = din.strb elif self.DATA_WIDTH == 8: in_mask = BIT.from_py(1, 1) else: raise NotImplementedError( "keep/strb can be ignored only for DATA_WIDTH=8") set_is_footer = self._sig("set_is_footer") set_is_footer(din.valid & din.last) mask_cases = [] for last_B_valid, bytes_in_last_input_word in iter_with_last( range(1, BYTE_CNT + 1)): footer_end = (LOOK_AHEAD * BYTE_CNT + bytes_in_last_input_word) * 8 footer_start = footer_end - FOOTER_WIDTH assert footer_start > 0, ( "otherwise we would not be able to send last for previous frame", footer_start) assert footer_start < D_W * 3, ( "footer start can appear only in last-1 or last-2 regster," " last register is output register", footer_start, D_W) _is_footer = set_bit_range(0, footer_start // 8, FOOTER_WIDTH // 8, mask(FOOTER_WIDTH // 8)) set_flags = [] for i, (_, _, is_footer_set_val, _, _) in enumerate(regs): if i == 0: is_footer_val = 0 is_footer_val_last_word = get_bit_range( _is_footer, (LOOK_AHEAD - i) * BYTE_CNT, BYTE_CNT) set_flags.append( If(set_is_footer, is_footer_set_val(is_footer_val_last_word)).Else( is_footer_set_val(is_footer_val))) else: is_footer_val = get_bit_range( _is_footer, (LOOK_AHEAD - i + 1) * BYTE_CNT, BYTE_CNT) set_flags.append(is_footer_set_val(is_footer_val)) if last_B_valid: # last byte also valid mask_default = set_flags else: # last 0 from the end of the validity mask mask_cases.append( (~in_mask[bytes_in_last_input_word], set_flags)) SwitchLogic(mask_cases, mask_default) return set_is_footer
def packData(self, data): """ Pack data into list of BitsVal of specified dataWidth :param data: dict of values for struct fields {fieldName: value} :return: list of BitsVal which are representing values of words """ typeOfWord = Bits(self.wordWidth, None) fieldToVal = self._fieldToTPart if fieldToVal is None: fieldToVal = self._fieldToTPart = self.fieldToDataDict( self.origin.dtype, data, {}) for _, transParts in self.walkWords(showPadding=True): # build a single data word actualVldMask = 0 actualVal = 0 for tPart in transParts: high, low = tPart.getBusWordBitRange() fhigh, flow = tPart.getFieldBitRange() if not tPart.isPadding: val = fieldToVal.get(tPart.tmpl.origin, None) else: val = None if val is None: newBits = 0 vld = 0 else: newBits = get_bit_range(val, flow, fhigh - flow) vld = mask(high - low) actualVal = set_bit_range(actualVal, low, high - low, newBits) actualVldMask = set_bit_range(actualVldMask, low, high - low, vld) v = typeOfWord.getValueCls()(typeOfWord, actualVal, actualVldMask) yield v
def set_tag(self, addr, way): u = self.u tag, index, offset = u.parse_addr_int(addr) assert offset == 0, addr tag_t = u.tag_array.tag_record_t tag_t_w = tag_t.bit_length() v = tag_t.from_py({"tag": tag, "valid": 1})._reinterpret_cast(Bits(tag_t_w)) cur_v = self._get_from_mems(self.TAGS, index) assert cur_v._is_full_valid(), (cur_v, index) val = set_bit_range(cur_v.val, way * tag_t_w, tag_t_w, v.val) self._set_to_mems(self.TAGS, index, val) return index
from enum import Enum from pyMathBitPrecise.bit_utils import set_bit_range # deassign_xyz_mux; ARITHMETIC_MODES_DRC_deassign_xyz_mux = [ # 0bxxx0101010 *[set_bit_range(0b0000101010, 7, 3, i) for i in range(8)], 0b0000000000, 0b0000011000, 0b0000011010, 0b0000101000, 0b0001000000, 0b0001011000, 0b0001011010, 0b0001100000, 0b0001100010, 0b0001111000, 0b0001111010, 0b0010000000, 0b0010011000, 0b0010011001, 0b0010011011, 0b0010101000, 0b0010101001, 0b0010101011, 0b0010101110, 0b0011000000, 0b0011011000, 0b0011011001, 0b0011011011, 0b0011100000,