Skip to content

Commit 9775df2

Browse files
authored
[FIRRTL] Support MarkDUTAnnotation on extmodules. (#8001)
In some cases, the "DUT" might be an extmodule from a separate compilation unit, and we still want all the old legacy "is DUT" logic to work. To support this, we need applyDUTAnno to allow the annotation to be applied to an extmodule, and we need extractDUT and its users to work with FModuleLikes instead of FModuleOp. The only other thing that appears to be using this "is DUT" logic is the newer InstanceInfo helper, which already works with igraph::ModuleOpInterfaces and seems to work fine with extmodules as the "DUT".
1 parent 50e3f9f commit 9775df2

File tree

7 files changed

+75
-8
lines changed

7 files changed

+75
-8
lines changed

include/circt/Dialect/FIRRTL/FIRRTLAnnotations.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ struct PortAnnoTarget : public AnnoTarget {
448448
/// found or if the DUT was found and a previous DUT was not set (if `dut` is
449449
/// null). This returns failure if a DUT was found and a previous DUT was set.
450450
/// This function generates an error message in the failure case.
451-
LogicalResult extractDUT(FModuleOp mod, FModuleOp &dut);
451+
LogicalResult extractDUT(FModuleLike mod, FModuleLike &dut);
452452

453453
} // namespace firrtl
454454
} // namespace circt

