From 8b8080a97ce30ca22b0da41dd16ac3a14b23cb56 Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Mon, 21 Oct 2019 10:24:45 -0400 Subject: Deprecate Driver methods in favor of ChiselStage Signed-off-by: Schuyler Eldridge --- src/main/scala/chisel3/Driver.scala | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src') diff --git a/src/main/scala/chisel3/Driver.scala b/src/main/scala/chisel3/Driver.scala index 28ed49ed..571fff60 100644 --- a/src/main/scala/chisel3/Driver.scala +++ b/src/main/scala/chisel3/Driver.scala @@ -82,6 +82,7 @@ case class ChiselExecutionSuccess( */ case class ChiselExecutionFailure(message: String) extends ChiselExecutionResult +@deprecated("Please switch to chisel3.stage.ChiselStage. Driver will be removed in 3.4.", "3.2.4") object Driver extends BackendCompilationUtilities { /** @@ -90,6 +91,7 @@ object Driver extends BackendCompilationUtilities { * @param gen A function that creates a Module hierarchy. * @return The resulting Chisel IR in the form of a Circuit. (TODO: Should be FIRRTL IR) */ + @deprecated("Use ChiselStage.elaborate or use a ChiselStage class. This will be removed in 3.4.", "3.2.4") def elaborate[T <: RawModule](gen: () => T): Circuit = internal.Builder.build(Module(gen()))._1 /** @@ -97,6 +99,7 @@ object Driver extends BackendCompilationUtilities { * * @param ir Chisel IR Circuit, generated e.g. by elaborate(). */ + @deprecated("Use ChiselStage.convert or use a ChiselStage class. This will be removed in 3.4.", "3.2.4") def toFirrtl(ir: Circuit): firrtl.ir.Circuit = Converter.convert(ir) /** @@ -105,6 +108,7 @@ object Driver extends BackendCompilationUtilities { * * @param gen A function that creates a Module hierarchy. */ + @deprecated("Use (new chisel3.stage.ChiselStage).emitChirrtl. This will be removed in 3.4.", "3.2.2") def emit[T <: RawModule](gen: () => T): String = Driver.emit(elaborate(gen)) /** @@ -112,6 +116,7 @@ object Driver extends BackendCompilationUtilities { * * @param ir Chisel IR Circuit, generated e.g. by elaborate(). */ + @deprecated("Use (new chisel3.stage.ChiselStage).emitChirrtl", "3.2.2") def emit[T <: RawModule](ir: Circuit): String = Emitter.emit(ir) /** @@ -120,6 +125,7 @@ object Driver extends BackendCompilationUtilities { * @param gen A function that creates a Module hierarchy. * @return A String containing the design in Verilog. */ + @deprecated("Use (new chisel3.stage.ChiselStage).emitVerilog. This will be removed in 3.4.", "3.2.2") def emitVerilog[T <: RawModule](gen: => T): String = { execute(Array[String](), { () => gen }) match { case ChiselExecutionSuccess(_, _, Some(firrtl.FirrtlExecutionSuccess(_, verilog))) => verilog @@ -137,6 +143,7 @@ object Driver extends BackendCompilationUtilities { * @param optName File to dump to. If unspecified, defaults to ".fir". * @return The File the circuit was dumped to. */ + @deprecated("Migrate to chisel3.stage.ChiselStage. This will be removed in 3.4.", "3.2.4") def dumpFirrtl(ir: Circuit, optName: Option[File]): File = { val f = optName.getOrElse(new File(ir.name + ".fir")) val w = new FileWriter(f) @@ -151,6 +158,7 @@ object Driver extends BackendCompilationUtilities { * @param ir The circuit containing annotations to be emitted * @param optName An optional filename (will use s"\${ir.name}.json" otherwise) */ + @deprecated("Migrate to chisel3.stage.ChiselStage. This will be removed in 3.4.", "3.2.4") def dumpAnnotations(ir: Circuit, optName: Option[File]): File = { val f = optName.getOrElse(new File(ir.name + ".anno.json")) val w = new FileWriter(f) @@ -169,6 +177,7 @@ object Driver extends BackendCompilationUtilities { * @param optFile Optional File to dump to. If unspecified, defaults to ".pb". * @return The File the circuit was dumped to. */ + @deprecated("Migrate to chisel3.stage.ChiselStage. This will be removed in 3.4.", "3.2.4") def dumpProto(c: Circuit, optFile: Option[File]): File = { val f = optFile.getOrElse(new File(c.name + ".pb")) val ostream = new java.io.FileOutputStream(f) @@ -179,6 +188,7 @@ object Driver extends BackendCompilationUtilities { } private var target_dir: Option[String] = None + @deprecated("Use chisel3.stage.ChiselStage with '--target-directory'. This will be removed in 3.4.", "3.2.2") def parseArgs(args: Array[String]): Unit = { for (i <- 0 until args.size) { if (args(i) == "--targetDir") { @@ -187,6 +197,7 @@ object Driver extends BackendCompilationUtilities { } } + @deprecated("This has no effect on Chisel3 Driver! This will be removed in 3.4.", "3.2.2") def targetDir(): String = { target_dir getOrElse new File(".").getCanonicalPath } /** @@ -196,6 +207,7 @@ object Driver extends BackendCompilationUtilities { * @param dut The device under test * @return An execution result with useful stuff, or failure with message */ + @deprecated("Use chisel3.stage.ChiselStage.execute. This will be removed in 3.4.", "3.2.2") def execute( // scalastyle:ignore method.length optionsManager: ExecutionOptionsManager with HasChiselExecutionOptions with HasFirrtlOptions, dut: () => RawModule): ChiselExecutionResult = { @@ -241,6 +253,7 @@ object Driver extends BackendCompilationUtilities { * @param dut The device under test * @return An execution result with useful stuff, or failure with message */ + @deprecated("Use chisel3.stage.ChiselStage.execute. This will be removed in 3.4.", "3.2.2") def execute(args: Array[String], dut: () => RawModule): ChiselExecutionResult = { val optionsManager = new ExecutionOptionsManager("chisel3") with HasChiselExecutionOptions with HasFirrtlOptions @@ -259,6 +272,7 @@ object Driver extends BackendCompilationUtilities { * * @param args unused args */ + @deprecated("Use chisel3.stage.ChiselMain. This will be removed in 3.4.", "3.2.2") def main(args: Array[String]) { execute(Array("--help"), null) } -- cgit v1.2.3 From 1c18667136d39b2005c83cb58d8c8f017fc11808 Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Tue, 24 Mar 2020 13:24:15 -0400 Subject: Add helper methods to ChiselStage for Driver migration This adds three new methods to ChiselStage to replace deprecated methods in the Driver for converting a Chisel circuit to a string: - emitChirrtl - emitFirrtl - emitVerilog This also adds a ChiselStage companion object that lets you generated a Chisel Circuit or a FIRRTL Circuit from a Chisel module: - elaborate - convert Signed-off-by: Schuyler Eldridge squash! Add string emission helper methods to ChiselStage --- src/main/scala/chisel3/stage/ChiselStage.scala | 113 ++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/main/scala/chisel3/stage/ChiselStage.scala b/src/main/scala/chisel3/stage/ChiselStage.scala index 99484425..ea40e92b 100644 --- a/src/main/scala/chisel3/stage/ChiselStage.scala +++ b/src/main/scala/chisel3/stage/ChiselStage.scala @@ -2,18 +2,20 @@ package chisel3.stage -import firrtl.AnnotationSeq +import firrtl.{ir => fir, AnnotationSeq, EmittedFirrtlCircuitAnnotation, EmittedVerilogCircuitAnnotation} +import firrtl.annotations.DeletedAnnotation import firrtl.options.{Dependency, Phase, PhaseManager, PreservesAll, Shell, Stage, StageError, StageMain} import firrtl.options.phases.DeletedWrapper -import firrtl.stage.FirrtlCli +import firrtl.stage.{FirrtlCircuitAnnotation, FirrtlCli} import firrtl.options.Viewer.view -import chisel3.ChiselException -import chisel3.internal.ErrorLog +import chisel3.{ChiselException, RawModule} +import chisel3.internal.{firrtl => cir, ErrorLog} import java.io.{StringWriter, PrintWriter} class ChiselStage extends Stage with PreservesAll[Phase] { + val shell: Shell = new Shell("chisel") with ChiselCli with FirrtlCli val targets: Seq[Dependency[Phase]] = @@ -47,6 +49,109 @@ class ChiselStage extends Stage with PreservesAll[Phase] { throw new StageError() } + /** Convert a Chisel module to a CHIRRTL string + * @param gen a call-by-name Chisel module + * @param args additional command line arguments to pass to Chisel + * param annotations additional annotations to pass to Chisel + * @return a string containing the Verilog output + */ + final def emitChirrtl( + gen: => RawModule, + args: Array[String] = Array.empty, + annotations: AnnotationSeq = Seq.empty): String = { + + execute(Array("-X", "none") ++ args, ChiselGeneratorAnnotation(() => gen) +: annotations) + .collectFirst { + case DeletedAnnotation(_, EmittedFirrtlCircuitAnnotation(a)) => a + } + .get + .value + + } + + /** Convert a Chisel module to a FIRRTL string + * @param gen a call-by-name Chisel module + * @param args additional command line arguments to pass to Chisel + * param annotations additional annotations to pass to Chisel + * @return a string containing the Verilog output + */ + final def emitFirrtl( + gen: => RawModule, + args: Array[String] = Array.empty, + annotations: AnnotationSeq = Seq.empty): String = { + + execute(Array("-X", "high") ++ args, ChiselGeneratorAnnotation(() => gen) +: annotations) + .collectFirst { + case DeletedAnnotation(_, EmittedFirrtlCircuitAnnotation(a)) => a + } + .get + .value + + } + + /** Convert a Chisel module to Verilog + * @param gen a call-by-name Chisel module + * @param args additional command line arguments to pass to Chisel + * param annotations additional annotations to pass to Chisel + * @return a string containing the Verilog output + */ + final def emitVerilog( + gen: => RawModule, + args: Array[String] = Array.empty, + annotations: AnnotationSeq = Seq.empty): String = { + + execute(Array("-X", "verilog") ++ args, ChiselGeneratorAnnotation(() => gen) +: annotations) + .collectFirst { + case DeletedAnnotation(_, EmittedVerilogCircuitAnnotation(a)) => a + } + .get + .value + } + } object ChiselMain extends StageMain(new ChiselStage) + +/** Helper methods for working with [[ChiselStage]] */ +object ChiselStage { + + /** Return a Chisel circuit for a Chisel module + * @param gen a call-by-name Chisel module + */ + def elaborate(gen: => RawModule): cir.Circuit = { + val stage = new ChiselStage { + override val targets = Seq( Dependency[chisel3.stage.phases.Checks], + Dependency[chisel3.stage.phases.Elaborate] ) + } + + stage + .execute(Array("--no-run-firrtl"), Seq(ChiselGeneratorAnnotation(() => gen))) + .collectFirst { + case ChiselCircuitAnnotation(a) => a + } + .get + } + + /** Return a CHIRRTL circuit for a Chisel module + * @param gen a call-by-name Chisel module + */ + def convert(gen: => RawModule): fir.Circuit = { + val stage = new ChiselStage { + override val targets = Seq( + Dependency[chisel3.stage.phases.Checks], + Dependency[chisel3.stage.phases.Elaborate], + Dependency[chisel3.stage.phases.AddImplicitOutputFile], + Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile], + Dependency[chisel3.stage.phases.MaybeAspectPhase], + Dependency[chisel3.stage.phases.Convert] ) + } + + stage + .execute(Array("--no-run-firrtl"), Seq(ChiselGeneratorAnnotation(() => gen))) + .collectFirst { + case FirrtlCircuitAnnotation(a) => a + } + .get + } + +} -- cgit v1.2.3 From 693e6ad61f5ad8e84ade2a51ebd7e23ad69587bb Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Tue, 24 Mar 2020 13:25:24 -0400 Subject: Add ChiselStageSpec for string/circuit emission Signed-off-by: Schuyler Eldridge --- .../scala/chiselTests/stage/ChiselStageSpec.scala | 59 ++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/test/scala/chiselTests/stage/ChiselStageSpec.scala (limited to 'src') diff --git a/src/test/scala/chiselTests/stage/ChiselStageSpec.scala b/src/test/scala/chiselTests/stage/ChiselStageSpec.scala new file mode 100644 index 00000000..b14d79a1 --- /dev/null +++ b/src/test/scala/chiselTests/stage/ChiselStageSpec.scala @@ -0,0 +1,59 @@ +// See LICENSE for license details. + +package chiselTests.stage + +import chisel3._ +import chisel3.stage.ChiselStage + +import org.scalatest.{FlatSpec, Matchers} + +object ChiselStageSpec { + + class Foo extends MultiIOModule { + val addr = IO(Input(UInt(4.W))) + val out = IO(Output(Bool())) + val bar = SyncReadMem(8, Bool()) + out := bar(addr) + } + +} + +class ChiselStageSpec extends FlatSpec with Matchers { + + import ChiselStageSpec._ + + private trait ChiselStageFixture { + val stage = new ChiselStage + } + + behavior of "ChiselStage.emitChirrtl" + + it should "return a CHIRRTL string" in new ChiselStageFixture { + stage.emitChirrtl(new Foo) should include ("infer mport") + } + + behavior of "ChiselStage.emitFirrtl" + + it should "return a High FIRRTL string" in new ChiselStageFixture { + stage.emitFirrtl(new Foo) should include ("mem bar") + } + + behavior of "ChiselStage.emitVerilog" + + it should "return a Verilog string" in new ChiselStageFixture { + stage.emitVerilog(new Foo) should include ("endmodule") + } + + behavior of "ChiselStage$.elaborate" + + it should "generate a Chisel circuit from a Chisel module" in { + ChiselStage.elaborate(new Foo) + } + + behavior of "ChiselStage$.convert" + + it should "generate a CHIRRTL circuit from a Chisel module" in { + ChiselStage.convert(new Foo) + } + +} -- cgit v1.2.3