diff --git a/lib/Conversion/FIRRTLToHW/LowerToHW.cpp b/lib/Conversion/FIRRTLToHW/LowerToHW.cpp index 53fa31878724..3e56fa7fde9c 100644 --- a/lib/Conversion/FIRRTLToHW/LowerToHW.cpp +++ b/lib/Conversion/FIRRTLToHW/LowerToHW.cpp @@ -268,6 +268,11 @@ struct CircuitLoweringState { return it != oldToNewModuleMap.end() ? it->second : nullptr; } + Operation *getOldModule(Operation *newModule) { + auto it = newToOldModuleMap.find(newModule); + return it != newToOldModuleMap.end() ? it->second : nullptr; + } + // Process remaining annotations and emit warnings on unprocessed annotations // still remaining in the annoSet. void processRemainingAnnotations(Operation *op, const AnnotationSet &annoSet); @@ -299,8 +304,11 @@ struct CircuitLoweringState { // Return true if this module is the DUT or is instantiated by the DUT. // Returns false if the module is not instantiated by the DUT or is - // instantiated under a bind. + // instantiated under a bind. This will accept either an old FIRRTL module or + // a new HW module. bool isInDUT(igraph::ModuleOpInterface child) { + if (auto hwModule = dyn_cast(child.getOperation())) + child = cast(getOldModule(hwModule)); return dutModules.contains(child); } @@ -330,14 +338,18 @@ struct CircuitLoweringState { CircuitLoweringState(const CircuitLoweringState &) = delete; void operator=(const CircuitLoweringState &) = delete; + /// Mapping of FModuleOp to HWModuleOp DenseMap oldToNewModuleMap; + /// Mapping of HWModuleOp to FModuleOp + DenseMap newToOldModuleMap; + /// Cache of module symbols. We need to test hirarchy-based properties to /// lower annotaitons. InstanceGraph &instanceGraph; - /// The set of modules that are instantiated under the DUT. This is - /// precomputed as a module being under the DUT may rely on knowledge of + /// The set of old FIRRTL modules that are instantiated under the DUT. This + /// is precomputed as a module being under the DUT may rely on knowledge of /// properties of the instance and is not suitable for querying in the /// parallel execution region of this pass when the backing instances may /// already be erased. @@ -599,6 +611,7 @@ void FIRRTLModuleLowering::runOnOperation() { return failure(); state.oldToNewModuleMap[&op] = loweredMod; + state.newToOldModuleMap[loweredMod] = &op; modulesToProcess.push_back(loweredMod); // Lower all the alias types. module.walk([&](Operation *op) { @@ -616,6 +629,7 @@ void FIRRTLModuleLowering::runOnOperation() { if (!loweredMod) return failure(); state.oldToNewModuleMap[&op] = loweredMod; + state.newToOldModuleMap[loweredMod] = &op; return success(); }) .Case([&](auto memModule) { @@ -624,6 +638,7 @@ void FIRRTLModuleLowering::runOnOperation() { if (!loweredMod) return failure(); state.oldToNewModuleMap[&op] = loweredMod; + state.newToOldModuleMap[loweredMod] = &op; return success(); }) .Default([&](Operation *op) { diff --git a/test/Conversion/FIRRTLToHW/lower-to-hw.mlir b/test/Conversion/FIRRTLToHW/lower-to-hw.mlir index 5878d8640004..7f3bc3ad86cc 100644 --- a/test/Conversion/FIRRTLToHW/lower-to-hw.mlir +++ b/test/Conversion/FIRRTLToHW/lower-to-hw.mlir @@ -1593,6 +1593,7 @@ firrtl.circuit "Directories" attributes { // CHECK: hw.module private @BoundUnderDUT // CHECK-SAME: output_file = #hw.output_file<"testbench{{/|\\\\}}" firrtl.module private @BoundUnderDUT() {} + // CHECK: hw.module private @DUT firrtl.module private @DUT() attributes { annotations = [ { @@ -1601,7 +1602,28 @@ firrtl.circuit "Directories" attributes { ] } { firrtl.instance boundUnderDUT {lowerToBind} @BoundUnderDUT() + // Memories in the DUT shouldn't be moved into the testbench. + // See: https://github.com/llvm/circt/issues/6775 + // CHECK: seq.firmem + // CHECK-NOT: output_file + %mem_r = firrtl.mem Undefined { + depth = 2 : i64, + name = "mem", + portNames = ["r"], + prefix = "", + readLatency = 1 : i32, + writeLatency = 1 : i32 + } : !firrtl.bundle, en: uint<1>, clk: clock, data flip: uint<32>> + %c0_clock = firrtl.specialconstant 0 : !firrtl.clock + %0 = firrtl.subfield %mem_r[clk] : !firrtl.bundle, en: uint<1>, clk: clock, data flip: uint<32>> + firrtl.strictconnect %0, %c0_clock : !firrtl.clock + %c0_ui1 = firrtl.constant 0 : !firrtl.uint<1> + %1 = firrtl.subfield %mem_r[en] : !firrtl.bundle, en: uint<1>, clk: clock, data flip: uint<32>> + firrtl.strictconnect %1, %c0_ui1 : !firrtl.uint<1> + %2 = firrtl.subfield %mem_r[addr] : !firrtl.bundle, en: uint<1>, clk: clock, data flip: uint<32>> + firrtl.strictconnect %2, %c0_ui1 : !firrtl.uint<1> } + // CHECK: hw.module @Directories firrtl.module @Directories() { firrtl.instance dut @DUT() firrtl.instance dut_A @Directories_A()