Add SitestBlackBoxLibrariesAnnotation; process in CreateSiFiveMetadataPass (#8670)

This commit is contained in:
Trevor McKay 2025-07-09 11:04:44 -07:00 committed by GitHub
parent 713a91ddff
commit bffff7d9a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 198 additions and 27 deletions

View File

@ -766,10 +766,14 @@ Example:
| filename | string | The file to write to |
This annotation triggers the creation of a file containing a JSON array of the
names of all external modules in the device under test which are not imported
`defname`s of all external modules in the device under test which are not imported
or inlined blackbox modules. This will only collect modules which are
instantiated under a module annotated with `MarkDUTAnnotation`.
If any external modules (including imported and inlined blackboxes) have a
`SitestBlackBoxLibrariesAnnotation`, the libraries specified in that annotation
will be included in the output.
Example:
```json
{
@ -786,10 +790,14 @@ Example:
| filename | string | The file to write to |
This annotation triggers the creation of a file containing a JSON array of the
names of all external modules in the test harness which are not imported or
`defname`s of all external modules in the test harness which are not imported or
inlined blackbox modules. This will only collect modules which are not
instantiated under a module annotated with `MarkDUTAnnotation`.
If any external modules (including imported and inlined blackboxes) have a
`SitestBlackBoxLibrariesAnnotation`, the libraries specified in that annotation
will also be included in the output.
Example:
```json
{
@ -798,6 +806,28 @@ Example:
}
```
### SitestBlackBoxLibrariesAnnotation
| Property | Type | Description |
| ---------- | ------ | ------------- |
| class | string | `sifive.enterprise.firrtl.SitestBlackBoxLibrariesAnnotation` |
| libraries | array | Array of library names to include in blackbox metadata |
This annotation is used to specify additional library names that should be
included in the blackbox metadata for an external module. When applied to an
external module, the specified libraries will be added to the blackbox resource
list in the generated metadata. Both the `defname` and any libraries specified by
this annotation will be included in the metadata for non-imported and non-inlined
blackboxes.
Example:
```json
{
"class":"sifive.enterprise.firrtl.SitestBlackBoxLibrariesAnnotation",
"libraries":["libmath", "libcrypto", "custom_lib"]
}
```
### TestBenchDirAnnotation
| Property | Type | Description |

View File

@ -143,6 +143,8 @@ constexpr const char *sitestBlackBoxAnnoClass =
"sifive.enterprise.firrtl.SitestBlackBoxAnnotation";
constexpr const char *sitestTestHarnessBlackBoxAnnoClass =
"sifive.enterprise.firrtl.SitestTestHarnessBlackBoxAnnotation";
constexpr const char *sitestBlackBoxLibrariesAnnoClass =
"sifive.enterprise.firrtl.SitestBlackBoxLibrariesAnnotation";
constexpr const char *dontObfuscateModuleAnnoClass =
"sifive.enterprise.firrtl.DontObfuscateModuleAnnotation";
constexpr const char *elaborationArtefactsDirectoryAnnoClass =

View File

@ -165,7 +165,9 @@ struct ObjectModelIR {
auto unknownLoc = mlir::UnknownLoc::get(context);
auto builderOM = mlir::ImplicitLocOpBuilder::atBlockEnd(
unknownLoc, circtOp.getBodyBlock());
Type classFieldTypes[] = {StringType::get(context), BoolType::get(context)};
Type classFieldTypes[] = {
StringType::get(context), BoolType::get(context),
ListType::get(context, cast<PropertyType>(StringType::get(context)))};
blackBoxModulesSchemaClass =
builderOM.create<ClassOp>("SitestBlackBoxModulesSchema",
blackBoxModulesParamNames, classFieldTypes);
@ -174,7 +176,8 @@ struct ObjectModelIR {
builderOM.getStringAttr("SitestBlackBoxMetadata"), mports);
}
void addBlackBoxModule(FExtModuleOp module, bool inDut) {
void addBlackBoxModule(FExtModuleOp module, bool inDut,
ArrayRef<StringRef> libraries) {
if (!blackBoxModulesSchemaClass)
addBlackBoxModulesSchema();
StringRef defName = *module.getDefname();
@ -184,6 +187,24 @@ struct ObjectModelIR {
module.getLoc(), blackBoxMetadataClass.getBodyBlock());
auto modEntry = builderOM.create<StringConstantOp>(module.getDefnameAttr());
auto inDutAttr = builderOM.create<BoolConstantOp>(inDut);
SmallVector<Value> libValues;
for (StringRef libName : libraries) {
Value libNameAttr;
if (libName == defName) {
libNameAttr = modEntry;
} else {
libNameAttr = builderOM.create<StringConstantOp>(
builderOM.getStringAttr(libName));
}
libValues.push_back(libNameAttr);
}
auto blackBoxResourcesList = builderOM.create<ListCreateOp>(
ListType::get(
builderOM.getContext(),
cast<PropertyType>(StringType::get(builderOM.getContext()))),
libValues);
auto object = builderOM.create<ObjectOp>(blackBoxModulesSchemaClass,
module.getModuleNameAttr());
@ -191,6 +212,10 @@ struct ObjectModelIR {
builderOM.create<PropAssignOp>(inPortModuleName, modEntry);
auto inPortInDut = builderOM.create<ObjectSubfieldOp>(object, 2);
builderOM.create<PropAssignOp>(inPortInDut, inDutAttr);
auto inPortBlackBoxResources =
builderOM.create<ObjectSubfieldOp>(object, 4);
builderOM.create<PropAssignOp>(inPortBlackBoxResources,
blackBoxResourcesList);
auto portIndex = blackBoxMetadataClass.getNumPorts();
SmallVector<std::pair<unsigned, PortInfo>> newPorts = {
{portIndex,
@ -463,7 +488,7 @@ struct ObjectModelIR {
"readLatency", "hierarchy", "inDut", "extraPorts",
"preExtInstName"};
StringRef retimeModulesParamNames[1] = {"moduleName"};
StringRef blackBoxModulesParamNames[2] = {"moduleName", "inDut"};
StringRef blackBoxModulesParamNames[3] = {"moduleName", "inDut", "libraries"};
llvm::SmallDenseSet<StringRef> blackboxModules;
}; // namespace
@ -797,7 +822,7 @@ LogicalResult
CreateSiFiveMetadataPass::emitSitestBlackboxMetadata(ObjectModelIR &omir) {
// Any extmodule with these annotations should be excluded from the blackbox
// list.
// list if it doesn't declare any additional libraries.
std::array<StringRef, 6> blackListedAnnos = {
blackBoxAnnoClass, blackBoxInlineAnnoClass, blackBoxPathAnnoClass,
dataTapsBlackboxClass, memTapBlackboxClass};
@ -819,30 +844,52 @@ CreateSiFiveMetadataPass::emitSitestBlackboxMetadata(ObjectModelIR &omir) {
// Find all extmodules in the circuit. Check if they are black-listed from
// being included in the list. If they are not, separate them into two
// groups depending on if theyre in the DUT or the test harness.
SmallVector<StringRef> dutModules;
SmallVector<StringRef> testModules;
SmallVector<StringRef> dutLibs;
SmallVector<StringRef> testLibs;
for (auto extModule : circuitOp.getBodyBlock()->getOps<FExtModuleOp>()) {
SmallVector<StringRef> libs;
// If the module doesn't have a defname, then we can't record it properly.
// Just skip it.
if (!extModule.getDefname())
continue;
// If its a generated blackbox, skip it.
AnnotationSet annos(extModule);
if (llvm::any_of(blackListedAnnos, [&](auto blackListedAnno) {
bool isBlacklistedBlackbox =
llvm::any_of(blackListedAnnos, [&](auto blackListedAnno) {
return annos.hasAnnotation(blackListedAnno);
}))
});
if (!isBlacklistedBlackbox)
libs.push_back(*extModule.getDefname());
bool hasLibs = false;
if (auto libsAnno = annos.getAnnotation(sitestBlackBoxLibrariesAnnoClass)) {
if (auto libsAttr = libsAnno.getMember<ArrayAttr>("libraries")) {
for (auto lib : libsAttr) {
if (auto libStr = dyn_cast<StringAttr>(lib)) {
libs.push_back(libStr.getValue());
hasLibs = true;
}
}
}
}
if (libs.empty())
continue;
// Record the defname of the module.
bool inDut = false;
if (instanceInfo->anyInstanceInEffectiveDesign(extModule)) {
inDut = true;
dutModules.push_back(*extModule.getDefname());
} else {
testModules.push_back(*extModule.getDefname());
}
omir.addBlackBoxModule(extModule, inDut);
for (StringRef lib : libs)
dutLibs.push_back(lib);
} else
for (StringRef lib : libs)
testLibs.push_back(lib);
omir.addBlackBoxModule(extModule, inDut, libs);
}
// This is a helper to create the verbatim output operation.
@ -874,8 +921,8 @@ CreateSiFiveMetadataPass::emitSitestBlackboxMetadata(ObjectModelIR &omir) {
});
};
createOutput(testModules, testFilename);
createOutput(dutModules, dutFilename);
createOutput(testLibs, testFilename);
createOutput(dutLibs, dutFilename);
return success();
}

View File

@ -630,6 +630,8 @@ static llvm::StringMap<AnnoRecord> annotationRecords{{
{injectDUTHierarchyAnnoClass, NoTargetAnnotation},
{convertMemToRegOfVecAnnoClass, NoTargetAnnotation},
{sitestBlackBoxAnnoClass, NoTargetAnnotation},
{sitestBlackBoxLibrariesAnnoClass,
{stdResolve, applyWithoutTarget<false, FExtModuleOp>}},
{enumComponentAnnoClass, {noResolve, drop}},
{enumDefAnnoClass, {noResolve, drop}},
{enumVecAnnoClass, {noResolve, drop}},

View File

@ -135,20 +135,23 @@ circuit TestHarness:
; SITEST_NODUT: FILE "testbench.sitest.json"
; SITEST_NODUT-NOT: FILE
; MLIR_OUT: om.class @SitestBlackBoxModulesSchema(%basepath: !om.basepath, %moduleName_in: !om.string, %inDut_in: i1) -> (moduleName: !om.string, inDut: i1) {
; MLIR_OUT: om.class.fields %moduleName_in, %inDut_in : !om.string, i1
; MLIR_OUT: om.class @SitestBlackBoxModulesSchema(%basepath: !om.basepath, %moduleName_in: !om.string, %inDut_in: i1, %libraries_in: !om.list<!om.string>) -> (moduleName: !om.string, inDut: i1, libraries: !om.list<!om.string>) {
; MLIR_OUT: om.class.fields %moduleName_in, %inDut_in, %libraries_in : !om.string, i1, !om.list<!om.string>
; MLIR_OUT: }
; MLIR_OUT: om.class @SitestBlackBoxMetadata(%basepath: !om.basepath) -> [[V1:.+]]: !om.class.type<@SitestBlackBoxModulesSchema>, [[V2:.+]]: !om.class.type<@SitestBlackBoxModulesSchema>, [[V3:.+]]: !om.class.type<@SitestBlackBoxModulesSchema>
; MLIR_OUT-DAG: [[STR1:%.+]] = om.constant "Foo_BlackBox" : !om.string
; MLIR_OUT-DAG: [[DUT1:%.+]] = om.constant true
; MLIR_OUT-DAG: [[OBJ1:%.+]] = om.object @SitestBlackBoxModulesSchema(%basepath, [[STR1]], [[DUT1]]) : (!om.basepath, !om.string, i1) -> !om.class.type<@SitestBlackBoxModulesSchema>
; MLIR_OUT-DAG: [[LIBS1:%.+]] = om.list_create [[STR1]] : !om.string
; MLIR_OUT-DAG: [[OBJ1:%.+]] = om.object @SitestBlackBoxModulesSchema(%basepath, [[STR1]], [[DUT1]], [[LIBS1]]) : (!om.basepath, !om.string, i1, !om.list<!om.string>) -> !om.class.type<@SitestBlackBoxModulesSchema>
; MLIR_OUT-DAG: [[STR2:%.+]] = om.constant "Bar_BlackBox" : !om.string
; MLIR_OUT-DAG: [[DUT2:%.+]] = om.constant true
; MLIR_OUT-DAG: [[OBJ2:%.+]] = om.object @SitestBlackBoxModulesSchema(%basepath, [[STR2]], [[DUT2]]) : (!om.basepath, !om.string, i1) -> !om.class.type<@SitestBlackBoxModulesSchema>
; MLIR_OUT-DAG: [[LIBS2:%.+]] = om.list_create [[STR2]] : !om.string
; MLIR_OUT-DAG: [[OBJ2:%.+]] = om.object @SitestBlackBoxModulesSchema(%basepath, [[STR2]], [[DUT2]], [[LIBS2]]) : (!om.basepath, !om.string, i1, !om.list<!om.string>) -> !om.class.type<@SitestBlackBoxModulesSchema>
; MLIR_OUT-DAG: [[STR3:%.+]] = om.constant "Baz_BlackBox" : !om.string
; MLIR_OUT-DAG: [[DUT3:%.+]] = om.constant true
; MLIR_OUT-DAG: [[OBJ3:%.+]] = om.object @SitestBlackBoxModulesSchema(%basepath, [[STR3]], [[DUT3]]) : (!om.basepath, !om.string, i1) -> !om.class.type<@SitestBlackBoxModulesSchema>
; MLIR_OUT-DAG: [[LIBS3:%.+]] = om.list_create [[STR3]] : !om.string
; MLIR_OUT-DAG: [[OBJ3:%.+]] = om.object @SitestBlackBoxModulesSchema(%basepath, [[STR3]], [[DUT3]], [[LIBS3]]) : (!om.basepath, !om.string, i1, !om.list<!om.string>) -> !om.class.type<@SitestBlackBoxModulesSchema>
; MLIR_OUT: om.class.fields [[OBJ1]], [[OBJ2]], [[OBJ3]] : !om.class.type<@SitestBlackBoxModulesSchema>, !om.class.type<@SitestBlackBoxModulesSchema>, !om.class.type<@SitestBlackBoxModulesSchema>
; MLIR_OUT: }

View File

@ -239,6 +239,7 @@ firrtl.circuit "BasicBlackboxes" attributes {
firrtl.instance test @DUTBlackbox_1()
firrtl.instance test @DUTBlackbox_2()
firrtl.instance layerBlackboxInDesign1 @LayerBlackboxInDesign()
firrtl.instance blacklistedWithLibsDut @InlineBlackboxWithLibs()
firrtl.layerblock @A {
firrtl.instance layerBlackboxInDesign2 @LayerBlackboxInDesign()
firrtl.instance layerBlackbox @LayerBlackbox()
@ -298,6 +299,37 @@ firrtl.circuit "BasicBlackboxes" attributes {
firrtl.extmodule @DUTBlackbox_2() attributes {defname = "DUTBlackbox1"}
firrtl.extmodule @LayerBlackboxInDesign() attributes {defname = "LayerBlackboxInDesign"}
firrtl.extmodule @LayerBlackbox() attributes {defname = "LayerBlackbox"}
// Test blacklisted blackbox with additional libraries - should be included
firrtl.extmodule @InlineBlackboxWithLibs() attributes {
annotations = [
{
class = "firrtl.transforms.BlackBoxInlineAnno"
},
{
class = "sifive.enterprise.firrtl.SitestBlackBoxLibrariesAnnotation",
libraries = ["lib1", "lib2"]
}
],
defname = "InlineBlackboxWithLibs"
}
// Test non-blacklisted blackbox with additional libraries - should be included
firrtl.extmodule @BlackboxWithLibs() attributes {
annotations = [
{
class = "sifive.enterprise.firrtl.SitestBlackBoxLibrariesAnnotation",
libraries = ["lib3", "lib4", "lib5"]
}
],
defname = "BlackboxWithLibs"
}
firrtl.module @TestHarness() {
firrtl.instance inlineBlackboxWithLibs @InlineBlackboxWithLibs()
firrtl.instance blackboxWithLibs @BlackboxWithLibs()
firrtl.instance test @TestBlackbox()
}
}
// (1) Class-based metadata ----------------------------------------------------
@ -306,10 +338,13 @@ firrtl.circuit "BasicBlackboxes" attributes {
// CHECK-SAME: in %[[moduleName_in:[^:]+]]: !firrtl.string,
// CHECK-SAME: out %moduleName: !firrtl.string,
// CHECK-SAME: in %[[inDut_in:[^:]+]]: !firrtl.bool,
// CHECK-SAME: out %inDut: !firrtl.bool
// CHECK-SAME: out %inDut: !firrtl.bool,
// CHECK-SAME: in %[[libraries_in:[^:]+]]: !firrtl.list<string>,
// CHECK-SAME: out %libraries: !firrtl.list<string>
// CHECK-SAME: ) {
// CHECK-NEXT: firrtl.propassign %moduleName, %[[moduleName_in]]
// CHECK-NEXT: firrtl.propassign %inDut, %[[inDut_in]]
// CHECK-NEXT: firrtl.propassign %libraries, %[[libraries_in]]
// CHECK: }
//
// CHECK: firrtl.class @SitestBlackBoxMetadata(
@ -318,61 +353,111 @@ firrtl.circuit "BasicBlackboxes" attributes {
// CHECK-SAME: out %DUTBlackbox_1_field: !firrtl.class<@SitestBlackBoxModulesSchema(
// CHECK-SAME: out %LayerBlackboxInDesign_field: !firrtl.class<@SitestBlackBoxModulesSchema(
// CHECK-SAME: out %LayerBlackbox_field: !firrtl.class<@SitestBlackBoxModulesSchema(
// CHECK-SAME: out %InlineBlackboxWithLibs_field: !firrtl.class<@SitestBlackBoxModulesSchema(
// CHECK-SAME: out %BlackboxWithLibs_field: !firrtl.class<@SitestBlackBoxModulesSchema(
// CHECK-NOT: !firrtl.class<@SitestBlackBoxModulesSchema(
//
// CHECK-NEXT: %[[#defname:]] = firrtl.string "TestBlackbox"
// CHECK-NEXT: %[[#inDutVal:]] = firrtl.bool false
// CHECK-NEXT: %[[#libsList:]] = firrtl.list.create %[[#defname]] : !firrtl.list<string>
// CHECK-NEXT: %[[object:.+]] = firrtl.object @SitestBlackBoxModulesSchema
// CHECK-NEXT: %[[#moduleName:]] = firrtl.object.subfield %[[object]][moduleName_in]
// CHECK-NEXT: firrtl.propassign %[[#moduleName]], %[[#defname:]] : !firrtl.string
// CHECK-NEXT: %[[#inDut:]] = firrtl.object.subfield %[[object]][inDut_in]
// CHECK-NEXT: firrtl.propassign %[[#inDut]], %[[#inDutVal]] : !firrtl.bool
// CHECK-NEXT: %[[#libraries:]] = firrtl.object.subfield %[[object]][libraries_in]
// CHECK-NEXT: firrtl.propassign %[[#libraries]], %[[#libsList]] : !firrtl.list<string>
// CHECK-NEXT: firrtl.propassign %TestBlackbox_field, %[[object]]
//
// CHECK-NEXT: %[[#defname:]] = firrtl.string "DUTBlackbox2"
// CHECK-NEXT: %[[#inDutVal:]] = firrtl.bool true
// CHECK-NEXT: %[[#libsList:]] = firrtl.list.create %[[#defname]] : !firrtl.list<string>
// CHECK-NEXT: %[[object:.+]] = firrtl.object @SitestBlackBoxModulesSchema
// CHECK-NEXT: %[[#moduleName:]] = firrtl.object.subfield %[[object]][moduleName_in]
// CHECK-NEXT: firrtl.propassign %[[#moduleName]], %[[#defname:]] : !firrtl.string
// CHECK-NEXT: %[[#inDut:]] = firrtl.object.subfield %[[object]][inDut_in]
// CHECK-NEXT: firrtl.propassign %[[#inDut]], %[[#inDutVal]] : !firrtl.bool
// CHECK-NEXT: %[[#libraries:]] = firrtl.object.subfield %[[object]][libraries_in]
// CHECK-NEXT: firrtl.propassign %[[#libraries]], %[[#libsList]] : !firrtl.list<string>
// CHECK-NEXT: firrtl.propassign %DUTBlackbox_0_field, %[[object]]
//
// CHECK-NEXT: %[[#defname:]] = firrtl.string "DUTBlackbox1"
// CHECK-NEXT: %[[#inDutVal:]] = firrtl.bool true
// CHECK-NEXT: %[[#libsList:]] = firrtl.list.create %[[#defname]] : !firrtl.list<string>
// CHECK-NEXT: %[[object:.+]] = firrtl.object @SitestBlackBoxModulesSchema
// CHECK-NEXT: %[[#moduleName:]] = firrtl.object.subfield %[[object]][moduleName_in]
// CHECK-NEXT: firrtl.propassign %[[#moduleName]], %[[#defname:]] : !firrtl.string
// CHECK-NEXT: %[[#inDut:]] = firrtl.object.subfield %[[object]][inDut_in]
// CHECK-NEXT: firrtl.propassign %[[#inDut]], %[[#inDutVal]] : !firrtl.bool
// CHECK-NEXT: %[[#libraries:]] = firrtl.object.subfield %[[object]][libraries_in]
// CHECK-NEXT: firrtl.propassign %[[#libraries]], %[[#libsList]] : !firrtl.list<string>
// CHECK-NEXT: firrtl.propassign %DUTBlackbox_1_field, %[[object]]
//
// CHECK-NEXT: %[[#defname:]] = firrtl.string "LayerBlackboxInDesign"
// CHECK-NEXT: %[[#inDutVal:]] = firrtl.bool true
// CHECK-NEXT: %[[#libsList:]] = firrtl.list.create %[[#defname]] : !firrtl.list<string>
// CHECK-NEXT: %[[object:.+]] = firrtl.object @SitestBlackBoxModulesSchema
// CHECK-NEXT: %[[#moduleName:]] = firrtl.object.subfield %[[object]][moduleName_in]
// CHECK-NEXT: firrtl.propassign %[[#moduleName]], %[[#defname:]] : !firrtl.string
// CHECK-NEXT: %[[#inDut:]] = firrtl.object.subfield %[[object]][inDut_in]
// CHECK-NEXT: firrtl.propassign %[[#inDut]], %[[#inDutVal]] : !firrtl.bool
// CHECK-NEXT: %[[#libraries:]] = firrtl.object.subfield %[[object]][libraries_in]
// CHECK-NEXT: firrtl.propassign %[[#libraries]], %[[#libsList]] : !firrtl.list<string>
// CHECK-NEXT: firrtl.propassign %LayerBlackboxInDesign_field, %[[object]]
//
// CHECK-NEXT: %[[#defname:]] = firrtl.string "LayerBlackbox"
// CHECK-NEXT: %[[#inDutVal:]] = firrtl.bool false
// CHECK-NEXT: %[[#libsList:]] = firrtl.list.create %[[#defname]] : !firrtl.list<string>
// CHECK-NEXT: %[[object:.+]] = firrtl.object @SitestBlackBoxModulesSchema
// CHECK-NEXT: %[[#moduleName:]] = firrtl.object.subfield %[[object]][moduleName_in]
// CHECK-NEXT: firrtl.propassign %[[#moduleName]], %[[#defname:]] : !firrtl.string
// CHECK-NEXT: %[[#inDut:]] = firrtl.object.subfield %[[object]][inDut_in]
// CHECK-NEXT: firrtl.propassign %[[#inDut]], %[[#inDutVal]] : !firrtl.bool
// CHECK-NEXT: %[[#libraries:]] = firrtl.object.subfield %[[object]][libraries_in]
// CHECK-NEXT: firrtl.propassign %[[#libraries]], %[[#libsList]] : !firrtl.list<string>
// CHECK-NEXT: firrtl.propassign %LayerBlackbox_field, %[[object]]
//
// CHECK-NEXT: %[[#defname:]] = firrtl.string "InlineBlackboxWithLibs"
// CHECK-NEXT: %[[#inDutVal:]] = firrtl.bool true
// CHECK-NEXT: %[[#lib1:]] = firrtl.string "lib1"
// CHECK-NEXT: %[[#lib2:]] = firrtl.string "lib2"
// CHECK-NEXT: %[[#libsList:]] = firrtl.list.create %[[#lib1]], %[[#lib2]] : !firrtl.list<string>
// CHECK-NEXT: %[[object:.+]] = firrtl.object @SitestBlackBoxModulesSchema
// CHECK-NEXT: %[[#moduleName:]] = firrtl.object.subfield %[[object]][moduleName_in]
// CHECK-NEXT: firrtl.propassign %[[#moduleName]], %[[#defname:]] : !firrtl.string
// CHECK-NEXT: %[[#inDut:]] = firrtl.object.subfield %[[object]][inDut_in]
// CHECK-NEXT: firrtl.propassign %[[#inDut]], %[[#inDutVal]] : !firrtl.bool
// CHECK-NEXT: %[[#libraries:]] = firrtl.object.subfield %[[object]][libraries_in]
// CHECK-NEXT: firrtl.propassign %[[#libraries]], %[[#libsList]] : !firrtl.list<string>
// CHECK-NEXT: firrtl.propassign %InlineBlackboxWithLibs_field, %[[object]]
//
// CHECK-NEXT: %[[#defname:]] = firrtl.string "BlackboxWithLibs"
// CHECK-NEXT: %[[#inDutVal:]] = firrtl.bool false
// CHECK-NEXT: %[[#lib3:]] = firrtl.string "lib3"
// CHECK-NEXT: %[[#lib4:]] = firrtl.string "lib4"
// CHECK-NEXT: %[[#lib5:]] = firrtl.string "lib5"
// CHECK-NEXT: %[[#libsList:]] = firrtl.list.create %[[#defname]], %[[#lib3]], %[[#lib4]], %[[#lib5]] : !firrtl.list<string>
// CHECK-NEXT: %[[object:.+]] = firrtl.object @SitestBlackBoxModulesSchema
// CHECK-NEXT: %[[#moduleName:]] = firrtl.object.subfield %[[object]][moduleName_in]
// CHECK-NEXT: firrtl.propassign %[[#moduleName]], %[[#defname:]] : !firrtl.string
// CHECK-NEXT: %[[#inDut:]] = firrtl.object.subfield %[[object]][inDut_in]
// CHECK-NEXT: firrtl.propassign %[[#inDut]], %[[#inDutVal]] : !firrtl.bool
// CHECK-NEXT: %[[#libraries:]] = firrtl.object.subfield %[[object]][libraries_in]
// CHECK-NEXT: firrtl.propassign %[[#libraries]], %[[#libsList]] : !firrtl.list<string>
// CHECK-NEXT: firrtl.propassign %BlackboxWithLibs_field, %[[object]]
//
// CHECK-NOT: firrtl.object
// (2) JSON file-based metadata ------------------------------------------------
//
// CHECK: emit.file "test_blackboxes.json" {
// CHECK-NEXT{LITERAL}: emit.verbatim "[\0A
// CHECK-SAME: \22BlackboxWithLibs\22,\0A
// CHECK-SAME: \22LayerBlackbox\22,\0A
// CHECK-SAME: \22TestBlackbox\22\0A
// CHECK-SAME: \22TestBlackbox\22,\0A
// CHECK-SAME: \22lib3\22,\0A
// CHECK-SAME: \22lib4\22,\0A
// CHECK-SAME: \22lib5\22\0A
// CHECK-SAME: ]"
// CHECK-NEXT: }
//
@ -380,7 +465,9 @@ firrtl.circuit "BasicBlackboxes" attributes {
// CHECK-NEXT{LITERAL}: emit.verbatim "[\0A
// CHECK-SAME: \22DUTBlackbox1\22,\0A
// CHECK-SAME: \22DUTBlackbox2\22,\0A
// CHECK-SAME: \22LayerBlackboxInDesign\22\0A
// CHECK-SAME: \22LayerBlackboxInDesign\22,\0A
// CHECK-SAME: \22lib1\22,\0A
// CHECK-SAME: \22lib2\22\0A
// CHECK-SAME: ]"
// CHECK-NEXT: }