tools/remove/etherbone: cosmetic cleanup, add assert for maximum burst size (255).

This commit is contained in:
Florent Kermarrec 2020-11-25 08:07:06 +01:00
parent 6fe2bcd1f0
commit 9b696373a2
1 changed files with 65 additions and 52 deletions

View File

@ -1,7 +1,7 @@
# #
# This file is part of LiteX. # This file is part of LiteX.
# #
# Copyright (c) 2015-2019 Florent Kermarrec <florent@enjoy-digital.fr> # Copyright (c) 2015-2020 Florent Kermarrec <florent@enjoy-digital.fr>
# Copyright (c) 2017 Tim Ansell <mithro@mithis.com> # Copyright (c) 2017 Tim Ansell <mithro@mithis.com>
# SPDX-License-Identifier: BSD-2-Clause # SPDX-License-Identifier: BSD-2-Clause
@ -10,45 +10,47 @@ import struct
from litex.soc.interconnect.packet import HeaderField, Header from litex.soc.interconnect.packet import HeaderField, Header
# Etherbone Constants / Headers / Helpers ----------------------------------------------------------
etherbone_magic = 0x4e6f etherbone_magic = 0x4e6f
etherbone_version = 1 etherbone_version = 1
etherbone_packet_header_length = 8 etherbone_packet_header_length = 8
etherbone_packet_header_fields = { etherbone_packet_header_fields = {
"magic": HeaderField(0, 0, 16), "magic": HeaderField(0, 0, 16),
"version": HeaderField(2, 4, 4), "version": HeaderField(2, 4, 4),
"nr": HeaderField(2, 2, 1), # No Reads "nr": HeaderField(2, 2, 1), # No Reads
"pr": HeaderField(2, 1, 1), # Probe Reply "pr": HeaderField(2, 1, 1), # Probe Reply
"pf": HeaderField(2, 0, 1), # Probe Flag "pf": HeaderField(2, 0, 1), # Probe Flag
"addr_size": HeaderField(3, 4, 4), # 1=8bits, 2=16bits, 4=32bits, 8=64bits "addr_size": HeaderField(3, 4, 4), # 1=8bits, 2=16bits, 4=32bits, 8=64bits
"port_size": HeaderField(3, 0, 4), # Same as above "port_size": HeaderField(3, 0, 4), # Same as above
} }
etherbone_packet_header = Header(etherbone_packet_header_fields, etherbone_packet_header = Header(
etherbone_packet_header_length, fields = etherbone_packet_header_fields,
swap_field_bytes=True) length = etherbone_packet_header_length,
swap_field_bytes = True)
# When reading/writing to a FIFO, you don't increase
# the address after each write.
etherbone_record_header_length = 4 etherbone_record_header_length = 4
etherbone_record_header_fields = { etherbone_record_header_fields = {
"bca": HeaderField(0, 0, 1), # ReplyToCfgSpace - ??? (C)onfig (A)dress "bca": HeaderField(0, 0, 1), # ReplyToCfgSpace - ??? (C)onfig (A)dress
"rca": HeaderField(0, 1, 1), # ReadFromCfgSpace - (R)ead from (C)onfig (A)dress "rca": HeaderField(0, 1, 1), # ReadFromCfgSpace - (R)ead from (C)onfig (A)dress
"rff": HeaderField(0, 2, 1), # ReadFIFO - (R)ead (F)I(F)O "rff": HeaderField(0, 2, 1), # ReadFIFO - (R)ead (F)I(F)O
"cyc": HeaderField(0, 4, 1), # DropCycle - Drop(Cyc)le "cyc": HeaderField(0, 4, 1), # DropCycle - Drop(Cyc)le
"wca": HeaderField(0, 5, 1), # WriteToCfgSpace - (W)rite to (C)onfig (A)dress "wca": HeaderField(0, 5, 1), # WriteToCfgSpace - (W)rite to (C)onfig (A)dress
"wff": HeaderField(0, 6, 1), # WriteFIFO - (W)rite (F)I(F)O "wff": HeaderField(0, 6, 1), # WriteFIFO - (W)rite (F)I(F)O
"byte_enable": HeaderField(1, 0, 8), # Select "byte_enable": HeaderField(1, 0, 8), # Select
"wcount": HeaderField(2, 0, 8), # Writes "wcount": HeaderField(2, 0, 8), # Writes
"rcount": HeaderField(3, 0, 8), # Reads "rcount": HeaderField(3, 0, 8), # Reads
} }
etherbone_record_header = Header(etherbone_record_header_fields, etherbone_record_header = Header(
etherbone_record_header_length, fields = etherbone_record_header_fields,
swap_field_bytes=True) length = etherbone_record_header_length,
swap_field_bytes = True)
def split_bytes(v, n, endianness="big"): def split_bytes(v, n, endianness="big"):
@ -64,14 +66,16 @@ def get_field_data(field, datas):
v = merge_bytes(datas[field.byte:field.byte+math.ceil(field.width/8)]) v = merge_bytes(datas[field.byte:field.byte+math.ceil(field.width/8)])
return (v >> field.offset) & (2**field.width-1) return (v >> field.offset) & (2**field.width-1)
# Packet -------------------------------------------------------------------------------------------
class Packet(list): class Packet(list):
def __init__(self, init=[]): def __init__(self, init=[]):
self.ongoing = False self.ongoing = False
self.done = False self.done = False
for data in init: for data in init:
self.append(data) self.append(data)
# Etherbone Write / Read ---------------------------------------------------------------------------
class EtherboneWrite: class EtherboneWrite:
def __init__(self, data): def __init__(self, data):
@ -88,13 +92,16 @@ class EtherboneRead:
def __repr__(self): def __repr__(self):
return "RD32 @ 0x{:08x}".format(self.addr) return "RD32 @ 0x{:08x}".format(self.addr)
# Etherbone Writes ---------------------------------------------------------------------------------
class EtherboneWrites(Packet): class EtherboneWrites(Packet):
def __init__(self, init=[], base_addr=0, datas=[]): def __init__(self, init=[], base_addr=0, datas=[]):
if isinstance(datas, list) and len(datas) > 255:
raise ValueError(f"Burst size of {len(datas)} exceeds maximum of 255 allowed by Etherbone.")
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 != [] self.encoded = init != []
for data in datas: for data in datas:
self.add(EtherboneWrite(data)) self.add(EtherboneWrite(data))
@ -124,7 +131,7 @@ class EtherboneWrites(Packet):
for i in range(4): for i in range(4):
base_addr.append(self.pop(0)) base_addr.append(self.pop(0))
self.base_addr = merge_bytes(base_addr) self.base_addr = merge_bytes(base_addr)
self.writes = [] self.writes = []
while len(self) != 0: while len(self) != 0:
write = [] write = []
for i in range(4): for i in range(4):
@ -140,13 +147,16 @@ class EtherboneWrites(Packet):
r += write.__repr__() + "\n" r += write.__repr__() + "\n"
return r return r
# Etherbone Reads ----------------------------------------------------------------------------------
class EtherboneReads(Packet): class EtherboneReads(Packet):
def __init__(self, init=[], base_ret_addr=0, addrs=[]): def __init__(self, init=[], base_ret_addr=0, addrs=[]):
if isinstance(addrs, list) and len(addrs) > 255:
raise ValueError(f"Burst size of {len(addrs)} exceeds maximum of 255 allowed by Etherbone.")
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 != [] self.encoded = init != []
for addr in addrs: for addr in addrs:
self.add(EtherboneRead(addr)) self.add(EtherboneRead(addr))
@ -176,7 +186,7 @@ class EtherboneReads(Packet):
for i in range(4): for i in range(4):
base_ret_addr.append(self.pop(0)) base_ret_addr.append(self.pop(0))
self.base_ret_addr = merge_bytes(base_ret_addr) self.base_ret_addr = merge_bytes(base_ret_addr)
self.reads = [] self.reads = []
while len(self) != 0: while len(self) != 0:
read = [] read = []
for i in range(4): for i in range(4):
@ -192,22 +202,23 @@ class EtherboneReads(Packet):
r += read.__repr__() + "\n" r += read.__repr__() + "\n"
return r return r
# Etherbone Record ---------------------------------------------------------------------------------
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.bca = 0 self.bca = 0
self.rca = 0 self.rca = 0
self.rff = 0 self.rff = 0
self.cyc = 0 self.cyc = 0
self.wca = 0 self.wca = 0
self.wff = 0 self.wff = 0
self.byte_enable = 0xf self.byte_enable = 0xf
self.wcount = 0 self.wcount = 0
self.rcount = 0 self.rcount = 0
self.encoded = init != [] self.encoded = init != []
def get_writes(self): def get_writes(self):
@ -288,6 +299,7 @@ class EtherboneRecord(Packet):
r += self.reads.__repr__() r += self.reads.__repr__()
return r return r
# Etherbone Packet ---------------------------------------------------------------------------------
class EtherbonePacket(Packet): class EtherbonePacket(Packet):
def __init__(self, init=[]): def __init__(self, init=[]):
@ -295,17 +307,17 @@ class EtherbonePacket(Packet):
self.encoded = init != [] self.encoded = init != []
self.records = [] self.records = []
self.magic = etherbone_magic self.magic = etherbone_magic
self.version = etherbone_version self.version = etherbone_version
self.addr_size = 32//8 self.addr_size = 32//8
self.port_size = 32//8 self.port_size = 32//8
self.nr = 0 self.nr = 0
self.pr = 0 self.pr = 0
self.pf = 0 self.pf = 0
def get_records(self): def get_records(self):
records = [] records = []
done = False done = False
payload = self payload = self
while len(payload) != 0: while len(payload) != 0:
record = EtherboneRecord(payload) record = EtherboneRecord(payload)
@ -356,6 +368,7 @@ class EtherbonePacket(Packet):
r += record.__repr__(i) r += record.__repr__(i)
return r return r
# Etherbone IPC ------------------------------------------------------------------------------------
class EtherboneIPC: class EtherboneIPC:
def send_packet(self, socket, packet): def send_packet(self, socket, packet):
@ -363,7 +376,7 @@ class EtherboneIPC:
def receive_packet(self, socket): def receive_packet(self, socket):
header_length = etherbone_packet_header_length + etherbone_record_header_length header_length = etherbone_packet_header_length + etherbone_record_header_length
packet = bytes() packet = bytes()
while len(packet) < header_length: while len(packet) < header_length:
chunk = socket.recv(header_length - len(packet)) chunk = socket.recv(header_length - len(packet))
if len(chunk) == 0: if len(chunk) == 0: