From 503ae520e7f997bcbc639b79869c9a4214d402ed Mon Sep 17 00:00:00 2001 From: Deborah Soung Date: Tue, 6 Jul 2021 14:40:59 -0700 Subject: Make printf return BaseSim subclass so it can be named/annotated (#1992) --- src/test/scala/chiselTests/PrintableSpec.scala | 66 ++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'src/test/scala/chiselTests/PrintableSpec.scala') diff --git a/src/test/scala/chiselTests/PrintableSpec.scala b/src/test/scala/chiselTests/PrintableSpec.scala index c76b26de..0325d3bc 100644 --- a/src/test/scala/chiselTests/PrintableSpec.scala +++ b/src/test/scala/chiselTests/PrintableSpec.scala @@ -3,11 +3,33 @@ package chiselTests import chisel3._ +import chisel3.experimental.{BaseSim, ChiselAnnotation} import chisel3.stage.ChiselStage import chisel3.testers.BasicTester +import firrtl.annotations.{ReferenceTarget, SingleTargetAnnotation} import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers +import java.io.File + +/** Dummy [[printf]] annotation. + * @param target target of component to be annotated + */ +case class PrintfAnnotation(target: ReferenceTarget) extends SingleTargetAnnotation[ReferenceTarget] { + def duplicate(n: ReferenceTarget): PrintfAnnotation = this.copy(target = n) +} + +object PrintfAnnotation { + /** Create annotation for a given [[printf]]. + * @param c component to be annotated + */ + def annotate(c: BaseSim): Unit = { + chisel3.experimental.annotate(new ChiselAnnotation { + def toFirrtl: PrintfAnnotation = PrintfAnnotation(c.toTarget) + }) + } +} + /* Printable Tests */ class PrintableSpec extends AnyFlatSpec with Matchers { // This regex is brittle, it specifically finds the clock and enable signals followed by commas @@ -194,4 +216,48 @@ class PrintableSpec extends AnyFlatSpec with Matchers { case e => fail() } } + it should "get emitted with a name and annotated" in { + + /** Test circuit containing annotated and renamed [[printf]]s. */ + class PrintfAnnotationTest extends Module { + val myBun = Wire(new Bundle { + val foo = UInt(32.W) + val bar = UInt(32.W) + }) + myBun.foo := 0.U + myBun.bar := 0.U + val howdy = printf(p"hello ${myBun}") + PrintfAnnotation.annotate(howdy) + PrintfAnnotation.annotate(printf(p"goodbye $myBun")) + PrintfAnnotation.annotate(printf(p"adieu $myBun").suggestName("farewell")) + } + + // compile circuit + val testDir = new File("test_run_dir", "PrintfAnnotationTest") + (new ChiselStage).emitSystemVerilog( + gen = new PrintfAnnotationTest, + args = Array("-td", testDir.getPath) + ) + + // read in annotation file + val annoFile = new File(testDir, "PrintfAnnotationTest.anno.json") + annoFile should exist + val annoLines = scala.io.Source.fromFile(annoFile).getLines.toList + + // check for expected annotations + exactly(3, annoLines) should include ("chiselTests.PrintfAnnotation") + exactly(1, annoLines) should include ("~PrintfAnnotationTest|PrintfAnnotationTest>farewell") + exactly(1, annoLines) should include ("~PrintfAnnotationTest|PrintfAnnotationTest>SIM") + exactly(1, annoLines) should include ("~PrintfAnnotationTest|PrintfAnnotationTest>howdy") + + // read in FIRRTL file + val firFile = new File(testDir, "PrintfAnnotationTest.fir") + firFile should exist + val firLines = scala.io.Source.fromFile(firFile).getLines.toList + + // check that verification components have expected names + exactly(1, firLines) should include ("""printf(clock, UInt<1>(1), "hello AnonymousBundle(foo -> %d, bar -> %d)", myBun.foo, myBun.bar): howdy""") + exactly(1, firLines) should include ("""printf(clock, UInt<1>(1), "goodbye AnonymousBundle(foo -> %d, bar -> %d)", myBun.foo, myBun.bar): SIM""") + exactly(1, firLines) should include ("""printf(clock, UInt<1>(1), "adieu AnonymousBundle(foo -> %d, bar -> %d)", myBun.foo, myBun.bar): farewell""") + } } -- cgit v1.2.3 From 73bd4ee6b9b510725b692c33e075362a19512d2c Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Fri, 20 Aug 2021 11:30:27 -0700 Subject: Remove chisel3's own firrtl Emitter, use firrtl Serializer This will be slightly slower as it involves converting from Chisel modules to FIRRTL modules before turning them into Strings. This cost is somewhat mitigated by doing that conversion lazily such that we never materialize the entire firrtl Circuit in memory, only 1 module at a time. --- src/test/scala/chiselTests/PrintableSpec.scala | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/test/scala/chiselTests/PrintableSpec.scala') diff --git a/src/test/scala/chiselTests/PrintableSpec.scala b/src/test/scala/chiselTests/PrintableSpec.scala index 0325d3bc..25b54966 100644 --- a/src/test/scala/chiselTests/PrintableSpec.scala +++ b/src/test/scala/chiselTests/PrintableSpec.scala @@ -150,7 +150,6 @@ class PrintableSpec extends AnyFlatSpec with Matchers { printf(p"${FullName(myInst.io.fizz)}") } val firrtl = ChiselStage.emitChirrtl(new MyModule) - println(firrtl) getPrintfs(firrtl) match { case Seq(Printf("foo", Seq()), Printf("myWire.foo", Seq()), @@ -256,8 +255,8 @@ class PrintableSpec extends AnyFlatSpec with Matchers { val firLines = scala.io.Source.fromFile(firFile).getLines.toList // check that verification components have expected names - exactly(1, firLines) should include ("""printf(clock, UInt<1>(1), "hello AnonymousBundle(foo -> %d, bar -> %d)", myBun.foo, myBun.bar): howdy""") - exactly(1, firLines) should include ("""printf(clock, UInt<1>(1), "goodbye AnonymousBundle(foo -> %d, bar -> %d)", myBun.foo, myBun.bar): SIM""") - exactly(1, firLines) should include ("""printf(clock, UInt<1>(1), "adieu AnonymousBundle(foo -> %d, bar -> %d)", myBun.foo, myBun.bar): farewell""") + exactly(1, firLines) should include ("""printf(clock, UInt<1>("h1"), "hello AnonymousBundle(foo -> %d, bar -> %d)", myBun.foo, myBun.bar) : howdy""") + exactly(1, firLines) should include ("""printf(clock, UInt<1>("h1"), "goodbye AnonymousBundle(foo -> %d, bar -> %d)", myBun.foo, myBun.bar) : SIM""") + exactly(1, firLines) should include ("""printf(clock, UInt<1>("h1"), "adieu AnonymousBundle(foo -> %d, bar -> %d)", myBun.foo, myBun.bar) : farewell""") } } -- cgit v1.2.3