diff --git a/litex/soc/interconnect/csr_bus.py b/litex/soc/interconnect/csr_bus.py index 00a40b7ee..707ae0952 100644 --- a/litex/soc/interconnect/csr_bus.py +++ b/litex/soc/interconnect/csr_bus.py @@ -2,16 +2,34 @@ # This file is part of LiteX. # # Copyright (c) 2015 Sebastien Bourdeauducq -# Copyright (c) 2015-2018 Florent Kermarrec +# Copyright (c) 2015-2023 Florent Kermarrec # Copyright (c) 2016-2019 Tim 'mithro' Ansell # SPDX-License-Identifier: BSD-2-Clause """ -CSR-2 bus -========= +CSR-Bus support for LiteX. -The CSR-2 bus is a low-bandwidth, resource-sensitive bus designed for accessing -the configuration and status registers of cores from software. +The CSR Bus is a lightweight and low-bandwidth bus design for accessing Configuration and Status +Registers (CSRs). + +It takes a minimalist approach, featuring only adr, we, dat_w, and dat_r signals and operate on +sys_clk domain of the SoC, completing writes in a single cycle and reads in two cycles. + + ┌───────────┐ Write in 1 cycle: + │ │ - adr/we/dat_w set by bridge. + │ ├───► adr + │ │ Read in 2 cycles: + Main SoC Bus ◄────► CSR ├───► we - adr set by bridge + │ Bridge │ - dat_r set returned by user logic. + │ ├───► dat_w + │ │ + │ ◄──── dat_r + └───────────┘ + +Think of it as LiteX's version of a local bus usually used in FPGA/SoC design to simplify creation +of registers in SoCs. + +More information available at: https://github.com/enjoy-digital/litex/wiki/CSR-Bus """ from migen import * @@ -33,7 +51,6 @@ _layout = [ ("dat_r", "data_width", DIR_S_TO_M) ] - class Interface(Record): def __init__(self, data_width=8, address_width=14, alignment=32): self.data_width = data_width @@ -41,15 +58,18 @@ class Interface(Record): self.alignment = alignment Record.__init__(self, set_layout_parameters(_layout, data_width = data_width, - address_width = address_width)) + address_width = address_width, + )) self.adr.reset_less = True self.dat_w.reset_less = True self.dat_r.reset_less = True @classmethod def like(self, other): - return Interface(len(other.dat_w), - len(other.adr)) + return Interface( + data_width = len(other.dat_w), + address_width = len(other.adr), + ) def write(self, adr, dat): yield self.adr.eq(adr) @@ -204,6 +224,7 @@ class CSRBank(csr.GenericBank): # Otherwise, it is a memory object belonging to source.name. # address_map is called exactly once for each object at each call to # scan(), so it can have side effects. + class CSRBankArray(Module): def __init__(self, source, address_map, *ifargs, paging=0x800, ordering="big", **ifkwargs): self.source = source