Skip to content

builder/gen: add full hierarchical Verilog generation - #2543

Open
hansfbaier wants to merge 1 commit into
enjoy-digital:masterfrom
hansfbaier:full-hierarchy-refactor
Open

builder/gen: add full hierarchical Verilog generation#2543
hansfbaier wants to merge 1 commit into
enjoy-digital:masterfrom
hansfbaier:full-hierarchy-refactor

Conversation

@hansfbaier

Copy link
Copy Markdown
Contributor

Adds hierarchical Verilog output (--hierarchical-verilog / --no-flatten) that preserves internal module boundaries by lifting parent-driven child-internal signals to proper input ports instead of inlining subtrees.

Implementation is structured in three phases:
_analyze_hierarchy — tree walking, ownership, inline policies, lowering
_emit_hierarchy — module generation with clock/reset aliasing
_convert_hierarchical — orchestrator

Key design decisions:

  • Reads ClockDomainsRenamer mappings from module.cd_remap_chain attribute (set by migen) instead of introspecting Python closures.
  • Adds ModulePort dataclass as foundation for explicit port abstraction.
  • Handles shared submodules, duplicate sibling names, memories, tristates, FSMs, renamed clock domains, reset-only constants, and structural invariants (no module assigns to its own input port).

Comprehensive test suite (22 tests) covers port directions, clock/reset wiring, sibling driver conflicts, nested renamers, reset-less domains, deep 3-level hierarchies, and the cd_remap_chain metadata contract.

Verified on Terasic DECA hardware with liteusb ACM serial and UAC2 audio, also with a LiteX SoC over ACM serial.

Please note that this more elegant approach needs a small patch to migen:
m-labs/migen@a1e58a7

Adds hierarchical Verilog output (--hierarchical-verilog / --no-flatten)
that preserves internal module boundaries by lifting parent-driven
child-internal signals to proper input ports instead of inlining subtrees.

Implementation is structured in three phases:
  _analyze_hierarchy  — tree walking, ownership, inline policies, lowering
  _emit_hierarchy     — module generation with clock/reset aliasing
  _convert_hierarchical — orchestrator

Key design decisions:
- Reads ClockDomainsRenamer mappings from module.cd_remap_chain attribute
  (set by migen) instead of introspecting Python closures.
- Adds ModulePort dataclass as foundation for explicit port abstraction.
- Handles shared submodules, duplicate sibling names, memories, tristates,
  FSMs, renamed clock domains, reset-only constants, and structural
  invariants (no module assigns to its own input port).

Comprehensive test suite (22 tests) covers port directions, clock/reset
wiring, sibling driver conflicts, nested renamers, reset-less domains,
deep 3-level hierarchies, and the cd_remap_chain metadata contract.

Verified on Terasic DECA hardware with liteusb ACM serial and UAC2 audio.
@hansfbaier
hansfbaier force-pushed the full-hierarchy-refactor branch from ef52250 to 2ad18a3 Compare July 27, 2026 11:59
@enjoy-digital

Copy link
Copy Markdown
Owner

Thanks @hansfbaier, I'll try to review this soon.

@hansfbaier

Copy link
Copy Markdown
Contributor Author

@enjoy-digital The tests fail, because they need the corresponding migen commit mentioned above

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.

2 participants