tools/remote/etherbone: speed up encoding/decoding.
This commit is contained in:
parent
3d2574a488
commit
595c6738a3
|
@ -57,6 +57,9 @@ def get_field_data(field, datas):
|
||||||
v = int.from_bytes(datas[field.byte:field.byte+math.ceil(field.width/8)], "big")
|
v = int.from_bytes(datas[field.byte:field.byte+math.ceil(field.width/8)], "big")
|
||||||
return (v >> field.offset) & (2**field.width-1)
|
return (v >> field.offset) & (2**field.width-1)
|
||||||
|
|
||||||
|
pack_to_uint32 = struct.Struct('>I').pack
|
||||||
|
unpack_uint32_from = struct.Struct('>I').unpack
|
||||||
|
|
||||||
# Packet -------------------------------------------------------------------------------------------
|
# Packet -------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
class Packet(list):
|
class Packet(list):
|
||||||
|
@ -107,20 +110,25 @@ class EtherboneWrites(Packet):
|
||||||
def encode(self):
|
def encode(self):
|
||||||
if self.encoded:
|
if self.encoded:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
self.bytes = self.base_addr.to_bytes(4, "big")
|
ba = bytearray()
|
||||||
|
ba += pack_to_uint32(self.base_addr)
|
||||||
for write in self.writes:
|
for write in self.writes:
|
||||||
self.bytes += write.data.to_bytes(4, "big")
|
ba += pack_to_uint32(write.data)
|
||||||
|
self.bytes = ba
|
||||||
self.encoded = True
|
self.encoded = True
|
||||||
|
|
||||||
def decode(self):
|
def decode(self):
|
||||||
if not self.encoded:
|
if not self.encoded:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
self.base_addr = int.from_bytes(self.bytes[:4], "big")
|
ba = self.bytes
|
||||||
|
self.base_addr = unpack_uint32_from(ba[:4])[0]
|
||||||
|
writes = []
|
||||||
offset = 4
|
offset = 4
|
||||||
self.writes = []
|
length = len(ba)
|
||||||
while len(self.bytes) > offset:
|
while length > offset:
|
||||||
self.writes.append(EtherboneWrite(int.from_bytes(self.bytes[offset:offset+4], "big")))
|
writes.append(EtherboneWrite(unpack_uint32_from(ba[offset:offset+4])[0]))
|
||||||
offset += 4
|
offset += 4
|
||||||
|
self.writes = writes
|
||||||
self.encoded = False
|
self.encoded = False
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -156,20 +164,25 @@ class EtherboneReads(Packet):
|
||||||
def encode(self):
|
def encode(self):
|
||||||
if self.encoded:
|
if self.encoded:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
self.bytes = self.base_ret_addr.to_bytes(4, "big")
|
ba = bytearray()
|
||||||
|
ba += pack_to_uint32(self.base_ret_addr)
|
||||||
for read in self.reads:
|
for read in self.reads:
|
||||||
self.bytes += read.addr.to_bytes(4, "big")
|
ba += pack_to_uint32(read.addr)
|
||||||
|
self.bytes = ba
|
||||||
self.encoded = True
|
self.encoded = True
|
||||||
|
|
||||||
def decode(self):
|
def decode(self):
|
||||||
if not self.encoded:
|
if not self.encoded:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
base_ret_addr = int.from_bytes(self.bytes[:4], "big")
|
ba = self.bytes
|
||||||
|
base_ret_addr = unpack_uint32_from(ba[:4])[0]
|
||||||
|
reads = []
|
||||||
offset = 4
|
offset = 4
|
||||||
self.reads = []
|
length = len(ba)
|
||||||
while len(self.bytes) > offset:
|
while length > offset:
|
||||||
self.reads.append(EtherboneRead(int.from_bytes(self.bytes[offset:offset+4], "big")))
|
reads.append(EtherboneRead(unpack_uint32_from(ba[offset:offset+4])[0]))
|
||||||
offset += 4
|
offset += 4
|
||||||
|
self.reads = reads
|
||||||
self.encoded = False
|
self.encoded = False
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -230,23 +243,26 @@ class EtherboneRecord(Packet):
|
||||||
self.wcount = 0 if self.writes is None else len(self.writes.writes)
|
self.wcount = 0 if self.writes is None else len(self.writes.writes)
|
||||||
self.rcount = 0 if self.reads is None else len(self.reads.reads)
|
self.rcount = 0 if self.reads is None else len(self.reads.reads)
|
||||||
|
|
||||||
|
ba = bytearray()
|
||||||
|
|
||||||
# Encode header
|
# Encode header
|
||||||
header = 0
|
header = 0
|
||||||
for k, v in sorted(etherbone_record_header.fields.items()):
|
for k, v in sorted(etherbone_record_header.fields.items()):
|
||||||
value = int.from_bytes(getattr(self, k).to_bytes(math.ceil(v.width/8), "big"), "little")
|
value = int.from_bytes(getattr(self, k).to_bytes(math.ceil(v.width/8), "big"), "little")
|
||||||
header += (value << v.offset+(v.byte*8))
|
header += (value << v.offset+(v.byte*8))
|
||||||
self.bytes = header.to_bytes(etherbone_record_header.length, "little")
|
ba += header.to_bytes(etherbone_record_header.length, "little")
|
||||||
|
|
||||||
# Encode writes
|
# Encode writes
|
||||||
if self.wcount:
|
if self.wcount:
|
||||||
self.writes.encode()
|
self.writes.encode()
|
||||||
self.bytes += self.writes.bytes
|
ba += self.writes.bytes
|
||||||
|
|
||||||
# Encode reads
|
# Encode reads
|
||||||
if self.rcount:
|
if self.rcount:
|
||||||
self.reads.encode()
|
self.reads.encode()
|
||||||
self.bytes += self.reads.bytes
|
ba += self.reads.bytes
|
||||||
|
|
||||||
|
self.bytes = ba
|
||||||
self.encoded = True
|
self.encoded = True
|
||||||
|
|
||||||
def __repr__(self, n=0):
|
def __repr__(self, n=0):
|
||||||
|
@ -284,15 +300,18 @@ class EtherbonePacket(Packet):
|
||||||
if not self.encoded:
|
if not self.encoded:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
|
|
||||||
|
ba = self.bytes
|
||||||
|
|
||||||
# Decode header
|
# Decode header
|
||||||
header = list(self.bytes[:etherbone_packet_header.length])
|
header = list(ba[:etherbone_packet_header.length])
|
||||||
for k, v in sorted(etherbone_packet_header.fields.items()):
|
for k, v in sorted(etherbone_packet_header.fields.items()):
|
||||||
setattr(self, k, get_field_data(v, header))
|
setattr(self, k, get_field_data(v, header))
|
||||||
offset = etherbone_packet_header.length
|
offset = etherbone_packet_header.length
|
||||||
|
|
||||||
# Decode records
|
# Decode records
|
||||||
while len(self.bytes) > offset:
|
length = len(ba)
|
||||||
record = EtherboneRecord(self.bytes[offset:])
|
while length > offset:
|
||||||
|
record = EtherboneRecord(ba[offset:])
|
||||||
record.decode()
|
record.decode()
|
||||||
self.records.append(record)
|
self.records.append(record)
|
||||||
offset += etherbone_record_header.length
|
offset += etherbone_record_header.length
|
||||||
|
@ -307,18 +326,21 @@ class EtherbonePacket(Packet):
|
||||||
if self.encoded:
|
if self.encoded:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
|
|
||||||
|
ba = bytearray()
|
||||||
|
|
||||||
# Encode header
|
# Encode header
|
||||||
header = 0
|
header = 0
|
||||||
for k, v in sorted(etherbone_packet_header.fields.items()):
|
for k, v in sorted(etherbone_packet_header.fields.items()):
|
||||||
value = int.from_bytes(getattr(self, k).to_bytes(math.ceil(v.width/8), "big"), "little")
|
value = int.from_bytes(getattr(self, k).to_bytes(math.ceil(v.width/8), "big"), "little")
|
||||||
header += (value << v.offset+(v.byte*8))
|
header += (value << v.offset+(v.byte*8))
|
||||||
self.bytes = header.to_bytes(etherbone_packet_header.length, "little")
|
ba += header.to_bytes(etherbone_packet_header.length, "little")
|
||||||
|
|
||||||
# Encode records
|
# Encode records
|
||||||
for record in self.records:
|
for record in self.records:
|
||||||
record.encode()
|
record.encode()
|
||||||
self.bytes += record.bytes
|
ba += record.bytes
|
||||||
|
|
||||||
|
self.bytes = ba
|
||||||
self.encoded = True
|
self.encoded = True
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
|
Loading…
Reference in New Issue