summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSchuyler Eldridge2019-01-11 15:55:59 -0500
committerSchuyler Eldridge2019-05-22 16:17:17 -0400
commit325e48809587fdf47d398578a1d94f856ab1f275 (patch)
tree8607f572ea9532de7487a169a3d5694804dbf5a5 /src
parent4c48d5a94f9242f471e4c1ad39c664c672eafe13 (diff)
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 <schuyler.eldridge@ibm.com> Co-Authored-By: chick <chick@qrhino.com> Signed-off-by: Schuyler Eldridge <schuyler.eldridge@ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/chisel3/stage/phases/Convert.scala41
-rw-r--r--src/test/scala/chiselTests/stage/phases/ConvertSpec.scala62
2 files changed, 103 insertions, 0 deletions
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]))
+ }
+
+}