Skip to content

soc/interconnect/csr: skip class references, reject CSRs hidden in plain Modules; Converter to LiteXModule. - #2763

Merged
enjoy-digital merged 2 commits into
masterfrom
csr/gatherer-robustness
Nov 6, 2026
Merged

enjoy-digital merged 2 commits into
masterfrom
csr/gatherer-robustness

Conversation

@enjoy-digital

Copy link
Copy Markdown
Owner

Follow-up to #2757 (which this supersedes; credit to rohanmathew05 for the analysis there).

Problem

The AutoCSR/AutoDoc gatherers (csr.py, doc.py) and CSRBankArray.scan (csr_bus.py) duck-type every attribute through hasattr(v, "get_csrs"). Two silent failure modes follow:

  • An attribute holding a class (ex: Converter.cls = _DownConverter) has get_csrs as a plain function: the gatherer called it without an instance and failed with TypeError: gatherer() missing 1 required positional argument: 'self', naming neither the module nor the attribute. This is why the one-word Module -> LiteXModule switch of Converter broke video framebuffer SoCs in interconnect/stream: Switch Converter to LiteXModule #2757.
  • A Migen Module without AutoCSR holding CSRs was skipped: its CSRs never reached the CSR map and nothing reported it.

Changes

  • The three gatherers skip class references (inspect.isclass).
  • New csr.check_dropped_csrs(), used by the get_csrs gatherer and by CSRBankArray.scan: raises an explicit TypeError when a plain Module holds CSRs, e.g. DUT.plain (Plain) holds CSRs ['ctrl', 'status'] but Plain is a Migen Module without AutoCSR: these CSRs would be silently dropped. Switch Plain to LiteXModule (or add 'plain' to DUT.autocsr_exclude to ignore them). autocsr_exclude remains the explicit escape hatch.
  • stream.Converter switched to LiteXModule (FIXME resolved), no exclude needed.
  • Tests: class skip, rejection (direct and nested plain Modules), exclude hatch, modules with a manual get_csrs, SoC-level scan, and a parent gathering CSRs/Docs with a Converter.

Not detected (on purpose): a plain Module that only wraps an AutoCSR child with CSRs. Attribute scanning cannot tell owned submodules from references (ethcore.mac in soc.py, CSRBankArray.source), so following them would create false positives and cycles. A static scan of LiteX + LiteDRAM/LiteEth/LitePCIe/LiteScope/LiteSDCard/LiteSPI/LiteICLink/LiteSATA/LiteI2C/LiteJESD204B/litex-boards found no plain Module creating CSRs except csr_bus.SRAM, which has its own get_csrs.

Tested

  • pytest: test/interconnect, test/cores, test/tools, test/hdl, test/build, test/software, test/support all pass. test/soc: the 15 failures (14 CPU boot tests missing pythondata packages/toolchains, serialboot) fail identically on master.
  • Elaboration with --no-compile: litex_sim (VexRiscv, SDRAM, Ethernet, SD card, video framebuffer), digilent_arty, xilinx_kc705, xilinx_kcu105, efinix_ti60_f225_dev_kit.
  • No hardware.

Written by Claude Code (AI agent), supervised by Florent Kermarrec.

🤖 Generated with Claude Code

enjoy-digital and others added 2 commits November 5, 2026 17:52
… plain Modules.

The AutoCSR/AutoDoc gatherers and CSRBankArray.scan duck-type every attribute through
hasattr(v, "get_csrs"), which hides two silent failure modes:
- an attribute holding a class (ex: Converter's self.cls = _DownConverter) has get_csrs as a plain
  function, so the gatherer called it without an instance and failed with a TypeError naming neither
  the module nor the attribute;
- a Migen Module without AutoCSR holding CSRs was skipped: its CSRs never reached the CSR map and
  nothing reported it.

Skip class references in the three gatherers and add csr.check_dropped_csrs(), used by the
get_csrs gatherer and by CSRBankArray.scan, which raises an explicit TypeError naming the parent
attribute, the CSR names and the fix (switch to LiteXModule, or autocsr_exclude). The check covers
CSRs held directly by plain Modules (and by nested plain Modules); a plain Module only wrapping an
AutoCSR child is not followed since attributes cannot tell owned submodules from references.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Resolves the FIXME: now that the gatherers skip class references, the self.cls attribute no longer
needs an autocsr/autodoc exclude. Add a test gathering CSRs/Docs of a parent holding a Converter
(scenario from #2757).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@enjoy-digital
enjoy-digital merged commit c2cceb8 into master Nov 6, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant