From c8723f40b15218025216db90fd4cc16d6e9eacfd Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Sun, 30 Jul 2023 13:17:26 -0700 Subject: [PATCH] Macrocompiler: FIRRTL-elab macros 1-at-a-time Elaborating all macros in a single Circuit with an arbitrary (last) macro selected as the circuit main main cause some macros to be dropped, even with the DCEAnnotation. Work around this for now by elaborating each module in the macrocompiled circuit independently, then concatenating the verilog. --- .../barstools/macros/MacroCompiler.scala | 39 +++++++++++++------ 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/src/main/scala/barstools/macros/MacroCompiler.scala b/src/main/scala/barstools/macros/MacroCompiler.scala index 968e6b30..baed8411 100644 --- a/src/main/scala/barstools/macros/MacroCompiler.scala +++ b/src/main/scala/barstools/macros/MacroCompiler.scala @@ -14,7 +14,6 @@ import firrtl.ir._ import firrtl.options.Dependency import firrtl.stage.TransformManager.TransformDependency import firrtl.stage.{FirrtlSourceAnnotation, FirrtlStage, Forms, OutputFileAnnotation, RunFirrtlTransformAnnotation} -import firrtl.transforms.NoDCEAnnotation import firrtl.{PrimOps, _} import mdf.macrolib.{PolarizedPort, PortPolarity, SRAMCompiler, SRAMGroup, SRAMMacro} @@ -898,16 +897,34 @@ object MacroCompiler extends App { val macroCompiled = (new MacroCompilerTransform).execute(macroCompilerInput) // Run FIRRTL compiler - (new FirrtlStage).execute( - Array.empty, - Seq( - OutputFileAnnotation(params.getOrElse(Verilog, "")), - RunFirrtlTransformAnnotation(new VerilogEmitter), - EmitCircuitAnnotation(classOf[VerilogEmitter]), - NoDCEAnnotation, - FirrtlSourceAnnotation(macroCompiled.circuit.serialize) - ) - ) + // For each generated module, have to create a new circuit with that module + // as top, and all other modules as ExtModules. This guarantees all modules + // are elaborated + val verilog = macroCompiled.circuit.modules + .map(_.name) + .map { macroName => + val (mainMod, otherMods) = macroCompiled.circuit.modules.partition(_.name == macroName) + val extMods = otherMods.map(m => ExtModule(NoInfo, m.name, m.ports, m.name, Nil)) + + val circuit = Circuit(NoInfo, mainMod ++ extMods, macroName) + (new FirrtlStage) + .execute( + Array.empty, + Seq( + RunFirrtlTransformAnnotation(new VerilogEmitter), + EmitCircuitAnnotation(classOf[VerilogEmitter]), + FirrtlSourceAnnotation(circuit.serialize) + ) + ) + .collect { case c: EmittedVerilogCircuitAnnotation => c } + .head + .value + .value + } + .mkString("\n") + val verilogWriter = new FileWriter(new File(params.get(Verilog).get)) + verilogWriter.write(verilog) + verilogWriter.close() params.get(HammerIR) match { case Some(hammerIRFile: String) =>