Skip to content

[FIRRTL] Add CheckInstanceChoice pass to reject nested instance choices#9743

Open
uenoku wants to merge 4 commits intomainfrom
dev/hidetou/ban-nest
Open

[FIRRTL] Add CheckInstanceChoice pass to reject nested instance choices#9743
uenoku wants to merge 4 commits intomainfrom
dev/hidetou/ban-nest

Conversation

@uenoku
Copy link
Member

@uenoku uenoku commented Feb 24, 2026

This commit introduces a verification pass to ensure that instance choices don't nest, since nested instance choices are challenging to compose with layer bind convention.

For example:

FIRRTL version 100.0.0

circuit Top:
  option Platform:
    FPGA
    ASIC
  
  option Optimization:
    Low
    High

  layer Verification, bind:


  module A:
    input clock: Clock

    node result = UInt<8>(42)

    layerblock Verification:
      node debug_value = UInt<8>(255)
      printf(clock, UInt<1>(1), "Module A: result = %d, debug_value = %d\n", result, debug_value)

  module B:
    input clock: Clock

  module ASICOptimizationWrapper:
    input clock: Clock

    instchoice b of A, Optimization:
      High => A
      Low => B

    connect b.clock, clock

  module FPGAOptimizationWrapper:
    input clock: Clock

    instchoice b of A, Optimization:
      Low => A
      High => B

    connect b.clock, clock

  module PlatformWrapper:
    input clock: Clock

    instchoice b of ASICOptimizationWrapper, Platform:
      ASIC => ASICOptimizationWrapper
      FPGA => FPGAOptimizationWrapper

    connect b.clock, clock
  
  public module Top:
    input clock: Clock

    inst platform of PlatformWrapper
    connect platform.clock, clock

Module A is instantiated by nested instance choice in 5 out of 9 possible settings ((Platform::default & Optimization::default), (default & High), (ASIC & default), (ASIC & High), (FPGA & Low)). It also has a Verification layer.

The bind statement should be elaborated only when these specific settings are met. We could use a macro to describe this logic, but that is too complicated for this first version. Hence this PR bans nested instances so that we can make the condition much simpler (there will be no conjunction &).

InstanceChoiceInfo is introduced to check paths from the top down. If it finds "nested" choices, it will fail.

Right now, InstanceChoiceInfo is not built as a standard MLIR Analysis because it could fail. It will be used later in the LowerLayer to handle these choices.
AI-assisted-by: Augment (Claude Sonnet 4.5)

@uenoku uenoku marked this pull request as draft February 24, 2026 03:43
@uenoku uenoku force-pushed the dev/hidetou/ban-nest branch from ed9f921 to 740926c Compare February 24, 2026 03:45
@uenoku uenoku marked this pull request as ready for review February 24, 2026 04:11
Copy link
Member

@seldridge seldridge left a comment

Choose a reason for hiding this comment

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

The fact that this is sort of an analysis, but sort of a check feels a bit odd. Did you consider an alternative implementation which directly extended the InstanceInfo analysis with anyInstanceUnderInstanceChoice and allInstancesUnderInstanceChoice and then used that information, coupled with information about being under a layer, to then do the checks and then do the more expensive computations when the checks unexpectedly fail?

With such a formulation, the InstanceInfo likely needs to know about bind vs. inline layers which smells a bit odd, but may be okay. Or: I've been intending to try to have InstanceInfo be the singular place for all information that can be computed via an O(n) walk of the instance graph.

You mention that there are uses for this in LowerLayers where the member functions of the analysis will come into play more.

@uenoku
Copy link
Member Author

uenoku commented Feb 25, 2026

which directly extended the InstanceInfo analysis with anyInstanceUnderInstanceChoice and allInstancesUnderInstanceChoice and then used that information

Good point, I think it's feasible to extend the IntanceInfo (and I realized it's necessary to update it anyway) to check if a module is under choice or not, but I didn't since we need more precise information than boolean.

  1. LatticeValue needs to be a set of pairs (`(option, case)) to precisely get what configuration we need bind statement.

  2. This must be computed for each public module because the result could be different for each public module:

FIRRTL version 10.0.0
circuit Top:
  option Optimization:
    Low
    High

  layer Verification, bind:

  module A:
    input clock: Clock

    node result = UInt<8>(42)

    layerblock Verification:
      node debug_value = UInt<8>(255)
      printf(clock, UInt<1>(1), "Module A: result = %d, debug_value = %d\n", result, debug_value)

  module B:
    input clock: Clock
  

  public module Top:
    input clock: Clock

    instchoice b of A, Optimization:
      Low => A
      High => B
    connect b.clock, clock

  public module AnotherTop:
    input clock: Clock
    inst a of A
    connect a.clock, clock

For this example module A is used on when Optimization::Low is enabled in Top. However in AnotherTop it's always instantiated. So bind statement must be guarded only inTop.

I think i can add the utility to InstanceInfo if it's acceptable to run analysis on all public modules.

Another direction might be to give colors to modules that restrict usage of options (e.g. module A must be instantiated under option Low, so the usage in AnotherTop is rejected in verifier). In that case we even don't need this kind of analysis. This is actually similar to layers attribute in module op. I haven't thought through enough how it would compose with Dedup etc though.

@uenoku uenoku force-pushed the dev/hidetou/ban-nest branch 2 times, most recently from 7ac590c to c78b62c Compare March 2, 2026 22:59
@uenoku
Copy link
Member Author

uenoku commented Mar 2, 2026

I updated to use InstanceInfo (stacked on #9811).

uenoku added 2 commits March 6, 2026 00:50
Implement tracking of modules that are instantiated within instance choice
operations (i.e., modules that are alternatives in an InstanceChoiceOp).
This follows the same pattern as other module attributes like `inDesign`
and `inEffectiveDesign`.

isUnderLayer is updated as well
…figurations

This commit introduces a new analysis and verification pass to ensure that
instance choices in FIRRTL circuits follow proper nesting rules. The pass
prevents nested instance choices with different options on the same path
while allowing the same module to be reached through different options on
different paths (disjunction is allowed, conjunction is banned).
@uenoku uenoku force-pushed the dev/hidetou/ban-nest branch from c78b62c to 7bce037 Compare March 6, 2026 08:50
@uenoku uenoku force-pushed the dev/hidetou/ban-nest branch from 7bce037 to 4b3aab5 Compare March 6, 2026 08:51
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