def __getitem__(self, key: Union[int, slice, "Bits3val"]) -> "Bits3val": "self[key]" if isinstance(key, slice): firstBitNo, size = normalize_slice(key, self._dtype.bit_length()) val = get_bit_range(self.val, firstBitNo, size) vld = get_bit_range(self.vld_mask, firstBitNo, size) elif isinstance(key, (int, Bits3val)): size = 1 try: _i = int(key) except ValidityError: _i = None if _i is None: val = 0 vld = 0 else: if _i < 0 or _i >= self._dtype.bit_length(): raise IndexError("Index out of range", _i) val = get_bit(self.val, _i) vld = get_bit(self.vld_mask, _i) else: raise TypeError(key) new_t = self._dtype.__class__(size, signed=self._dtype.signed) return new_t.from_py(val, vld)
def _impl(self): DW = int(self.DATA_WIDTH) polyBits, PW = self.parsePoly(self.POLY, self.POLY_WIDTH) XOROUT = int(self.XOROUT) _INIT = int(self.INIT) initBits = [BIT.from_py(get_bit(_INIT, i)) for i in range(PW)] finBits = [BIT.from_py(get_bit(XOROUT, i)) for i in range(PW)] # rename to have shorter code _inD = self._sig("d", self.dataIn._dtype) _inD(self.dataIn) inBits = list(iterBits(_inD)) if not self.IN_IS_BIGENDIAN: # we need to process lower byte first inBits = bit_list_reversed_endianity(inBits, extend=False) crcMatrix = self.buildCrcXorMatrix(DW, polyBits) res = self.applyCrcXorMatrix(crcMatrix, inBits, initBits, bool(self.REFIN)) if self.REFOUT: res = list(reversed(res)) finBits = bit_list_reversed_bits_in_bytes(finBits, extend=False) outBits = iterBits(self.dataOut) for ob, b, fb in zip(outBits, res, finBits): ob(b ^ fb)
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 check_r_trans(self, ar_ref, driver_r_ref): u = self.u self.assertEqual(len(u.driver._ag.req.data), 0) self.assertEqual(len(u.axi.r._ag.data), 0) r_data = [] m_width = u.driver.r.strb._dtype.bit_length() for (d, m, l) in u.driver.r._ag.data: if l: m = int(m) invalid_seen = False for B_i in range(m_width): B = get_bit_range(d.vld_mask, B_i * 8, 8) _m = get_bit(m, B_i) if _m and B != 0xff: d = None break if invalid_seen: if _m: raise ValueError( "The value prefix is invalid, but there is a part of the value which is valid", d, B_i) else: if not _m: invalid_seen = True if d is not None: # mask removes the potentially invalid bytes d = d.val r_data.append((d, m, l)) self.assertValSequenceEqual(r_data, driver_r_ref) self.assertValSequenceEqual(u.axi.ar._ag.data, ar_ref)
def on_read(self, phyaddr, regaddr): data = self.data[(phyaddr, regaddr)] D_W = self.intf.D_W tx_bits = self.tx_bits_tmp # turn arround (1 is actually Z but due to open-drain...) tx_bits.append(1) tx_bits.append(0) for i in range(D_W): # MSB first tx_bits.append(get_bit(data, D_W - i - 1))
def addValues(unit, data): for d in data: # because there are 4 bits for i in range(4): databit = getattr(unit, f"a{i:d}") if d is None: dataBitval = None else: dataBitval = get_bit(d, i) databit._ag.data.append(dataBitval)
def test_7bitAddr(self): u = self.u addr = 13 mode = I2cAgent.READ u.cntrl._ag.data.extend( [(START, 0), ] + [(WRITE, get_bit(addr, 7 - i - 1)) for i in range(7)] + [(WRITE, mode), (READ, 0), (NOP, 0) ]) u.clk_cnt_initVal._ag.data.append(4) self.runSim(70 * CLK_PERIOD) self.assertValSequenceEqual( u.i2c._ag.bit_cntrl_rx, [I2cAgent.START] + [get_bit(addr, 7 - i - 1) for i in range(7)] + [mode])
def sendStr(self, string): START_BIT = 0 STOP_BIT = 1 rx = self.u.rxd._ag.data os = self.FREQ // self.BAUD for ch in string: rx.extend([START_BIT for _ in range(os)]) for i in range(8): d = get_bit(ord(ch), i) rx.extend([d for _ in range(os)]) rx.extend([STOP_BIT for _ in range(os)])
def _impl(self): accumulator = self._reg("accumulator", Bits(self.POLY_WIDTH), def_val=self.INIT) POLY = int(self.POLY) xorBits = [] for i, b in enumerate(iterBits(accumulator)): if get_bit(POLY, i): xorBits.append(b) assert xorBits nextBit = Xor(*xorBits) accumulator(Concat(accumulator[self.POLY_WIDTH - 1:], nextBit)) self.dataOut(accumulator[0])
def parsePoly(POLY, POLY_WIDTH) -> List[int]: """ :return: list of bits from polynome, extra MSB 1 is added len of this list is POLY_WIDTH + 1 """ PW = int(POLY_WIDTH) poly = int(POLY) # [TODO] poly in str if isinstance(poly, str): polyCoefs = parsePolyStr(poly, PW) elif isinstance(poly, int): polyCoefs = [get_bit(poly, i) for i in range(PW)] else: raise NotImplementedError() # LSB is usuaaly 1 return polyCoefs, PW
def asciiArtOfChar(ch, inverted=True): ch = ord(ch) imgBuf = [] for y in range(8): row = getCharRow(ch, y) lineBuf = [] for x in range(8): pix = get_bit(row, 8 - x - 1) if inverted: pix = not pix if pix: pix = ' ' else: pix = '#' lineBuf.append(pix) imgBuf.append("".join(lineBuf)) lineBuf.clear() return "\n".join(imgBuf)
def applyRequests(ram, requests): """ request has to be tuple (WRITE, addr, data) or (READ, addr) data can be only 0 or 1 (because width of data port is 1) """ for req in requests: m = req[0] if m == WRITE: data = req[2] assert data == 1 or data == 0 ram.d._ag.data.append(data) ram.we._ag.data.append(1) elif m == READ: ram.we._ag.data.append(0) else: raise Exception(f"invalid mode {req[0]}") addr = req[1] # ram addr has 6 bits for i in range(6): addrbit = getattr(ram, f"a{i:d}") addrBitval = get_bit(addr, i) addrbit._ag.data.append(addrBitval)
def test_parsePolyStr(self): crc32_str = ("x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8" " + x^7 + x^5 + x^4 + x^2 + x^1 + 1") poly = parsePolyStr(crc32_str, 32) expected = [get_bit(CRC_32.POLY, i) for i in range(CRC_32.WIDTH)] self.assertEqual(poly, expected)
def _axis_recieve_bytes(ag_data, D_B, use_keep, use_id, offset=0) -> Tuple[int, List[int]]: offset = None data_B = [] last = False first = True current_id = 0 mask_all = mask(D_B) while ag_data: _d = ag_data.popleft() if use_id: if use_keep: id_, data, keep, last = _d keep = int(keep) else: id_, data, last = _d keep = mask_all id_ = int(id_) else: if use_keep: data, keep, last = _d keep = int(keep) else: data, last = _d keep = mask_all id_ = 0 last = int(last) assert keep > 0 if offset is None: # first iteration # expecting potential 0s in keep and the rest 1 for i in range(D_B): # i represents number of 0 from te beginning of of the keep # value if keep & (1 << i): offset = i break assert offset is not None, keep for i in range(D_B): if get_bit(keep, i): d = get_bit_range(data.val, i * 8, 8) if get_bit_range(data.vld_mask, i * 8, 8) != 0xff: raise AssertionError( "Data not valid but it should be" f" based on strb/keep B_i:{i:d}, 0x{keep:x}, 0x{data.vld_mask:x}" ) data_B.append(d) if first: offset_mask = mask(offset) assert offset_mask & keep == 0, (offset_mask, keep) first = False current_id = id_ elif not last: assert keep == mask_all, keep if not first: assert current_id == id_, ("id changed in frame beats", current_id, "->", id_) if last: break if not last: if data_B: raise ValueError("Unfinished frame", data_B) else: raise ValueError("No frame available") if use_id: return offset, id_, data_B else: return offset, data_B
def crcToBf(crc): return [get_bit(crc.POLY, i) for i in range(crc.WIDTH)]
def _impl(self): # prepare constants and bit arrays for inputs poly_bits, PW = CrcComb.parsePoly(self.POLY, self.POLY_WIDTH) din = self.dataIn # rename "dataIn_data" to "d" to make code shorter _d = rename_signal(self, din.data, "d") data_in_bits = list(iterBits(_d)) if not self.IN_IS_BIGENDIAN: data_in_bits = bit_list_reversed_endianity(data_in_bits) if self.MASK_GRANULARITY: din.rd(1) rst = self.rst_n._isOn() | (din.vld & din.last) else: rst = self.rst_n state = self._reg("c", Bits(self.POLY_WIDTH), self.INIT, rst=rst) state_in_bits = list(iterBits(state)) if self.MASK_GRANULARITY is None or self.MASK_GRANULARITY == self.DATA_WIDTH: state_next = self.build_crc_xor_matrix(state_in_bits, poly_bits, data_in_bits) If( din.vld, # state_next is in format 0 ... N, # we need to reverse it to litle-endian state(Concat(*reversed(state_next)))) else: mask_in = din.mask mask_width = mask_in._dtype.bit_length() state_next_cases = [] for vld_byte_cnt in range(1, mask_width + 1): # because bytes are already reversed in bit vector of input bits _data_in_bits = data_in_bits[(mask_width - vld_byte_cnt) * self.MASK_GRANULARITY:] state_next = self.build_crc_xor_matrix(state_in_bits, poly_bits, _data_in_bits) # reversed because of because of MSB..LSB state_next_cases.append( (mask(vld_byte_cnt), state(Concat(*reversed(state_next))))) If( din.vld, Switch(mask_in).add_cases(state_next_cases).Default( state(None))) # output connection if self.LATENCY == 0: state = state.next elif self.LATENCY == 1: if self.MASK_GRANULARITY is not None: # to avoid the case where the state is restarted by dataIn.last state_tmp = self._reg("state_tmp", state._dtype) state_tmp(state.next) state = state_tmp else: raise NotImplementedError(self.LATENCY) XOROUT = int(self.XOROUT) fin_bits = [BIT.from_py(get_bit(XOROUT, i)) for i in range(PW)] fin_bits = rename_signal(self, Concat(*fin_bits), "fin_bits") if self.REFOUT: state_reversed = rename_signal(self, Concat(*iterBits(state)), "state_revered") state = state_reversed self.dataOut(state ^ fin_bits)
def monitor(self): i = self.intf while True: # print(self.sim.now // Time.ns) yield Edge(i.en) yield WaitTimeslotEnd() if i.en.read(): rs = int(i.rs.read()) rw = int(i.rw.read()) d = int(i.d.read()) if rs == Hd44780Intf.RS_CONTROL: # command processing if rw == Hd44780Intf.RW_WRITE: if d & 0b10000000: # cursor position set (DDRAM addr) d = get_bit_range(d, 0, 7) self.cursor[0] = ceil(d / i.COLS) assert self.cursor[0] < i.ROWS, self.cursor[0] self.cursor[1] = d % i.ROWS elif d & 0b01000000: raise NotImplementedError() elif d & 0b00100000: # CMD_FUNCTION_SET self.data_len = get_bit(d, 4) self.lines = get_bit(d, 3) self.font = get_bit(d, 2) elif d & 0b00010000: # CMD_CURSOR_OR_DISPLAY_SHIFT shift_or_cursor = get_bit(d, 3) right_left = get_bit(d, 2) if shift_or_cursor == Hd44780Intf.SC_CURSOR_MOVE: c = self.cursor if right_left == Hd44780Intf.SHIFT_RIGHT: c[1] += 1 if c[1] == i.COLS: c[1] = 0 c[0] += 1 if c[0] == i.ROWS: c[0] = 0 else: raise NotImplementedError() elif d & 0b00001000: # CMD_DISPLAY_CONTROL self.display_on = get_bit(d, 2) self.cursor_on = get_bit(d, 1) self.cursor_blink = get_bit(d, 0) elif d & 0b00000100: # CMD_ENTRY_MODE_SET shift_en = get_bit(d, 0) incr_decr = get_bit(d, 1) if shift_en: self.shift = 1 if incr_decr == Hd44780Intf.INCR else -1 else: self.shift = 0 elif d & Hd44780Intf.CMD_RETURN_HOME: raise NotImplementedError() elif d == Hd44780Intf.CMD_CLEAR_DISPLAY: for line in self.screen: for x in range(i.COLS): line[x] = ' ' self.cursor = [0, 0] else: raise NotImplementedError("{0:8b}".format(d)) else: assert rw == Hd44780Intf.RW_READ, rw raise NotImplementedError() else: # data processing assert rs == Hd44780Intf.RS_DATA, rs if self.data_len == Hd44780Intf.DATA_LEN_8b: d = int(d) d = self.REV_CHAR_MAP.get(d, " ") cur = self.cursor self.screen[cur[0]][cur[1]] = d cur[1] += self.shift else: raise NotImplementedError()
def splitBits(self, v): return deque( [get_bit(v, i) for i in range(self.BITS_IN_WORD - 1, -1, -1)])
def test_crc32_py(self): self.assertEqual(crc32(b"aa"), crc32(b"a", crc32(b"a"))) # ! self.assertEqual(crc32(b"abcdefgh"), # crc32(b"abcd", crc32(b"efgh"))) self.assertEqual(crc32(b"abcdefgh"), crc32(b"efgh", crc32(b"abcd"))) # ! self.assertEqual(crc32(b"abcdefgh"), # crc32(b"efgh") ^ crc32(b"abcd")) self.assertEqual(crc_hqx(b"aa", CRC_16_CCITT.INIT), crc_hqx(b"a", crc_hqx(b"a", CRC_16_CCITT.INIT))) # ! self.assertEqual(crc_hqx(b"abcdefgh", 0), # crc_hqx(b"abcd", crc_hqx(b"efgh", 0))) self.assertEqual(crc_hqx(b"abcdefgh", CRC_16_CCITT.INIT), crc_hqx(b"efgh", crc_hqx(b"abcd", CRC_16_CCITT.INIT))) # ! self.assertEqual(crc_hqx(b"abcdefgh", CRC_16_CCITT.INIT), # crc_hqx(b"efgh", CRC_16_CCITT.INIT) ^ crc_hqx(b"abcd", CRC_16_CCITT.INIT)) crc8 = crcToBf(CRC_8_CCITT) crc8_aes = crcToBf(CRC_8_SAE_J1850) cur8 = [0 for _ in range(8)] c2 = [get_bit(0xC2, i) for i in range(8)] self.assertEqual(naive_crc(c2, cur8, crc8_aes), 0xF) c = [get_bit(ord("c"), i) for i in range(8)] self.assertEqual(naive_crc(c, cur8, crc8), 0x2E) cur8_half_1 = [get_bit(0x0f, i) for i in range(8)] self.assertEqual(naive_crc(c2, cur8_half_1, crc8_aes), 0xB4) self.assertEqual(naive_crc(c, cur8_half_1, crc8_aes), 0x8) ab = [get_bit(stoi("ab"), i) for i in range(16)] self.assertEqual(naive_crc(ab, cur8, crc8_aes), 0x7D) self.assertEqual(naive_crc(ab, cur8_half_1, crc8_aes), 0xDE) _12 = [get_bit(0x0102, i) for i in range(16)] self.assertEqual(naive_crc(_12, cur8, crc8_aes), 0x85) self.assertEqual(naive_crc(_12, cur8_half_1, crc8_aes), 0x26) self.assertEqual(naive_crc(_12, cur8_half_1, crc8_aes, refin=True), 0x6F) cur32 = [0 for _ in range(32)] _crc32 = crcToBf(CRC_32) self.assertEqual(naive_crc(c, cur32, _crc32), 0xA1E6E04E) _s = ("0x00000000 0x04C11DB7 0x09823B6E 0x0D4326D9\n" "0x130476DC 0x17C56B6B 0x1A864DB2 0x1E475005\n") assert len(_s) % 4 == 0 s = stoi(_s) s = [get_bit(s, i) for i in range(len(_s) * 8)] self.assertEqual(naive_crc(s, cur32, _crc32), 0x59F59BE0) cur32_1 = [1 for _ in range(32)] self.assertEqual(naive_crc(s, cur32_1, _crc32), 0x141026C0) self.assertEqual(naive_crc(s, cur32, _crc32, refout=True), 0x07D9AF9A) self.assertEqual(naive_crc(s, cur32_1, _crc32, refout=True), 0x03640828) self.assertEqual(naive_crc(s, cur32, _crc32, refin=True), 0xAE007AB1) self.assertEqual(naive_crc(s, cur32_1, _crc32, refin=True), 0xE3E5C791) self.assertEqual(naive_crc(s, cur32, _crc32, refin=True, refout=True), 0x8D5E0075) self.assertEqual( naive_crc(s, cur32_1, _crc32, refin=True, refout=True), 0x89E3A7C7) self.assertEqual( naive_crc(s, cur32_1, _crc32, refin=True, refout=True) ^ 0xffffffff, crc32(_s.encode()))