From a423db5fa5a9fb106c1b0048b7dcf97fc83953b6 Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Thu, 10 Jan 2019 12:47:18 -0500 Subject: Add chisel3.stage Annotations This adds the following FIRRTL Annotations to Chisel: - NoRunFirrtlCompilerAnnotation - PrintFullStackTraceAnnotation - ChiselGeneratorAnnotation - ChiselCircuitAnnotation - ChiselOutputFileAnnotation This includes tests for ChiselGeneratorAnnotation as this Annotation is able to be constructed from a String and to elaborate itself. Co-Authored-By: Schuyler Eldridge Co-Authored-By: chick Signed-off-by: Schuyler Eldridge --- .../chiselTests/stage/ChiselAnnotationsSpec.scala | 65 ++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 src/test/scala/chiselTests/stage/ChiselAnnotationsSpec.scala (limited to 'src/test') diff --git a/src/test/scala/chiselTests/stage/ChiselAnnotationsSpec.scala b/src/test/scala/chiselTests/stage/ChiselAnnotationsSpec.scala new file mode 100644 index 00000000..c89955f2 --- /dev/null +++ b/src/test/scala/chiselTests/stage/ChiselAnnotationsSpec.scala @@ -0,0 +1,65 @@ +// See LICENSE for license details. + +package chiselTests.stage + +import org.scalatest.{FlatSpec, Matchers} + +import chisel3._ +import chisel3.stage.{ChiselCircuitAnnotation, ChiselGeneratorAnnotation} +import chisel3.experimental.RawModule + +import firrtl.options.OptionsException + +class ChiselAnnotationsSpecFoo extends RawModule { + val in = IO(Input(Bool())) + val out = IO(Output(Bool())) + out := ~in +} + +class ChiselAnnotationsSpecBaz(name: String) extends ChiselAnnotationsSpecFoo { + override val desiredName = name +} + +class ChiselAnnotationsSpecQux extends ChiselAnnotationsSpecFoo { + /* This printf requires an implicit clock and reset, but RawModule has none. This will thereby fail elaboration. */ + printf("hello") +} + +class ChiselAnnotation + +class ChiselAnnotationsSpec extends FlatSpec with Matchers { + + behavior of "ChiselGeneratorAnnotation elaboration" + + it should "elaborate to a ChiselCircuitAnnotation" in { + val annotation = ChiselGeneratorAnnotation(() => new ChiselAnnotationsSpecFoo) + annotation.elaborate shouldBe a [ChiselCircuitAnnotation] + } + + it should "throw an exception if elaboration fails" in { + val annotation = ChiselGeneratorAnnotation(() => new ChiselAnnotationsSpecQux) + intercept [ChiselException] { annotation.elaborate } + } + + behavior of "ChiselGeneratorAnnotation when stringly constructing from Module names" + + it should "elaborate from a String" in { + val annotation = ChiselGeneratorAnnotation("chiselTests.stage.ChiselAnnotationsSpecFoo") + annotation.elaborate shouldBe a [ChiselCircuitAnnotation] + } + + it should "throw an exception if elaboration from a String refers to nonexistant class" in { + val bar = "chiselTests.stage.ChiselAnnotationsSpecBar" + val annotation = ChiselGeneratorAnnotation(bar) + intercept [OptionsException] { annotation.elaborate } + .getMessage should startWith (s"Unable to locate module '$bar'") + } + + it should "throw an exception if elaboration from a String refers to an anonymous class" in { + val baz = "chiselTests.stage.ChiselAnnotationsSpecBaz" + val annotation = ChiselGeneratorAnnotation(baz) + intercept [OptionsException] { annotation.elaborate } + .getMessage should startWith (s"Unable to create instance of module '$baz'") + } + +} -- cgit v1.2.3 From 06c5e3e82f7dd4aa8ce159aa4c13b9bc36abce96 Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Fri, 1 Feb 2019 03:17:15 -0500 Subject: Add ChiselOptionsView Co-Authored-By: Schuyler Eldridge Co-Authored-By: chick Signed-off-by: Schuyler Eldridge --- .../chiselTests/stage/ChiselOptionsViewSpec.scala | 40 ++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/test/scala/chiselTests/stage/ChiselOptionsViewSpec.scala (limited to 'src/test') diff --git a/src/test/scala/chiselTests/stage/ChiselOptionsViewSpec.scala b/src/test/scala/chiselTests/stage/ChiselOptionsViewSpec.scala new file mode 100644 index 00000000..7dbeb9fa --- /dev/null +++ b/src/test/scala/chiselTests/stage/ChiselOptionsViewSpec.scala @@ -0,0 +1,40 @@ +// See LICENSE for license details. + +package chiselTests.stage + +import org.scalatest.{FlatSpec, Matchers} + +import firrtl.options.Viewer.view + +import chisel3.stage._ +import chisel3.internal.firrtl.Circuit + +class ChiselOptionsViewSpec extends FlatSpec with Matchers { + + behavior of ChiselOptionsView.getClass.getName + + it should "construct a view from an AnnotationSeq" in { + val bar = Circuit("bar", Seq.empty, Seq.empty) + val annotations = Seq( + NoRunFirrtlCompilerAnnotation, + PrintFullStackTraceAnnotation, + ChiselOutputFileAnnotation("foo"), + ChiselCircuitAnnotation(bar) + ) + val out = view[ChiselOptions](annotations) + + info("runFirrtlCompiler was set to false") + out.runFirrtlCompiler should be (false) + + info("printFullStackTrace was set to true") + out.printFullStackTrace should be (true) + + info("outputFile was set to 'foo'") + out.outputFile should be (Some("foo")) + + info("chiselCircuit was set to circuit 'bar'") + out.chiselCircuit should be (Some(bar)) + + } + +} -- cgit v1.2.3 From f447c2253081f7c2ede0658d059bc00c184312f9 Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Thu, 10 Jan 2019 13:07:21 -0500 Subject: Add chisel3.stage.phases.Checks Phase Signed-off-by: Schuyler Eldridge --- .../chiselTests/stage/phases/ChecksSpec.scala | 43 ++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/test/scala/chiselTests/stage/phases/ChecksSpec.scala (limited to 'src/test') diff --git a/src/test/scala/chiselTests/stage/phases/ChecksSpec.scala b/src/test/scala/chiselTests/stage/phases/ChecksSpec.scala new file mode 100644 index 00000000..6d01e38e --- /dev/null +++ b/src/test/scala/chiselTests/stage/phases/ChecksSpec.scala @@ -0,0 +1,43 @@ +// See LICENSE for license details. + +package chiselTests.stage.phases + +import org.scalatest.{FlatSpec, Matchers} + +import chisel3.stage.{ChiselOutputFileAnnotation, NoRunFirrtlCompilerAnnotation, PrintFullStackTraceAnnotation} +import chisel3.stage.phases.Checks + +import firrtl.AnnotationSeq +import firrtl.annotations.NoTargetAnnotation +import firrtl.options.{OptionsException, Phase} + +class ChecksSpec extends FlatSpec with Matchers { + + def checkExceptionMessage(phase: Phase, annotations: AnnotationSeq, messageStart: String): Unit = + intercept[OptionsException]{ phase.transform(annotations) }.getMessage should startWith(messageStart) + + class Fixture { val phase: Phase = new Checks } + + behavior of classOf[Checks].toString + + it should "do nothing on sane annotation sequences" in new Fixture { + val a = Seq(NoRunFirrtlCompilerAnnotation, PrintFullStackTraceAnnotation) + phase.transform(a).toSeq should be (a) + } + + it should "throw an OptionsException if more than one NoRunFirrtlCompilerAnnotation is specified" in new Fixture { + val a = Seq(NoRunFirrtlCompilerAnnotation, NoRunFirrtlCompilerAnnotation) + checkExceptionMessage(phase, a, "At most one NoRunFirrtlCompilerAnnotation") + } + + it should "throw an OptionsException if more than one PrintFullStackTraceAnnotation is specified" in new Fixture { + val a = Seq(PrintFullStackTraceAnnotation, PrintFullStackTraceAnnotation) + checkExceptionMessage(phase, a, "At most one PrintFullStackTraceAnnotation") + } + + it should "throw an OptionsException if more than one ChiselOutputFileAnnotation is specified" in new Fixture { + val a = Seq(ChiselOutputFileAnnotation("foo"), ChiselOutputFileAnnotation("bar")) + checkExceptionMessage(phase, a, "At most one Chisel output file") + } + +} -- cgit v1.2.3 From 4c48d5a94f9242f471e4c1ad39c664c672eafe13 Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Wed, 30 Jan 2019 12:06:00 -0500 Subject: Add chisel3.stage.phases.Elaborate Phase This adds an Elaborate Phase that expands ChiselGeneratorAnnotations into ChiselCircuitAnnotations and deletes the original. Co-Authored-By: Schuyler Eldridge Co-Authored-By: chick Signed-off-by: Schuyler Eldridge --- .../chiselTests/stage/phases/ElaborateSpec.scala | 46 ++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/test/scala/chiselTests/stage/phases/ElaborateSpec.scala (limited to 'src/test') diff --git a/src/test/scala/chiselTests/stage/phases/ElaborateSpec.scala b/src/test/scala/chiselTests/stage/phases/ElaborateSpec.scala new file mode 100644 index 00000000..4d99b24c --- /dev/null +++ b/src/test/scala/chiselTests/stage/phases/ElaborateSpec.scala @@ -0,0 +1,46 @@ +// See LICENSE for license details. + +package chiselTests.stage.phases + +import org.scalatest.{FlatSpec, Matchers} + +import chisel3._ +import chisel3.stage.{ChiselCircuitAnnotation, ChiselGeneratorAnnotation} +import chisel3.stage.phases.Elaborate + +import firrtl.options.Phase + +class ElaborateSpec extends FlatSpec with Matchers { + + class Foo extends Module { + override def desiredName: String = "Foo" + val io = IO( + new Bundle { + val in = Input(Bool()) + val out = Output(Bool()) + }) + + io.out := ~io.in + } + + class Bar extends Foo { + override def desiredName: String = "Bar" + } + + class Fixture { val phase: Phase = new Elaborate } + + behavior of classOf[Elaborate].toString + + it should "expand ChiselGeneratorAnnotations into ChiselCircuitAnnotations and delete originals" in new Fixture { + val annotations = Seq( ChiselGeneratorAnnotation(() => new Foo), + ChiselGeneratorAnnotation(() => new Bar) ) + val out = phase.transform(annotations) + + info("original annotations removed") + out.collect{ case a: ChiselGeneratorAnnotation => a } should be (empty) + + info("circuits created with the expected names") + out.collect{ case a: ChiselCircuitAnnotation => a.circuit.name } should be (Seq("Foo", "Bar")) + } + +} -- cgit v1.2.3 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 --- .../chiselTests/stage/phases/ConvertSpec.scala | 62 ++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/test/scala/chiselTests/stage/phases/ConvertSpec.scala (limited to 'src/test') 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 From 20ba486ab1988e57e2b2ca163c9c83e1d8904bba Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Mon, 14 Jan 2019 11:59:48 -0500 Subject: Add chisel3.stage.phases.Emitter Phase This adds an Emitter Phase that writes a ChiselCircuitAnnotation to a file if a ChiselOutputFileAnnotation is present. Signed-off-by: Schuyler Eldridge --- .../chiselTests/stage/phases/EmitterSpec.scala | 60 ++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/test/scala/chiselTests/stage/phases/EmitterSpec.scala (limited to 'src/test') diff --git a/src/test/scala/chiselTests/stage/phases/EmitterSpec.scala b/src/test/scala/chiselTests/stage/phases/EmitterSpec.scala new file mode 100644 index 00000000..63498adb --- /dev/null +++ b/src/test/scala/chiselTests/stage/phases/EmitterSpec.scala @@ -0,0 +1,60 @@ +// See LICENSE for license details. + +package chiselTests.stage.phases + +import org.scalatest.{FlatSpec, Matchers} + +import chisel3.experimental.RawModule +import chisel3.stage.{ChiselCircuitAnnotation, ChiselGeneratorAnnotation, ChiselOutputFileAnnotation} +import chisel3.stage.phases.{Convert, Elaborate, Emitter} + +import firrtl.{AnnotationSeq, EmittedFirrtlCircuitAnnotation} +import firrtl.annotations.DeletedAnnotation +import firrtl.options.{Phase, TargetDirAnnotation} + +import java.io.File + +class EmitterSpec extends FlatSpec with Matchers { + + class FooModule extends RawModule { override val desiredName = "Foo" } + class BarModule extends RawModule { override val desiredName = "Bar" } + + class Fixture { val phase: Phase = new Emitter } + + behavior of classOf[Emitter].toString + + it should "do nothing if no ChiselOutputFileAnnotations are present" in new Fixture { + val dir = new File("test_run_dir/EmitterSpec") + val annotations = (new Elaborate).transform(Seq( TargetDirAnnotation(dir.toString), + ChiselGeneratorAnnotation(() => new FooModule) )) + val annotationsx = phase.transform(annotations) + + val Seq(fooFile, barFile) = Seq("Foo.fir", "Bar.fir").map(f => new File(dir + "/" + f)) + + info(s"$fooFile does not exist") + fooFile should not (exist) + + info("annotations are unmodified") + annotationsx.toSeq should be (annotations.toSeq) + } + + it should "emit a ChiselCircuitAnnotation to a specific file" in new Fixture { + val dir = new File("test_run_dir/EmitterSpec") + val circuit = (new Elaborate) + .transform(Seq(ChiselGeneratorAnnotation(() => new BarModule))) + .collectFirst{ case a: ChiselCircuitAnnotation => a} + .get + val annotations = phase.transform(Seq( TargetDirAnnotation(dir.toString), + circuit, + ChiselOutputFileAnnotation("Baz") )) + + val bazFile = new File(dir + "/Baz.fir") + + info(s"$bazFile exists") + bazFile should (exist) + + info("a deleted EmittedFirrtlCircuitAnnotation should be generated") + annotations.collect{ case a @ DeletedAnnotation(_, _: EmittedFirrtlCircuitAnnotation) => a }.size should be (1) + } + +} -- cgit v1.2.3 From 0e6eb5b35a442edf70ad37f963526609f2ba1f3c Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Mon, 14 Jan 2019 12:20:44 -0500 Subject: Add chisel.stage.phases.AddImplicitOutputFile Signed-off-by: Schuyler Eldridge --- .../stage/phases/AddImplicitOutputFileSpec.scala | 49 ++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/test/scala/chiselTests/stage/phases/AddImplicitOutputFileSpec.scala (limited to 'src/test') diff --git a/src/test/scala/chiselTests/stage/phases/AddImplicitOutputFileSpec.scala b/src/test/scala/chiselTests/stage/phases/AddImplicitOutputFileSpec.scala new file mode 100644 index 00000000..411aa6ba --- /dev/null +++ b/src/test/scala/chiselTests/stage/phases/AddImplicitOutputFileSpec.scala @@ -0,0 +1,49 @@ +// See LICENSE for license details. + +package chiselTests.stage.phases + +import org.scalatest.{FlatSpec, Matchers} + +import chisel3.experimental.RawModule +import chisel3.stage.{ChiselGeneratorAnnotation, ChiselOutputFileAnnotation} +import chisel3.stage.phases.{AddImplicitOutputFile, Elaborate} + +import firrtl.AnnotationSeq +import firrtl.options.{Phase, StageOptions, TargetDirAnnotation} +import firrtl.options.Viewer.view + +class AddImplicitOutputFileSpec extends FlatSpec with Matchers { + + class Foo extends RawModule { override val desiredName = "Foo" } + + class Fixture { val phase: Phase = new AddImplicitOutputFile } + + behavior of classOf[AddImplicitOutputFile].toString + + it should "not override an existing ChiselOutputFileAnnotation" in new Fixture { + val annotations: AnnotationSeq = Seq( + ChiselGeneratorAnnotation(() => new Foo), + ChiselOutputFileAnnotation("Bar") ) + + Seq( new Elaborate, phase ) + .foldLeft(annotations)((a, p) => p.transform(a)) + .collect{ case a: ChiselOutputFileAnnotation => a.file } + .toSeq should be (Seq("Bar")) + } + + it should "generate a ChiselOutputFileAnnotation from a ChiselCircuitAnnotation" in new Fixture { + val annotations: AnnotationSeq = Seq( + ChiselGeneratorAnnotation(() => new Foo), + TargetDirAnnotation("test_run_dir") ) + + Seq( new Elaborate, phase ) + .foldLeft(annotations)((a, p) => p.transform(a)) + .collect{ case a: ChiselOutputFileAnnotation => a.file } + .toSeq should be (Seq("Foo")) + } + + it should "do nothing to an empty annotation sequence" in new Fixture { + phase.transform(AnnotationSeq(Seq.empty)).toSeq should be (empty) + } + +} -- cgit v1.2.3 From 121e3d87598f2056b76846472970620d046c2487 Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Mon, 14 Jan 2019 14:29:46 -0500 Subject: Add stage.phases.AddImplicitOutputAnnotationFile Co-Authored-By: Schuyler Eldridge Co-Authored-By: chick Signed-off-by: Schuyler Eldridge --- .../AddImplicitOutputAnnotationFileSpec.scala | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/test/scala/chiselTests/stage/phases/AddImplicitOutputAnnotationFileSpec.scala (limited to 'src/test') diff --git a/src/test/scala/chiselTests/stage/phases/AddImplicitOutputAnnotationFileSpec.scala b/src/test/scala/chiselTests/stage/phases/AddImplicitOutputAnnotationFileSpec.scala new file mode 100644 index 00000000..f5fe0440 --- /dev/null +++ b/src/test/scala/chiselTests/stage/phases/AddImplicitOutputAnnotationFileSpec.scala @@ -0,0 +1,42 @@ +// See LICENSE for license details. + +package chiselTests.stage.phases + +import org.scalatest.{FlatSpec, Matchers} + +import chisel3.experimental.RawModule +import chisel3.stage.ChiselGeneratorAnnotation +import chisel3.stage.phases.{AddImplicitOutputAnnotationFile, Elaborate} + +import firrtl.AnnotationSeq +import firrtl.options.{OutputAnnotationFileAnnotation, Phase} + +class AddImplicitOutputAnnotationFileSpec extends FlatSpec with Matchers { + + class Foo extends RawModule { override val desiredName = "Foo" } + + class Fixture { val phase: Phase = new AddImplicitOutputAnnotationFile } + + behavior of classOf[AddImplicitOutputAnnotationFile].toString + + it should "not override an existing OutputAnnotationFileAnnotation" in new Fixture { + val annotations: AnnotationSeq = Seq( + ChiselGeneratorAnnotation(() => new Foo), + OutputAnnotationFileAnnotation("Bar") ) + + Seq( new Elaborate, phase ) + .foldLeft(annotations)((a, p) => p.transform(a)) + .collect{ case a: OutputAnnotationFileAnnotation => a.file } + .toSeq should be (Seq("Bar")) + } + + it should "generate an OutputAnnotationFileAnnotation from a ChiselCircuitAnnotation" in new Fixture { + val annotations: AnnotationSeq = Seq( ChiselGeneratorAnnotation(() => new Foo) ) + + Seq( new Elaborate, phase ) + .foldLeft(annotations)((a, p) => p.transform(a)) + .collect{ case a: OutputAnnotationFileAnnotation => a.file } + .toSeq should be (Seq("Foo")) + } + +} -- cgit v1.2.3 From 41482912bd2216d4f95043414798120536398e54 Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Mon, 14 Jan 2019 12:35:02 -0500 Subject: Add Driver Compatibility Layer This includes phases necessary to provide backwards compatibility with the old Chisel3 Driver. These are placed in a DriverCompatibility object inside chisel3.stage.phases. The following four phases are included: - AddImplicitOutputFile (from a TopNameAnnotation) - AddImplicitOutputAnnotationFile phase - DisableFirrtlStage (to disable ChiselStage running FirrtlStage) - MutateOptionsManager (to update options after ChiselStage) - ReEnableFirrtlStage (to renable FirrtlStage if needed) Additionally, this adds a view of a ChiselExecutionResult for providing the legacy return type of the Chisel Driver. Co-Authored-By: Schuyler Eldridge Co-Authored-By: chick Signed-off-by: Schuyler Eldridge --- .../stage/phases/DriverCompatibilitySpec.scala | 70 ++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/test/scala/chisel3/stage/phases/DriverCompatibilitySpec.scala (limited to 'src/test') diff --git a/src/test/scala/chisel3/stage/phases/DriverCompatibilitySpec.scala b/src/test/scala/chisel3/stage/phases/DriverCompatibilitySpec.scala new file mode 100644 index 00000000..c478db27 --- /dev/null +++ b/src/test/scala/chisel3/stage/phases/DriverCompatibilitySpec.scala @@ -0,0 +1,70 @@ +// See LICENSE for license details. + +package chisel3.stage.phases + +import org.scalatest.{FlatSpec, Matchers} + +import chisel3.stage.{NoRunFirrtlCompilerAnnotation, ChiselOutputFileAnnotation} + +import firrtl.options.{OutputAnnotationFileAnnotation, StageOptions} +import firrtl.options.Viewer.view +import firrtl.stage.phases.DriverCompatibility.TopNameAnnotation + +class DriverCompatibilitySpec extends FlatSpec with Matchers { + + behavior of classOf[DriverCompatibility.AddImplicitOutputFile].toString + + it should "do nothing if a ChiselOutputFileAnnotation is present" in { + val annotations = Seq( + ChiselOutputFileAnnotation("Foo"), + TopNameAnnotation("Bar") ) + (new DriverCompatibility.AddImplicitOutputFile).transform(annotations).toSeq should be (annotations) + } + + it should "add a ChiselOutputFileAnnotation derived from a TopNameAnnotation" in { + val annotations = Seq( TopNameAnnotation("Bar") ) + val expected = ChiselOutputFileAnnotation("Bar") +: annotations + (new DriverCompatibility.AddImplicitOutputFile).transform(annotations).toSeq should be (expected) + } + + behavior of classOf[DriverCompatibility.AddImplicitOutputAnnotationFile].toString + + it should "do nothing if an OutputAnnotationFileAnnotation is present" in { + val annotations = Seq( + OutputAnnotationFileAnnotation("Foo"), + TopNameAnnotation("Bar") ) + (new DriverCompatibility.AddImplicitOutputAnnotationFile).transform(annotations).toSeq should be (annotations) + } + + it should "add an OutputAnnotationFileAnnotation derived from a TopNameAnnotation" in { + val annotations = Seq( TopNameAnnotation("Bar") ) + val expected = OutputAnnotationFileAnnotation("Bar") +: annotations + (new DriverCompatibility.AddImplicitOutputAnnotationFile).transform(annotations).toSeq should be (expected) + } + + behavior of classOf[DriverCompatibility.DisableFirrtlStage].toString + + it should "add a NoRunFirrtlCompilerAnnotation if one does not exist" in { + val annos = Seq(NoRunFirrtlCompilerAnnotation) + val expected = DriverCompatibility.RunFirrtlCompilerAnnotation +: annos + (new DriverCompatibility.DisableFirrtlStage).transform(Seq.empty).toSeq should be (expected) + } + + it should "NOT add a NoRunFirrtlCompilerAnnotation if one already exists" in { + val annos = Seq(NoRunFirrtlCompilerAnnotation) + (new DriverCompatibility.DisableFirrtlStage).transform(annos).toSeq should be (annos) + } + + behavior of classOf[DriverCompatibility.ReEnableFirrtlStage].toString + + it should "NOT strip a NoRunFirrtlCompilerAnnotation if NO RunFirrtlCompilerAnnotation is present" in { + val annos = Seq(NoRunFirrtlCompilerAnnotation, DriverCompatibility.RunFirrtlCompilerAnnotation) + (new DriverCompatibility.ReEnableFirrtlStage).transform(annos).toSeq should be (Seq.empty) + } + + it should "strip a NoRunFirrtlCompilerAnnotation if a RunFirrtlCompilerAnnotation is present" in { + val annos = Seq(NoRunFirrtlCompilerAnnotation) + (new DriverCompatibility.ReEnableFirrtlStage).transform(annos).toSeq should be (annos) + } + +} -- cgit v1.2.3 From 23641521174ba828feb32dc1c65c13a3d6b46970 Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Mon, 14 Jan 2019 21:01:29 -0500 Subject: Make Driver a ChiselStage compatibility layer This converts the original chisel3.Driver to use chisel3.stage.ChiselStage. This is implemented in the following way: 1. ExecutionOptions are converted to an AnnotationSeq 2. The AnnotationSeq is preprocessed using phases contained in the Chisel DriverCompatibility objects. One of these *disables* the execution of FirrtlStage by ChiselStage. 3. ChiselStage runs on the preprocessed AnnotationSeq 4. The input ExecutionOptionsManager is mutated based on the output of ChiselStage. 5. The FIRRTL stage is re-enabled if it's supposed to run and selected FIRRTL DriverCompatibility phases run. 6. FirrtlStage runs 7. The output AnnotationSeq is "viewed" as a ChiselExecutionResult This modifies the original DriverSpec to make it more verbose with the addition of info statements. The functionality of the DriverSpec is unmodified. Signed-off-by: Schuyler Eldridge --- src/test/scala/chiselTests/DriverSpec.scala | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/test') diff --git a/src/test/scala/chiselTests/DriverSpec.scala b/src/test/scala/chiselTests/DriverSpec.scala index 612bdef2..8fc58e21 100644 --- a/src/test/scala/chiselTests/DriverSpec.scala +++ b/src/test/scala/chiselTests/DriverSpec.scala @@ -28,6 +28,7 @@ class DriverSpec extends FreeSpec with Matchers { val exts = List("anno.json", "fir", "v") for (ext <- exts) { val dummyOutput = new File(targetDir, "DummyModule" + "." + ext) + info(s"${dummyOutput.toString} exists") dummyOutput.exists() should be(true) dummyOutput.delete() } @@ -44,6 +45,7 @@ class DriverSpec extends FreeSpec with Matchers { val exts = List("anno.json", "fir", "v") for (ext <- exts) { val dummyOutput = new File(targetDir, "dm" + "." + ext) + info(s"${dummyOutput.toString} exists") dummyOutput.exists() should be(true) dummyOutput.delete() } @@ -53,14 +55,21 @@ class DriverSpec extends FreeSpec with Matchers { } } + "execute returns a chisel execution result" in { val targetDir = "test_run_dir" val args = Array("--compiler", "low", "--target-dir", targetDir) + + info("Driver returned a ChiselExecutionSuccess") val result = Driver.execute(args, () => new DummyModule) result shouldBe a[ChiselExecutionSuccess] + + info("emitted circuit included 'circuit DummyModule'") val successResult = result.asInstanceOf[ChiselExecutionSuccess] successResult.emitted should include ("circuit DummyModule") + val dummyOutput = new File(targetDir, "DummyModule.lo.fir") + info(s"${dummyOutput.toString} exists") dummyOutput.exists() should be(true) dummyOutput.delete() } -- cgit v1.2.3