From 244bd8d773a2c6c63843354266ef5d953ba82cf0 Mon Sep 17 00:00:00 2001
From: Arnav Sacheti <36746504+arnavsacheti@users.noreply.github.com>
Date: Tue, 3 Feb 2026 08:47:18 +0000
Subject: [PATCH] revamp docs
---
docs/api.rst | 11 +-
docs/architecture.rst | 92 +++---
docs/conf.py | 4 +-
docs/configuring.rst | 33 +--
docs/cpuif/apb.rst | 12 +-
docs/cpuif/avalon.rst | 33 ---
docs/cpuif/axi4lite.rst | 23 +-
docs/cpuif/customizing.rst | 8 +-
docs/cpuif/internal_protocol.rst | 217 ++------------
docs/cpuif/introduction.rst | 18 +-
docs/cpuif/passthrough.rst | 10 -
docs/faq.rst | 131 ---------
docs/hwif.rst | 61 ----
docs/index.rst | 64 ++--
docs/limitations.rst | 66 ++---
docs/props/addrmap.rst | 28 --
docs/props/field.rst | 491 -------------------------------
docs/props/reg.rst | 14 -
docs/props/rhs_props.rst | 182 ------------
docs/props/signal.rst | 28 --
docs/rdl_features/external.rst | 155 ----------
docs/requirements.txt | 1 -
docs/udps/intro.rst | 79 -----
pyproject.toml | 1 -
24 files changed, 178 insertions(+), 1584 deletions(-)
delete mode 100644 docs/cpuif/avalon.rst
delete mode 100644 docs/cpuif/passthrough.rst
delete mode 100644 docs/faq.rst
delete mode 100644 docs/hwif.rst
delete mode 100644 docs/props/addrmap.rst
delete mode 100644 docs/props/field.rst
delete mode 100644 docs/props/reg.rst
delete mode 100644 docs/props/rhs_props.rst
delete mode 100644 docs/props/signal.rst
delete mode 100644 docs/rdl_features/external.rst
delete mode 100644 docs/udps/intro.rst
diff --git a/docs/api.rst b/docs/api.rst
index 5da2c00..02f1954 100644
--- a/docs/api.rst
+++ b/docs/api.rst
@@ -15,10 +15,11 @@ implementation from SystemRDL source.
.. code-block:: python
:emphasize-lines: 2-4, 29-33
+ import sys
+
from systemrdl import RDLCompiler, RDLCompileError
from peakrdl_busdecoder import BusDecoderExporter
- from peakrdl_busdecoder.cpuif.axi4lite import AXI4Lite_Cpuif
- from peakrdl_busdecoder.udps import ALL_UDPS
+ from peakrdl_busdecoder.cpuif.axi4lite import AXI4LiteCpuif
input_files = [
"PATH/TO/my_register_block.rdl"
@@ -27,10 +28,6 @@ implementation from SystemRDL source.
# Create an instance of the compiler
rdlc = RDLCompiler()
- # Register all UDPs that 'busdecoder' requires
- for udp in ALL_UDPS:
- rdlc.register_udp(udp)
-
try:
# Compile your RDL files
for input_file in input_files:
@@ -46,5 +43,5 @@ implementation from SystemRDL source.
exporter = BusDecoderExporter()
exporter.export(
root, "path/to/output_dir",
- cpuif_cls=AXI4Lite_Cpuif
+ cpuif_cls=AXI4LiteCpuif
)
diff --git a/docs/architecture.rst b/docs/architecture.rst
index 30abfa2..3ea1e00 100644
--- a/docs/architecture.rst
+++ b/docs/architecture.rst
@@ -1,64 +1,54 @@
-Register Block Architecture
-===========================
+Bus Decoder Architecture
+========================
-The generated bus decoder RTL is organized into several sections.
-Each section is automatically generated based on the source register model and
-is rendered into the output SystemVerilog RTL module. The bus decoder serves as
-an address decode and routing layer that splits a single CPU interface into
-multiple sub-address spaces corresponding to child addrmaps in your SystemRDL design.
+The generated RTL is a pure bus-routing layer. It accepts a single CPU interface
+on the slave side and fans transactions out to a set of child interfaces on the
+master side. No register storage or field logic is generated.
-.. figure:: diagrams/arch.png
-
-Although it is not completely necessary to know the inner workings of the
-generated RTL, it can be helpful to understand the implications of various
-exporter configuration options.
+Although you do not need to know the inner workings to use the exporter, the
+sections below explain the structure of the generated module and how it maps to
+SystemRDL hierarchy.
-CPU Interface
--------------
-The CPU interface logic layer provides an abstraction between the
-application-specific bus protocol and the internal register file logic.
-This logic layer normalizes external CPU read & write transactions into a common
-:ref:`cpuif_protocol` that is used to interact with the register file. When the
-design contains multiple child addrmaps, the CPU interface handles fanout of
-transactions to the appropriate sub-address space.
+CPU Interface Adapter
+---------------------
+Each supported CPU interface protocol (APB3, APB4, AXI4-Lite) provides a small
+adapter that translates the external bus protocol into internal request/response
+signals. These internal signals are then used by the address decoder and fanout
+logic.
+
+If you write a custom CPU interface, it must implement the internal signals
+described in :ref:`cpuif_protocol`.
Address Decode
--------------
-A common address decode operation is generated which computes individual access
-strobes for each software-accessible register or child addrmap in the design.
-This operation is performed completely combinationally. The decoder determines
-which sub-address space should handle each transaction based on the address range.
+The address decoder computes per-child select signals based on address ranges.
+The decode boundary is controlled by ``max_decode_depth``:
+
+* ``0``: Decode all the way down to leaf registers
+* ``1`` (default): Decode only top-level children
+* ``N``: Decode down to depth ``N`` from the top-level
+
+This allows you to choose whether the bus decoder routes to large blocks (e.g.,
+child addrmaps) or to smaller sub-blocks.
-Field Logic
------------
-This layer of the register block implements the storage elements and state-change
-logic for every field in the design. Field state is updated based on address
-decode strobes from software read/write actions, as well as events from the
-hardware interface input struct.
-This section also assigns any hardware interface outputs.
+Fanout to Child Interfaces
+--------------------------
+For each decoded child, the bus decoder drives a master-side CPU interface.
+All address, data, and control signals are forwarded to the selected child.
+
+Arrayed children can be kept as arrays or unrolled into discrete interfaces using
+``--unroll``. This only affects port structure and naming; decode semantics are
+unchanged.
-Readback
---------
-The readback layer aggregates and reduces all readable registers into a single
-read response. During a read operation, the same address decode strobes are used
-to select the active register that is being accessed.
-This allows for a simple OR-reduction operation to be used to compute the read
-data response.
+Fanin and Error Handling
+------------------------
+Read and write responses are muxed back from the selected child to the slave
+interface. If no child is selected for a transaction, the decoder generates an
+error response on the slave interface.
-For designs with a large number of software-readable registers, an optional
-fanin re-timing stage can be enabled. This stage is automatically inserted at a
-balanced point in the read-data reduction so that fanin and logic-levels are
-optimally reduced.
-
-.. figure:: diagrams/readback.png
- :width: 65%
- :align: center
-
-A second optional read response retiming register can be enabled in-line with the
-path back to the CPU interface layer. This can be useful if the CPU interface protocol
-used has a fully combinational response path, and the design's complexity requires
-this path to be retimed further.
+The exact error signaling depends on the chosen CPU interface protocol (e.g.,
+``PSLVERR`` for APB, ``RRESP/BRESP`` for AXI4-Lite).
diff --git a/docs/conf.py b/docs/conf.py
index 3ac801d..bf9da04 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -32,9 +32,7 @@ author = "Arnav Sacheti"
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.napoleon",
- "sphinxcontrib.wavedrom",
]
-render_using_wavedrompy = True
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
@@ -42,7 +40,7 @@ templates_path = ["_templates"]
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
-exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
+exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "dev_notes", "dev_notes/**"]
# -- Options for HTML output -------------------------------------------------
diff --git a/docs/configuring.rst b/docs/configuring.rst
index 4e18f7a..20967ba 100644
--- a/docs/configuring.rst
+++ b/docs/configuring.rst
@@ -4,10 +4,10 @@ Configuring PeakRDL-BusDecoder
==============================
If using the `PeakRDL command line tool `_,
-some aspects of the ``busdecoder`` command have additional configuration options
-available via the PeakRDL TOML file.
+some aspects of the ``busdecoder`` command can be configured via the PeakRDL
+TOML file.
-All busdecoder-specific options are defined under the ``[busdecoder]`` TOML heading.
+All busdecoder-specific options are defined under the ``[busdecoder]`` heading.
.. data:: cpuifs
@@ -24,22 +24,15 @@ All busdecoder-specific options are defined under the ``[busdecoder]`` TOML head
cpuifs.my-cpuif-name = "my_cpuif_module:MyCPUInterfaceClass"
-.. data:: default_reset
+Command-Line Options
+--------------------
- Choose the default style of reset signal if not explicitly
- specified by the SystemRDL design. If unspecified, the default reset
- is active-high and synchronous.
+The following options are available on the ``peakrdl busdecoder`` command:
- Choice of:
-
- * ``rst`` (default)
- * ``rst_n``
- * ``arst``
- * ``arst_n``
-
- For example:
-
- .. code-block:: toml
-
- [busdecoder]
- default_reset = "arst"
+* ``--cpuif``: Select the CPU interface (``apb3``, ``apb3-flat``, ``apb4``,
+ ``apb4-flat``, ``axi4-lite``, ``axi4-lite-flat``)
+* ``--module-name``: Override the generated module name
+* ``--package-name``: Override the generated package name
+* ``--addr-width``: Override the slave address width
+* ``--unroll``: Unroll arrayed children into discrete interfaces
+* ``--max-decode-depth``: Control how far the decoder descends into hierarchy
diff --git a/docs/cpuif/apb.rst b/docs/cpuif/apb.rst
index e5d9998..44af40b 100644
--- a/docs/cpuif/apb.rst
+++ b/docs/cpuif/apb.rst
@@ -20,7 +20,7 @@ Both APB3 and APB4 standards are supported.
APB3
----
-Implements the register block using an
+Implements the bus decoder using an
`AMBA 3 APB `_
CPU interface.
@@ -29,19 +29,19 @@ The APB3 CPU interface comes in two i/o port flavors:
SystemVerilog Interface
* Command line: ``--cpuif apb3``
* Interface Definition: :download:`apb3_intf.sv <../../hdl-src/apb3_intf.sv>`
- * Class: :class:`peakrdl_busdecoder.cpuif.apb3.APB3_Cpuif`
+ * Class: :class:`peakrdl_busdecoder.cpuif.apb3.APB3Cpuif`
Flattened inputs/outputs
Flattens the interface into discrete input and output ports.
* Command line: ``--cpuif apb3-flat``
- * Class: :class:`peakrdl_busdecoder.cpuif.apb3.APB3_Cpuif_flattened`
+ * Class: :class:`peakrdl_busdecoder.cpuif.apb3.APB3CpuifFlat`
APB4
----
-Implements the register block using an
+Implements the bus decoder using an
`AMBA 4 APB `_
CPU interface.
@@ -50,10 +50,10 @@ The APB4 CPU interface comes in two i/o port flavors:
SystemVerilog Interface
* Command line: ``--cpuif apb4``
* Interface Definition: :download:`apb4_intf.sv <../../hdl-src/apb4_intf.sv>`
- * Class: :class:`peakrdl_busdecoder.cpuif.apb4.APB4_Cpuif`
+ * Class: :class:`peakrdl_busdecoder.cpuif.apb4.APB4Cpuif`
Flattened inputs/outputs
Flattens the interface into discrete input and output ports.
* Command line: ``--cpuif apb4-flat``
- * Class: :class:`peakrdl_busdecoder.cpuif.apb4.APB4_Cpuif_flattened`
+ * Class: :class:`peakrdl_busdecoder.cpuif.apb4.APB4CpuifFlat`
diff --git a/docs/cpuif/avalon.rst b/docs/cpuif/avalon.rst
deleted file mode 100644
index 7455d0a..0000000
--- a/docs/cpuif/avalon.rst
+++ /dev/null
@@ -1,33 +0,0 @@
-Intel Avalon
-============
-
-Implements the register block using an
-`Intel Avalon MM `_
-CPU interface.
-
-The Avalon interface comes in two i/o port flavors:
-
-SystemVerilog Interface
- * Command line: ``--cpuif avalon-mm``
- * Interface Definition: :download:`avalon_mm_intf.sv <../../hdl-src/avalon_mm_intf.sv>`
- * Class: :class:`peakrdl_busdecoder.cpuif.avalon.Avalon_Cpuif`
-
-Flattened inputs/outputs
- Flattens the interface into discrete input and output ports.
-
- * Command line: ``--cpuif avalon-mm-flat``
- * Class: :class:`peakrdl_busdecoder.cpuif.avalon.Avalon_Cpuif_flattened`
-
-
-Implementation Details
-----------------------
-This implementation of the Avalon protocol has the following features:
-
-* Interface uses word addressing.
-* Supports `pipelined transfers `_
-* Responses may have variable latency
-
- In most cases, latency is fixed and is determined by how many retiming
- stages are enabled in your design.
- However if your design contains external components, access latency is
- not guaranteed to be uniform.
diff --git a/docs/cpuif/axi4lite.rst b/docs/cpuif/axi4lite.rst
index 0fc68cb..82915e6 100644
--- a/docs/cpuif/axi4lite.rst
+++ b/docs/cpuif/axi4lite.rst
@@ -3,7 +3,7 @@
AMBA AXI4-Lite
==============
-Implements the register block using an
+Implements the bus decoder using an
`AMBA AXI4-Lite `_
CPU interface.
@@ -12,21 +12,22 @@ The AXI4-Lite CPU interface comes in two i/o port flavors:
SystemVerilog Interface
* Command line: ``--cpuif axi4-lite``
* Interface Definition: :download:`axi4lite_intf.sv <../../hdl-src/axi4lite_intf.sv>`
- * Class: :class:`peakrdl_busdecoder.cpuif.axi4lite.AXI4Lite_Cpuif`
+ * Class: :class:`peakrdl_busdecoder.cpuif.axi4lite.AXI4LiteCpuif`
Flattened inputs/outputs
Flattens the interface into discrete input and output ports.
* Command line: ``--cpuif axi4-lite-flat``
- * Class: :class:`peakrdl_busdecoder.cpuif.axi4lite.AXI4Lite_Cpuif_flattened`
+ * Class: :class:`peakrdl_busdecoder.cpuif.axi4lite.AXI4LiteCpuifFlat`
-Pipelined Performance
----------------------
-This implementation of the AXI4-Lite interface supports transaction pipelining
-which can significantly improve performance of back-to-back transfers.
+Protocol Notes
+--------------
+The AXI4-Lite adapter is intentionally simplified:
-In order to support transaction pipelining, the CPU interface will accept multiple
-concurrent transactions. The number of outstanding transactions allowed is automatically
-determined based on the register file pipeline depth (affected by retiming options),
-and influences the depth of the internal transaction response skid buffer.
+* AW and W channels must be asserted together for writes. The adapter does not
+ support decoupled address/data for writes.
+* Only a single outstanding transaction is supported. Masters should wait for
+ the corresponding response before issuing the next request.
+* Burst transfers are not supported (single-beat transfers only), consistent
+ with AXI4-Lite.
diff --git a/docs/cpuif/customizing.rst b/docs/cpuif/customizing.rst
index 863b4dc..75091de 100644
--- a/docs/cpuif/customizing.rst
+++ b/docs/cpuif/customizing.rst
@@ -29,15 +29,15 @@ Rather than rewriting a new CPU interface definition, you can extend and adjust
.. code-block:: python
- from peakrdl_busdecoder.cpuif.axi4lite import AXI4Lite_Cpuif
+ from peakrdl_busdecoder.cpuif.axi4lite import AXI4LiteCpuif
- class My_AXI4Lite(AXI4Lite_Cpuif):
+ class My_AXI4Lite(AXI4LiteCpuif):
@property
def port_declaration(self) -> str:
# Override the port declaration text to use the alternate interface name and modport style
return "axi4_lite_interface.Slave_mp s_axil"
- def signal(self, name:str) -> str:
+ def signal(self, name: str, node=None, indexer=None) -> str:
# Override the signal names to be lowercase instead
return "s_axil." + name.lower()
@@ -72,7 +72,7 @@ you can define your own.
2. Create a Python class that defines your CPUIF
- Extend your class from :class:`peakrdl_busdecoder.cpuif.CpuifBase`.
+ Extend your class from :class:`peakrdl_busdecoder.cpuif.BaseCpuif`.
Define the port declaration string, and provide a reference to your template file.
3. Use your new CPUIF definition when exporting.
diff --git a/docs/cpuif/internal_protocol.rst b/docs/cpuif/internal_protocol.rst
index a47face..d6c8d86 100644
--- a/docs/cpuif/internal_protocol.rst
+++ b/docs/cpuif/internal_protocol.rst
@@ -3,10 +3,10 @@
Internal CPUIF Protocol
=======================
-Internally, the busdecoder generator uses a common CPU interface handshake
-protocol. This strobe-based protocol is designed to add minimal overhead to the
-busdecoder implementation, while also being flexible enough to support advanced
-features of a variety of bus interface standards.
+Internally, the bus decoder uses a small set of common request/response signals
+that each CPU interface adapter must drive. This protocol is intentionally simple
+and supports a single outstanding transaction at a time. The CPU interface logic
+is responsible for holding request signals stable until the transaction completes.
Signal Descriptions
@@ -15,62 +15,49 @@ Signal Descriptions
Request
^^^^^^^
cpuif_req
- When asserted, a read or write transfer will be initiated.
- Denotes that the following signals are valid: ``cpuif_addr``,
- ``cpuif_req_is_wr``, and ``cpuif_wr_data``.
+ When asserted, a read or write transfer is in progress. Request signals must
+ remain stable until the transfer completes.
- A transfer will only initiate if the relevant stall signal is not asserted.
- If stalled, the request shall be held until accepted. A request's parameters
- (type, address, etc) shall remain static throughout the stall.
+cpuif_wr_en
+ When asserted alongside ``cpuif_req``, denotes a write transfer.
-cpuif_addr
- Byte-address of the transfer.
+cpuif_rd_en
+ When asserted alongside ``cpuif_req``, denotes a read transfer.
-cpuif_req_is_wr
- If ``1``, denotes that the current transfer is a write. Otherwise transfer is
- a read.
+cpuif_wr_addr / cpuif_rd_addr
+ Byte address of the write or read transfer, respectively.
cpuif_wr_data
- Data to be written for the write transfer. This signal is ignored for read
- transfers.
+ Data to be written for the write transfer.
-cpuif_wr_biten
- Active-high bit-level write-enable strobes.
- Only asserted bit positions will change the register value during a write
- transfer.
-
-cpuif_req_stall_rd
- If asserted, and the next pending request is a read operation, then the
- transfer will not be accepted until this signal is deasserted.
-
-cpuif_req_stall_wr
- If asserted, and the next pending request is a write operation, then the
- transfer will not be accepted until this signal is deasserted.
+cpuif_wr_byte_en
+ Active-high byte-enable strobes for writes. Some CPU interfaces do not
+ provide byte enables and may drive this as all-ones.
Read Response
^^^^^^^^^^^^^
cpuif_rd_ack
Single-cycle strobe indicating a read transfer has completed.
- Qualifies that the following signals are valid: ``cpuif_rd_err`` and
- ``cpuif_rd_data``
+ Qualifies ``cpuif_rd_err`` and ``cpuif_rd_data``.
cpuif_rd_err
- If set, indicates that the read transaction failed and the CPUIF logic
- should return an error response if possible.
+ Indicates that the read transaction failed. The CPU interface should return
+ an error response if possible.
cpuif_rd_data
- Read data. Is sampled on the same cycle that ``cpuif_rd_ack`` is asserted.
+ Read data. Sampled on the same cycle that ``cpuif_rd_ack`` is asserted.
+
Write Response
^^^^^^^^^^^^^^
cpuif_wr_ack
Single-cycle strobe indicating a write transfer has completed.
- Qualifies that the ``cpuif_wr_err`` signal is valid.
+ Qualifies ``cpuif_wr_err``.
cpuif_wr_err
- If set, indicates that the write transaction failed and the CPUIF logic
- should return an error response if possible.
+ Indicates that the write transaction failed. The CPU interface should return
+ an error response if possible.
Transfers
@@ -78,155 +65,7 @@ Transfers
Transfers have the following characteristics:
-* Only one transfer can be initiated per clock-cycle. This is implicit as there
- is only one set of request signals.
-* The register block implementation shall guarantee that only one response can be
- asserted in a given clock cycle. Only one ``cpuif_*_ack`` signal can be
- asserted at a time.
-* Responses shall arrive in the same order as their corresponding request was
- dispatched.
-
-
-Basic Transfer
-^^^^^^^^^^^^^^
-
-Depending on the configuration of the exported register block, transfers can be
-fully combinational or they may require one or more clock cycles to complete.
-Both are valid and CPU interface logic shall be designed to anticipate either.
-
-.. wavedrom::
-
- {
- "signal": [
- {"name": "clk", "wave": "p...."},
- {"name": "cpuif_req", "wave": "010.."},
- {"name": "cpuif_req_is_wr", "wave": "x2x.."},
- {"name": "cpuif_addr", "wave": "x2x..", "data": ["A"]},
- {},
- {"name": "cpuif_*_ack", "wave": "010.."},
- {"name": "cpuif_*_err", "wave": "x2x.."}
- ],
- "foot": {
- "text": "Zero-latency transfer"
- }
- }
-
-.. wavedrom::
-
- {
- "signal": [
- {"name": "clk", "wave": "p..|..."},
- {"name": "cpuif_req", "wave": "010|..."},
- {"name": "cpuif_req_is_wr", "wave": "x2x|..."},
- {"name": "cpuif_addr", "wave": "x2x|...", "data": ["A"]},
- {},
- {"name": "cpuif_*_ack", "wave": "0..|10."},
- {"name": "cpuif_*_err", "wave": "x..|2x."}
- ],
- "foot": {
- "text": "Transfer with non-zero latency"
- }
- }
-
-
-Read & Write Transactions
--------------------------
-
-Waveforms below show the timing relationship of simple read/write transactions.
-For brevity, only showing non-zero latency transfers.
-
-.. wavedrom::
-
- {
- "signal": [
- {"name": "clk", "wave": "p..|..."},
- {"name": "cpuif_req", "wave": "010|..."},
- {"name": "cpuif_req_is_wr", "wave": "x0x|..."},
- {"name": "cpuif_addr", "wave": "x3x|...", "data": ["A"]},
- {},
- {"name": "cpuif_rd_ack", "wave": "0..|10."},
- {"name": "cpuif_rd_err", "wave": "x..|0x."},
- {"name": "cpuif_rd_data", "wave": "x..|5x.", "data": ["D"]}
- ],
- "foot": {
- "text": "Read Transaction"
- }
- }
-
-
-.. wavedrom::
-
- {
- "signal": [
- {"name": "clk", "wave": "p..|..."},
- {"name": "cpuif_req", "wave": "010|..."},
- {"name": "cpuif_req_is_wr", "wave": "x1x|..."},
- {"name": "cpuif_addr", "wave": "x3x|...", "data": ["A"]},
- {"name": "cpuif_wr_data", "wave": "x5x|...", "data": ["D"]},
- {},
- {"name": "cpuif_wr_ack", "wave": "0..|10."},
- {"name": "cpuif_wr_err", "wave": "x..|0x."}
- ],
- "foot": {
- "text": "Write Transaction"
- }
- }
-
-
-Transaction Pipelining & Stalls
--------------------------------
-If the CPU interface supports it, read and write operations can be pipelined.
-
-.. wavedrom::
-
- {
- "signal": [
- {"name": "clk", "wave": "p......"},
- {"name": "cpuif_req", "wave": "01..0.."},
- {"name": "cpuif_req_is_wr", "wave": "x0..x.."},
- {"name": "cpuif_addr", "wave": "x333x..", "data": ["A1", "A2", "A3"]},
- {},
- {"name": "cpuif_rd_ack", "wave": "0.1..0."},
- {"name": "cpuif_rd_err", "wave": "x.0..x."},
- {"name": "cpuif_rd_data", "wave": "x.555x.", "data": ["D1", "D2", "D3"]}
- ]
- }
-
-It is very likely that the transfer latency of a read transaction will not
-be the same as a write for a given register block configuration. Typically read
-operations will be more deeply pipelined. This latency asymmetry would create a
-hazard for response collisions.
-
-In order to eliminate this hazard, additional stall signals (``cpuif_req_stall_rd``
-and ``cpuif_req_stall_wr``) are provided to delay the next incoming transfer
-request if necessary. When asserted, the CPU interface shall hold the next pending
-request until the stall is cleared.
-
-For non-pipelined CPU interfaces that only allow one outstanding transaction at a time,
-these stall signals can be safely ignored.
-
-In the following example, the busdecoder is configured such that:
-
-* A read transaction takes 1 clock cycle to complete
-* A write transaction takes 0 clock cycles to complete
-
-.. wavedrom::
-
- {
- "signal": [
- {"name": "clk", "wave": "p......."},
- {"name": "cpuif_req", "wave": "01.....0"},
- {"name": "cpuif_req_is_wr", "wave": "x1.0.1.x"},
- {"name": "cpuif_addr", "wave": "x33443.x", "data": ["W1", "W2", "R1", "R2", "W3"]},
- {"name": "cpuif_req_stall_wr", "wave": "0...1.0."},
- {},
- {"name": "cpuif_rd_ack", "wave": "0...220.", "data": ["R1", "R2"]},
- {"name": "cpuif_wr_ack", "wave": "0220..20", "data": ["W1", "W2", "W3"]}
- ]
- }
-
-In the above waveform, observe that:
-
-* The ``R2`` read request is not affected by the assertion of the write stall,
- since the write stall only applies to write requests.
-* The ``W3`` write request is stalled for one cycle, and is accepted once the stall is cleared.
+* Only one outstanding transaction is supported.
+* The CPU interface must hold ``cpuif_req`` and request parameters stable until
+ the corresponding ``cpuif_*_ack`` is asserted.
+* Responses shall arrive in the same order as requests.
diff --git a/docs/cpuif/introduction.rst b/docs/cpuif/introduction.rst
index cc34574..4720f46 100644
--- a/docs/cpuif/introduction.rst
+++ b/docs/cpuif/introduction.rst
@@ -2,16 +2,17 @@ Introduction
============
The CPU interface logic layer provides an abstraction between the
-application-specific bus protocol and the internal register file logic.
-When exporting a design, you can select from a variety of popular CPU interface
-protocols. These are described in more detail in the pages that follow.
+application-specific bus protocol and the internal bus decoder logic.
+When exporting a design, you can select from supported CPU interface protocols.
+These are described in more detail in the pages that follow.
Bus Width
^^^^^^^^^
-The CPU interface bus width is automatically determined from the contents of the
-design being exported. The bus width is equal to the widest ``accesswidth``
-encountered in the design.
+The CPU interface bus width is inferred from the contents of the design.
+It is intended to be equal to the widest ``accesswidth`` encountered in the
+design. If the exported addrmap contains only external components, the width
+cannot be inferred and will default to 32 bits.
Addressing
@@ -32,5 +33,6 @@ For example, consider a fictional AXI4-Lite device that:
- If care is taken to align the global address offset to the size of the device,
creating a relative address is as simple as pruning down address bits.
-By default, the bit-width of the address bus will be the minimum size to span the contents
-of the register block. If needed, the address width can be overridden to a larger range.
+By default, the bit-width of the address bus will be the minimum size to span the
+contents of the decoded address space. If needed, the address width can be
+overridden to a larger range using ``--addr-width``.
diff --git a/docs/cpuif/passthrough.rst b/docs/cpuif/passthrough.rst
deleted file mode 100644
index 9426e06..0000000
--- a/docs/cpuif/passthrough.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-CPUIF Passthrough
-=================
-
-This CPUIF mode bypasses the protocol converter stage and directly exposes the
-internal CPUIF handshake signals to the user.
-
-* Command line: ``--cpuif passthrough``
-* Class: :class:`peakrdl_busdecoder.cpuif.passthrough.PassthroughCpuif`
-
-For more details on the protocol itself, see: :ref:`cpuif_protocol`.
diff --git a/docs/faq.rst b/docs/faq.rst
deleted file mode 100644
index 6b082d6..0000000
--- a/docs/faq.rst
+++ /dev/null
@@ -1,131 +0,0 @@
-Frequently Asked Questions
-==========================
-
-Why isn't there an option for a flat non-struct hardware interface?
--------------------------------------------------------------------
-SystemRDL is inherently a very hierarchical language.
-For small register blocks, flattening the hardware interface may be acceptable,
-but this ends up scaling very poorly as the design becomes larger and has more
-complex hierarchy.
-Using struct compositions for the hardware interface has the benefit of
-preserving conceptual hierarchy and arrays exactly as defined in the original
-SystemRDL.
-
-How do I know I connected everything? Structs are harder to review
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Initially this can be daunting, but fortunately the tool has an option to generate a
-flattened hardware interface report upon export. Try using the ``--hwif-report``
-command line option when exporting. This is the easiest way to quickly
-understand the structure of the hardware interface.
-
-
-
-Why does the tool generate un-packed structs? I prefer packed structs.
-----------------------------------------------------------------------
-Packed structs are great when describing vectors that have bit-level structure.
-In this tool, the use of un-packed structs is intentional since the hardware
-interface is not something that is meant to be bit-accessible. In the case of
-the hardware interface structs, using a packed struct is semantically inappropriate.
-
-... Then how can I initialize the struct?
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-We get this request most often because designers want to initialize the ``hwif_in``
-struct with a simple assignment:
-
-.. code:: systemverilog
-
- always_comb begin
- hwif_in = '0;
- end
-
-Of course since the struct actually is **unpacked**, this will result in a
-compile error which usually leads to the inappropriate assumption that it ought
-to be packed. (See this amusing blog post about `X/Y problems `_)
-
-If your goal is to initialize the packed struct, fortunately SystemVerilog already
-has syntax to do this:
-
-.. code:: systemverilog
-
- always_comb begin
- hwif_in = '{default: '0};
- end
-
-This is lesser-known syntax, but still very well supported by synthesis
-tools, and is the recommended way to handle this.
-
-... What if I want to assign it to a bit-vector?
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Assigning the hwif struct to a bit-vector is strongly discouraged. This tool makes
-no guarantees regarding the field ordering of the hwif structure, so doing so
-should be considered functionally dangerous.
-
-That said, if you still need to do this, it is still trivially possible to
-without requiring packed structs. Instead, use the SystemVerilog streaming operator:
-
-.. code:: systemverilog
-
- my_packed_vector = {<<{hwif_out}};
-
-
-... Why are unpacked structs preferred?
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-In the case of the hardware interface ports, unpacked structs help prevent
-mistakes that are very easy to make.
-Consider the following situation - a designer has a field that sets the following
-properties: ``sw=rw; hw=rw; we;``, and wants to assign the hardware input value,
-so they erroneously do the following assignment in Verilog:
-
-.. code:: systemverilog
-
- assign hwif_in.my_register.my_field = ;
-
-This is actually a bug since the ``my_field`` member is actually a struct that
-has two members: ``we`` and ``next``. If this were a packed struct, this would
-silently compile and you would potentially have a bug that may not be noticed
-(depending on how thorough the test campaign is).
-With an unpacked struct, this gets flagged immediately as a compile error since
-the assignment is invalid.
-
-The designer may have simply forgotten that the field is an aggregate of multiple
-members and intended to do the following:
-
-.. code:: systemverilog
-
- assign hwif.my_register.my_field.next = ;
- assign hwif.my_register.my_field.we = ;
-
-
-The generated output does not match our organization's coding style
--------------------------------------------------------------------
-SystemVerilog coding styles vary wildly, and unfortunately there is little
-consensus on this topic within the digital design community.
-
-The output generated by PeakRDL-BusDecoder strives to be as human-readable as possible,
-and follow consistent indentation and styling. We do our best to use the most
-widely accepted coding style, but since this is a very opinionated space, it is
-impossible to satisfy everyone.
-
-In general, we strive to follow the
-`SystemVerilog style guide by lowRISC `_,
-but may deviate in some areas if not practical or would impose excessive complexity on the code generator.
-
-
-The lint tool I am using is flagging violations in generated code
------------------------------------------------------------------
-Code linting tools are a great way to check for user-error, flag inconsistencies,
-and enforce best-practices within an organization. In many cases, linter tools
-may be configured to also enforce stylistic preferences.
-Unfortunately just like coding styles, lint rules can often be more
-opinionated than practical.
-
-In general, we will not address lint violations unless they flag actual
-structural issues or semantically dangerous code.
-Stylistic violations that pose no actual danger to the correctness of the design
-will rarely be addressed, especially if the change would add unreasonable
-complexity to the tool.
-
-If you encounter a lint violation, please carefully review and consider waiving
-it if it does not pose an actual danger. If you still believe it is a problem,
-please let us know by `submitting an issue `_
-that describes the problem.
diff --git a/docs/hwif.rst b/docs/hwif.rst
deleted file mode 100644
index 3bf50db..0000000
--- a/docs/hwif.rst
+++ /dev/null
@@ -1,61 +0,0 @@
-Hardware Interface
-------------------
-
-The generated register block will present the entire hardware interface to the user
-using two struct ports:
-
-* ``hwif_in``
-* ``hwif_out``
-
-All field inputs and outputs as well as signals are consolidated into these
-struct ports. The presence of each depends on the specific contents of the design
-being exported.
-
-
-Using structs for the hardware interface has the following benefits:
-
-* Preserves register map component grouping, arrays, and hierarchy.
-* Avoids naming collisions and cumbersome signal name flattening.
-* Allows for more natural mapping and distribution of register block signals to a design's hardware components.
-* Use of unpacked arrays/structs prevents common assignment mistakes as they are enforced by the compiler.
-
-
-Structs are organized as follows: ``hwif_out..``
-
-For example, a simple design such as:
-
-.. code-block:: systemrdl
-
- addrmap my_design {
- reg {
- field {
- sw = rw;
- hw = rw;
- we;
- } my_field;
- } my_reg[2];
- };
-
-... results in the following struct members:
-
-.. code-block:: text
-
- hwif_out.my_reg[0].my_field.value
- hwif_in.my_reg[0].my_field.next
- hwif_in.my_reg[0].my_field.we
- hwif_out.my_reg[1].my_field.value
- hwif_in.my_reg[1].my_field.next
- hwif_in.my_reg[1].my_field.we
-
-For brevity in this documentation, hwif features will be described using shorthand
-notation that omits the hierarchical path: ``hwif_out..``
-
-
-.. important::
-
- The PeakRDL tool makes no guarantees on the field order of the hwif structs.
- For this reason, it is strongly recommended to always access struct members
- directly, by name.
-
- If using the SystemVerilog streaming operator to assign the hwif struct to a
- packed vector, be extremely careful to avoid assumptions on the resulting bit-position of a field.
diff --git a/docs/index.rst b/docs/index.rst
index 9d9f59a..7a74a64 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1,28 +1,34 @@
Introduction
============
-PeakRDL-BusDecoder is a free and open-source bus decoder generator for hierarchical register address maps.
-This code generator translates your SystemRDL register description into a synthesizable
-SystemVerilog RTL module that decodes CPU interface transactions and routes them to
-multiple sub-address spaces (child addrmaps). This is particularly useful for:
+PeakRDL-BusDecoder is a free and open-source bus decoder generator for hierarchical
+SystemRDL address maps. It produces a synthesizable SystemVerilog RTL module that
+accepts a single CPU interface (slave side) and fans transactions out to multiple
+child address spaces (master side).
+
+This tool **does not** generate register storage or field logic. It is strictly a
+bus-routing layer that decodes addresses and forwards requests to child blocks.
+
+This is particularly useful for:
* Creating hierarchical register maps with multiple sub-components
* Splitting a single CPU interface bus to serve multiple independent register blocks
-* Organizing large register designs into logical sub-address spaces
+* Organizing large address spaces into logical sub-regions
* Implementing address decode logic for multi-drop bus architectures
The generated bus decoder provides:
* Fully synthesizable SystemVerilog RTL (IEEE 1800-2012)
-* Support for many popular CPU interface protocols (AMBA APB, AXI4-Lite, and more)
+* A top-level slave CPU interface and per-child master CPU interfaces
* Address decode logic that routes transactions to child address maps
-* Configurable pipelining options for designs with fast clock rates
-* Broad support for SystemRDL 2.0 features
+* Support for APB3, APB4, and AXI4-Lite (plus plugin-defined CPU interfaces)
+* Configurable decode depth and array unrolling
Quick Start
-----------
-The easiest way to use PeakRDL-BusDecoder is via the `PeakRDL command line tool `_:
+The easiest way to use PeakRDL-BusDecoder is via the
+`PeakRDL command line tool `_:
.. code-block:: bash
@@ -32,6 +38,20 @@ The easiest way to use PeakRDL-BusDecoder is via the `PeakRDL command line tool
# Export!
peakrdl busdecoder atxmega_spi.rdl -o busdecoder/ --cpuif axi4-lite
+The exporter writes two files:
+
+* A SystemVerilog module (the bus decoder)
+* A SystemVerilog package (constants like data width and per-child address widths)
+
+Key command-line options:
+
+* ``--cpuif``: Select the CPU interface (``apb3``, ``apb3-flat``, ``apb4``, ``apb4-flat``, ``axi4-lite``, ``axi4-lite-flat``)
+* ``--module-name``: Override the generated module name
+* ``--package-name``: Override the generated package name
+* ``--addr-width``: Override the slave address width
+* ``--unroll``: Unroll arrayed children into discrete interfaces
+* ``--max-decode-depth``: Control how far the decoder descends into hierarchy
+
Looking for VHDL?
-----------------
@@ -55,10 +75,8 @@ Links
self
architecture
- hwif
configuring
limitations
- faq
licensing
api
@@ -69,29 +87,5 @@ Links
cpuif/introduction
cpuif/apb
cpuif/axi4lite
- cpuif/avalon
- cpuif/passthrough
cpuif/internal_protocol
cpuif/customizing
-
-.. toctree::
- :hidden:
- :caption: SystemRDL Properties
-
- props/field
- props/reg
- props/addrmap
- props/signal
- props/rhs_props
-
-.. toctree::
- :hidden:
- :caption: Other SystemRDL Features
-
- rdl_features/external
-
-.. toctree::
- :hidden:
- :caption: Extended Properties
-
- udps/intro
diff --git a/docs/limitations.rst b/docs/limitations.rst
index 2f0afc4..3911e8b 100644
--- a/docs/limitations.rst
+++ b/docs/limitations.rst
@@ -1,53 +1,47 @@
Known Limitations
=================
-Not all SystemRDL features are supported by this exporter. For a listing of
-supported properties, see the appropriate property listing page in the sections
-that follow.
+The busdecoder exporter intentionally focuses on address decode and routing.
+Some SystemRDL features are ignored, and a few are explicitly disallowed.
-Alias Registers
----------------
-Registers instantiated using the ``alias`` keyword are not supported yet.
+Address Alignment
+-----------------
+All address offsets and array strides must be aligned to the CPU interface data
+bus width (in bytes). Misaligned offsets/strides are rejected.
-Unaligned Registers
--------------------
-All address offsets & strides shall be a multiple of the cpuif bus width used. Specifically:
-
-* Bus width is inferred by the maximum accesswidth used in the busdecoder.
-* Each component's address and array stride shall be aligned to the bus width.
+Wide Registers
+--------------
+If a register is wider than its ``accesswidth`` (a multi-word register), its
+``accesswidth`` must match the CPU interface data width. Multi-word registers
+with a smaller accesswidth are not supported.
-Uniform accesswidth
--------------------
-All registers within a register block shall use the same accesswidth.
+Fields Spanning Sub-Words
+-------------------------
+If a field spans multiple sub-words of a wide register:
-One exception is that registers with regwidth that is narrower than the cpuif
-bus width are permitted, provided that their regwidth is equal to their accesswidth.
+* Software-writable fields must have write buffering enabled
+* Fields with ``onread`` side-effects must have read buffering enabled
-For example:
+These rules are enforced to avoid ambiguous multi-word access behavior.
-.. code-block:: systemrdl
- // (Largest accesswidth used is 32, therefore the CPUIF bus width is 32)
+External Boundary References
+----------------------------
+Property references are not allowed to cross the internal/external boundary of
+the exported addrmap. References must point to components that are internal to
+the busdecoder being generated.
- reg {
- regwidth = 32;
- accesswidth = 32;
- } reg_a @ 0x00; // OK. Regular 32-bit register
+CPU Interface Reset Location
+----------------------------
+Only ``cpuif_reset`` signals instantiated at the top-level addrmap (or above)
+are honored. Nested ``cpuif_reset`` signals are ignored.
- reg {
- regwidth = 64;
- accesswidth = 32;
- } reg_b @ 0x08; // OK. "Wide" register of 64-bits, but is accessed using 32-bit subwords
- reg {
- regwidth = 8;
- accesswidth = 8;
- } reg_c @ 0x10; // OK. Is aligned to the cpuif bus width
+Unsupported Properties
+----------------------
+The following SystemRDL properties are explicitly rejected:
- reg {
- regwidth = 32;
- accesswidth = 8;
- } bad_reg @ 0x14; // NOT OK. accesswidth conflicts with cpuif width
+* ``sharedextbus`` on addrmap/regfile components
diff --git a/docs/props/addrmap.rst b/docs/props/addrmap.rst
deleted file mode 100644
index 888056a..0000000
--- a/docs/props/addrmap.rst
+++ /dev/null
@@ -1,28 +0,0 @@
-Addrmap/Regfile Properties
-==========================
-
-.. note:: Any properties not explicitly listed here are either implicitly
- supported, or are not relevant to the busdecoder exporter and are ignored.
-
-
-errextbus
----------
-|NO|
-
-sharedextbus
-------------
-|NO|
-
-
---------------------------------------------------------------------------------
-
-Addrmap Properties
-==================
-
-bigendian/littleendian
-----------------------
-|NO|
-
-rsvdset
--------
-|NO|
diff --git a/docs/props/field.rst b/docs/props/field.rst
deleted file mode 100644
index 2e869ad..0000000
--- a/docs/props/field.rst
+++ /dev/null
@@ -1,491 +0,0 @@
-Field Properties
-================
-
-.. note:: Any properties not explicitly listed here are either implicitly
- supported, or are not relevant to the busdecoder exporter and are ignored.
-
-Software Access Properties
---------------------------
-
-onread/onwrite
-^^^^^^^^^^^^^^
-
-All onread/onwrite actions are supported (except for ruser/wuser)
-
-rclr/rset
-^^^^^^^^^
-
-See ``onread``. These are effectively aliases of the onread property.
-
-singlepulse
-^^^^^^^^^^^
-
-If set, field will get cleared back to zero after being written.
-
-.. wavedrom::
-
- {"signal": [
- {"name": "clk", "wave": "p....."},
- {"name": "", "wave": "0.10.."},
- {"name": "hwif_out..value", "wave": "0..10."}
- ]}
-
-sw
-^^^
-All sw access modes are supported except for ``w1`` and ``rw1``.
-
-swacc
-^^^^^
-
-If true, infers an output signal ``hwif_out..swacc`` that is asserted when
-accessed by software. Specifically, on the same clock cycle that the field is
-being sampled during a software read operation, or as it is being written.
-
-.. wavedrom::
-
- {"signal": [
- {"name": "clk", "wave": "p...."},
- {"name": "hwif_in..next", "wave": "x.=x.", "data": ["D"]},
- {"name": "hwif_out..swacc", "wave": "0.10."}
- ]}
-
-
-swmod
-^^^^^
-
-If true, infers an output signal ``hwif_out..swmod`` that is asserted as the
-field is being modified by software. This can be due to a software write
-operation, or a software read operation that has clear/set side-effects.
-
-
-.. wavedrom::
-
- {"signal": [
- {"name": "clk", "wave": "p....."},
- {"name": "hwif_out..value", "wave": "=..=..", "data": ["old", "new"]},
- {"name": "hwif_out..swmod", "wave": "0.10.."}
- ]}
-
-
-swwe/swwel
-^^^^^^^^^^
-
-Provides a mechanism that allows hardware to override whether the field is
-writable by software.
-
-boolean
- If True, infers an input signal ``hwif_in..swwe`` or ``hwif_in..swwel``.
-
-reference
- Single-bit reference controls field's behavior.
-
-
-woclr/woset
-^^^^^^^^^^^
-See ``onwrite``. These are effectively aliases of the onwrite property.
-
---------------------------------------------------------------------------------
-
-Hardware Access Properties
---------------------------
-
-anded/ored/xored
-^^^^^^^^^^^^^^^^
-If true, infers the existence of output signal: ``hwif_out..anded``,
-``hwif_out..ored``, ``hwif_out..xored``
-
-
-hw
-^^^
-Controls hardware access to the field.
-
-If readable, enables output signal ``hwif_out..value``. If writable, enables
-input ``hwif_in..next``.
-
-Hardware-writable fields can optionally define the ``next`` property which replaces
-the inferred ``hwif_in..next`` input with an alternate reference.
-
-
-hwclr/hwset
-^^^^^^^^^^^
-If both ``hwclr`` and ``hwset`` properties are used, and both are asserted at
-the same clock cycle, then ``hwset`` will take precedence.
-
-boolean
- If true, infers the existence of input signal: ``hwif_in..hwclr``, ``hwif_in..hwset``
-
-reference
- Reference to any single-bit internal object to drive this control.
-
-
-hwenable/hwmask
-^^^^^^^^^^^^^^^
-Reference to a component that provides bit-level control of hardware writeability.
-
-
-we/wel
-^^^^^^
-Write-enable control from hardware interface.
-
-If true, infers the existence of input signal: ``hwif_in..we``, ``hwif_in..wel``
-
-.. wavedrom::
-
- {"signal": [
- {"name": "clk", "wave": "p...."},
- {"name": "hwif_in..next", "wave": "x.=x.", "data": ["D"]},
- {"name": "hwif_in..we", "wave": "0.10."},
- {"name": "hwif_in..wel", "wave": "1.01."},
- {"name": "", "wave": "x..=.", "data": ["D"]}
- ]}
-
-boolean
- If true, infers the existence of input signal ``hwif_in..we`` or ``hwif_in..wel``
-
-reference
- Reference to any single-bit internal object to drive this control.
-
---------------------------------------------------------------------------------
-
-Counter Properties
-------------------
-
-counter
-^^^^^^^
-If true, marks this field as a counter. The counter direction is inferred based
-based on which properties are assigned. By default, an up-counter is implemented.
-If any of the properties associated with an up-counter are used, then up-counting
-capabilities will be implemented. The same is true for down-counters and up/down
-counters.
-
-Unless alternate control signals are specified, the existence of input signals
-``hwif_in..incr`` and ``hwif_in..decr`` will be inferred depending on the type
-of counter described.
-
-
-incr
-^^^^
-Assign a reference to an alternate control signal to increment the counter.
-If assigned, the inferred ``hwif_in..incr`` input will not be generated.
-
-incrsaturate/saturate
-^^^^^^^^^^^^^^^^^^^^^
-If assigned, indicates that the counter will saturate instead of wrapping.
-If an alternate saturation point is specified, the counter value will be
-adjusted so that it does not exceed that limit, even after non-increment actions.
-
-boolean
- If true, saturation point is at the counter's maximum count value. (2^width - 1)
-
-integer
- Specify a static saturation value.
-
-reference
- Specify a dynamic saturation value.
-
-
-incrthreshold/threshold
-^^^^^^^^^^^^^^^^^^^^^^^
-If assigned, infers a ``hwif_out..incrthreshold`` output signal. This signal is
-asserted if the counter value is greater or equal to the threshold.
-
-.. wavedrom::
-
- {
- "signal": [
- {"name": "clk", "wave": "p......"},
- {"name": "hwif_in..incr", "wave": "01...0."},
- {"name": "", "wave": "=.=3==..", "data": [4,5,6,7,8,9]},
- {"name": "hwif_out..incrthreshold", "wave": "0..1...."}
- ],
- "foot": {
- "text": "Example where incrthreshold = 6"
- }
- }
-
-
-boolean
- If true, threshold is the counter's maximum count value. (2^width - 1)
-
-integer
- Specify a static threshold value.
-
-reference
- Specify a dynamic threshold value.
-
-
-incrvalue
-^^^^^^^^^
-Override the counter's increment step size.
-
-integer
- Specify a static increment step size.
-
-reference
- Reference a component that controls the step size.
-
-incrwidth
-^^^^^^^^^
-If assigned, infers an input signal ``hwif_in..incrvalue``. The value of this
-property defines the signal's width.
-
-
-overflow
-^^^^^^^^
-If true, infers an output signal ``hwif_out..overflow`` that is asserted when
-the counter is about to wrap.
-
-.. wavedrom::
-
- {
- "signal": [
- {"name": "clk", "wave": "p......."},
- {"name": "hwif_in..incr", "wave": "0101010."},
- {"name": "", "wave": "=.=.=.=.", "data": [14,15,0,1]},
- {"name": "hwif_out..overflow", "wave": "0..10..."}
- ],
- "foot": {
- "text": "A 4-bit counter overflowing"
- }
- }
-
-
-decr
-^^^^
-Assign a reference to an alternate control signal to decrement the counter.
-If assigned, the inferred ``hwif_in..decr`` input will not be generated.
-
-
-decrsaturate
-^^^^^^^^^^^^
-If assigned, indicates that the counter will saturate instead of wrapping.
-If an alternate saturation point is specified, the counter value will be
-adjusted so that it does not exceed that limit, even after non-decrement actions.
-
-boolean
- If true, saturation point is when the counter reaches 0.
-
-integer
- Specify a static saturation value.
-
-reference
- Specify a dynamic saturation value.
-
-
-decrthreshold
-^^^^^^^^^^^^^
-If assigned, infers a ``hwif_out..decrthreshold`` output signal. This signal is
-asserted if the counter value is less than or equal to the threshold.
-
-.. wavedrom::
-
- {
- "signal": [
- {"name": "clk", "wave": "p......"},
- {"name": "hwif_in..decr", "wave": "01...0."},
- {"name": "", "wave": "=.=3==.", "data": [9,8,7,6,5,4]},
- {"name": "hwif_out..decrthreshold", "wave": "0..1..."}
- ],
- "foot": {
- "text": "Example where incrthreshold = 7"
- }
- }
-
-
-boolean
- If true, threshold is 0.
-
-integer
- Specify a static threshold value.
-
-reference
- Specify a dynamic threshold value.
-
-
-decrvalue
-^^^^^^^^^
-Override the counter's decrement step size.
-
-integer
- Specify a static step size.
-
-reference
- Reference to a component that controls the step size.
-
-
-decrwidth
-^^^^^^^^^
-If assigned, infers an input signal ``hwif_in..decrvalue``. The value of this
-property defines the signal's width.
-
-
-underflow
-^^^^^^^^^
-If true, infers an output signal ``hwif_out..underflow`` that is asserted when
-the counter is about to wrap.
-
-.. wavedrom::
-
- {
- "signal": [
- {"name": "clk", "wave": "p......."},
- {"name": "hwif_in..decr", "wave": "0101010."},
- {"name": "", "wave": "=.=.=.=.", "data": [1,0,15,14]},
- {"name": "hwif_out..underflow", "wave": "0..10..."}
- ],
- "foot": {
- "text": "A 4-bit counter underflowing"
- }
- }
-
---------------------------------------------------------------------------------
-
-Interrupt Properties
---------------------
-
-intr
-^^^^
-
-If set, this field becomes an interrupt field.
-The enclosing register infers an output signal ``hwif_out..intr`` which denotes
-that an interrupt is active. This is an or-reduction of all interrupt fields
-after applying the appropriate ``enable`` or ``mask`` to the field value.
-
-level (default)
- Interrupt is level-sensitive. If a bit on the field's ``hwif_in..next`` input
- is '1', it will trigger an interrupt event.
-
-posedge
- If a bit on the field's ``hwif_in..next`` input transitions from '0' to '1',
- it will trigger an interrupt event. This transition shall still be synchronous
- to the register block's clock.
-
-negedge
- If a bit on the field's ``hwif_in..next`` input transitions from '1' to '0',
- it will trigger an interrupt event. This transition shall still be synchronous
- to the register block's clock.
-
-bothedge
- If a bit on the field's ``hwif_in..next`` input transitions from '0' to '1' or '1' to '0',
- it will trigger an interrupt event. This transition shall still be synchronous
- to the register block's clock.
-
-nonsticky
- Interrupt event is not sticky.
-
-
-enable
-^^^^^^
-Reference to a field or signal that, if set to 1, define which bits in the field
-are used to assert an interrupt.
-
-
-mask
-^^^^
-Reference to a field or signal that, if set to 1, define which bits in the field
-are *not* used to assert an interrupt.
-
-
-haltenable
-^^^^^^^^^^
-Reference to a field or signal that, if set to 1, define which bits in the field
-are used to assert the halt output.
-
-If this property is set, the enclosing register will infer a ``hwif_out..halt`` output.
-
-
-haltmask
-^^^^^^^^
-Reference to a field or signal that, if set to 1, define which bits in the field
-are *not* used to assert the halt output.
-
-If this property is set, the enclosing register will infer a ``hwif_out..halt`` output.
-
-
-stickybit
-^^^^^^^^^
-When an interrupt trigger occurs, a stickybit field will set the corresponding
-bit to '1' and hold it until it is cleared by a software access.
-
-The interrupt trigger depends on the interrupt type. By default, interrupts are
-level-sensitive, but the interrupt modifiers allow for edge-sensitive triggers as
-well.
-
-The waveform below demonstrates a level-sensitive interrupt:
-
-.. wavedrom::
-
- {
- "signal": [
- {"name": "clk", "wave": "p....."},
- {"name": "hwif_in..next", "wave": "010..."},
- {"name": "", "wave": "0.1..."}
- ]
- }
-
-
-sticky
-^^^^^^
-Unlike ``stickybit`` fields, a sticky field will latch an entire value. The
-value is latched as soon as ``hwif_in..next`` is nonzero, and is held until the
-field contents are cleared back to 0 by a software access.
-
-.. wavedrom::
-
- {
- "signal": [
- {"name": "clk", "wave": "p....."},
- {"name": "hwif_in..next", "wave": "23.22.", "data": [0,10,20,30]},
- {"name": "", "wave": "2.3...", "data": [0, 10]}
- ]
- }
-
-
---------------------------------------------------------------------------------
-
-Misc
-----
-
-encode
-^^^^^^
-If assigned a user-defined enumeration, the resulting package file will include
-its definition. Due to limitations from type-strictness rules in SystemVerilog,
-the field will remain as a ``logic`` datatype.
-
-
-next
-^^^^
-If assigned, replaces the inferred ``hwif_in..next`` input with an explicit reference.
-
-
-paritycheck
-^^^^^^^^^^^
-If set, enables parity checking for this field.
-
-Adds a ``parity_error`` output signal to the module.
-
-.. note::
-
- If this field does not implement storage, the ``partycheck`` property is ignored.
-
-
-
-precedence
-^^^^^^^^^^
-Control whether hardware or software has precedence when field value update
-contention occurs. Software has precedence by default.
-
-reset
-^^^^^
-Control the reset value of the field's storage element.
-If not specified, the field will not be reset.
-
-integer
- Static reset value
-
-reference
- Reference to a dynamic reset value.
-
-resetsignal
-^^^^^^^^^^^
-Provide an alternate reset trigger for this field.
diff --git a/docs/props/reg.rst b/docs/props/reg.rst
deleted file mode 100644
index 8472f07..0000000
--- a/docs/props/reg.rst
+++ /dev/null
@@ -1,14 +0,0 @@
-Register Properties
-===================
-
-.. note:: Any properties not explicitly listed here are either implicitly
- supported, or are not relevant to the busdecoder exporter and are ignored.
-
-accesswidth
------------
-Control the software access width. The register block's CPUIF bus width is
-determined by the maximum accesswidth encountered.
-
-regwidth
---------
-Control the bit-width of the register.
diff --git a/docs/props/rhs_props.rst b/docs/props/rhs_props.rst
deleted file mode 100644
index 6234bd5..0000000
--- a/docs/props/rhs_props.rst
+++ /dev/null
@@ -1,182 +0,0 @@
-RHS Property References
-=======================
-
-SystemRDL allows some properties to be referenced in the righthand-side of
-property assignment expressions:
-
- .. code-block:: systemrdl
-
- some_property = my_reg.my_field -> some_property;
-
-The official SystemRDL spec refers to these as "Ref targets" in Table G1, but
-unfortunately does not describe their semantics in much detail.
-
-The text below describes the interpretations used for this exporter.
-
---------------------------------------------------------------------------------
-
-Field
------
-
-field -> swacc
-^^^^^^^^^^^^^^
-Single-cycle strobe that indicates the field is being accessed by software
-(read or write).
-
-
-field -> swmod
-^^^^^^^^^^^^^^^
-Single-cycle strobe that indicates the field is being modified during a software
-access operation.
-
-
-field -> swwe/swwel
-^^^^^^^^^^^^^^^^^^^
-Represents the signal that controls the field's swwe/swwel behavior.
-
-
-field -> anded/ored/xored
-^^^^^^^^^^^^^^^^^^^^^^^^^
-Represents the current and/or/xor reduction of the field's value.
-
-
-field -> hwclr/hwset
-^^^^^^^^^^^^^^^^^^^^
-|EX|
-
-Represents the signal that controls the field's hwclr/hwset behavior.
-
-
-field -> hwenable/hwmask
-^^^^^^^^^^^^^^^^^^^^^^^^
-Represents the signal that controls the field's hwenable/hwmask behavior.
-
-field -> we/wel
-^^^^^^^^^^^^^^^
-Represents the signal that controls the field's we/wel behavior.
-
-field -> next
-^^^^^^^^^^^^^
-|EX|
-
-field -> reset
-^^^^^^^^^^^^^^
-Represents the value that was assigned to this property.
-
-field -> resetsignal
-^^^^^^^^^^^^^^^^^^^^
-Represents the value that was assigned to this property.
-
---------------------------------------------------------------------------------
-
-Field Counter Properties
-------------------------
-
-field -> incr
-^^^^^^^^^^^^^
-Represents the signal that controls the field's counter increment control.
-
-
-field -> incrsaturate/saturate
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Represents the internal 1-bit event signal that indicates whether the counter is saturated
-at its saturation value.
-
-.. wavedrom::
-
- {
- "signal": [
- {"name": "clk", "wave": "p......"},
- {"name": "hwif_in..decr", "wave": "0101010"},
- {"name": "", "wave": "=.=....", "data": [1,0]},
- {"name": "", "wave": "0.1...."}
- ],
- "foot": {
- "text": "A 4-bit counter saturating"
- }
- }
-
-
-field -> incrthreshold/threshold
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Represents the 1-bit event signal that indicates whether the counter has met or
-exceeded its incrthreshold.
-
-field -> incrvalue
-^^^^^^^^^^^^^^^^^^
-Represents the value that was assigned to this property.
-
-field -> overflow
-^^^^^^^^^^^^^^^^^
-Represents the event signal that is asserted when the counter is about to wrap.
-
-field -> decr
-^^^^^^^^^^^^^
-Represents the signal that controls the field's counter decrement control.
-
-field -> decrsaturate
-^^^^^^^^^^^^^^^^^^^^^
-Represents the internal 1-bit event signal that indicates whether the counter is saturated
-at its saturation value.
-
-.. wavedrom::
-
- {
- "signal": [
- {"name": "clk", "wave": "p......"},
- {"name": "hwif_in..incr", "wave": "0101010"},
- {"name": "", "wave": "=.=....", "data": [14,15]},
- {"name": "", "wave": "0.1...."}
- ],
- "foot": {
- "text": "A 4-bit counter saturating"
- }
- }
-
-field -> decrthreshold
-^^^^^^^^^^^^^^^^^^^^^^
-Represents the 1-bit event signal that indicates whether the counter has met or
-exceeded its incrthreshold.
-
-field -> decrvalue
-^^^^^^^^^^^^^^^^^^
-Represents the value that was assigned to this property.
-
-field -> underflow
-^^^^^^^^^^^^^^^^^^
-Represents the event signal that is asserted when the counter is about to wrap.
-
---------------------------------------------------------------------------------
-
-Field Interrupt Properties
---------------------------
-
-field -> enable
-^^^^^^^^^^^^^^^
-Represents the value that was assigned to this property.
-
-field -> mask
-^^^^^^^^^^^^^
-Represents the value that was assigned to this property.
-
-field -> haltenable
-^^^^^^^^^^^^^^^^^^^
-Represents the value that was assigned to this property.
-
-field -> haltmask
-^^^^^^^^^^^^^^^^^
-Represents the value that was assigned to this property.
-
-
---------------------------------------------------------------------------------
-
-Register
---------
-
-reg -> intr
-^^^^^^^^^^^
-References the register's ``hwif_out..intr`` signal.
-
-reg -> halt
-^^^^^^^^^^^
-References the register's ``hwif_out..halt`` signal.
diff --git a/docs/props/signal.rst b/docs/props/signal.rst
deleted file mode 100644
index 2a34ead..0000000
--- a/docs/props/signal.rst
+++ /dev/null
@@ -1,28 +0,0 @@
-Signal Properties
-=================
-
-.. note:: Any properties not explicitly listed here are either implicitly
- supported, or are not relevant to the busdecoder exporter and are ignored.
-
-
-activehigh/activelow
---------------------
-Only relevant for signals used as resets. Defines the reset signal's polarity.
-
-
-sync/async
-----------
-Only supported for signals used as resets to infer edge-sensitive reset.
-Ignored in all other contexts.
-
-
-cpuif_reset
------------
-Specify that this signal shall be used as alternate reset signal for the CPU
-interface for this busdecoder.
-
-
-field_reset
------------
-Specify that this signal is used as an alternate reset signal for all fields
-instantiated in sub-hierarchies relative to this signal.
diff --git a/docs/rdl_features/external.rst b/docs/rdl_features/external.rst
deleted file mode 100644
index ee12f39..0000000
--- a/docs/rdl_features/external.rst
+++ /dev/null
@@ -1,155 +0,0 @@
-External Components
-===================
-SystemRDL allows some component instances to be defined as "external" elements
-of an address space definition. In the context of this busdecoder generator,
-the implementation of an external component is left up to the designer. When
-generating the RTL for a busdecoder, the implementations of external components
-are omitted and instead a user-interface is presented on the
-``hwif_in``/``hwif_out`` i/o structs.
-
-External component signals on the hardware interface closely follow the semantics
-of the :ref:`cpuif_protocol`.
-
-
-Things you should know
-----------------------
-
-* By default external ``hwif_out`` signals are driven combinationally. An
- optional output retiming stage can be enabled if needed.
-* Due to the uncertain access latency of external components, the busdecoder will
- only issue one outstanding transaction to an external component at a time.
- This is enforced even if the CPUIF is capable of pipelined accesses such as
- AXI4-Lite.
-
-
-External Registers
-------------------
-External registers can be useful if it is necessary to implement a register that
-cannot easily be expressed using SystemRDL semantics. This could be a unique
-access policy, or FIFO-like push/pop registers.
-
-External registers are annotated as such by using the ``external`` keyword:
-
-.. code-block:: systemrdl
-
- // An internal register
- my_reg int_reg;
-
- // An external register
- external my_reg ext_reg;
-
-Request
-^^^^^^^
-hwif_out..req
- When asserted, a read or write transfer will be initiated.
- Qualifies all other request signals.
-
- If the register is wide (``regwidth`` > ``accesswidth``), then the
- ``hwif_out..req`` will consist of multiple bits, representing the access
- strobe for each sub-word of the register.
-
- If the register does not contain any readable fields, this strobe will be
- suppressed for read operations.
-
- If the register does not contain any writable readable fields, this strobe
- will be suppressed for write operations.
-
-hwif_out..req_is_wr
- If ``1``, denotes that the current transfer is a write. Otherwise transfer is
- a read.
-
-hwif_out..wr_data
- Data to be written for the write transfer. This signal is ignored for read
- transfers.
-
- The bit-width of this signal always matches the CPUIF's bus width,
- regardless of the regwidth.
-
- If the register does not contain any writable fields, this signal is omitted.
-
-hwif_out..wr_biten
- Active-high bit-level write-enable strobes.
- Only asserted bit positions will change the register value during a write
- transfer.
-
- If the register does not contain any writable fields, this signal is omitted.
-
-
-Read Response
-^^^^^^^^^^^^^
-hwif_in..rd_ack
- Single-cycle strobe indicating a read transfer has completed.
- Qualifies all other read response signals.
-
- If the transfer is always completed in the same cycle, it is acceptable to
- tie this signal to ``hwif_out..req && !hwif_out..req_is_wr``.
-
- If the register does not contain any readable fields, this signal is omitted.
-
-hwif_in..rd_data
- Read response data.
-
- If the register does not contain any readable fields, this signal is omitted.
-
-Write Response
-^^^^^^^^^^^^^^
-hwif_in..wr_ack
- Single-cycle strobe indicating a write transfer has completed.
-
- If the transfer is always completed in the same cycle, it is acceptable to
- tie this signal to ``hwif_out..req && hwif_out..req_is_wr``.
-
- If the register does not contain any writable fields, this signal is omitted.
-
-
-
-External Blocks
----------------
-Broader external address regions can be represented by external block-like
-components such as ``addrmap``, ``regfile`` or ``mem`` elements.
-
-To ensure address decoding for external blocks is simple (only requires simple bit-pruning),
-blocks that are external to an exported busdecoder shall be aligned to their size.
-
-Request
-^^^^^^^
-hwif_out..req
- When asserted, a read or write transfer will be initiated.
- Qualifies all other request signals.
-
-hwif_out..addr
- Byte-address of the transfer.
-
- Address is always relative to the block's local addressing. i.e: The first
- byte within an external block is represented as ``hwif_out..addr`` == 0,
- regardless of the absolute address of the block.
-
-hwif_out..req_is_wr
- If ``1``, denotes that the current transfer is a write. Otherwise transfer is
- a read.
-
-hwif_out..wr_data
- Data to be written for the write transfer. This signal is ignored for read
- transfers.
-
- The bit-width of this signal always matches the CPUIF's bus width,
- regardless of the contents of the block.
-
-hwif_out..wr_biten
- Active-high bit-level write-enable strobes.
- Only asserted bit positions will change the register value during a write
- transfer.
-
-Read Response
-^^^^^^^^^^^^^
-hwif_in..rd_ack
- Single-cycle strobe indicating a read transfer has completed.
- Qualifies all other read response signals.
-
-hwif_in..rd_data
- Read response data.
-
-Write Response
-^^^^^^^^^^^^^^
-hwif_in..wr_ack
- Single-cycle strobe indicating a write transfer has completed.
diff --git a/docs/requirements.txt b/docs/requirements.txt
index d37f57f..ce1be3f 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,3 +1,2 @@
pygments-systemrdl
-sphinxcontrib-wavedrom
sphinx-book-theme
diff --git a/docs/udps/intro.rst b/docs/udps/intro.rst
deleted file mode 100644
index b019c29..0000000
--- a/docs/udps/intro.rst
+++ /dev/null
@@ -1,79 +0,0 @@
-Introduction
-============
-
-Although the official SystemRDL spec defines numerous properties that allow you
-to define complex register map structures, sometimes they are not enough to
-accurately describe a necessary feature. Fortunately the SystemRDL spec allows
-the language to be extended using "User Defined Properties" (UDPs).
-
-Current UDP Support
--------------------
-
-**Note:** PeakRDL-BusDecoder currently does not implement any User Defined Properties.
-The focus of this tool is on bus decoding and address space routing rather than
-field-level or register-level behavioral extensions.
-
-If you need UDPs for field-level behaviors (such as buffering, signedness, or
-fixed-point representations), consider using `PeakRDL-regblock `_,
-which is designed for comprehensive register block generation with extensive UDP support.
-
-Extending with Custom UDPs
----------------------------
-
-If your bus decoder design requires custom User Defined Properties, you can extend
-PeakRDL-BusDecoder by:
-
-1. **Define your UDP in SystemRDL**
-
- Create a ``.rdl`` file that defines your custom properties:
-
- .. code-block:: systemrdl
-
- property my_custom_prop {
- component = addrmap;
- type = boolean;
- };
-
-2. **Implement the UDP in Python**
-
- Create a Python UDP definition class in your project:
-
- .. code-block:: python
-
- from systemrdl.udp import UDPDefinition
-
- class MyCustomUDP(UDPDefinition):
- name = "my_custom_prop"
- valid_components = {"addrmap"}
- valid_type = bool
- default = False
-
-3. **Register the UDP with the compiler**
-
- When using PeakRDL-BusDecoder programmatically, register your UDP:
-
- .. code-block:: python
-
- from systemrdl import RDLCompiler
- from peakrdl_busdecoder import BusDecoderExporter
-
- rdlc = RDLCompiler()
- rdlc.register_udp(MyCustomUDP)
-
- # Compile your RDL files
- rdlc.compile_file("my_udp_defs.rdl")
- rdlc.compile_file("my_design.rdl")
-
- root = rdlc.elaborate()
-
- # Export
- exporter = BusDecoderExporter()
- exporter.export(root, "output/")
-
-4. **Access UDP values in your design**
-
- UDP values can be accessed from nodes in the SystemRDL tree and used to
- customize the generated bus decoder logic as needed.
-
-For more information on creating User Defined Properties, see the
-`SystemRDL Compiler documentation `_.
diff --git a/pyproject.toml b/pyproject.toml
index c5fe61d..bc8e139 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -55,7 +55,6 @@ Documentation = "https://peakrdl-busdecoder.readthedocs.io/"
docs = [
"pygments-systemrdl>=1.3.0",
"sphinx-book-theme>=1.1.4",
- "sphinxcontrib-wavedrom>=3.0.4",
]
test = [
"parameterized>=0.9.0",