Skip to content

Commit

Permalink
tools/remote/comms: base CommXY on CSRBuilder to allow using Comms di…
Browse files Browse the repository at this point in the history
…rectly in python scripts.

This way, user scripts can be use RemoteClient (communicating with the Server that has
already been opened on the right interface) or directly use CommXY in the scripts.

Using RemoteClient is more generic but can be slower (due to the Etherbone encoding between
the client and server). On fixed configuration using CommXY directly can then be faster
and also avoid manual opening of the server.
  • Loading branch information
enjoy-digital committed Nov 25, 2020
1 parent 2c36879 commit 3d2574a
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 50 deletions.
9 changes: 7 additions & 2 deletions litex/tools/remote/comm_pcie.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@
import ctypes
import mmap

class CommPCIe:
def __init__(self, bar, debug=False):
from litex.tools.remote.csr_builder import CSRBuilder

# CommPCIe -----------------------------------------------------------------------------------------

class CommPCIe(CSRBuilder):
def __init__(self, bar, csr_csr=None, debug=False):
CSRBuilder.__init__(self, comm=self, csr_csv=csr_csv)
self.bar = bar
self.debug = debug

Expand Down
24 changes: 15 additions & 9 deletions litex/tools/remote/comm_uart.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
#
# This file is part of LiteX.
#
# Copyright (c) 2015-2019 Florent Kermarrec <[email protected]>
# Copyright (c) 2015-2020 Florent Kermarrec <[email protected]>
# SPDX-License-Identifier: BSD-2-Clause

import serial
import struct

from litex.tools.remote.csr_builder import CSRBuilder

# Constants ----------------------------------------------------------------------------------------

CMD_WRITE_BURST_INCR = 0x01
CMD_READ_BURST_INCR = 0x02
CMD_WRITE_BURST_FIXED = 0x03
CMD_READ_BURST_FIXED = 0x04

class CommUART:
def __init__(self, port, baudrate=115200, debug=False):
self.port = port
# CommUART -----------------------------------------------------------------------------------------

class CommUART(CSRBuilder):
def __init__(self, port, baudrate=115200, csr_csv=None, debug=False):
CSRBuilder.__init__(self, comm=self, csr_csv=csr_csv)
self.port = serial.serial_for_url(port, baudrate)
self.baudrate = str(baudrate)
self.debug = debug
self.port = serial.serial_for_url(port, baudrate)
self.debug = debug

def open(self):
if hasattr(self, "port"):
Expand Down Expand Up @@ -50,9 +56,9 @@ def _flush(self):

