class Access(enum.Enum):
"""Register access mode.
- Coarse access mode for the entire register. Individual fields can have more restrictive
- access mode, e.g. R/O fields can be a part of an R/W register.
+ Coarse access mode for the entire register. Individual fields
+ can have more restrictive access mode, e.g. R/O fields can be
+ a part of an R/W register.
"""
R = "r"
W = "w"
"""Peripheral-side CSR interface.
- A low-level interface to a single atomically readable and writable register in a peripheral.
- This interface supports any register width and semantics, provided that both reads and writes
- always succeed and complete in one cycle.
+ A low-level interface to a single atomically readable and writable
+ register in a peripheral. This interface supports any register
+ width and semantics, provided that both reads and writes always
+ succeed and complete in one cycle.
Parameters
----------
Attributes
----------
r_data : Signal(width)
- Read data. Must be always valid, and is sampled when ``r_stb`` is asserted.
+ Read data. Must be always valid, and is sampled when ``r_stb``
+ is asserted.
r_stb : Signal()
- Read strobe. Registers with read side effects should perform the read side effect when this
- strobe is asserted.
+ Read strobe. Registers with read side effects should perform
+ the read side effect when this strobe is asserted.
w_data : Signal(width)
Write data. Valid only when ``w_stb`` is asserted.
w_stb : Signal()
- Write strobe. Registers should update their value or perform the write side effect when
- this strobe is asserted.
+ Write strobe. Registers should update their value or perform
+ the write side effect when this strobe is asserted.
"""
def __init__(self, width, access, *, name=None, src_loc_at=0):
if not isinstance(width, int) or width < 0:
class Interface(Record):
"""CPU-side CSR interface.
- A low-level interface to a set of atomically readable and writable peripheral CSR registers.
+ A low-level interface to a set of atomically readable and writable
+ peripheral CSR registers.
Operation
---------
- CSR registers mapped to the CSR bus are split into chunks according to the bus data width.
- Each chunk is assigned a consecutive address on the bus. This allows accessing CSRs of any
- size using any datapath width.
+ CSR registers mapped to the CSR bus are split into chunks according to
+ the bus data width. Each chunk is assigned a consecutive address on
+ the bus. This allows accessing CSRs of any size using any datapath
+ width.
- When the first chunk of a register is read, the value of a register is captured, and reads
- from subsequent chunks of the same register return the captured values. When any chunk except
- the last chunk of a register is written, the written value is captured; a write to the last
- chunk writes the captured value to the register. This allows atomically accessing CSRs larger
- than datapath width.
+ When the first chunk of a register is read, the value of a register
+ is captured, and reads from subsequent chunks of the same register
+ return the captured values. When any chunk except the last chunk
+ of a register is written, the written value is captured; a write
+ to the last chunk writes the captured value to the register. This
+ allows atomically accessing CSRs larger than datapath width.
Parameters
----------
addr_width : int
- Address width. At most ``(2 ** addr_width) * data_width`` register bits will be available.
+ Address width. At most ``(2 ** addr_width) * data_width``
+ register bits will be available.
data_width : int
Data width. Registers are accessed in ``data_width`` sized chunks.
alignment : int
addr : Signal(addr_width)
Address for reads and writes.
r_data : Signal(data_width)
- Read data. Valid on the next cycle after ``r_stb`` is asserted. Otherwise, zero. (Keeping
- read data of an unused interface at zero simplifies multiplexers.)
+ Read data. Valid on the next cycle after ``r_stb`` is
+ asserted. Otherwise, zero. (Keeping read data of an unused
+ interface at zero simplifies multiplexers.)
r_stb : Signal()
- Read strobe. If ``addr`` points to the first chunk of a register, captures register value
- and causes read side effects to be performed (if any). If ``addr`` points to any chunk
- of a register, latches the captured value to ``r_data``. Otherwise, latches zero
- to ``r_data``.
+ Read strobe. If ``addr`` points to the first chunk of a
+ register, captures register value and causes read side effects
+ to be performed (if any). If ``addr`` points to any chunk of a
+ register, latches the captured value to ``r_data``. Otherwise,
+ latches zero to ``r_data``.
w_data : Signal(data_width)
Write data. Must be valid when ``w_stb`` is asserted.
w_stb : Signal()
- Write strobe. If ``addr`` points to the last chunk of a register, writes captured value
- to the register and causes write side effects to be performed (if any). If ``addr`` points
- to any chunk of a register, latches ``w_data`` to the captured value. Otherwise, does
- nothing.
+ Write strobe. If ``addr`` points to the last chunk of a register,
+ writes captured value to the register and causes write side
+ effects to be performed (if any). If ``addr`` points to
+ any chunk of a register, latches ``w_data`` to the captured
+ value. Otherwise, does nothing.
"""
def __init__(self, *, addr_width, data_width, alignment=0, name=None):
Latency
-------
- Writes are registered, and are performed 1 cycle after ``w_stb`` is asserted.
+ Writes are registered, and are performed 1 cycle after ``w_stb``
+ is asserted.
Alignment
---------
- Because the CSR bus conserves logic and routing resources, it is common to e.g. access
- a CSR bus with an *n*-bit data path from a CPU with a *k*-bit datapath (*k>n*) in cases
- where CSR access latency is less important than resource usage. In this case, two strategies
+ Because the CSR bus conserves logic and routing resources, it is
+ common to e.g. access a CSR bus with an *n*-bit data path from a CPU
+ with a *k*-bit datapath (*k>n*) in cases where CSR access latency
+ is less important than resource usage. In this case, two strategies
are possible for connecting the CSR bus to the CPU:
- * The CPU could access the CSR bus directly (with no intervening logic other than simple
- translation of control signals). In this case, the register alignment should be set
- to 1, and each *w*-bit register would occupy *ceil(w/n)* addresses from the CPU
- perspective, requiring the same amount of memory instructions to access.
- * The CPU could also access the CSR bus through a width down-converter, which would issue
- *k/n* CSR accesses for each CPU access. In this case, the register alignment should be
- set to *k/n*, and each *w*-bit register would occupy *ceil(w/k)* addresses from the CPU
- perspective, requiring the same amount of memory instructions to access.
-
- If alignment is greater than 1, it affects which CSR bus write is considered a write to
- the last register chunk. For example, if a 24-bit register is used with a 8-bit CSR bus and
- a CPU with a 32-bit datapath, a write to this register requires 4 CSR bus writes to complete
- and the 4th write is the one that actually writes the value to the register. This allows
- determining write latency solely from the amount of addresses the register occupies in
- the CPU address space, and the width of the CSR bus.
+ * The CPU could access the CSR bus directly (with no intervening
+ logic other than simple translation of control signals). In
+ this case, the register alignment should be set to 1, and each
+ *w*-bit register would occupy *ceil(w/n)* addresses from the CPU
+ perspective, requiring the same amount of memory instructions
+ to access.
+ * The CPU could also access the CSR bus through a width
+ down-converter, which would issue *k/n* CSR accesses for each
+ CPU access. In this case, the register alignment should be set
+ to *k/n*, and each *w*-bit register would occupy *ceil(w/k)*
+ addresses from the CPU perspective, requiring the same amount
+ of memory instructions to access.
+
+ If alignment is greater than 1, it affects which CSR bus write
+ is considered a write to the last register chunk. For example,
+ if a 24-bit register is used with a 8-bit CSR bus and a CPU with a
+ 32-bit datapath, a write to this register requires 4 CSR bus writes
+ to complete and the 4th write is the one that actually writes the
+ value to the register. This allows determining write latency solely
+ from the amount of addresses the register occupies in the CPU address
+ space, and the width of the CSR bus.
Parameters
----------
Usage
-----
- Although there is no functional difference between adding a set of registers directly to
- a :class:`Multiplexer` and adding a set of registers to multiple :class:`Multiplexer`s that are
- aggregated with a :class:`Decoder`, hierarchical CSR buses are useful for organizing
- a hierarchical design. If many peripherals are directly served by a single
- :class:`Multiplexer`, a very large amount of ports will connect the peripheral registers with
- the decoder, and the cost of decoding logic would not be attributed to specific peripherals.
- With a decoder, only five signals per peripheral will be used, and the logic could be kept
- together with the peripheral.
+ Although there is no functional difference between adding a set of
+ registers directly to a :class:`Multiplexer` and adding a set of
+ registers to multiple :class:`Multiplexer`s that are aggregated with
+ a :class:`Decoder`, hierarchical CSR buses are useful for organizing
+ a hierarchical design. If many peripherals are directly served by
+ a single :class:`Multiplexer`, a very large amount of ports will
+ connect the peripheral registers with the decoder, and the cost of
+ decoding logic would not be attributed to specific peripherals.
+ With a decoder, only five signals per peripheral will be used,
+ and the logic could be kept together with the peripheral.
Parameters
----------