Skip to content

Commit f79553f

Browse files
committed
[FIRRTL] Update InstanceInfo to handle instance choice
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
1 parent 327529c commit f79553f

File tree

4 files changed

+49
-4
lines changed

4 files changed

+49
-4
lines changed

include/circt/Analysis/FIRRTLInstanceInfo.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ class InstanceInfo {
109109
/// is deemed to be in the design except those which are explicitly
110110
/// verification code.
111111
InstanceInfo::LatticeValue inEffectiveDesign;
112+
113+
/// Indicates if this module is instantiated within (or transitively within)
114+
/// an instance choice operation.
115+
InstanceInfo::LatticeValue inInstanceChoice;
112116
};
113117

114118
//===--------------------------------------------------------------------===//
@@ -183,6 +187,12 @@ class InstanceInfo {
183187
/// withiin) the effective design.
184188
bool allInstancesInEffectiveDesign(igraph::ModuleOpInterface op);
185189

190+
/// Return true if any instance of this module is within (or transitively
191+
/// within) an instance choice.
192+
/// Note: allInstancesInInstanceChoice is intentionally not provided because
193+
/// that property is relative to the public module.
194+
bool anyInstanceInInstanceChoice(igraph::ModuleOpInterface op);
195+
186196
private:
187197
/// Stores circuit-level attributes.
188198
CircuitAttributes circuitAttributes = {/*dut=*/nullptr,

lib/Analysis/FIRRTLInstanceInfo.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ InstanceInfo::InstanceInfo(Operation *op, mlir::AnalysisManager &am) {
104104
attributes.inDesign.mergeIn(isDut(moduleOp));
105105
attributes.inEffectiveDesign.mergeIn(isEffectiveDut(moduleOp) || !hasDut());
106106
attributes.underLayer.mergeIn(false);
107+
attributes.inInstanceChoice.mergeIn(false);
107108
}
108109

109110
// Visit modules in reverse post-order (visit parents before children) to
@@ -146,6 +147,16 @@ InstanceInfo::InstanceInfo(Operation *op, mlir::AnalysisManager &am) {
146147
underLayer = true;
147148
}
148149

150+
// Update inInstanceChoice.
151+
if (auto instanceChoiceOp =
152+
useIt->template getInstance<InstanceChoiceOp>()) {
153+
attributes.inInstanceChoice.mergeIn(true);
154+
if (instanceChoiceOp->template getParentOfType<LayerBlockOp>() ||
155+
instanceChoiceOp->template getParentOfType<sv::IfDefOp>())
156+
underLayer = true;
157+
} else
158+
attributes.inInstanceChoice.mergeIn(parentAttrs.inInstanceChoice);
159+
149160
if (!isGCCompanion) {
150161
if (underLayer)
151162
attributes.underLayer.mergeIn(true);
@@ -194,7 +205,9 @@ InstanceInfo::InstanceInfo(Operation *op, mlir::AnalysisManager &am) {
194205
<< llvm::indent(6) << "underLayer: " << attributes.underLayer << "\n"
195206
<< llvm::indent(6) << "inDesign: " << attributes.inDesign << "\n"
196207
<< llvm::indent(6)
197-
<< "inEffectiveDesign: " << attributes.inEffectiveDesign << "\n";
208+
<< "inEffectiveDesign: " << attributes.inEffectiveDesign << "\n"
209+
<< llvm::indent(6)
210+
<< "inInstanceChoice: " << attributes.inInstanceChoice << "\n";
198211
});
199212
});
200213
}
@@ -273,3 +286,9 @@ bool InstanceInfo::allInstancesInEffectiveDesign(igraph::ModuleOpInterface op) {
273286
auto inEffectiveDesign = getModuleAttributes(op).inEffectiveDesign;
274287
return inEffectiveDesign.isConstant() && inEffectiveDesign.getConstant();
275288
}
289+
290+
bool InstanceInfo::anyInstanceInInstanceChoice(igraph::ModuleOpInterface op) {
291+
auto inInstanceChoice = getModuleAttributes(op).inInstanceChoice;
292+
return inInstanceChoice.isMixed() ||
293+
(inInstanceChoice.isConstant() && inInstanceChoice.getConstant());
294+
}

lib/Analysis/TestPasses.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,9 @@ static void printModuleInfo(igraph::ModuleOpInterface op,
254254
<< " anyInstanceInEffectiveDesign: "
255255
<< iInfo.anyInstanceInEffectiveDesign(op) << "\n"
256256
<< " allInstancesInEffectiveDesign: "
257-
<< iInfo.allInstancesInEffectiveDesign(op) << "\n";
257+
<< iInfo.allInstancesInEffectiveDesign(op) << "\n"
258+
<< " anyInstanceInInstanceChoice: "
259+
<< iInfo.anyInstanceInInstanceChoice(op) << "\n";
258260
}
259261

