diff --git a/litex/tools/remote/comm_pcie.py b/litex/tools/remote/comm_pcie.py index 09acf7134..371fd765f 100644 --- a/litex/tools/remote/comm_pcie.py +++ b/litex/tools/remote/comm_pcie.py @@ -8,8 +8,13 @@ import os 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 diff --git a/litex/tools/remote/comm_uart.py b/litex/tools/remote/comm_uart.py index 9daccb1db..bb124fb36 100644 --- a/litex/tools/remote/comm_uart.py +++ b/litex/tools/remote/comm_uart.py @@ -1,23 +1,29 @@ # # This file is part of LiteX. # -# Copyright (c) 2015-2019 Florent Kermarrec +# Copyright (c) 2015-2020 Florent Kermarrec # 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"): @@ -50,9 +56,9 @@ class CommUART: 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] @@ -69,7 +75,7 @@ class CommUART: 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: diff --git a/litex/tools/remote/comm_udp.py b/litex/tools/remote/comm_udp.py index 79ed27b5d..b64e3e9de 100644 --- a/litex/tools/remote/comm_udp.py +++ b/litex/tools/remote/comm_udp.py @@ -10,12 +10,16 @@ import socket 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"): diff --git a/litex/tools/remote/comm_usb.py b/litex/tools/remote/comm_usb.py index 4fdc19b46..69b6b9625 100644 --- a/litex/tools/remote/comm_usb.py +++ b/litex/tools/remote/comm_usb.py @@ -7,6 +7,8 @@ import usb.core import time +from litex.tools.remote.csr_builder import CSRBuilder + # Wishbone USB Protocol Bridge # ============================ # @@ -57,13 +59,16 @@ import time # 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"): @@ -123,12 +128,12 @@ class CommUSB: 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): @@ -154,5 +159,5 @@ class CommUSB: 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) diff --git a/litex/tools/remote/csr_builder.py b/litex/tools/remote/csr_builder.py index 011784216..3cffa2b96 100644 --- a/litex/tools/remote/csr_builder.py +++ b/litex/tools/remote/csr_builder.py @@ -1,12 +1,13 @@ # # This file is part of LiteX. # -# Copyright (c) 2015-2019 Florent Kermarrec +# Copyright (c) 2015-2020 Florent Kermarrec # Copyright (c) 2016 Tim 'mithro' Ansell # SPDX-License-Identifier: BSD-2-Clause import csv +# CSR Elements ------------------------------------------------------------------------------------- class CSRElements: def __init__(self, d): @@ -23,16 +24,15 @@ class CSRElements: 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"]: @@ -55,32 +55,34 @@ class CSRRegister: 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() + 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)) + # 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() + 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):