Skip to content

[core] Add knownLayers API to BlackBox, ExtModule #4983

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 25, 2025

Conversation

seldridge
Copy link
Member

@seldridge seldridge commented Jul 18, 2025

Add an API to add knownlayer specifications to FIRRTL extmodules.
This is a mechanism to declare that an external module was compiled with
support for specific layers. This then allows a FIRRTL comopiler compiler
to know that it should automatically enable these layers if needed.

Release Notes

Add knownLayers API to BlackBox and ExternalModule. This allows for external modules to declare that they will contain layers, e.g., that they contain debug collateral. This allows a FIRRTL compiler using them to know that they should enable these layers in concert with the parent circuit.

@seldridge seldridge requested review from jackkoenig and rwy7 July 18, 2025 00:18
@seldridge seldridge changed the base branch from main to ci/ci-circt-nightly July 18, 2025 02:00
@rwy7
Copy link
Contributor

rwy7 commented Jul 18, 2025

It looks like, when a layer is used as a knownlayer, it doesn't automatically get added to the list of layers on the builder, it would be nice if we could do that.

    object A extends layer.Layer(layer.LayerConfig.Extract()) {
    }
    class Qux extends BlackBox(knownLayers = Seq(A)) {
      final val io = IO(new Bundle {})
    }

@@ -296,6 +296,19 @@ abstract class RawModule extends BaseModule {
protected[chisel3] override def moduleBuilt(): Unit = _afterModuleBuilt.foreach(_())

private[chisel3] def initializeInParent(): Unit = {}

final var _knownLayers: Option[Seq[layer.Layer]] = None
atModuleBodyEnd {
Copy link
Contributor

@mwachs5 mwachs5 Jul 18, 2025

Choose a reason for hiding this comment

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

are there any sneaky APIs that add layers with atModuleBodyEnd? Can bored probes impact this? Should we at least add some sort of check that no one tries to add a new layer after this _knownLayers was evaluated?

Copy link
Member Author

Choose a reason for hiding this comment

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

Boring could definitely cause this to be incorrect. I can probably show that this is a problem if it's not updated there.

The thing that's really annoying about this is that really only ExtModule/BlackBox should have known layers. However, because there are APIs that let you create an Instance from a Definition without examining the DesignAnnotation (which has layer information) then this forces everything up to BaseModule to need to record this.

It perhaps makes more sense this way, just this is surprisingly invasive just to get the separate elaboration examples working correctly.

@jackkoenig: Do you have any ideas on how to architect this more cleanly?

Copy link
Contributor

Choose a reason for hiding this comment

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

However, because there are APIs that let you create an Instance from a Definition without examining the DesignAnnotation (which has layer information) then this forces everything up to BaseModule to need to record this.

I think this is a key observation that applies to a lot of things. We have Modules and then we have auxiliary information stored in the Builder that is largely lost once you exit the build phase for that particular circuit. Definitions act like small circuits and copy things to the Builder of the outer elaboration (if there is one).

I think what we probably need is to actually lean more in to Definitions as circuit. Instead of making knownLayers a public method on BaseModule, can it instead be on Definition? And then could Definitions capture more information from their DynamicContexts (in this case obviously the layers)?

Copy link
Member Author

Choose a reason for hiding this comment

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

The problem with Definition is that it's currently too generic. I.e., you can have a Definition[A] for any A. Hence, it's weird to have this live on Definition[A], when it's really a property of A. (I generally agree with this, though, and we should move towards having a Definition be more tied to a module/extmodule and less generic.)

Copy link
Contributor

@jackkoenig jackkoenig left a comment

Choose a reason for hiding this comment

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

LGTM with a couple of thoughts for consideration

@github-actions github-actions bot force-pushed the ci/ci-circt-nightly branch from 78c8ac1 to 121c08e Compare July 22, 2025 11:06
Add an API to add `knownlayers` specifications to FIRRTL `extmodule`s.
This is a mechanism to declare that an external module was compiled with
support for specific layers.  This then allows a FIRRTL comopiler compiler
to know that it should automatically enable these layers if needed.

In order to make this work, a number of other changes had to be made.

First, move `atModuleBodyEnd` from `RawModule` to `BaseModule`.  This
allows capturing of the `Builder` state when the module closes.  Here,
this is used to capture the layers that are known to the `Builder` if a
module is later converted to a `Definition`.

Second, the default layers are now added to the `Builder` when it starts
as opposed to when it ends.  This allows for the default layers to be
captured by module or external modules and then emitted correctly if
needed (in the `Definition` or as FIRRTL `knownlayers`).

Third, when an `Instance` is created, any layers that it has need to be
added to the `Builder`.  This can arise if a `Definition` is imported via
an annotation and used to create a blackbox which will define additional
`knownlayers`.  If these layers are not added to the FIRRTL circuit, then
this is illegal FIRRTL.

Signed-off-by: Schuyler Eldridge <[email protected]>
@seldridge seldridge force-pushed the dev/seldridge/blackbox-knownlayers branch from 1227b95 to 200bef0 Compare July 23, 2025 02:01
@seldridge
Copy link
Member Author

The main change here since the last review is that now external modules which add layer-colored probe ports or use the layer.addLayer API will have those layers added to a BaseBlackBox-internal set of knownLayers. This will then be used when generating the FIRRTL extmodule.

@seldridge
Copy link
Member Author

☝️ I talked to @jackkoenig about this offline and he's good with this approach.

@seldridge seldridge merged commit e18af94 into ci/ci-circt-nightly Jul 25, 2025
13 checks passed
@seldridge seldridge deleted the dev/seldridge/blackbox-knownlayers branch July 25, 2025 03:40
chiselbot pushed a commit that referenced this pull request Jul 25, 2025
Add an API to add `knownlayers` specifications to FIRRTL `extmodule`s.
This is a mechanism to declare that an external module was compiled with
support for specific layers.  This then allows a FIRRTL comopiler compiler
to know that it should automatically enable these layers if needed.

In order to make this work, a number of other changes had to be made.

First, move `atModuleBodyEnd` from `RawModule` to `BaseModule`.  This
allows capturing of the `Builder` state when the module closes.  Here,
this is used to capture the layers that are known to the `Builder` if a
module is later converted to a `Definition`.

Second, the default layers are now added to the `Builder` when it starts
as opposed to when it ends.  This allows for the default layers to be
captured by module or external modules and then emitted correctly if
needed (in the `Definition` or as FIRRTL `knownlayers`).

Third, when an `Instance` is created, any layers that it has need to be
added to the `Builder`.  This can arise if a `Definition` is imported via
an annotation and used to create a blackbox which will define additional
`knownlayers`.  If these layers are not added to the FIRRTL circuit, then
this is illegal FIRRTL.

Signed-off-by: Schuyler Eldridge <[email protected]>
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.

4 participants