mirror of https://github.com/llvm/circt.git
[FIRRTL] Add GrandCentral no-bind option
Add an option to the GrandCentral pass that will _not_ bind in the companion module and will _not_ emit the SV interface instantiation. This is done to enable GrandCentral collateral to be synthesizable. This is motivated by making all the assertions that are frequently crammed into a Grand Central companion as eligible for synthesis. Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
This commit is contained in:
parent
8784c8c377
commit
acb8ba5c61
|
@ -102,7 +102,8 @@ std::unique_ptr<mlir::Pass> createPrintNLATablePass();
|
||||||
std::unique_ptr<mlir::Pass>
|
std::unique_ptr<mlir::Pass>
|
||||||
createBlackBoxReaderPass(std::optional<mlir::StringRef> inputPrefix = {});
|
createBlackBoxReaderPass(std::optional<mlir::StringRef> inputPrefix = {});
|
||||||
|
|
||||||
std::unique_ptr<mlir::Pass> createGrandCentralPass();
|
std::unique_ptr<mlir::Pass>
|
||||||
|
createGrandCentralPass(bool instantiateCompanionOnly = false);
|
||||||
|
|
||||||
std::unique_ptr<mlir::Pass> createCheckCombCyclesPass();
|
std::unique_ptr<mlir::Pass> createCheckCombCyclesPass();
|
||||||
|
|
||||||
|
|
|
@ -420,6 +420,10 @@ def GrandCentral : Pass<"firrtl-grand-central", "CircuitOp"> {
|
||||||
|
|
||||||
let constructor = "circt::firrtl::createGrandCentralPass()";
|
let constructor = "circt::firrtl::createGrandCentralPass()";
|
||||||
let dependentDialects = ["circt::sv::SVDialect", "circt::hw::HWDialect"];
|
let dependentDialects = ["circt::sv::SVDialect", "circt::hw::HWDialect"];
|
||||||
|
let options = [
|
||||||
|
Option<"instantiateCompanionOnly", "instantiate-companion-only", "bool", "false",
|
||||||
|
"Instantiate the companion without a bind and drop the interface">
|
||||||
|
];
|
||||||
let statistics = [
|
let statistics = [
|
||||||
Statistic<"numViews", "num-views-created",
|
Statistic<"numViews", "num-views-created",
|
||||||
"Number of top-level SystemVerilog interfaces that were created">,
|
"Number of top-level SystemVerilog interfaces that were created">,
|
||||||
|
|
|
@ -577,6 +577,10 @@ struct InterfaceElemsBuilder {
|
||||||
/// instantiate interfaces and to generate the "mappings" file that produces
|
/// instantiate interfaces and to generate the "mappings" file that produces
|
||||||
/// cross-module references (XMRs) to drive the interface.
|
/// cross-module references (XMRs) to drive the interface.
|
||||||
struct GrandCentralPass : public GrandCentralBase<GrandCentralPass> {
|
struct GrandCentralPass : public GrandCentralBase<GrandCentralPass> {
|
||||||
|
GrandCentralPass(bool instantiateCompanionOnlyFlag) {
|
||||||
|
instantiateCompanionOnly = instantiateCompanionOnlyFlag;
|
||||||
|
}
|
||||||
|
|
||||||
void runOnOperation() override;
|
void runOnOperation() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -1116,7 +1120,8 @@ parseAugmentedType(ApplyState &state, DictionaryAttr augmentedType,
|
||||||
NamedAttrList attrs;
|
NamedAttrList attrs;
|
||||||
attrs.append("class", classAttr);
|
attrs.append("class", classAttr);
|
||||||
attrs.append("name", name);
|
attrs.append("name", name);
|
||||||
auto value = tryGetAs<Attribute>(augmentedType, root, "value", loc, clazz, path);
|
auto value =
|
||||||
|
tryGetAs<Attribute>(augmentedType, root, "value", loc, clazz, path);
|
||||||
if (!value)
|
if (!value)
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
attrs.append("value", value);
|
attrs.append("value", value);
|
||||||
|
@ -1890,7 +1895,11 @@ void GrandCentralPass::runOnOperation() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*instance)->setAttr("lowerToBind", builder.getUnitAttr());
|
// Lower the companion to a bind unless the user told us
|
||||||
|
// explicitly not to.
|
||||||
|
if (!instantiateCompanionOnly)
|
||||||
|
(*instance)->setAttr("lowerToBind", builder.getUnitAttr());
|
||||||
|
|
||||||
(*instance)->setAttr(
|
(*instance)->setAttr(
|
||||||
"output_file",
|
"output_file",
|
||||||
hw::OutputFileAttr::getFromFilename(
|
hw::OutputFileAttr::getFromFilename(
|
||||||
|
@ -2024,6 +2033,14 @@ void GrandCentralPass::runOnOperation() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// If we are in "instantiateCompanionOnly" mode, then just exit here. We
|
||||||
|
// don't need to create the interface. This is a janky hack for situations
|
||||||
|
// where you want to synthesize assertion logic included in the companion, but
|
||||||
|
// don't want to have a dead interface hanging around (or have problems with
|
||||||
|
// tools understanding interfaces).
|
||||||
|
if (instantiateCompanionOnly)
|
||||||
|
return;
|
||||||
|
|
||||||
// Now, iterate over the worklist of interface-encoding annotations to create
|
// Now, iterate over the worklist of interface-encoding annotations to create
|
||||||
// the interface and all its sub-interfaces (interfaces that it instantiates),
|
// the interface and all its sub-interfaces (interfaces that it instantiates),
|
||||||
// instantiate the top-level interface, and generate a "mappings file" that
|
// instantiate the top-level interface, and generate a "mappings file" that
|
||||||
|
@ -2250,6 +2267,7 @@ void GrandCentralPass::runOnOperation() {
|
||||||
// Pass Creation
|
// Pass Creation
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
std::unique_ptr<mlir::Pass> circt::firrtl::createGrandCentralPass() {
|
std::unique_ptr<mlir::Pass>
|
||||||
return std::make_unique<GrandCentralPass>();
|
circt::firrtl::createGrandCentralPass(bool instantiateCompanionOnly) {
|
||||||
|
return std::make_unique<GrandCentralPass>(instantiateCompanionOnly);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue