def resetdm(self): if self.currentir!= 0x10: self.write_ir(BitSequence(value = 0x10, length=self._irlen)) self.currentir = 0x10 self._engine.write_dr(BitSequence(value = (3<<16), length = 32)) self._engine.go_idle() self._engine.write_dr(BitSequence(value = 0, length = 32)) self._engine.go_idle() pass
def writeapb(self, adr, data): if self.currentir!=0x11: self.write_ir(BitSequence(value = 0x11, length=self._irlen)) self.currentir = 0x11 self._engine.write_dr(BitSequence(value = ((adr&0xffff)<<34)| ((data&0xffffffff)<<2)|(2), length = 41)) self._engine.go_idle() for i in range(2): self._engine.write_tms(BitSequence(value=0 ,length=5))
def writecmd(self, adr, data, size, write): adr = adr + self.adrofs; if(self.virtual): self._engine.write_dr(BitSequence(value = ((adr&0xffffffff)<<10)| ((data&0xffffffff)<<42)|(write<<74) + (size<<75), length = 77)) else: self._engine.write_ir(BitSequence(value = 0x2, length=self._irlen)) self._engine.write_dr(BitSequence(value = ((adr&0xffffffff)<<8)| ((data&0xffffffff)<<40)|(write<<72) + (size<<73), length = 75))
def test_conversion(self): bs = BitSequence(0xCA, msb=True, length=8) self.assertEqual('%02x' % bs.tobyte(False), '53') self.assertEqual('%02x' % bs.tobyte(True), 'ca') self.assertEqual(bs, BitSequence(bs.tobyte(True), msb=True, length=8)) self.assertRaises(BitSequenceError, BitZSequence.__int__, self.bzs5) self.assertRaises(BitSequenceError, BitZSequence.tobyte, self.bzs5) self.assertRaises(BitSequenceError, BitZSequence.tobytes, self.bzs5) bzs = BitZSequence(0xaa) self.assertEqual(int(bzs), 0xaa)
def resetdm(self): if self.currentir!= 0x10: self.write_ir(BitSequence(value = 0x10, length=self._irlen)) self.currentir = 0x10 self._engine.write_dr(BitSequence(value = (3<<16), length = 32)) self._engine.go_idle() self._engine.write_dr(BitSequence(value = 0, length = 32)) self._engine.go_idle() self.writeapb(PulpOCD.DMCONTROLREG, (1<<PulpOCD.ACTIVEBIT)) self._engine.go_idle()
def readrsp(self, adr): adr = adr + self.adrofs; self.writecmd(adr, 0, 2, 0) if(self.virtual): val = int(self._engine.readwrite_dr(BitSequence(value = 0x1, length=36))) val = val>>2 else: self._engine.write_ir(BitSequence(value = 0x3, length=self._irlen)) val = int(self._engine.read_dr(34)) val = (val>>2) & 0xffffffff return val
def readapb(self, adr): if self.currentir!=0x11: self.write_ir(BitSequence(value = 0x11, length=self._irlen)) self.currentir = 0x11 self._engine.write_dr(BitSequence(value = ((adr&0xffff)<<34)|(1), length = 50)) self._engine.go_idle() for i in range(8): self._engine.write_tms(BitSequence(value=0 ,length=7)) val = (int(self._engine.read_dr(50))>>2) & 0xffffffff return val
def shift_register(self, out, use_last=False): """Shift a BitSequence into the current register and retrieve the register output""" if not isinstance(out, BitSequence): return JtagError('Expect a BitSequence') length = len(out) if use_last: (out, self._last) = (out[:-1], int(out[-1])) byte_count = len(out)//8 pos = 8*byte_count bit_count = len(out)-pos if not byte_count and not bit_count: raise JtagError("Nothing to shift") if byte_count: blen = byte_count-1 #print "RW OUT %s" % out[:pos] cmd = Array('B', [Ftdi.RW_BYTES_PVE_NVE_LSB, blen, (blen>>8)&0xff]) cmd.extend(out[:pos].tobytes(msby=True)) self._stack_cmd(cmd) #print "push %d bytes" % byte_count if bit_count: #print "RW OUT %s" % out[pos:] cmd = Array('B', [Ftdi.RW_BITS_PVE_NVE_LSB, bit_count-1]) cmd.append(out[pos:].tobyte()) self._stack_cmd(cmd) #print "push %d bits" % bit_count self.sync() bs = BitSequence() byte_count = length//8 pos = 8*byte_count bit_count = length-pos if byte_count: data = self._ftdi.read_data_bytes(byte_count, 4) if not data: raise JtagError('Unable to read data from FTDI') byteseq = BitSequence(bytes_=data, length=8*byte_count) #print "RW IN %s" % byteseq bs.append(byteseq) #print "pop %d bytes" % byte_count if bit_count: data = self._ftdi.read_data_bytes(1, 4) if not data: raise JtagError('Unable to read data from FTDI') byte = data[0] # need to shift bits as they are shifted in from the MSB in FTDI byte >>= 8-bit_count bitseq = BitSequence(byte, length=bit_count) bs.append(bitseq) #print "pop %d bits" % bit_count if len(bs) != length: raise AssertionError("Internal error") #self._ftdi.validate_mpsse() return bs
def read(self, length): """Read out a sequence of bits from TDO""" byte_count = length // 8 bit_count = length - 8 * byte_count bs = BitSequence() if byte_count: bytes_ = self._read_bytes(byte_count) bs.append(bytes_) if bit_count: bits = self._read_bits(bit_count) bs.append(bits) return bs
def fetch_data(self): if len(self.bits_in_read_queue) > 0: length = self.bits_in_read_queue.popleft() bs = BitSequence() byte_count = length // 8 pos = 8 * byte_count bit_count = length - pos if byte_count: data = self._ftdi.read_data_bytes(byte_count, 4) if not data: raise JtagError('Unable to read data from FTDI') byteseq = BitSequence(bytes_=data, length=8 * byte_count) # print("RW IN %s" % byteseq) bs.append(byteseq) # print("pop %d bytes" % byte_count) if bit_count: data = self._ftdi.read_data_bytes(1, 4) if not data: raise JtagError('Unable to read data from FTDI') byte = data[0] # need to shift bits as they are shifted in from the MSB in FTDI byte >>= 8 - bit_count bitseq = BitSequence(byte, length=bit_count) bs.append(bitseq) # print("pop %d bits" % bit_count) if len(bs) != length: raise ValueError("Internal error") return bs return None
def test_rotations(self): b = BitSequence('10101110') b.lsr(2) self.assertEqual(str(b), '8: 01011101') b.lsr(10) self.assertEqual(str(b), '8: 01010111') b.rsr(3) self.assertEqual(str(b), '8: 10111010')
def reset(self, sync=False): """Reset the attached TAP controller. sync sends the command immediately (no caching) """ # we can either send a TRST HW signal or perform 5 cycles with TMS=1 # to move the remote TAP controller back to 'test_logic_reset' state # do both for now if not self._ftdi: raise JtagError("FTDI controller terminated") if self._trst: # nTRST value = 0 cmd = array('B', (Ftdi.SET_BITS_LOW, value, self.direction)) self._stack_cmd(cmd) self.sync() time.sleep(0.1) # nTRST should be left to the high state value = JtagController.TRST_BIT cmd = array('B', (Ftdi.SET_BITS_LOW, value, self.direction)) self._stack_cmd(cmd) self.sync() time.sleep(0.1) # TAP reset (even with HW reset, could be removed though) self.write_tms(BitSequence('11111')) if sync: self.sync()
def _change_state(self, tms): """Change the TAP controller state""" if not isinstance(tms, BitSequence): raise Exception('Expect a BitSequence') length = len(tms) if not (0 < length < 8): raise Exception('Invalid TMS length') out = BitSequence(tms, length=8) # apply the last TDO bit if self._last is not None: out[7] = self._last # print("TMS", tms, (self._last is not None) and 'w/ Last' or '') # reset last bit self._last = None cmd = array('B', (Ftdi.WRITE_BITS_TMS_NVE, length-1, out.tobyte())) self._stack_cmd(cmd)
def write_tms(self, tms, should_read=False): """Change the TAP controller state""" if not isinstance(tms, BitSequence): raise JtagError('Expect a BitSequence') tdo = 0 for val in tms: if(self._last): if(self.debug): print(">>Tmsout:" + bin(val)) if(should_read): tdo = self.readwritebit(val,1) if(self.debug): print(">>Tmsin:" + bin(tdo)) else: self.writebit(val, 1) else: if(should_read): tdo = self.readwritebit(val,0) if(self.debug): print(">>Tmsin:" + bin(tdo)) else: self.writebit(val, 0) should_read = False self._last = None return BitSequence(tdo, 1)
def write_tms(self, tms): """Change the TAP controller state""" if not isinstance(tms, BitSequence): raise JtagError('Expect a BitSequence') length = len(tms) if not (0 < length < 8): raise JtagError('Invalid TMS length') out = BitSequence(tms, length=8) # apply the last TDO bit if self._last is not None: out[7] = self._last # print "TMS", tms, (self._last is not None) and 'w/ Last' or '' # reset last bit self._last = None cmd = Array('B', [Ftdi.WRITE_BITS_TMS_NVE, length - 1, out.tobyte()]) self._stack_cmd(cmd) self.sync()
def shift_register(self, length): if not self._sm.state_of('shift'): raise JtagError("Invalid state: %s" % self._sm.state()) if self._sm.state_of('capture'): bs = BitSequence(False) self._ctrl.write_tms(bs) self._sm.handle_events(bs) return self._ctrl.shift_register(length)
def write_tms(self, tms): """Change the TAP controller state""" if not isinstance(tms, BitSequence): raise JtagError("Expect a BitSequence") length = len(tms) if not (0 < length < 8): raise JtagError("Invalid TMS length") out = BitSequence(tms, length=8) # apply the last TDO bit if self._last is not None: out[7] = self._last # print_("TMS", tms, (self._last is not None) and 'w/ Last' or '') # reset last bit self._last = None cmd = Array("B", (Ftdi.WRITE_BITS_TMS_NVE, length - 1, out.tobyte())) self._stack_cmd(cmd) self.sync()
def writeread(self, out, use_last=True): if not isinstance(out, BitSequence): return JtagError('Expect a BitSequence') if use_last: (out, self._last) = (out[:-1], bool(out[-1])) length = len(out) bs = BitSequence(value=self.shiftinoutval(length, int(out)), length=length) return bs
def detect_register_size(self): # Freely inpired from UrJTAG # Need to contact authors, or to replace this code to comply with # the GPL license (GPL vs. LGPL with Python is a bit fuzzy for me) if not self._engine._sm.state_of("shift"): raise JtagError("Invalid state: %s" % self._engine._sm.state()) if self._engine._sm.state_of("capture"): bs = BitSequence(False) self._engine._ctrl.write_tms(bs) self._engine._sm.handle_events(bs) MAX_REG_LEN = 1024 PATTERN_LEN = 8 stuck = None for length in range(1, MAX_REG_LEN): print_("Testing for length %d" % length) if length > 5: return zero = BitSequence(length=length) inj = BitSequence(length=length + PATTERN_LEN) inj.inc() ok = False for p in range(1, 1 << PATTERN_LEN): ok = False self._engine.write(zero, False) rcv = self._engine.shift_register(inj) try: tdo = rcv.invariant() except ValueError: tdo = None if stuck is None: stuck = tdo if stuck != tdo: stuck = None rcv >>= length if rcv == inj: ok = True else: break inj.inc() if ok: print_("Register detected length: %d" % length) return length if stuck is not None: raise JtagError("TDO seems to be stuck") raise JtagError("Unable to detect register length")
def shift_register(self, out, use_last=False): """Shift a BitSequence into the current register and retrieve the register output""" if not isinstance(out, BitSequence): return JtagError('Expect a BitSequence') length = len(out) if use_last: (out, self._last) = (out[:-1], int(out[-1])) byte_count = len(out) // 8 pos = 8 * byte_count bit_count = len(out) - pos if not byte_count and not bit_count: raise JtagError("Nothing to shift") if byte_count: blen = byte_count - 1 # print("RW OUT %s" % out[:pos]) cmd = array('B', (Ftdi.RW_BYTES_PVE_NVE_LSB, blen, (blen >> 8) & 0xff)) cmd.extend(out[:pos].tobytes(msby=True)) self._stack_cmd(cmd) # print("push %d bytes" % byte_count) if bit_count: # print("RW OUT %s" % out[pos:]) cmd = array('B', (Ftdi.RW_BITS_PVE_NVE_LSB, bit_count - 1)) cmd.append(out[pos:].tobyte()) self._stack_cmd(cmd) # print("push %d bits" % bit_count) self.sync( ) # we cannot skip sync here, because we expect data to be returned from MPSSE bs = BitSequence() byte_count = length // 8 pos = 8 * byte_count bit_count = length - pos if byte_count: data = self._ftdi.read_data_bytes(byte_count, 4) if not data: raise JtagError('Unable to read data from FTDI') byteseq = BitSequence(bytes_=data, length=8 * byte_count) # print("RW IN %s" % byteseq) bs.append(byteseq) # print("pop %d bytes" % byte_count) if bit_count: data = self._ftdi.read_data_bytes(1, 4) if not data: raise JtagError('Unable to read data from FTDI') byte = data[0] # need to shift bits as they are shifted in from the MSB in FTDI byte >>= 8 - bit_count bitseq = BitSequence(byte, length=bit_count) bs.append(bitseq) # print("pop %d bits" % bit_count) if len(bs) != length: raise ValueError("Internal error") return bs
def write(self, out, use_last=True): """Write a sequence of bits to TDI""" if isinstance(out, str): if len(out) > 1: self._write_bytes_raw(out[:-1]) out = out[-1] out = BitSequence(bytes_=out) elif not isinstance(out, BitSequence): out = BitSequence(out) if use_last: (out, self._last) = (out[:-1], bool(out[-1])) byte_count = len(out) // 8 pos = 8 * byte_count bit_count = len(out) - pos if byte_count: self._write_bytes(out[:pos]) if bit_count: self._write_bits(out[pos:])
def readreg(self, regnr): debugregnr = regnr + 0x1000 self.writeapb(PulpOCD.ABSTRACTCMDREG, debugregnr + PulpOCD.WORDSIZE + (1<<PulpOCD.REGTRANSFERBIT)) self._engine.go_idle() for i in range(9): self._engine.write_tms(BitSequence(value=0 ,length=7)) val = self.readapb(PulpOCD.ABSTRACTDATAREG) return val
def reset(self): """Reset the attached TAP controller. sync sends the command immediately (no caching) """ # we can either send a TRST HW signal or perform 5 cycles with TMS=1 # to move the remote TAP controller back to 'test_logic_reset'state # TAP reset (even with HW reset, could be removed though) self.write_tms(BitSequence('11111'))
def readbus(self, adr): WORDSIZE = 2 self.writeapb(PulpOCD.SYSTEMBUSCONTROLREG, (WORDSIZE<<17) + (1<<PulpOCD.BUSREADONADDRBIT)) self.writeapb(PulpOCD.SYSTEMBUSADR0, adr) self._engine.go_idle() for i in range(9): self._engine.write_tms(BitSequence(value=0 ,length=7)) val = self.readapb(PulpOCD.SYSTEMBUSDATA0)# & (1<<((WORDSIZE + 1)*8) - 1) return val
def shift_register(self, out): if not self._sm.state_of('shift'): raise JtagError("Invalid state: %s" % self._sm.state()) if self._sm.state_of('capture'): bs = BitSequence(False) self._ctrl.write_tms(bs) self._sm.handle_events(bs) bs = self._ctrl.writeread(out, use_last=False) return bs
def shift_register(self, out, use_last=False): """Shift a BitSequence into the current register and retrieve the register output""" if not isinstance(out, BitSequence): return JtagError('Expect a BitSequence') if use_last: (out, self._last) = (out[:-1], bool(out[-1])) length = len(out) bs = BitSequence(value=self.readsetdr(length, int(out)), length=length) return bs
def readwrite_dr(self, out): """Read the data register from the TAP controller""" self.change_state('shift_dr') data = int(self._ctrl.writeread(out, use_last=True)) events = BitSequence('11') tdo = int(self.write_tms(events, should_read=True)) # (write_tms calls sync()) # update the current state machine's state self._sm.handle_events(events) data += tdo << (len(out) - 1) return data
def test_idcode_shift_register(self): """Read the IDCODE using the dedicated instruction with shift_and_update_register""" instruction = JTAG_INSTR['IDCODE'] self.jtag.change_state('shift_ir') retval = self.jtag.shift_and_update_register(instruction) print("retval: 0x%x" % int(retval)) self.jtag.go_idle() self.jtag.change_state('shift_dr') idcode = self.jtag.shift_and_update_register(BitSequence('0' * 32)) self.jtag.go_idle() print("IDCODE (idcode): 0x%08x" % int(idcode))
def get_events(self, path): """Build up an event sequence from a state sequence, so that the resulting event sequence allows the JTAG state machine to advance from the first state to the last one of the input sequence""" events = [] for s, d in zip(path[:-1], path[1:]): for e, x in enumerate(s.exits): if x == d: events.append(e) if len(events) != len(path) - 1: raise JtagError("Invalid path") return BitSequence(events)
def test_bitwise_ops(self): self.assertEqual( int(BitSequence(0x01, length=8) | BitSequence(0x02, length=8)), 3) self.assertEqual( int(BitSequence(0x07, length=8) & BitSequence(0x02, length=8)), 2) self.assertEqual( int(BitZSequence(0x01, length=8) | BitSequence(0x02, length=8)), 3) self.assertEqual( int(BitSequence(0x07, length=8) & BitZSequence(0x02, length=8)), 2) self.assertRaises(BitSequenceError, BitZSequence.__or__, self.bzs4, self.bzs5) self.assertRaises(BitSequenceError, BitZSequence.__and__, self.bzs4, self.bzs5) self.assertEqual(repr(self.bzs6), '00000000100Z01') self.assertEqual(repr(self.bzs6 | self.bzs4), '11Z1Z010ZZ0Z01') self.assertEqual(repr(self.bzs6 & self.bzs4), '00Z0Z000ZZ0Z00') self.assertEqual(repr(self.bzs4 & self.bs7), '11Z1Z010ZZ0000') self.assertEqual(repr(self.bs7 & self.bzs4), '11Z1Z010ZZ0000') self.assertEqual(repr(self.bzs4 | self.bs7), '11Z1Z010ZZ1101') self.assertEqual(repr(self.bs7 | self.bzs4), '11Z1Z010ZZ1101') self.assertEqual(repr(self.bs7.invert()), '00000101010110') self.assertEqual(repr(self.bzs4.invert()), '00Z0Z101ZZ1011') self.assertLess(self.bs5, self.bs6) self.assertLessEqual(self.bs5, self.bs6) self.assertLess(self.bs6, self.bs5) self.assertLessEqual(self.bs6, self.bs5)
def _read_bytes(self, length): """Read out bytes from TDO""" if length > JtagController.FTDI_PIPE_LEN: raise JtagError("Cannot fit into FTDI fifo") alen = length - 1 cmd = Array('B', (Ftdi.READ_BYTES_NVE_LSB, alen & 0xff, (alen >> 8) & 0xff)) self._stack_cmd(cmd) self.sync() data = self._ftdi.read_data_bytes(length, 4) bs = BitSequence(bytes_=data, length=8 * length) # print_("READ BYTES %s" % bs) return bs
def _read_bits(self, length): """Read out bits from TDO""" if length > 8: raise JtagError("Cannot fit into FTDI fifo") cmd = Array('B', (Ftdi.READ_BITS_NVE_LSB, length - 1)) self._stack_cmd(cmd) self.sync() data = self._ftdi.read_data_bytes(1, 4) # need to shift bits as they are shifted in from the MSB in FTDI byte = data[0] >> 8 - length bs = BitSequence(byte, length=length) # print_("READ BITS %s" % bs) return bs
def setUp(self): self.bs1 = BitSequence(0x01, msb=True, length=8) self.bs2 = BitSequence(0x02, msb=True, length=8) self.bs3 = BitSequence(0x04, msb=True, length=7) self.bs4 = BitSequence(0x04, msb=True, length=11) self.bs5 = BitSequence(299999999999998) self.bs6 = BitSequence(299999999999999) self.bs7 = BitSequence(value="10010101011111") self.bzs1 = BitZSequence(0x01, msb=True, length=8) self.bzs2 = BitZSequence('0Z1') self.bzs3 = BitZSequence('0Z1', length=5) self.bzs4 = BitZSequence("0010ZZ010Z1Z11") self.bzs5 = BitZSequence(value=[True, False, None, False, False, True]) self.bzs6 = BitZSequence(value=[True, False, None, False, False, True], length=len(self.bzs4))
def test_bypass_shift_register(self): """Test the BYPASS instruction using shift_and_update_register""" instruction = JTAG_INSTR['BYPASS'] self.jtag.change_state('shift_ir') retval = self.jtag.shift_and_update_register(instruction) print("retval: 0x%x" % int(retval)) self.jtag.go_idle() self.jtag.change_state('shift_dr') _in = BitSequence('011011110000' * 2, length=24) out = self.jtag.shift_and_update_register(_in) self.jtag.go_idle() print( "BYPASS sent: %s, received: %s (should be left shifted by one)" % (_in, out))
def setUp(self): self.bs1 = BitSequence(0x01, msb=True, length=8) self.bs2 = BitSequence(0x02, msb=True, length=8) self.bs3 = BitSequence(0x04, msb=True, length=7) self.bs4 = BitSequence(0x04, msb=True, length=11) self.bs5 = BitSequence(299999999999998) self.bs6 = BitSequence(299999999999999) self.bs7 = BitSequence(value='10010101011111') self.bzs1 = BitZSequence(0x01, msb=True, length=8) self.bzs2 = BitZSequence('0Z1') self.bzs3 = BitZSequence('0Z1', length=5) self.bzs4 = BitZSequence('0010ZZ010Z1Z11') self.bzs5 = BitZSequence(value=[True, False, None, False, False, True]) self.bzs6 = BitZSequence(value=[True, False, None, False, False, True], length=len(self.bzs4))
def test_cmp(self): self.assertTrue(self.bs1 == self.bs1) self.assertTrue(self.bs1 != self.bs2) self.assertTrue(self.bs2 != BitSequence(0x02, msb=True, length=4)) self.assertTrue(self.bzs2 == self.bzs2) self.assertTrue(self.bzs1 != self.bzs2) self.assertTrue(self.bs1 == self.bzs1) self.assertTrue(self.bzs1 == self.bs1) self.assertTrue(self.bzs3 != self.bzs2) self.assertNotEqual(self.bzs4, self.bzs5) bzs = BitZSequence(self.bs7) self.assertTrue(bzs == self.bs7) bzs |= BitZSequence('00Z0Z000ZZ0Z00') self.assertFalse(bzs == self.bs7) self.assertTrue(bzs.matches(self.bs7))
class BitSequenceTestCase(unittest.TestCase): def setUp(self): self.bs1 = BitSequence(0x01, msb=True, length=8) self.bs2 = BitSequence(0x02, msb=True, length=8) self.bs3 = BitSequence(0x04, msb=True, length=7) self.bs4 = BitSequence(0x04, msb=True, length=11) self.bs5 = BitSequence(299999999999998) self.bs6 = BitSequence(299999999999999) self.bs7 = BitSequence(value='10010101011111') self.bzs1 = BitZSequence(0x01, msb=True, length=8) self.bzs2 = BitZSequence('0Z1') self.bzs3 = BitZSequence('0Z1', length=5) self.bzs4 = BitZSequence('0010ZZ010Z1Z11') self.bzs5 = BitZSequence(value=[True, False, None, False, False, True]) self.bzs6 = BitZSequence(value=[True, False, None, False, False, True], length=len(self.bzs4)) def test_bitwise_ops(self): self.assertEqual(int(BitSequence(0x01, length=8) | BitSequence(0x02, length=8)), 3) self.assertEqual(int(BitSequence(0x07, length=8) & BitSequence(0x02, length=8)), 2) self.assertEqual(int(BitZSequence(0x01, length=8) | BitSequence(0x02, length=8)), 3) self.assertEqual(int(BitSequence(0x07, length=8) & BitZSequence(0x02, length=8)), 2) self.assertRaises(BitSequenceError, BitZSequence.__or__, self.bzs4, self.bzs5) self.assertRaises(BitSequenceError, BitZSequence.__and__, self.bzs4, self.bzs5) self.assertEqual(repr(self.bzs6), '00000000100Z01') self.assertEqual(repr(self.bzs6 | self.bzs4), '11Z1Z010ZZ0Z01') self.assertEqual(repr(self.bzs6 & self.bzs4), '00Z0Z000ZZ0Z00') self.assertEqual(repr(self.bzs4 & self.bs7), '11Z1Z010ZZ0000') self.assertEqual(repr(self.bs7 & self.bzs4), '11Z1Z010ZZ0000') self.assertEqual(repr(self.bzs4 | self.bs7), '11Z1Z010ZZ1101') self.assertEqual(repr(self.bs7 | self.bzs4), '11Z1Z010ZZ1101') self.assertEqual(repr(self.bs7.invert()), '00000101010110') self.assertEqual(repr(self.bzs4.invert()), '00Z0Z101ZZ1011') def test_cmp(self): self.assertTrue(self.bs1 == self.bs1) self.assertTrue(self.bs1 != self.bs2) self.assertTrue(self.bs2 != BitSequence(0x02, msb=True, length=4)) self.assertTrue(self.bzs2 == self.bzs2) self.assertTrue(self.bzs1 != self.bzs2) self.assertTrue(self.bs1 == self.bzs1) self.assertTrue(self.bzs1 == self.bs1) self.assertTrue(self.bzs3 != self.bzs2) self.assertNotEqual(self.bzs4, self.bzs5) bzs = BitZSequence(self.bs7) self.assertTrue(bzs == self.bs7) bzs |= BitZSequence('00Z0Z000ZZ0Z00') self.assertFalse(bzs == self.bs7) self.assertTrue(bzs.matches(self.bs7)) def test_representation(self): self.assertEqual("%s / %r" % (self.bs1, self.bs1), "8: 10000000 / 10000000") self.assertEqual("%s / %r" % (self.bs2, self.bs2), "8: 01000000 / 01000000") self.assertEqual("%s / %r" % (self.bs3, self.bs3), "7: 0010000 / 0010000") self.assertEqual("%s / %r" % (self.bs4, self.bs4), "11: 001 00000000 / 00100000000") self.assertEqual("%s / %r" % (self.bs5, self.bs5), "49: 1 00010000 11011001 00110001 01101110 10111111 " "11111110 / 100010000110110010011000101101110101111" "1111111110") self.assertEqual("%s / %r" % (self.bs6, self.bs6), "49: 1 00010000 11011001 00110001 01101110 10111111 " "11111111 / 100010000110110010011000101101110101111" "1111111111") self.assertEqual(repr(self.bzs4), '11Z1Z010ZZ0100') self.assertEqual(repr(self.bzs5), '100Z01') def test_init(self): self.assertEqual(int(BitSequence([0, 0, 1, 0])), 4) self.assertEqual(int(BitSequence((0, 1, 0, 0), msb=True)), 4) self.assertEqual(int(BitSequence(4, length=8)), 4) self.assertEqual(int(BitSequence(long(4), msb=True, length=8)), 32) self.assertEqual(int(BitSequence("0010")), 4) self.assertEqual(int(BitSequence("0100", msb=True)), 4) bs = BitSequence("0100", msb=True) self.assertEqual(bs, BitSequence(bs)) bssub = BitSequence(bs[1:3]) self.assertEqual(str(bssub), '2: 10') bs[0:3] = '11' self.assertEqual(str(bs), '4: 0011') bzs = BitZSequence(self.bzs4) self.assertEqual(bzs, self.bzs4) bs = BitSequence('11111010101001', msb=True) bs[8:12] = BitSequence(value='0000') self.assertEqual(repr(bs), '11000010101001') try: bs[8:12] = BitZSequence(value='ZZZZ') except BitSequenceError: pass except Exception as e: self.fail("Unexpected exception %s" % e) else: self.fail("Error was expected") bs = BitZSequence('1111101010100111Z1Z010ZZ0100', msb=True) bs[8:12] = BitZSequence(value='ZZZZ') self.assertEqual(repr(bs), '1111101010100111ZZZZ10ZZ0100') bs[8:12] = BitSequence(value='0000') self.assertEqual(repr(bs), '1111101010100111000010ZZ0100') n = 548521358 bs = BitSequence(bin(n), msb=True) self.assertEqual(int(bs), n) bzs = BitZSequence(bin(n), msb=True) self.assertEqual(str(bzs), '30: 100000 10110001 11000101 10001110') bs = BitSequence(bytes_=[0x44, 0x66, 0xcc], msby=False) self.assertEqual(int(bs), 0x4466cc) bs = BitSequence(bytes_=(0x44, 0x66, 0xcc), msby=True) self.assertEqual(int(bs), 0xcc6644) try: bs = BitSequence(bytes_=[0x44, 0x666, 0xcc], msby=False) except BitSequenceError: pass except Exception as e: self.fail("Unexpected exception %s" % e) else: self.fail("Error was expected") def test_conversion(self): bs = BitSequence(0xCA, msb=True, length=8) self.assertEqual('%02x' % bs.tobyte(False), '53') self.assertEqual('%02x' % bs.tobyte(True), 'ca') self.assertEqual(bs, BitSequence(bs.tobyte(True), msb=True, length=8)) self.assertRaises(BitSequenceError, BitZSequence.__int__, self.bzs5) self.assertRaises(BitSequenceError, BitZSequence.tobyte, self.bzs5) self.assertRaises(BitSequenceError, BitZSequence.tobytes, self.bzs5) bzs = BitZSequence(0xaa) self.assertEqual(int(bzs), 0xaa) def test_misc(self): ba = BitSequence(12, msb=True, length=16) bb = BitSequence(12, msb=True, length=14) l = [ba, bb] l.sort(key=int) self.assertEqual(str(l), "[00110000000000, 0011000000000000]") self.assertEqual(str(ba.tobytes()), "[48, 0]") self.assertEqual(str(ba.tobytes(True)), "[0, 12]") self.assertEqual(str(bb.tobytes(True)), "[0, 12]") b = BitSequence(length=254) b[0:4] = '1111' self.assertEqual(str(b), '254: 000000 00000000 00000000 00000000 ' '00000000 00000000 00000000 00000000 00000000 00000000 00000000 ' '00000000 00000000 00000000 00000000 00000000 00000000 00000000 ' '00000000 00000000 00000000 00000000 00000000 00000000 00000000 ' '00000000 00000000 00000000 00000000 00000000 00000000 00001111') self.assertEqual(str(b.tobytes()), '[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ' '0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15]') b = BitSequence(bytes_=[0xa0, '\x0f', 0x77], msb=False, msby=False) self.assertEqual(str(['%02x' % x for x in b.tobytes(False)]), "['a0', '0f', '77']") b = BitSequence(bytes_=[0xa0, '\x0f', 0x77], msb=True, msby=True) self.assertEqual(str(['%02x' % x for x in b.tobytes(True)]), "['a0', '0f', '77']") b = BitSequence(length=7) b[6] = '1' self.assertEqual(str(b), '7: 1000000') def test_rotations(self): b = BitSequence('10101110') b.lsr(2) self.assertEqual(str(b), '8: 01011101') b.lsr(10) self.assertEqual(str(b), '8: 01010111') b.rsr(3) self.assertEqual(str(b), '8: 10111010') def test_concat(self): self.assertEqual(repr(self.bzs4+self.bzs5), '100Z0111Z1Z010ZZ0100') self.assertEqual(repr(self.bzs4+self.bs7), '1111101010100111Z1Z010ZZ0100') self.assertEqual(repr(self.bs7+self.bzs4), '11Z1Z010ZZ010011111010101001')
def test_misc(self): ba = BitSequence(12, msb=True, length=16) bb = BitSequence(12, msb=True, length=14) l = [ba, bb] l.sort(key=int) self.assertEqual(str(l), "[00110000000000, 0011000000000000]") self.assertEqual(str(ba.tobytes()), "[48, 0]") self.assertEqual(str(ba.tobytes(True)), "[0, 12]") self.assertEqual(str(bb.tobytes(True)), "[0, 12]") b = BitSequence(length=254) b[0:4] = '1111' self.assertEqual(str(b), '254: 000000 00000000 00000000 00000000 ' '00000000 00000000 00000000 00000000 00000000 00000000 00000000 ' '00000000 00000000 00000000 00000000 00000000 00000000 00000000 ' '00000000 00000000 00000000 00000000 00000000 00000000 00000000 ' '00000000 00000000 00000000 00000000 00000000 00000000 00001111') self.assertEqual(str(b.tobytes()), '[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ' '0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15]') b = BitSequence(bytes_=[0xa0, '\x0f', 0x77], msb=False, msby=False) self.assertEqual(str(['%02x' % x for x in b.tobytes(False)]), "['a0', '0f', '77']") b = BitSequence(bytes_=[0xa0, '\x0f', 0x77], msb=True, msby=True) self.assertEqual(str(['%02x' % x for x in b.tobytes(True)]), "['a0', '0f', '77']") b = BitSequence(length=7) b[6] = '1' self.assertEqual(str(b), '7: 1000000')
class BitSequenceTestCase(unittest.TestCase): def setUp(self): self.bs1 = BitSequence(0x01, msb=True, length=8) self.bs2 = BitSequence(0x02, msb=True, length=8) self.bs3 = BitSequence(0x04, msb=True, length=7) self.bs4 = BitSequence(0x04, msb=True, length=11) self.bs5 = BitSequence(299999999999998) self.bs6 = BitSequence(299999999999999) self.bs7 = BitSequence(value="10010101011111") self.bzs1 = BitZSequence(0x01, msb=True, length=8) self.bzs2 = BitZSequence('0Z1') self.bzs3 = BitZSequence('0Z1', length=5) self.bzs4 = BitZSequence("0010ZZ010Z1Z11") self.bzs5 = BitZSequence(value=[True, False, None, False, False, True]) self.bzs6 = BitZSequence(value=[True, False, None, False, False, True], length=len(self.bzs4)) def test_bitwise_ops(self): self.assertEqual(int(BitSequence(0x01, length=8) | \ BitSequence(0x02, length=8)), 3) self.assertEqual(int(BitSequence(0x07, length=8) & \ BitSequence(0x02, length=8)), 2) self.assertEqual(int(BitZSequence(0x01, length=8) | \ BitSequence(0x02, length=8)), 3) self.assertEqual(int(BitSequence(0x07, length=8) & \ BitZSequence(0x02, length=8)), 2) self.assertRaises(BitSequenceError, BitZSequence.__or__, self.bzs4, self.bzs5) self.assertRaises(BitSequenceError, BitZSequence.__and__, self.bzs4, self.bzs5) self.assertEqual(repr(self.bzs6), '00000000100Z01') self.assertEqual(repr(self.bzs6 | self.bzs4), '11Z1Z010ZZ0Z01') self.assertEqual(repr(self.bzs6 & self.bzs4), '00Z0Z000ZZ0Z00') self.assertEqual(repr(self.bzs4 & self.bs7), '11Z1Z010ZZ0000') self.assertEqual(repr(self.bs7 & self.bzs4), '11Z1Z010ZZ0000') self.assertEqual(repr(self.bzs4 | self.bs7), '11Z1Z010ZZ1101') self.assertEqual(repr(self.bs7 | self.bzs4), '11Z1Z010ZZ1101') self.assertEqual(repr(self.bs7.invert()), '00000101010110') self.assertEqual(repr(self.bzs4.invert()), '00Z0Z101ZZ1011') def test_cmp(self): self.assertTrue(self.bs1 == self.bs1) self.assertTrue(self.bs1 != self.bs2) self.assertTrue(self.bs2 != BitSequence(0x02, msb=True, length=4)) self.assertTrue(self.bzs2 == self.bzs2) self.assertTrue(self.bzs1 != self.bzs2) self.assertTrue(self.bs1 == self.bzs1) self.assertTrue(self.bzs1 == self.bs1) self.assertTrue(self.bzs3 != self.bzs2) self.assertNotEqual(self.bzs4, self.bzs5) bzs = BitZSequence(self.bs7) self.assertTrue(bzs == self.bs7) bzs |= BitZSequence('00Z0Z000ZZ0Z00') self.assertFalse(bzs == self.bs7) self.assertTrue(bzs.matches(self.bs7)) def test_representation(self): self.assertEqual("%s / %r" % (self.bs1, self.bs1), "8: 10000000 / 10000000") self.assertEqual("%s / %r" % (self.bs2, self.bs2), "8: 01000000 / 01000000") self.assertEqual("%s / %r" % (self.bs3, self.bs3), "7: 0010000 / 0010000") self.assertEqual("%s / %r" % (self.bs4, self.bs4), "11: 001 00000000 / 00100000000") self.assertEqual("%s / %r" % (self.bs5, self.bs5), "49: 1 00010000 11011001 00110001 01101110 10111111 "\ "11111110 / 100010000110110010011000101101110101111"\ "1111111110") self.assertEqual("%s / %r" % (self.bs6, self.bs6), "49: 1 00010000 11011001 00110001 01101110 10111111 "\ "11111111 / 100010000110110010011000101101110101111"\ "1111111111") self.assertEqual(repr(self.bzs4), '11Z1Z010ZZ0100') self.assertEqual(repr(self.bzs5), '100Z01') def test_init(self): self.assertEqual(int(BitSequence([0, 0, 1, 0])), 4) self.assertEqual(int(BitSequence((0, 1, 0, 0), msb=True)), 4) self.assertEqual(int(BitSequence(4, length=8)), 4) self.assertEqual(int(BitSequence(4L, msb=True, length=8)), 32) self.assertEqual(int(BitSequence("0010")), 4) self.assertEqual(int(BitSequence("0100", msb=True)), 4) bs = BitSequence("0100", msb=True) self.assertEqual(bs, BitSequence(bs)) bssub = BitSequence(bs[1:3]) self.assertEqual(str(bssub), '2: 10') bs[0:3] = '11' self.assertEqual(str(bs), '3: 011') bzs = BitZSequence(self.bzs4) self.assertEqual(bzs, self.bzs4) bs = BitSequence('11111010101001', msb=True) bs[8:12] = BitSequence(value = '0000') self.assertEqual(repr(bs), '11000010101001') try: bs[8:12] = BitZSequence(value = 'ZZZZ') except BitSequenceError: pass except Exception, e: self.fail("Unexpected exception %s" % e) else: