[FIRRTL] Make emit-metadata a mlir::ModuleOp pass (#5247)

Make the `CreateSiFiveMetadata` a `mlir::ModuleOp` pass.
This is required to generate `om` Dialect operations (#5224).
The `om::ClassOp` must have `mlir::ModuleOp` as the parent. This PR updates the
Pass infrastructure and also the lit tests.
This commit is contained in:
Prithayan Barua 2023-05-24 12:32:33 -04:00 committed by GitHub
parent 6723ec62de
commit cc5c6c84f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 37 additions and 12 deletions

View File

@ -169,7 +169,7 @@ def AddSeqMemPorts : Pass<"firrtl-add-seqmem-ports", "firrtl::CircuitOp"> {
];
}
def CreateSiFiveMetadata : Pass<"firrtl-emit-metadata", "firrtl::CircuitOp"> {
def CreateSiFiveMetadata : Pass<"firrtl-emit-metadata", "mlir::ModuleOp"> {
let summary = "Emit metadata of the FIRRTL modules";
let description = [{
This pass handles the emission of several different kinds of metadata.

View File

@ -41,6 +41,7 @@ class CreateSiFiveMetadataPass
DenseSet<Operation *> dutModuleSet;
// The design under test module.
FModuleOp dutMod;
CircuitOp circuitOp;
public:
CreateSiFiveMetadataPass(bool _replSeqMem, StringRef _replSeqMemCircuit,
@ -58,7 +59,6 @@ LogicalResult CreateSiFiveMetadataPass::emitMemoryMetadata() {
if (!replSeqMem)
return success();
CircuitOp circuitOp = getOperation();
// The instance graph analysis will be required to print the hierarchy names
// of the memory.
auto instancePathCache = InstancePathCache(getAnalysis<InstanceGraph>());
@ -266,7 +266,6 @@ static LogicalResult removeAnnotationWithFilename(Operation *op,
LogicalResult CreateSiFiveMetadataPass::emitRetimeModulesMetadata() {
auto *context = &getContext();
auto circuitOp = getOperation();
// Get the filename, removing the annotation from the circuit.
StringRef filename;
@ -324,7 +323,6 @@ LogicalResult CreateSiFiveMetadataPass::emitSitestBlackboxMetadata() {
dataTapsBlackboxClass, memTapBlackboxClass};
auto *context = &getContext();
auto circuitOp = getOperation();
// Get the filenames from the annotations.
StringRef dutFilename, testFilename;
@ -419,7 +417,17 @@ void CreateSiFiveMetadataPass::getDependentDialects(
}
void CreateSiFiveMetadataPass::runOnOperation() {
auto circuitOp = getOperation();
auto moduleOp = getOperation();
auto circuits = moduleOp.getOps<CircuitOp>();
if (circuits.empty())
return;
auto cIter = circuits.begin();
circuitOp = *cIter++;
assert(cIter == circuits.end() &&
"cannot handle more than one CircuitOp in a mlir::ModuleOp");
auto *body = circuitOp.getBodyBlock();
// Find the device under test and create a set of all modules underneath it.
@ -444,6 +452,7 @@ void CreateSiFiveMetadataPass::runOnOperation() {
// Clear pass-global state as required by MLIR pass infrastructure.
dutMod = {};
circuitOp = {};
dutModuleSet.empty();
}

View File

@ -125,7 +125,7 @@ LogicalResult firtool::populateCHIRRTLToLowFIRRTL(mlir::PassManager &pm,
pm.addNestedPass<firrtl::CircuitOp>(firrtl::createAddSeqMemPortsPass());
pm.nest<firrtl::CircuitOp>().addPass(firrtl::createCreateSiFiveMetadataPass(
pm.addPass(firrtl::createCreateSiFiveMetadataPass(
opt.replSeqMem, opt.replSeqMemCircuit, opt.replSeqMemFile));
pm.addNestedPass<firrtl::CircuitOp>(firrtl::createExtractInstancesPass());

View File

@ -1,4 +1,4 @@
// RUN: circt-opt --pass-pipeline='builtin.module(firrtl.circuit(firrtl-emit-metadata))' --verify-diagnostics --split-input-file %s
// RUN: circt-opt --firrtl-emit-metadata="repl-seq-mem=true repl-seq-mem-file='dut.conf'" --verify-diagnostics -split-input-file %s
//===----------------------------------------------------------------------===//
// RetimeModules

View File

@ -1,4 +1,4 @@
// RUN: circt-opt --pass-pipeline='builtin.module(firrtl.circuit(firrtl-emit-metadata{repl-seq-mem=true repl-seq-mem-file="dut.conf"}))' %s | FileCheck %s
// RUN: circt-opt --firrtl-emit-metadata="repl-seq-mem=true repl-seq-mem-file='dut.conf'" -split-input-file %s | FileCheck %s
firrtl.circuit "empty" {
firrtl.module @empty() {
@ -9,6 +9,8 @@ firrtl.circuit "empty" {
// CHECK-NEXT: }
// CHECK-NEXT: }
// -----
//===----------------------------------------------------------------------===//
// RetimeModules
//===----------------------------------------------------------------------===//
@ -36,6 +38,8 @@ firrtl.circuit "retime0" attributes { annotations = [{
// CHECK-SAME: output_file = #hw.output_file<"retime_modules.json", excludeFromFileList>
// CHECK-SAME: symbols = [@retime0, @retime2]
// -----
//===----------------------------------------------------------------------===//
// SitestBlackbox
//===----------------------------------------------------------------------===//
@ -53,6 +57,8 @@ firrtl.circuit "DUTBlackboxes" attributes { annotations = [{
// CHECK-NOT: sv.verbatim "[]" {output_file = #hw.output_file<"", excludeFromFileList>}
}
// -----
// CHECK-LABEL: firrtl.circuit "TestBlackboxes" {
firrtl.circuit "TestBlackboxes" attributes { annotations = [{
class = "sifive.enterprise.firrtl.SitestTestHarnessBlackBoxAnnotation",
@ -66,6 +72,8 @@ firrtl.circuit "TestBlackboxes" attributes { annotations = [{
// CHECK-NOT: sv.verbatim "[]" {output_file = #hw.output_file<"", excludeFromFileList>}
}
// -----
// CHECK-LABEL: firrtl.circuit "BasicBlackboxes" {
firrtl.circuit "BasicBlackboxes" attributes { annotations = [{
class = "sifive.enterprise.firrtl.SitestBlackBoxAnnotation",
@ -107,6 +115,8 @@ firrtl.circuit "BasicBlackboxes" attributes { annotations = [{
// CHECK: sv.verbatim "[\0A \22DUTBlackbox1\22,\0A \22DUTBlackbox2\22\0A]" {output_file = #hw.output_file<"dut_blackboxes.json", excludeFromFileList>}
}
// -----
//===----------------------------------------------------------------------===//
// MemoryMetadata
//===----------------------------------------------------------------------===//
@ -117,9 +127,11 @@ firrtl.circuit "top"
firrtl.module @top() { }
// When there are no memories, we still need to emit the memory metadata.
// CHECK: sv.verbatim "[]" {output_file = #hw.output_file<"metadata{{/|\\\\}}seq_mems.json", excludeFromFileList>}
// CHECK: sv.verbatim "" {output_file = #hw.output_file<"\22dut.conf\22", excludeFromFileList>}
// CHECK: sv.verbatim "" {output_file = #hw.output_file<"'dut.conf'", excludeFromFileList>}
}
// -----
// CHECK-LABEL: firrtl.circuit "OneMemory"
firrtl.circuit "OneMemory" {
firrtl.module @OneMemory() {
@ -127,9 +139,11 @@ firrtl.circuit "OneMemory" {
}
firrtl.memmodule @MWrite_ext(in W0_addr: !firrtl.uint<4>, in W0_en: !firrtl.uint<1>, in W0_clk: !firrtl.clock, in W0_data: !firrtl.uint<42>, in user_input: !firrtl.uint<5>) attributes {dataWidth = 42 : ui32, depth = 12 : ui64, extraPorts = [{direction = "input", name = "user_input", width = 5 : ui32}], maskBits = 1 : ui32, numReadPorts = 0 : ui32, numReadWritePorts = 0 : ui32, numWritePorts = 1 : ui32, readLatency = 1 : ui32, writeLatency = 1 : ui32}
// CHECK: "[\0A {\0A \22module_name\22: \22MWrite_ext\22,\0A \22depth\22: 12,\0A \22width\22: 42,\0A \22masked\22: false,\0A \22read\22: 0,\0A \22write\22: 1,\0A \22readwrite\22: 0,\0A \22extra_ports\22: [\0A {\0A \22name\22: \22user_input\22,\0A \22direction\22: \22input\22,\0A \22width\22: 5\0A }\0A ],\0A \22hierarchy\22: [\0A \22OneMemory.MWrite_ext\22\0A ]\0A }\0A]"
// CHECK: sv.verbatim "name MWrite_ext depth 12 width 42 ports write\0A" {output_file = #hw.output_file<"\22dut.conf\22"
// CHECK: sv.verbatim "name MWrite_ext depth 12 width 42 ports write\0A" {output_file = #hw.output_file<"'dut.conf'"
}
// -----
// CHECK-LABEL: firrtl.circuit "DualReadsSMem"
firrtl.circuit "DualReadsSMem" {
firrtl.module @DualReadsSMem() {
@ -138,9 +152,11 @@ firrtl.circuit "DualReadsSMem" {
firrtl.memmodule @DualReads_ext(in R0_addr: !firrtl.uint<4>, in R0_en: !firrtl.uint<1>, in R0_clk: !firrtl.clock, in R0_data: !firrtl.uint<42>, in R1_addr: !firrtl.uint<4>, in R1_en: !firrtl.uint<1>, in R1_clk: !firrtl.clock, in R1_data: !firrtl.uint<42>, in W0_addr: !firrtl.uint<4>, in W0_en: !firrtl.uint<1>, in W0_clk: !firrtl.clock, in W0_data: !firrtl.uint<42>) attributes {dataWidth = 42 : ui32, depth = 12 : ui64, extraPorts = [], maskBits = 1 : ui32, numReadPorts = 2 : ui32, numReadWritePorts = 0 : ui32, numWritePorts = 1 : ui32, readLatency = 1 : ui32, writeLatency = 1 : ui32}
// CHECK: sv.verbatim "[\0A {\0A \22module_name\22: \22DualReads_ext\22,\0A \22depth\22: 12,\0A \22width\22: 42,\0A \22masked\22: false,\0A \22read\22: 2,\0A \22write\22: 1,\0A \22readwrite\22: 0,\0A \22extra_ports\22: [],\0A \22hierarchy\22: [\0A \22DualReadsSMem.DualReads_ext\22\0A ]\0A }\0A]"
// CHECK: {output_file = #hw.output_file<"metadata{{/|\\\\}}seq_mems.json", excludeFromFileList>}
// CHECK: sv.verbatim "name DualReads_ext depth 12 width 42 ports write,read,read\0A" {output_file = #hw.output_file<"\22dut.conf\22"
// CHECK: sv.verbatim "name DualReads_ext depth 12 width 42 ports write,read,read\0A" {output_file = #hw.output_file<"'dut.conf'"
}
// -----
// CHECK-LABEL: firrtl.circuit "top"
firrtl.circuit "top" {
firrtl.module @top() {
@ -169,5 +185,5 @@ firrtl.circuit "top" {
// CHECK: sv.verbatim "[\0A {\0A \22module_name\22: \22memory_ext\22,\0A \22depth\22: 16,\0A \22width\22: 8,\0A \22masked\22: false,\0A \22read\22: 1,\0A \22write\22: 0,\0A \22readwrite\22: 1,\0A \22extra_ports\22: [],\0A \22hierarchy\22: [\0A \22DUT.mem1.memory_ext\22\0A ]\0A },\0A {\0A \22module_name\22: \22dumm_ext\22,\0A \22depth\22: 20,\0A \22width\22: 5,\0A \22masked\22: false,\0A \22read\22: 1,\0A \22write\22: 1,\0A \22readwrite\22: 0,\0A \22extra_ports\22: [],\0A \22hierarchy\22: [\0A \22DUT.mem1.dumm_ext\22\0A ]\0A }\0A]"
// CHECK-SAME: output_file = #hw.output_file<"metadata{{/|\\\\}}seq_mems.json", excludeFromFileList>
// CHECK: sv.verbatim "name head_ext depth 20 width 5 ports write\0Aname head_0_ext depth 20 width 5 ports write\0Aname memory_ext depth 16 width 8 ports read,rw\0Aname dumm_ext depth 20 width 5 ports write,read\0A"
// CHECK-SAME: {output_file = #hw.output_file<"\22dut.conf\22", excludeFromFileList>}
// CHECK-SAME: {output_file = #hw.output_file<"'dut.conf'", excludeFromFileList>}
}