ethetbone software is now integrated in LiteX
This commit is contained in:
parent
155be56f9c
commit
f1725d5fd1
|
@ -1,302 +0,0 @@
|
|||
from copy import deepcopy
|
||||
|
||||
from liteeth.common import *
|
||||
|
||||
|
||||
def split_bytes(v, n, endianness="big"):
|
||||
r = []
|
||||
r_bytes = v.to_bytes(n, byteorder=endianness)
|
||||
for byte in r_bytes:
|
||||
r.append(int(byte))
|
||||
return r
|
||||
|
||||
|
||||
def merge_bytes(b, endianness="big"):
|
||||
return int.from_bytes(bytes(b), endianness)
|
||||
|
||||
|
||||
def get_field_data(field, datas):
|
||||
v = merge_bytes(datas[field.byte:field.byte+math.ceil(field.width/8)])
|
||||
return (v >> field.offset) & (2**field.width-1)
|
||||
|
||||
|
||||
class Packet(list):
|
||||
def __init__(self, init=[]):
|
||||
self.ongoing = False
|
||||
self.done = False
|
||||
for data in init:
|
||||
self.append(data)
|
||||
|
||||
|
||||
class EtherboneWrite:
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
|
||||
def __repr__(self):
|
||||
return "WR32 0x{:08x}".format(self.data)
|
||||
|
||||
|
||||
class EtherboneRead:
|
||||
def __init__(self, addr):
|
||||
self.addr = addr
|
||||
|
||||
def __repr__(self):
|
||||
return "RD32 @ 0x{:08x}".format(self.addr)
|
||||
|
||||
|
||||
class EtherboneWrites(Packet):
|
||||
def __init__(self, init=[], base_addr=0, datas=[]):
|
||||
Packet.__init__(self, init)
|
||||
self.base_addr = base_addr
|
||||
self.writes = []
|
||||
self.encoded = init != []
|
||||
for data in datas:
|
||||
self.add(EtherboneWrite(data))
|
||||
|
||||
def add(self, write):
|
||||
self.writes.append(write)
|
||||
|
||||
def get_datas(self):
|
||||
datas = []
|
||||
for write in self.writes:
|
||||
datas.append(write.data)
|
||||
return datas
|
||||
|
||||
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))
|
||||
self.base_addr = merge_bytes(base_addr)
|
||||
self.writes = []
|
||||
while len(self) != 0:
|
||||
write = []
|
||||
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, addrs=[]):
|
||||
Packet.__init__(self, init)
|
||||
self.base_ret_addr = base_ret_addr
|
||||
self.reads = []
|
||||
self.encoded = init != []
|
||||
for addr in addrs:
|
||||
self.add(EtherboneRead(addr))
|
||||
|
||||
def add(self, read):
|
||||
self.reads.append(read)
|
||||
|
||||
def get_addrs(self):
|
||||
addrs = []
|
||||
for read in self.reads:
|
||||
addrs.append(read.addr)
|
||||
return addrs
|
||||
|
||||
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))
|
||||
self.base_ret_addr = merge_bytes(base_ret_addr)
|
||||
self.reads = []
|
||||
while len(self) != 0:
|
||||
read = []
|
||||
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:
|
||||
return None
|
||||
else:
|
||||
writes = []
|
||||
for i in range((self.wcount+1)*4):
|
||||
writes.append(self.pop(0))
|
||||
return EtherboneWrites(writes)
|
||||
|
||||
def get_reads(self):
|
||||
if self.rcount == 0:
|
||||
return None
|
||||
else:
|
||||
reads = []
|
||||
for i in range((self.rcount+1)*4):
|
||||
reads.append(self.pop(0))
|
||||
return EtherboneReads(reads)
|
||||
|
||||
def decode(self):
|
||||
if not self.encoded:
|
||||
raise ValueError
|
||||
header = []
|
||||
for byte in self[:etherbone_record_header.length]:
|
||||
header.append(self.pop(0))
|
||||
for k, v in sorted(etherbone_record_header.fields.items()):
|
||||
setattr(self, k, get_field_data(v, header))
|
||||
self.writes = self.get_writes()
|
||||
if self.writes is not None:
|
||||
self.writes.decode()
|
||||
self.reads = self.get_reads()
|
||||
if self.reads is not None:
|
||||
self.reads.decode()
|
||||
self.encoded = False
|
||||
|
||||
def set_writes(self, writes):
|
||||
self.wcount = len(writes.writes)
|
||||
writes.encode()
|
||||
for byte in writes:
|
||||
self.append(byte)
|
||||
|
||||
def set_reads(self, reads):
|
||||
self.rcount = len(reads.reads)
|
||||
reads.encode()
|
||||
for byte in reads:
|
||||
self.append(byte)
|
||||
|
||||
def encode(self):
|
||||
if self.encoded:
|
||||
raise ValueError
|
||||
if self.writes is not None:
|
||||
self.set_writes(self.writes)
|
||||
if self.reads is not None:
|
||||
self.set_reads(self.reads)
|
||||
header = 0
|
||||
for k, v in sorted(etherbone_record_header.fields.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.length):
|
||||
self.insert(0, 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.fields.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 = []
|
||||
|
||||
self.magic = etherbone_magic
|
||||
self.version = etherbone_version
|
||||
self.addr_size = 32//8
|
||||
self.port_size = 32//8
|
||||
self.nr = 0
|
||||
self.pr = 0
|
||||
self.pf = 0
|
||||
|
||||
def get_records(self):
|
||||
records = []
|
||||
done = False
|
||||
payload = self
|
||||
while len(payload) != 0:
|
||||
record = EtherboneRecord(payload)
|
||||
record.decode()
|
||||
records.append(deepcopy(record))
|
||||
payload = record
|
||||
return records
|
||||
|
||||
def decode(self):
|
||||
if not self.encoded:
|
||||
raise ValueError
|
||||
header = []
|
||||
for byte in self[:etherbone_packet_header.length]:
|
||||
header.append(self.pop(0))
|
||||
for k, v in sorted(etherbone_packet_header.fields.items()):
|
||||
setattr(self, k, get_field_data(v, header))
|
||||
self.records = self.get_records()
|
||||
self.encoded = False
|
||||
|
||||
def set_records(self, 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_packet_header.fields.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_packet_header.length):
|
||||
self.insert(0, d)
|
||||
self.encoded = True
|
||||
|
||||
def __repr__(self):
|
||||
r = "Packet\n"
|
||||
r += "--------\n"
|
||||
if self.encoded:
|
||||
for d in self:
|
||||
r += "{:02x}".format(d)
|
||||
else:
|
||||
for k in sorted(etherbone_packet_header.fields.keys()):
|
||||
r += k + " : 0x{:0x}\n".format(getattr(self, k))
|
||||
for i, record in enumerate(self.records):
|
||||
r += record.__repr__(i)
|
||||
return r
|
|
@ -1,84 +0,0 @@
|
|||
import socket
|
||||
|
||||
from litescope.software.driver.reg import *
|
||||
from liteeth.software.etherbone import *
|
||||
|
||||
|
||||
class LiteEthWishboneBridgeDriver:
|
||||
def __init__(self, ip_address, udp_port=20000, addrmap=None, busword=8, debug=False):
|
||||
self.ip_address = ip_address
|
||||
self.udp_port = udp_port
|
||||
self.debug = debug
|
||||
|
||||
self.tx_sock = None
|
||||
self.rx_sock = None
|
||||
if addrmap is not None:
|
||||
self.regs = build_map(addrmap, busword, self.read, self.write)
|
||||
|
||||
def open(self):
|
||||
self.tx_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
self.rx_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
self.rx_sock.bind(("", self.udp_port))
|
||||
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
def read(self, addr, burst_length=1):
|
||||
reads_addrs = [addr+4*j for j in range(burst_length)]
|
||||
reads = EtherboneReads(base_ret_addr=0x1000, addrs=reads_addrs)
|
||||
record = EtherboneRecord()
|
||||
record.writes = None
|
||||
record.reads = reads
|
||||
record.bca = 0
|
||||
record.rca = 0
|
||||
record.rff = 0
|
||||
record.cyc = 0
|
||||
record.wca = 0
|
||||
record.wff = 0
|
||||
record.byte_enable = 0xf
|
||||
record.wcount = 0
|
||||
record.rcount = len(reads_addrs)
|
||||
|
||||
packet = EtherbonePacket()
|
||||
packet.records = [record]
|
||||
packet.encode()
|
||||
self.tx_sock.sendto(bytes(packet), (self.ip_address, self.udp_port))
|
||||
|
||||
datas, addrs = self.rx_sock.recvfrom(8192)
|
||||
packet = EtherbonePacket(datas)
|
||||
packet.decode()
|
||||
datas = packet.records.pop().writes.get_datas()
|
||||
if self.debug:
|
||||
for i, data in enumerate(datas):
|
||||
print("RD {:08X} @ {:08X}".format(data, addr + 4*i))
|
||||
if burst_length == 1:
|
||||
return datas[0]
|
||||
else:
|
||||
return datas
|
||||
|
||||
def write(self, addr, datas):
|
||||
if not isinstance(datas, list):
|
||||
datas = [datas]
|
||||
writes_datas = [d for d in datas]
|
||||
writes = EtherboneWrites(base_addr=addr, datas=writes_datas)
|
||||
record = EtherboneRecord()
|
||||
record.writes = writes
|
||||
record.reads = None
|
||||
record.bca = 0
|
||||
record.rca = 0
|
||||
record.rff = 0
|
||||
record.cyc = 0
|
||||
record.wca = 0
|
||||
record.wff = 0
|
||||
record.byte_enable = 0xf
|
||||
record.wcount = len(writes_datas)
|
||||
record.rcount = 0
|
||||
|
||||
packet = EtherbonePacket()
|
||||
packet.records = [record]
|
||||
packet.encode()
|
||||
self.tx_sock.sendto(bytes(packet), (self.ip_address, self.udp_port))
|
||||
|
||||
if self.debug:
|
||||
for i, data in enumerate(datas):
|
||||
print("WR {:08X} @ {:08X}".format(data, addr + 4*i))
|
|
@ -2,9 +2,9 @@ import math
|
|||
import copy
|
||||
|
||||
from litex.soc.interconnect.stream_sim import *
|
||||
from litex.soc.tools.remote.etherbone import *
|
||||
|
||||
from liteeth.common import *
|
||||
from liteeth.software.etherbone import *
|
||||
|
||||
from test.model import udp
|
||||
|
||||
|
@ -63,22 +63,12 @@ if __name__ == "__main__":
|
|||
record = EtherboneRecord()
|
||||
record.writes = writes
|
||||
record.reads = reads
|
||||
record.bca = 0
|
||||
record.rca = 0
|
||||
record.rff = 0
|
||||
record.cyc = 0
|
||||
record.wca = 0
|
||||
record.wff = 0
|
||||
record.byte_enable = 0
|
||||
record.wcount = len(writes.get_datas())
|
||||
record.rcount = len(reads.get_addrs())
|
||||
|
||||
# Packet
|
||||
packet = EtherbonePacket()
|
||||
packet.records = [deepcopy(record) for i in range(8)]
|
||||
packet.nr = 0
|
||||
packet.pr = 0
|
||||
packet.pf = 0
|
||||
# print(packet)
|
||||
packet.encode()
|
||||
# print(packet)
|
||||
|
|
Loading…
Reference in New Issue