etherbone: cleanup model
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Wed, 11 Feb 2015 10:11:54 +0000 (11:11 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Wed, 11 Feb 2015 10:11:54 +0000 (11:11 +0100)
liteeth/test/model/etherbone.py

index 7e547e3b600f2de0232684045e88706c9c256746..2f05d2e0a40ec4bce4b937fd3530c861475568f8 100644 (file)
@@ -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)
-
-       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
+               self.encoded = True
+
+       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)