From 325e48809587fdf47d398578a1d94f856ab1f275 Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Fri, 11 Jan 2019 15:55:59 -0500 Subject: Add chisel3.stage.phases.Convert Phase This coalesces three distinct operations into one Convert Phase: 1. Chisel Circuit to FIRRTL Circuit (CHIRRTL) conversion 2. Conversion of Chisel Annotations to FIRRTL Annotations 3. Generation of RunFirrtlTransformAnnotations Co-Authored-By: Schuyler Eldridge Co-Authored-By: chick Signed-off-by: Schuyler Eldridge --- src/main/scala/chisel3/stage/phases/Convert.scala | 41 ++++++++++++++ .../chiselTests/stage/phases/ConvertSpec.scala | 62 ++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 src/main/scala/chisel3/stage/phases/Convert.scala create mode 100644 src/test/scala/chiselTests/stage/phases/ConvertSpec.scala (limited to 'src') diff --git a/src/main/scala/chisel3/stage/phases/Convert.scala b/src/main/scala/chisel3/stage/phases/Convert.scala new file mode 100644 index 00000000..174030ae --- /dev/null +++ b/src/main/scala/chisel3/stage/phases/Convert.scala @@ -0,0 +1,41 @@ +// See LICENSE for license details. + +package chisel3.stage.phases + +import chisel3.experimental.RunFirrtlTransform +import chisel3.internal.firrtl.Converter +import chisel3.stage.ChiselCircuitAnnotation + +import firrtl.{AnnotationSeq, Transform} +import firrtl.options.Phase +import firrtl.stage.{FirrtlCircuitAnnotation, RunFirrtlTransformAnnotation} + +/** This prepares a [[ChiselCircuitAnnotation]] for compilation with FIRRTL. This does three things: + * - Uses [[chisel3.internal.firrtl.Converter]] to generate a [[FirrtlCircuitAnnotation]] + * - Extracts all [[firrtl.annotations.Annotation]]s from the [[chisel3.internal.firrtl.Circuit]] + * - Generates any needed [[RunFirrtlTransformAnnotation]]s from extracted [[firrtl.annotations.Annotation]]s + */ +class Convert extends Phase { + + def transform(annotations: AnnotationSeq): AnnotationSeq = annotations.flatMap { + case a: ChiselCircuitAnnotation => { + /* Convert this Chisel Circuit to a FIRRTL Circuit */ + Some(FirrtlCircuitAnnotation(Converter.convert(a.circuit))) ++ + /* Convert all Chisel Annotations to FIRRTL Annotations */ + a + .circuit + .annotations + .map(_.toFirrtl) ++ + /* Add requested FIRRTL Transforms for any Chisel Annotations which mixed in RunFirrtlTransform */ + a + .circuit + .annotations + .collect { case b: RunFirrtlTransform => b.transformClass } + .distinct + .filterNot(_ == classOf[firrtl.Transform]) + .map { c: Class[_ <: Transform] => RunFirrtlTransformAnnotation(c.newInstance()) } + } + case a => Some(a) + } + +} diff --git a/src/test/scala/chiselTests/stage/phases/ConvertSpec.scala b/src/test/scala/chiselTests/stage/phases/ConvertSpec.scala new file mode 100644 index 00000000..30fad4f5 --- /dev/null +++ b/src/test/scala/chiselTests/stage/phases/ConvertSpec.scala @@ -0,0 +1,62 @@ +// See LICENSE for license details. + +package chiselTests.stage.phases + +import org.scalatest.{FlatSpec, Matchers} + +import chisel3._ +import chisel3.experimental.{ChiselAnnotation, RawModule, RunFirrtlTransform} +import chisel3.stage.ChiselGeneratorAnnotation +import chisel3.stage.phases.{Convert, Elaborate} + +import firrtl.{AnnotationSeq, CircuitForm, CircuitState, Transform, UnknownForm} +import firrtl.annotations.{Annotation, NoTargetAnnotation} +import firrtl.options.Phase +import firrtl.stage.{FirrtlCircuitAnnotation, RunFirrtlTransformAnnotation} + +class ConvertSpecFirrtlTransform extends Transform { + def inputForm: CircuitForm = UnknownForm + def outputForm: CircuitForm = UnknownForm + def execute(state: CircuitState): CircuitState = state +} + +case class ConvertSpecFirrtlAnnotation(name: String) extends NoTargetAnnotation + +case class ConvertSpecChiselAnnotation(name: String) extends ChiselAnnotation with RunFirrtlTransform { + def toFirrtl: Annotation = ConvertSpecFirrtlAnnotation(name) + def transformClass: Class[_ <: Transform] = classOf[ConvertSpecFirrtlTransform] +} + +class ConvertSpecFoo extends RawModule { + override val desiredName: String = "foo" + + val in = IO(Input(Bool())) + val out = IO(Output(Bool())) + + experimental.annotate(ConvertSpecChiselAnnotation("bar")) +} + +class ConvertSpec extends FlatSpec with Matchers { + + class Fixture { val phase: Phase = new Convert } + + behavior of classOf[Convert].toString + + it should "convert a Chisel Circuit to a FIRRTL Circuit" in new Fixture { + val annos: AnnotationSeq = Seq(ChiselGeneratorAnnotation(() => new ConvertSpecFoo)) + + val annosx = Seq(new Elaborate, phase) + .foldLeft(annos)( (a, p) => p.transform(a) ) + + info("FIRRTL circuit generated") + annosx.collect{ case a: FirrtlCircuitAnnotation => a.circuit.main }.toSeq should be (Seq("foo")) + + info("FIRRTL annotations generated") + annosx.collect{ case a: ConvertSpecFirrtlAnnotation => a.name }.toSeq should be (Seq("bar")) + + info("FIRRTL transform annotations generated") + annosx.collect{ case a: RunFirrtlTransformAnnotation => a.transform.getClass} + .toSeq should be (Seq(classOf[ConvertSpecFirrtlTransform])) + } + +} -- cgit v1.2.3