Skip to content

Conversation

@tmckay-sifive
Copy link
Contributor

@tmckay-sifive tmckay-sifive commented Oct 23, 2025

This PR adds an sv.verbatim.module op and lowers inline black boxes (firrtl.extmodule with BlackBoxInlineAnno or BlackBoxPathAnno) to the new op.

Emitted verilog is semantically the same (there can be a difference in emission order)--so, this is mostly an IR-only change.

Before:

  • BlackBoxReader
    • For each firrtl.extmodule with BlackBoxInlineAnno or BlackBoxPathAnno, create emit.file and emit.verbatim operations for the inline content
  • LowerToHW pass: For each firrtl.extmodule, creates a hw.module.extern operation

After:

  • BlackBoxReader
    • For each firrtl.extmodule with verbatim annotations:
      • Process each BlackBoxInlineAnno and BlackBoxPathAnno to calculate the verbatim content and determine the output file path
      • Store this information in a new annotation type designed for consumption by the LowerToHW pass
      • Remove the original BlackBoxInlineAnno/BlackBoxPathAnno annotations
  • LowerToHW:
    • For each firrtl.extmodule with the new verbatim annotation:
      • On the first verbatim annotation encountered, create a sv.verbatim.module operation
      • For additional verbatim annotations on the same module, add them to the additional_files attribute of the existing sv.verbatim.module operation
      • Do not create hw.module.extern for modules with verbatim content

BlackBoxReader

It is a bit strange to partially lower the BlackBoxInlineAnno BlackBoxPathAnno. The intention here was to preserve the fragile logic around calculating output directories for black boxes.

Eventually, I think we can remove BlackBoxReader entirely and rely on AssignOutputDirs for this. Then, by the time we get to LowerToHW, we don't need to special case any of this stuff for black boxes.

Supporting multiple files

firtool currently accepts multiple instances of BlackBoxInlineAnno and BlackBoxPathAnno annotations. This is often used to include additional SV libraries, C files, or headers. In the future, we should disallow this and ensure that one module corresponds to one SV file. Before we do this however, we need to provide another mechanism for specifying external dependencies.

The addition_files attribute is a way to support the existing behavior in the meantime. Once we have addressed this tech-debt, we can just remove that attribute.

@tmckay-sifive tmckay-sifive force-pushed the tmckay/sv.verbatim.module branch 6 times, most recently from d883171 to 98810c1 Compare October 23, 2025 20:09
@tmckay-sifive tmckay-sifive force-pushed the tmckay/sv.verbatim.module branch from 98810c1 to bc5fb1d Compare October 23, 2025 20:11
@tmckay-sifive tmckay-sifive marked this pull request as ready for review October 23, 2025 21:52
Copy link
Member

@uenoku uenoku left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation direction makes sense, could you include tests for ExportVerilog, lower-to-hw, and sv dialect? It's a bit unclear to me how additional_files are used.

@tmckay-sifive
Copy link
Contributor Author

The implementation direction makes sense, could you include tests for ExportVerilog, lower-to-hw, and sv dialect?

Yep, will do.

It's a bit unclear to me how additional_files are used.

Sorry, I meant to talk about that in the PR description. I've added it but I'll paste it here too:

firtool currently accepts multiple instances of BlackBoxInlineAnno and BlackBoxPathAnno annotations. This is often used to include additional SV libraries, C files, or headers. In the future, we should disallow this and ensure that one module corresponds to one SV file. Before we do this however, we need to provide another mechanism for specifying external dependencies.

The addition_files attribute is a way to support the existing behavior in the meantime. Once we have addressed this tech-debt, we can just remove that attribute.

@tmckay-sifive
Copy link
Contributor Author

The implementation direction makes sense, could you include tests for ExportVerilog, lower-to-hw, and sv dialect?

I added some tests for LowerToHW and ExportVerilog. I wasn't sure what SV dialect tests should exercise that isn't covered by the LowerToHW, ExportVerilog, or BlackBox tests. If you have something in mind please let me know.

@tmckay-sifive tmckay-sifive requested a review from uenoku October 28, 2025 16:48
Copy link
Member

@uenoku uenoku left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally looks great! Could you add round-trip test for SV dialect?

@tmckay-sifive tmckay-sifive requested a review from uenoku November 4, 2025 00:48
Copy link
Member

@uenoku uenoku left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, mostly style comments but please fix DenseMap iteration (non-determinism) and remove getnearestSymbolTable in verifySymbolUses.

@fabianschuiki fabianschuiki merged commit 8e122aa into llvm:main Nov 6, 2025
7 checks passed
fabianschuiki pushed a commit that referenced this pull request Nov 7, 2025
#9131 was recently merged but does not correctly handle
`firrtl.extmodule`s with inout ports. This implements the same logic
used in `HWModuleOp` in the lowering for `sv.verbatim.module`.
tmckay-sifive pushed a commit to tmckay-sifive/circt that referenced this pull request Nov 11, 2025
…lackBoxInlineAnno/BlackBoxPathAnno (llvm#9131)"

This reverts commit 8e122aa.
seldridge pushed a commit that referenced this pull request Nov 11, 2025
* Revert "Fix inout port lowering for sv.verbatim.module (#9209)"

This reverts commit 91872b2.

* Revert "Add sv.module.verbatim op and use for firrtl.extmodule with BlackBoxInlineAnno/BlackBoxPathAnno (#9131)"

This reverts commit 8e122aa.
seldridge pushed a commit that referenced this pull request Nov 18, 2025
…x extmodules (#9227)

A second attempt of #9131. Changes from the first PR were made in order to
support parametrized black boxes. Because parameters can affect the port
interface of a module, we need two ops:

1. sv.verbatim.source to represent the shared verbatim definition of a module
2. sv.verbatim.module to represent a particular parametrization of that module
   that can be instantiated

The pipeline is largely the same:

- BlackBoxInlineAnno and BlackBoxPathAnno are converted to VerbatimBlackBoxAnno
  by BlackBoxReader for consumption by LowerToHW.

- LowerToHW will lower firrtl.extmodules with a VerbatimBlackBoxAnno to a
  sv.verbatim.source (only one per file) and a sv.verbatim.module.
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.

5 participants