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