def read(self, addr, length=None, burst="incr"):
self._flush()
data = []
data = []
length_int = 1 if length is None else length
cmd = {
cmd = {
"incr" : CMD_READ_BURST_INCR,
"fixed": CMD_READ_BURST_FIXED,
}[burst]
Expand All @@ -69,7 +75,7 @@ def read(self, addr, length=None, burst="incr"):

def write(self, addr, data, burst="incr"):
self._flush()
data = data if isinstance(data, list) else [data]
data = data if isinstance(data, list) else [data]
length = len(data)
offset = 0
while length:
Expand Down
12 changes: 8 additions & 4 deletions litex/tools/remote/comm_udp.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@
from litex.tools.remote.etherbone import EtherbonePacket, EtherboneRecord
from litex.tools.remote.etherbone import EtherboneReads, EtherboneWrites

from litex.tools.remote.csr_builder import CSRBuilder

class CommUDP:
def __init__(self, server="192.168.1.50", port=1234, debug=False):
# CommUDP ------------------------------------------------------------------------------------------

class CommUDP(CSRBuilder):
def __init__(self, server="192.168.1.50", port=1234, csr_csv=None, debug=False):
CSRBuilder.__init__(self, comm=self, csr_csv=csr_csv)
self.server = server
self.port = port
self.debug = debug
self.port = port
self.debug = debug

def open(self):
if hasattr(self, "socket"):
Expand Down
23 changes: 14 additions & 9 deletions litex/tools/remote/comm_usb.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import usb.core
import time

from litex.tools.remote.csr_builder import CSRBuilder

# Wishbone USB Protocol Bridge
# ============================
#
Expand Down Expand Up @@ -57,13 +59,16 @@
# we only support 32-bit reads and writes, this is always 4. On big endian
# USB, this has the value {04, 00}.

class CommUSB:
def __init__(self, vid=None, pid=None, max_retries=10, debug=False):
self.vid = vid
self.pid = pid
self.debug = debug
# CommUSB ------------------------------------------------------------------------------------------

class CommUSB(CSRBuilder):
def __init__(self, vid=None, pid=None, max_retries=10, csr_csr=None, debug=False):
CSRBuilder.__init__(self, comm=self, csr_csv=csr_csv)
self.vid = vid
self.pid = pid
self.debug = debug
self.max_retries = max_retries
self.MAX_RECURSION_COUNT = 5
self.max_recursion_count = 5

def open(self):
if hasattr(self, "dev"):
Expand Down Expand Up @@ -123,12 +128,12 @@ def usb_read(self, addr, depth=0):
print("Access Denied. Maybe try using sudo?")
self.close()
self.open()
if depth < self.MAX_RECURSION_COUNT:
if depth < self.max_recursion_count:
return self.usb_read(addr, depth+1)
except TypeError:
self.close()
self.open()
if depth < self.MAX_RECURSION_COUNT:
if depth < self.max_recursion_count:
return self.usb_read(addr, depth+1)

def write(self, addr, data):
Expand All @@ -154,5 +159,5 @@ def usb_write(self, addr, value, depth=0):
print("Access Denied. Maybe try using sudo?")
self.close()
self.open()
if depth < self.MAX_RECURSION_COUNT:
if depth < self.max_recursion_count:
return self.usb_write(addr, value, depth+1)
54 changes: 28 additions & 26 deletions litex/tools/remote/csr_builder.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
#
# This file is part of LiteX.
#
# Copyright (c) 2015-2019 Florent Kermarrec <[email protected]>
# Copyright (c) 2015-2020 Florent Kermarrec <[email protected]>
# Copyright (c) 2016 Tim 'mithro' Ansell <[email protected]>
# SPDX-License-Identifier: BSD-2-Clause

import csv

# CSR Elements -------------------------------------------------------------------------------------

class CSRElements:
def __init__(self, d):
Expand All @@ -23,16 +24,15 @@ def __getattr__(self, attr):
pass
raise AttributeError("No such element " + attr)


class CSRRegister:
def __init__(self, readfn, writefn, name, addr, length, data_width, mode):
self.readfn = readfn
self.writefn = writefn
self.name = name
self.addr = addr
self.length = length
self.readfn = readfn
self.writefn = writefn
self.name = name
self.addr = addr
self.length = length
self.data_width = data_width
self.mode = mode
self.mode = mode

def read(self):
if self.mode not in ["rw", "ro"]:
Expand All @@ -55,32 +55,34 @@ def write(self, value):
datas.append((value >> ((self.length-1-i)*self.data_width)) & (2**self.data_width-1))
self.writefn(self.addr, datas)


class CSRMemoryRegion:
def __init__(self, base, size, type):
self.base = base
self.size = size
self.type = type

# CSR Builder --------------------------------------------------------------------------------------

class CSRBuilder:
def __init__(self, comm, csr_csv, csr_data_width=None):
self.items = self.get_csr_items(csr_csv)
self.constants = self.build_constants()

# Load csr_data_width from the constants, otherwise it must be provided
constant_csr_data_width = self.constants.d.get("config_csr_data_width", None)
if csr_data_width is None:
csr_data_width = constant_csr_data_width
if csr_data_width is None:
raise KeyError("csr_data_width not found in constants, please provide!")
if csr_data_width != constant_csr_data_width:
raise KeyError("csr_data_width of {} provided but {} found in constants".format(
csr_data_width, constant_csr_data_width))

self.csr_data_width = csr_data_width
self.bases = self.build_bases()
self.regs = self.build_registers(comm.read, comm.write)
self.mems = self.build_memories()
if csr_csv is not None:
self.items = self.get_csr_items(csr_csv)
self.constants = self.build_constants()

# Load csr_data_width from the constants, otherwise it must be provided
constant_csr_data_width = self.constants.d.get("config_csr_data_width", None)
if csr_data_width is None:
csr_data_width = constant_csr_data_width
if csr_data_width is None:
raise KeyError("csr_data_width not found in constants, please provide!")
if csr_data_width != constant_csr_data_width:
raise KeyError("csr_data_width of {} provided but {} found in constants".format(
csr_data_width, constant_csr_data_width))

self.csr_data_width = csr_data_width
self.bases = self.build_bases()
self.regs = self.build_registers(comm.read, comm.write)
self.mems = self.build_memories()

@staticmethod
def get_csr_items(csr_csv):
Expand Down

0 comments on commit 3d2574a

Please sign in to comment.