lib/Dialect/FIRRTL/FIRRTLAnnotations.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,8 @@ FIRRTLType PortAnnoTarget::getType() const {
564564
// TODO: Remove these in favor of first-class annotations.
565565
//===----------------------------------------------------------------------===//
566566

567-
LogicalResult circt::firrtl::extractDUT(const FModuleOp mod, FModuleOp &dut) {
567+
LogicalResult circt::firrtl::extractDUT(const FModuleLike mod,
568+
FModuleLike &dut) {
568569
if (!AnnotationSet(mod).hasAnnotation(dutAnnoClass))
569570
return success();
570571

lib/Dialect/FIRRTL/Transforms/BlackBoxReader.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ struct BlackBoxReaderPass
104104
/// The design-under-test (DUT) as indicated by the presence of a
105105
/// "sifive.enterprise.firrtl.MarkDUTAnnotation". This will be null if no
106106
/// annotation is present.
107-
FModuleOp dut;
107+
FModuleLike dut;
108108

109109
/// The file list file name (sic) for black boxes. If set, generates a file
110110
/// that lists all non-header source files for black boxes. Can be changed
@@ -207,7 +207,7 @@ void BlackBoxReaderPass::runOnOperation() {
207207
// Do a shallow walk of the circuit to collect information necessary before we
208208
// do real work.
209209
for (auto &op : *circuitOp.getBodyBlock()) {
210-
FModuleOp module = dyn_cast<FModuleOp>(op);
210+
FModuleLike module = dyn_cast<FModuleLike>(op);
211211
// Find the DUT if it exists or error if there are multiple DUTs.
212212
if (module)
213213
if (failed(extractDUT(module, dut)))

lib/Dialect/FIRRTL/Transforms/GrandCentral.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -613,7 +613,7 @@ struct GrandCentralPass
613613
/// The design-under-test (DUT) as determined by the presence of a
614614
/// "sifive.enterprise.firrtl.MarkDUTAnnotation". This will be null if no DUT
615615
/// was found.
616-
FModuleOp dut;
616+
FModuleLike dut;
617617

618618
/// An optional directory for testbench-related files. This is null if no
619619
/// "TestBenchDirAnnotation" is found.
@@ -1577,7 +1577,7 @@ void GrandCentralPass::runOnOperation() {
15771577

15781578
// Find the DUT if it exists. This needs to be known before the circuit is
15791579
// walked.
1580-
for (auto mod : circuitOp.getOps<FModuleOp>()) {
1580+
for (auto mod : circuitOp.getOps<FModuleLike>()) {
15811581
if (failed(extractDUT(mod, dut)))
15821582
removalError = true;
15831583
}

lib/Dialect/FIRRTL/Transforms/LowerAnnotations.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,10 +246,10 @@ static LogicalResult applyDUTAnno(const AnnoPathValue &target,
246246
if (!target.isLocal())
247247
return mlir::emitError(loc) << "must be local";
248248

249-
if (!isa<OpAnnoTarget>(target.ref) || !isa<FModuleOp>(op))
249+
if (!isa<OpAnnoTarget>(target.ref) || !isa<FModuleLike>(op))
250250
return mlir::emitError(loc) << "can only target to a module";
251251

252-
auto moduleOp = cast<FModuleOp>(op);
252+
auto moduleOp = cast<FModuleLike>(op);
253253

254254
// DUT has public visibility.
255255
moduleOp.setPublic();

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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,3 +487,40 @@ firrtl.circuit "Foo" {
487487
firrtl.instance a {lowerToBind} @Foo_A()
488488
}
489489
}
490+
491+
// -----
492+
493+
// Test that the DUT can be an extmodule
494+
// CHECK: - operation: firrtl.circuit "Testharness"
495+
// CHECK-NEXT: hasDut: true
496+
// CHECK-NEXT: dut: firrtl.extmodule private @DUT
497+
// CHECK-NEXT: effectiveDut: firrtl.extmodule private @DUT
498+
firrtl.circuit "Testharness" {
499+
// CHECK: - operation: firrtl.module @Testharness
500+
// CHECK-NEXT: isDut: false
501+
// CHECK-NEXT: anyInstanceUnderDut: false
502+
// CHECK-NEXT: allInstancesUnderDut: false
503+
firrtl.module @Testharness() {
504+
firrtl.instance dut @DUT()
505+
firrtl.instance foo @Foo()
506+
}
507+
508+
// CHECK: - operation: firrtl.extmodule private @DUT
509+
// CHECK-NEXT: isDut: true
510+
// CHECK-NEXT: anyInstanceUnderDut: true
511+
// CHECK-NEXT: allInstancesUnderDut: true
512+
firrtl.extmodule private @DUT() attributes {
513+
annotations = [
514+
{
515+
class = "sifive.enterprise.firrtl.MarkDUTAnnotation"
516+
}
517+
]
518+
}
519+
520+
// CHECK: - operation: firrtl.module private @Foo
521+
// CHECK-NEXT: isDut: false
522+
// CHECK-NEXT: anyInstanceUnderDut: false
523+
// CHECK-NEXT: allInstancesUnderDut: false
524+
firrtl.module private @Foo() {
525+
}
526+
}

test/firtool/mark-dut.fir

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
; RUN: firtool %s -ir-verilog | FileCheck %s
2+
3+
FIRRTL version 4.1.0
4+
5+
; COM: Check that we can even target an extmodule.
6+
circuit Test : %[[
7+
{
8+
"class": "sifive.enterprise.firrtl.MarkDUTAnnotation",
9+
"target": "~Test|DUT"
10+
}
11+
]]
12+
; CHECK: hw.hierpath private [[DUT_NLA:@.+]] [@Test::[[DUT_SYM:@.+]]]
13+
public module Test :
14+
input in : UInt<1>
15+
output out : UInt<1>
16+
17+
; CHECK: hw.instance "dut" sym [[DUT_SYM]]
18+
inst dut of DUT
19+
20+
connect dut.in, in
21+
connect out, dut.out
22+
23+
extmodule DUT :
24+
input in : UInt<1>
25+
output out : UInt<1>
26+
27+
; COM: Check that metadata includes the dutModulePath pointing to Test::dut.
28+
; CHECK: om.class @SiFive_Metadata(%basepath: !om.basepath) -> (dutModulePath
29+
; CHECK-NEXT: om.path_create instance %basepath [[DUT_NLA]]

0 commit comments

Comments
 (0)