260262
void FIRRTLInstanceInfoPass::runOnOperation() {

test/Analysis/firrtl-test-instance-info.mlir

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
firrtl.circuit "Foo" {
1111
firrtl.layer @A bind {
1212
}
13+
firrtl.option @Platform {
14+
firrtl.option_case @FPGA
15+
}
1316
// CHECK: @Corge
1417
// CHECK-NEXT: isDut: false
1518
// CHECK-NEXT: anyInstanceUnderDut: false
@@ -18,6 +21,7 @@ firrtl.circuit "Foo" {
1821
// CHECK-NEXT: allInstancesUnderEffectiveDut: false
1922
// CHECK-NEXT: anyInstanceUnderLayer: true
2023
// CHECK-NEXT: allInstancesUnderLayer: false
24+
// CHECK: anyInstanceInInstanceChoice: true
2125
firrtl.module private @Corge() {}
2226
// CHECK: @Quz
2327
// CHECK-NEXT: isDut: false
@@ -27,6 +31,7 @@ firrtl.circuit "Foo" {
2731
// CHECK-NEXT: allInstancesUnderEffectiveDut: false
2832
// CHECK-NEXT: anyInstanceUnderLayer: true
2933
// CHECK-NEXT: allInstancesUnderLayer: true
34+
// CHECK: anyInstanceInInstanceChoice: false
3035
firrtl.module private @Quz() {}
3136
// CHECK: @Qux
3237
// CHECK-NEXT: isDut: false
@@ -36,6 +41,7 @@ firrtl.circuit "Foo" {
3641
// CHECK-NEXT: allInstancesUnderEffectiveDut: false
3742
// CHECK-NEXT: anyInstanceUnderLayer: false
3843
// CHECK-NEXT: allInstancesUnderLayer: false
44+
// CHECK: anyInstanceInInstanceChoice: true
3945
firrtl.module private @Qux() {}
4046
// CHECK: @Baz
4147
// CHECK-NEXT: isDut: false
@@ -45,6 +51,7 @@ firrtl.circuit "Foo" {
4551
// CHECK-NEXT: allInstancesUnderEffectiveDut: true
4652
// CHECK-NEXT: anyInstanceUnderLayer: false
4753
// CHECK-NEXT: allInstancesUnderLayer: false
54+
// CHECK: anyInstanceInInstanceChoice: false
4855
firrtl.module private @Baz() {}
4956
// CHECK: @Bar
5057
// CHECK-NEXT: isDut: true
@@ -54,6 +61,7 @@ firrtl.circuit "Foo" {
5461
// CHECK-NEXT: allInstancesUnderEffectiveDut: true
5562
// CHECK-NEXT: anyInstanceUnderLayer: false
5663
// CHECK-NEXT: allInstancesUnderLayer: false
64+
// CHECK: anyInstanceInInstanceChoice: false
5765
firrtl.module private @Bar() attributes {
5866
annotations = [
5967
{class = "sifive.enterprise.firrtl.MarkDUTAnnotation"}
@@ -70,12 +78,17 @@ firrtl.circuit "Foo" {
7078
// CHECK-NEXT: allInstancesUnderEffectiveDut: false
7179
// CHECK-NEXT: anyInstanceUnderLayer: false
7280
// CHECK-NEXT: allInstancesUnderLayer: false
81+
// CHECK: anyInstanceInInstanceChoice: false
7382
firrtl.module @Foo() {
7483
firrtl.instance bar @Bar()
75-
firrtl.instance qux @Qux()
84+
firrtl.instance_choice qux @Qux alternatives @Platform {
85+
@FPGA -> @Corge
86+
} ()
7687
firrtl.layerblock @A {
7788
firrtl.instance quz @Quz()
78-
firrtl.instance corge @Corge()
89+
firrtl.instance_choice corge @Corge alternatives @Platform {
90+
@FPGA -> @Corge
91+
} ()
7992
}
8093
firrtl.instance corge2 @Corge()
8194
}
@@ -98,6 +111,7 @@ firrtl.circuit "Foo" {
98111
// CHECK-NEXT: allInstancesUnderEffectiveDut: true
99112
// CHECK-NEXT: anyInstanceUnderLayer: false
100113
// CHECK-NEXT: allInstancesUnderLayer: false
114+
// CHECK: anyInstanceInInstanceChoice: false
101115
firrtl.module @Foo() {}
102116
}
103117

0 commit comments

Comments
 (0)