// SPDX-License-Identifier: Apache-2.0 package chiselTests.stage import chisel3._ import chisel3.stage.{ChiselCircuitAnnotation, ChiselGeneratorAnnotation, DesignAnnotation} import firrtl.options.OptionsException import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers 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 AnyFlatSpec with Matchers { behavior.of("ChiselGeneratorAnnotation elaboration") it should "elaborate to a ChiselCircuitAnnotation" in { val annotation = ChiselGeneratorAnnotation(() => new ChiselAnnotationsSpecFoo) val res = annotation.elaborate res(0) shouldBe a[ChiselCircuitAnnotation] res(1) shouldBe a[DesignAnnotation[ChiselAnnotationsSpecFoo]] } 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") val res = annotation.elaborate res(0) shouldBe a[ChiselCircuitAnnotation] res(1) shouldBe a[DesignAnnotation[ChiselAnnotationsSpecFoo]] } 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'" ) } }