Skip to content
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

[FIRRTL] Use walk, InstanceInfo in AddSeqMemPorts #7599

Merged
merged 7 commits into from
Sep 27, 2024

Conversation

seldridge
Copy link
Member

@seldridge seldridge commented Sep 14, 2024

Change the AddSeqMemPorts pass (whic adds MBIST ports to memories) to
use a walk when adding ports to memories. Practically, this causes the
pass to now be capable of adding MBIST to memories under WhenOps or
LayerBlockOps. However, because this pass is intentionally not
supposed to add MBIST ports to anything that is not in the "design", this
will skip over any layers or modules that are instantiated wholly under
layers.

To do this, this pass was changed to use the new InstanceInfo analysis
instead of computing information about what modules are under the
design-under-test (DUT) manually. Any checking related to layers is
similarly done using this analysis.

This change is prerequisite work to move the LowerLayers after
AddSeqMemPorts while still preserving the functionality of the original
pass order. Unfortunately, layers do not compose sanely with
AddSeqMemPorts. This is a failing of the original pass and its
assumptions about what is "design" vs. "verification" as opposed to any
fundamental issue with layers. Generally, layers are intended as
verification features. However, there is no actual requirement or
expectation that they will be used this way. Going forward,
AddSeqMemPorts is intended to be removed and replaced with a feature in
Chisel.

Additionally, this this commit includes a small change to the pass output
where the connects created are placed immediately following the memory
instance. This is necessary to create the connects inside the layer
blocks. However, it is also slightly better output than before. (This
changed one test superficially.)

@seldridge
Copy link
Member Author

seldridge commented Sep 14, 2024

This does not handle some of the weirder things that could be going on here related to the memory metadata file. This file is intended to show where these extra ports are on which memory. However, the memory may be moved under a layer block bind file.

It may be better to instead completely disallow this pass for memories under layer blocks. It just really doesn't make sense to be adding MBIST ports to memories which are basically design verification collateral. Alternative way of arguing this, because layers are new, nobody is using this behavior, thereby we can punt on what to do here until there is an actual user.

This PR was changed to use a walk, but to skip over memories that are wholly instantiated under layer blocks. Memories that are partially instantiated under layer blocks will error.

@seldridge seldridge force-pushed the dev/seldridge/layers-add-seq-mem-ports branch 2 times, most recently from acd26fe to 6c362e0 Compare September 24, 2024 15:11
@seldridge seldridge changed the title [FIRRTL] Add layer block support to AddSeqMemPorts [FIRRTL] Use walk, InstanceInfo in AddSeqMemPorts Sep 24, 2024
@seldridge seldridge force-pushed the dev/seldridge/layers-add-seq-mem-ports branch from 6c362e0 to a998fbc Compare September 24, 2024 15:49
Change the `AddSeqMemPorts` pass (whic adds MBIST ports to memories) to
use a walk when adding ports to memories.  Practically, this causes the
pass to now be capable of adding MBIST to memories under `WhenOp`s or
`LayerBlockOp`s.  However, because this pass is intentionally _not_
supposed to add MBIST ports to anything that is not in the "design", this
will skip over any layers or modules that are instantiated wholly under
layers.

To do this, this pass was changed to use the new `InstanceInfo` analysis
instead of computing information about what modules are under the
design-under-test (DUT) manually.  Any checking related to layers is
similarly done using this analysis.

This change is prerequisite work to move the `LowerLayers` after
`AddSeqMemPorts` while still preserving the functionality of the original
pass order.  Unfortunately, layers do not compose sanely with
`AddSeqMemPorts`.  This is a failing of the original pass and its
assumptions about what is "design" vs. "verification" as opposed to any
fundamental issue with layers.  Generally, layers are intended as
verification features.  However, there is no actual requirement or
expectation that they will be used this way.  Going forward,
`AddSeqMemPorts` is intended to be removed and replaced with a feature in
Chisel.

Additionally, this this commit includes a small change to the pass output
where the connects created are placed immediately following the memory
instance.  This is necessary to create the connects inside the layer
blocks.  However, it is also slightly better output than before.  (This
changed one test superficially.)

Signed-off-by: Schuyler Eldridge <[email protected]>
@seldridge seldridge force-pushed the dev/seldridge/layers-add-seq-mem-ports branch from 914e069 to ed23a81 Compare September 25, 2024 04:01
lib/Dialect/FIRRTL/Transforms/CMakeLists.txt Show resolved Hide resolved

// Add the extra ports to this module.
moduleOp.insertPorts(extraPorts);

// Connect the submodule ports to the parent module ports.
DenseMap<Operation *, OpBuilder::InsertPoint> instToInsertionPoint;
Copy link
Contributor

@rwy7 rwy7 Sep 26, 2024

Choose a reason for hiding this comment

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

Maybe you could walk the values in reverse, or change the storage of the values to group by instance? or just ignore me and leave your patch as-is :)

Copy link
Member Author

Choose a reason for hiding this comment

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

I like this idea. I realized that this change was now very out-of-place for this PR. This PR doesn't need this anymore (as it is not creating connects under layer blocks). I opted instead to just back this out of the patch in b11b072.

Copy link
Member Author

Choose a reason for hiding this comment

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

I realized that this code is still necessary as this pass should work for WhenOps and it was still busted. I reverted the removal of this in f83e453. I then added code to handle WhenOps in c43c02c. This uses invalidation to handle the case of output ports.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm going to leave this for a follow-up as this would permute the code a bit too much in this PR. I like the idea.

lib/Dialect/FIRRTL/Transforms/AddSeqMemPorts.cpp Outdated Show resolved Hide resolved
lib/Dialect/FIRRTL/Transforms/AddSeqMemPorts.cpp Outdated Show resolved Hide resolved
Comment on lines +441 to +442
if (instanceInfo->allInstancesUnderLayer(op))
continue;
Copy link
Contributor

Choose a reason for hiding this comment

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

If the DUT is wholly under a layer, then we won't add any MBIST ports. Seems OK.

Copy link
Member Author

Choose a reason for hiding this comment

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

That seems reasonable, though I suppose it could work? E.g., there's no problem wiring to the DUT as long as you don't have to pass through any intermediary layers to do it. (InstanceInfo doesn't track that, though!)

This smells like a missing check that should be in LowerAnnotations (as I don't think we can do it with a verifier).

lib/Dialect/FIRRTL/Transforms/AddSeqMemPorts.cpp Outdated Show resolved Hide resolved
Make AddSeqMemPorts work for memories under WhenOps.  This takes a necessary
interpretation of how this should work which may create disagreement.  However,
it is the only reasonable thing to do.  Namely, for a memory that is under a
WhenOp that is having _output_ ports added to it, this will drive the port under
the WhenOp and invalidate it at the top of the module.

This interpretation is that the MBIST outputs are only driven under the WhenOp
and indeterminate otherwise.  CIRCT will treat this as an unconditional connect
after ExpandWhens, however, the spec allows for it to connect it to anything.
@seldridge seldridge merged commit dabd7d2 into main Sep 27, 2024
4 checks passed
@seldridge seldridge deleted the dev/seldridge/layers-add-seq-mem-ports branch September 27, 2024 02:26
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