From e8edc8f6207ac5a4a0d1d5811045927aac553e4e Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Mon, 1 Jul 2024 14:41:11 -0700 Subject: [PATCH] Add ChiselStage.emitCHIRRTLFile (#4232) Emits a file without returning the serialized object which is more memory efficient and supports > 2 GiB of serialized FIRRTL text. --- src/main/scala/circt/stage/ChiselStage.scala | 17 +++++++++++- .../circtTests/stage/ChiselStageSpec.scala | 26 ++++++++++++++++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/main/scala/circt/stage/ChiselStage.scala b/src/main/scala/circt/stage/ChiselStage.scala index 44e2855b55..991fbccb74 100644 --- a/src/main/scala/circt/stage/ChiselStage.scala +++ b/src/main/scala/circt/stage/ChiselStage.scala @@ -91,6 +91,21 @@ object ChiselStage { circuitAnno.get.emitLazily(inFileAnnos).mkString } + /** Elaborates a Chisel circuit and emits it to a file + * + * @param gen a call-by-name Chisel module + * @param args additional command line arguments to pass to Chisel + */ + def emitCHIRRTLFile( + gen: => RawModule, + args: Array[String] = Array.empty + ): AnnotationSeq = { + (new circt.stage.ChiselStage).execute( + Array("--target", "chirrtl") ++ args, + Seq(ChiselGeneratorAnnotation(() => gen)) + ) + } + /** Return a CHIRRTL circuit for a Chisel module * * @param gen a call-by-name Chisel module @@ -186,7 +201,7 @@ object ChiselStage { gen: => RawModule, args: Array[String] = Array.empty, firtoolOpts: Array[String] = Array.empty - ) = + ): AnnotationSeq = (new circt.stage.ChiselStage).execute( Array("--target", "systemverilog") ++ args, Seq(ChiselGeneratorAnnotation(() => gen)) ++ firtoolOpts.map(FirtoolOption(_)) diff --git a/src/test/scala/circtTests/stage/ChiselStageSpec.scala b/src/test/scala/circtTests/stage/ChiselStageSpec.scala index f21712e9fa..eb937f5126 100644 --- a/src/test/scala/circtTests/stage/ChiselStageSpec.scala +++ b/src/test/scala/circtTests/stage/ChiselStageSpec.scala @@ -2,7 +2,7 @@ package circtTests.stage -import chisel3.stage.ChiselGeneratorAnnotation +import chisel3.stage.{ChiselGeneratorAnnotation, CircuitSerializationAnnotation} import chisel3.experimental.SourceLine import circt.stage.{ChiselStage, FirtoolOption, PreserveAggregate} @@ -1060,6 +1060,30 @@ class ChiselStageSpec extends AnyFunSpec with Matchers with chiselTests.Utils { } + it("should emit CHIRRTL files") { + val targetDir = new File("test_run_dir/ChiselStageSpec/emitCHIRRTLFile") + + val args: Array[String] = Array( + "--target-dir", + targetDir.toString + ) + + // Should we be returning the CircuitSerializationAnnotation? It's consistent with emitSystemVerilogFile to do so. + ChiselStage + .emitCHIRRTLFile( + new ChiselStageSpec.Bar, + args + ) + .collectFirst { + case CircuitSerializationAnnotation(_, filename, _) => filename + } + .get should be("Bar") + + val expectedOutput = new File(targetDir, "Bar.fir") + expectedOutput should (exist) + info(s"'$expectedOutput' exists") + } + it("should emit FIRRTL dialect") { ChiselStage.emitFIRRTLDialect(new ChiselStageSpec.Foo) should include(" firrtl.module")