etherbone: cleanup model

This commit is contained in:
Florent Kermarrec 2015-02-11 11:11:54 +01:00
parent 02bfc0a5a8
commit 227fc4f5e5
1 changed files with 86 additions and 42 deletions

View File

@ -14,33 +14,38 @@ class EtherboneWrite:
self.data = data self.data = data
def __repr__(self): def __repr__(self):
return "Write data : {}".format(self.data) return "WR32 0x{:08x}".format(self.data)
class EtherboneRead: class EtherboneRead:
def __init__(self, addr): def __init__(self, addr):
self.addr = addr self.addr = addr
def __repr__(self): def __repr__(self):
return "Read addr : {}".format(self.addr) return "RD32 @ 0x{:08x}".format(self.addr)
class EtherboneWrites(Packet): class EtherboneWrites(Packet):
def __init__(self, init=[], base_addr=0): def __init__(self, init=[], base_addr=0):
Packet.__init__(self, init) Packet.__init__(self, init)
self.base_addr = base_addr self.base_addr = base_addr
self.writes = [] self.writes = []
self.encoded = init != []
def add(self, write): def add(self, write):
self.writes.append(write) self.writes.append(write)
def encode(self): def encode(self):
if self.encoded:
raise ValueError
for byte in split_bytes(self.base_addr, 4): for byte in split_bytes(self.base_addr, 4):
self.append(byte) self.append(byte)
for write in self.writes: for write in self.writes:
for byte in split_bytes(write.data, 4): for byte in split_bytes(write.data, 4):
self.append(byte) self.append(byte)
self.encoded = True
def decode(self): def decode(self):
if not self.encoded:
raise ValueError
base_addr = [] base_addr = []
for i in range(4): for i in range(4):
base_addr.append(self.pop(0)) base_addr.append(self.pop(0))
@ -51,24 +56,39 @@ class EtherboneWrites(Packet):
for i in range(4): for i in range(4):
write.append(self.pop(0)) write.append(self.pop(0))
self.writes.append(EtherboneWrite(merge_bytes(write))) self.writes.append(EtherboneWrite(merge_bytes(write)))
self.encoded = False
def __repr__(self):
r = "Writes\n"
r += "--------\n"
r += "BaseAddr @ 0x{:08x}\n".format(self.base_addr)
for write in self.writes:
r += write.__repr__() + "\n"
return r
class EtherboneReads(Packet): class EtherboneReads(Packet):
def __init__(self, init=[], base_ret_addr=0): def __init__(self, init=[], base_ret_addr=0):
Packet.__init__(self, init) Packet.__init__(self, init)
self.base_ret_addr = base_ret_addr self.base_ret_addr = base_ret_addr
self.reads = [] self.reads = []
self.encoded = init != []
def add(self, read): def add(self, read):
self.reads.append(read) self.reads.append(read)
def encode(self): def encode(self):
if self.encoded:
raise ValueError
for byte in split_bytes(self.base_ret_addr, 4): for byte in split_bytes(self.base_ret_addr, 4):
self.append(byte) self.append(byte)
for read in self.reads: for read in self.reads:
for byte in split_bytes(read.addr, 4): for byte in split_bytes(read.addr, 4):
self.append(byte) self.append(byte)
self.encoded = True
def decode(self): def decode(self):
if not self.encoded:
raise ValueError
base_ret_addr = [] base_ret_addr = []
for i in range(4): for i in range(4):
base_ret_addr.append(self.pop(0)) base_ret_addr.append(self.pop(0))
@ -79,12 +99,22 @@ class EtherboneReads(Packet):
for i in range(4): for i in range(4):
read.append(self.pop(0)) read.append(self.pop(0))
self.reads.append(EtherboneRead(merge_bytes(read))) self.reads.append(EtherboneRead(merge_bytes(read)))
self.encoded = False
def __repr__(self):
r = "Reads\n"
r += "--------\n"
r += "BaseRetAddr @ 0x{:08x}\n".format(self.base_ret_addr)
for read in self.reads:
r += read.__repr__() + "\n"
return r
class EtherboneRecord(Packet): class EtherboneRecord(Packet):
def __init__(self, init=[]): def __init__(self, init=[]):
Packet.__init__(self, init) Packet.__init__(self, init)
self.writes = None self.writes = None
self.reads = None self.reads = None
self.encoded = init != []
def get_writes(self): def get_writes(self):
if self.wcount == 0: if self.wcount == 0:
@ -105,46 +135,64 @@ class EtherboneRecord(Packet):
return EtherboneReads(reads) return EtherboneReads(reads)
def decode(self): def decode(self):
if not self.encoded:
raise ValueError
header = [] header = []
for byte in self[:etherbone_record_header_len]: for byte in self[:etherbone_record_header_len]:
header.append(self.pop(0)) header.append(self.pop(0))
for k, v in sorted(etherbone_record_header.items()): for k, v in sorted(etherbone_record_header.items()):
setattr(self, k, get_field_data(v, header)) setattr(self, k, get_field_data(v, header))
self.writes = self.get_writes()
self.writes.decode()
self.reads = self.get_reads()
self.reads.decode()
self.encoded = False
def set_writes(self, writes): def set_writes(self, writes):
self.writes = writes self.wcount = len(writes.writes)
writes.encode() writes.encode()
for byte in writes: for byte in writes:
self.append(byte) self.append(byte)
self.wcount = len(writes)-4
def set_reads(self, reads): def set_reads(self, reads):
self.reads = reads self.rcount = len(reads.reads)
reads.encode() reads.encode()
for byte in reads: for byte in reads:
self.append(byte) self.append(byte)
self.rcount = len(reads)-4
def encode(self): def encode(self):
if self.encoded:
raise ValueError
self.set_writes(self.writes)
self.set_reads(self.reads)
header = 0 header = 0
for k, v in sorted(etherbone_record_header.items()): for k, v in sorted(etherbone_record_header.items()):
value = merge_bytes(split_bytes(getattr(self, k), math.ceil(v.width/8)), "little") value = merge_bytes(split_bytes(getattr(self, k), math.ceil(v.width/8)), "little")
header += (value << v.offset+(v.byte*8)) header += (value << v.offset+(v.byte*8))
for d in split_bytes(header, etherbone_record_header_len): for d in split_bytes(header, etherbone_record_header_len):
self.insert(0, d) self.insert(0, d)
self.encoded = True
def __repr__(self): def __repr__(self, n=0):
r = "--------\n" r = "Record {}\n".format(n)
for k in sorted(etherbone_record_header.keys()): r += "--------\n"
r += k + " : 0x%x" %getattr(self,k) + "\n" if self.encoded:
r += "payload: "
for d in self: for d in self:
r += "%02x" %d r += "{:02x}".format(d)
else:
for k in sorted(etherbone_record_header.keys()):
r += k + " : 0x{:0x}\n".format(getattr(self,k))
if self.wcount != 0:
r += self.writes.__repr__()
if self.rcount != 0:
r += self.reads.__repr__()
return r return r
class EtherbonePacket(Packet): class EtherbonePacket(Packet):
def __init__(self, init=[]): def __init__(self, init=[]):
Packet.__init__(self, init) Packet.__init__(self, init)
self.encoded = init != []
self.records = []
def get_records(self): def get_records(self):
records = [] records = []
@ -154,39 +202,49 @@ class EtherbonePacket(Packet):
record = EtherboneRecord(payload) record = EtherboneRecord(payload)
record.decode() record.decode()
records.append(copy.deepcopy(record)) records.append(copy.deepcopy(record))
writes = record.get_writes()
reads = record.get_reads()
payload = record payload = record
return records return records
def decode(self): def decode(self):
if not self.encoded:
raise ValueError
header = [] header = []
for byte in self[:etherbone_header_len]: for byte in self[:etherbone_header_len]:
header.append(self.pop(0)) header.append(self.pop(0))
for k, v in sorted(etherbone_header.items()): for k, v in sorted(etherbone_header.items()):
setattr(self, k, get_field_data(v, header)) setattr(self, k, get_field_data(v, header))
self.records = self.get_records()
self.encoded = False
def set_records(self, records): def set_records(self, records):
self.records = records
for record in records: for record in records:
record.encode()
for byte in record: for byte in record:
self.append(byte) self.append(byte)
def encode(self): def encode(self):
if self.encoded:
raise ValueError
self.set_records(self.records)
header = 0 header = 0
for k, v in sorted(etherbone_header.items()): for k, v in sorted(etherbone_header.items()):
value = merge_bytes(split_bytes(getattr(self, k), math.ceil(v.width/8)), "little") value = merge_bytes(split_bytes(getattr(self, k), math.ceil(v.width/8)), "little")
header += (value << v.offset+(v.byte*8)) header += (value << v.offset+(v.byte*8))
for d in split_bytes(header, etherbone_header_len): for d in split_bytes(header, etherbone_header_len):
self.insert(0, d) self.insert(0, d)
self.encoded = True
def __repr__(self): def __repr__(self):
r = "--------\n" r = "Packet\n"
for k in sorted(etherbone_header.keys()): r += "--------\n"
r += k + " : 0x%x" %getattr(self,k) + "\n" if self.encoded:
r += "payload: "
for d in self: for d in self:
r += "%02x" %d r += "{:02x}".format(d)
else:
for k in sorted(etherbone_header.keys()):
r += k + " : 0x{:0x}\n".format(getattr(self,k))
for i, record in enumerate(self.records):
r += record.__repr__(i)
return r return r
class Etherbone(Module): class Etherbone(Module):
@ -233,8 +291,8 @@ if __name__ == "__main__":
# Record # Record
record = EtherboneRecord() record = EtherboneRecord()
record.set_writes(writes) record.writes = writes
record.set_reads(reads) record.reads = reads
record.bca = 0 record.bca = 0
record.rca = 0 record.rca = 0
record.rff = 0 record.rff = 0
@ -244,11 +302,10 @@ if __name__ == "__main__":
record.byte_enable = 0 record.byte_enable = 0
record.wcount = 16 record.wcount = 16
record.rcount = 16 record.rcount = 16
record.encode()
# Packet # Packet
packet = EtherbonePacket() packet = EtherbonePacket()
packet.set_records([record for i in range(8)]) packet.records = [copy.deepcopy(record) for i in range(8)]
packet.magic = etherbone_magic packet.magic = etherbone_magic
packet.version = etherbone_version packet.version = etherbone_version
packet.nr = 0 packet.nr = 0
@ -258,6 +315,7 @@ if __name__ == "__main__":
packet.port_size = 32//8 packet.port_size = 32//8
#print(packet) #print(packet)
packet.encode() packet.encode()
#print(packet)
# Send packet over UDP to check against Wireshark dissector # Send packet over UDP to check against Wireshark dissector
import socket import socket
@ -266,18 +324,4 @@ if __name__ == "__main__":
packet = EtherbonePacket(packet) packet = EtherbonePacket(packet)
packet.decode() packet.decode()
#print(packet) print(packet)
# Record
records = packet.get_records()
for record in records:
writes = record.get_writes()
writes.decode()
print(writes.base_addr)
for e in writes.writes:
print(e)
reads = record.get_reads()
reads.decode()
print(reads.base_ret_addr)
for e in reads.reads:
print(e)