From 227fc4f5e5fa7f44727f6f46db8b3209043fabe4 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 11 Feb 2015 11:11:54 +0100 Subject: [PATCH] etherbone: cleanup model --- liteeth/test/model/etherbone.py | 128 +++++++++++++++++++++----------- 1 file changed, 86 insertions(+), 42 deletions(-) diff --git a/liteeth/test/model/etherbone.py b/liteeth/test/model/etherbone.py index 7e547e3b6..2f05d2e0a 100644 --- a/liteeth/test/model/etherbone.py +++ b/liteeth/test/model/etherbone.py @@ -14,33 +14,38 @@ class EtherboneWrite: self.data = data def __repr__(self): - return "Write data : {}".format(self.data) - + return "WR32 0x{:08x}".format(self.data) class EtherboneRead: def __init__(self, addr): self.addr = addr def __repr__(self): - return "Read addr : {}".format(self.addr) + return "RD32 @ 0x{:08x}".format(self.addr) class EtherboneWrites(Packet): def __init__(self, init=[], base_addr=0): Packet.__init__(self, init) self.base_addr = base_addr self.writes = [] + self.encoded = init != [] def add(self, write): self.writes.append(write) def encode(self): + if self.encoded: + raise ValueError for byte in split_bytes(self.base_addr, 4): self.append(byte) for write in self.writes: for byte in split_bytes(write.data, 4): self.append(byte) + self.encoded = True def decode(self): + if not self.encoded: + raise ValueError base_addr = [] for i in range(4): base_addr.append(self.pop(0)) @@ -51,24 +56,39 @@ class EtherboneWrites(Packet): for i in range(4): write.append(self.pop(0)) 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): def __init__(self, init=[], base_ret_addr=0): Packet.__init__(self, init) self.base_ret_addr = base_ret_addr self.reads = [] + self.encoded = init != [] def add(self, read): self.reads.append(read) def encode(self): + if self.encoded: + raise ValueError for byte in split_bytes(self.base_ret_addr, 4): self.append(byte) for read in self.reads: for byte in split_bytes(read.addr, 4): self.append(byte) + self.encoded = True def decode(self): + if not self.encoded: + raise ValueError base_ret_addr = [] for i in range(4): base_ret_addr.append(self.pop(0)) @@ -79,12 +99,22 @@ class EtherboneReads(Packet): for i in range(4): read.append(self.pop(0)) 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): def __init__(self, init=[]): Packet.__init__(self, init) self.writes = None self.reads = None + self.encoded = init != [] def get_writes(self): if self.wcount == 0: @@ -105,46 +135,64 @@ class EtherboneRecord(Packet): return EtherboneReads(reads) def decode(self): + if not self.encoded: + raise ValueError header = [] for byte in self[:etherbone_record_header_len]: header.append(self.pop(0)) for k, v in sorted(etherbone_record_header.items()): 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): - self.writes = writes + self.wcount = len(writes.writes) writes.encode() for byte in writes: self.append(byte) - self.wcount = len(writes)-4 def set_reads(self, reads): - self.reads = reads + self.rcount = len(reads.reads) reads.encode() for byte in reads: self.append(byte) - self.rcount = len(reads)-4 def encode(self): + if self.encoded: + raise ValueError + self.set_writes(self.writes) + self.set_reads(self.reads) header = 0 for k, v in sorted(etherbone_record_header.items()): value = merge_bytes(split_bytes(getattr(self, k), math.ceil(v.width/8)), "little") header += (value << v.offset+(v.byte*8)) for d in split_bytes(header, etherbone_record_header_len): self.insert(0, d) + self.encoded = True - def __repr__(self): - r = "--------\n" - for k in sorted(etherbone_record_header.keys()): - r += k + " : 0x%x" %getattr(self,k) + "\n" - r += "payload: " - for d in self: - r += "%02x" %d + def __repr__(self, n=0): + r = "Record {}\n".format(n) + r += "--------\n" + if self.encoded: + for d in self: + 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 class EtherbonePacket(Packet): def __init__(self, init=[]): Packet.__init__(self, init) + self.encoded = init != [] + self.records = [] def get_records(self): records = [] @@ -154,39 +202,49 @@ class EtherbonePacket(Packet): record = EtherboneRecord(payload) record.decode() records.append(copy.deepcopy(record)) - writes = record.get_writes() - reads = record.get_reads() payload = record return records def decode(self): + if not self.encoded: + raise ValueError header = [] for byte in self[:etherbone_header_len]: header.append(self.pop(0)) for k, v in sorted(etherbone_header.items()): setattr(self, k, get_field_data(v, header)) + self.records = self.get_records() + self.encoded = False def set_records(self, records): - self.records = records for record in records: + record.encode() for byte in record: self.append(byte) def encode(self): + if self.encoded: + raise ValueError + self.set_records(self.records) header = 0 for k, v in sorted(etherbone_header.items()): value = merge_bytes(split_bytes(getattr(self, k), math.ceil(v.width/8)), "little") header += (value << v.offset+(v.byte*8)) for d in split_bytes(header, etherbone_header_len): self.insert(0, d) + self.encoded = True def __repr__(self): - r = "--------\n" - for k in sorted(etherbone_header.keys()): - r += k + " : 0x%x" %getattr(self,k) + "\n" - r += "payload: " - for d in self: - r += "%02x" %d + r = "Packet\n" + r += "--------\n" + if self.encoded: + for d in self: + 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 class Etherbone(Module): @@ -233,8 +291,8 @@ if __name__ == "__main__": # Record record = EtherboneRecord() - record.set_writes(writes) - record.set_reads(reads) + record.writes = writes + record.reads = reads record.bca = 0 record.rca = 0 record.rff = 0 @@ -244,11 +302,10 @@ if __name__ == "__main__": record.byte_enable = 0 record.wcount = 16 record.rcount = 16 - record.encode() # Packet 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.version = etherbone_version packet.nr = 0 @@ -258,6 +315,7 @@ if __name__ == "__main__": packet.port_size = 32//8 #print(packet) packet.encode() + #print(packet) # Send packet over UDP to check against Wireshark dissector import socket @@ -266,18 +324,4 @@ if __name__ == "__main__": packet = EtherbonePacket(packet) packet.decode() - #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) + print(packet)