diff options
| author | Aditya Naik | 2023-11-23 03:11:56 -0800 |
|---|---|---|
| committer | Aditya Naik | 2023-11-23 03:11:56 -0800 |
| commit | af415532cf160e63e971ceb301833b8433c18a50 (patch) | |
| tree | 1fef70139846f57298c8e24a590490a74249f7dd /src/test/scala/chiselTests/PrintableSpec.scala | |
| parent | 8200c0cdf1d471453946d5ae24bc99757b2ef02d (diff) | |
cleanup
Diffstat (limited to 'src/test/scala/chiselTests/PrintableSpec.scala')
| -rw-r--r-- | src/test/scala/chiselTests/PrintableSpec.scala | 393 |
1 files changed, 0 insertions, 393 deletions
diff --git a/src/test/scala/chiselTests/PrintableSpec.scala b/src/test/scala/chiselTests/PrintableSpec.scala deleted file mode 100644 index 8039918d..00000000 --- a/src/test/scala/chiselTests/PrintableSpec.scala +++ /dev/null @@ -1,393 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -package chiselTests - -import chisel3._ -import chisel3.experimental.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 chisel3.util._ -import org.scalactic.source.Position -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: VerificationStatement): Unit = { - chisel3.experimental.annotate(new ChiselAnnotation { - def toFirrtl: PrintfAnnotation = PrintfAnnotation(c.toTarget) - }) - } -} - -/* Printable Tests */ -class PrintableSpec extends AnyFlatSpec with Matchers with Utils { - // This regex is brittle, it specifically finds the clock and enable signals followed by commas - private val PrintfRegex = """\s*printf\(\w+, [^,]+,(.*)\).*""".r - private val StringRegex = """([^"]*)"(.*?)"(.*)""".r - private case class Printf(str: String, args: Seq[String]) - private def getPrintfs(firrtl: String): Seq[Printf] = { - def processArgs(str: String): Seq[String] = - str.split(",").map(_.trim).filter(_.nonEmpty) - def processBody(str: String): (String, Seq[String]) = { - str match { - case StringRegex(_, fmt, args) => - (fmt, processArgs(args)) - case _ => fail(s"Regex to process Printf should work on $str!") - } - } - firrtl.split("\n").collect { - case PrintfRegex(matched) => - val (str, args) = processBody(matched) - Printf(str, args) - } - } - - // Generates firrtl, gets Printfs - // Calls fail() if failed match; else calls the partial function which could have its own check - private def generateAndCheck(gen: => RawModule)(check: PartialFunction[Seq[Printf], Unit])(implicit pos: Position) = { - val firrtl = ChiselStage.emitChirrtl(gen) - val printfs = getPrintfs(firrtl) - if (!check.isDefinedAt(printfs)) { - fail() - } else { - check(printfs) - } - } - - behavior.of("Printable & Custom Interpolator") - - it should "pass exact strings through" in { - class MyModule extends BasicTester { - printf(p"An exact string") - } - generateAndCheck(new MyModule) { - case Seq(Printf("An exact string", Seq())) => - } - } - it should "handle Printable and String concatination" in { - class MyModule extends BasicTester { - printf(p"First " + PString("Second ") + "Third") - } - generateAndCheck(new MyModule) { - case Seq(Printf("First Second Third", Seq())) => - } - } - it should "call toString on non-Printable objects" in { - class MyModule extends BasicTester { - val myInt = 1234 - printf(p"myInt = $myInt") - } - generateAndCheck(new MyModule) { - case Seq(Printf("myInt = 1234", Seq())) => - } - } - it should "generate proper printf for simple Decimal printing" in { - class MyModule extends BasicTester { - val myWire = WireDefault(1234.U) - printf(p"myWire = ${Decimal(myWire)}") - } - generateAndCheck(new MyModule) { - case Seq(Printf("myWire = %d", Seq("myWire"))) => - } - } - it should "handle printing literals" in { - class MyModule extends BasicTester { - printf(Decimal(10.U(32.W))) - } - generateAndCheck(new MyModule) { - case Seq(Printf("%d", Seq(lit))) => - assert(lit contains "UInt<32>") - } - } - it should "correctly escape percent" in { - class MyModule extends BasicTester { - printf(p"%") - } - generateAndCheck(new MyModule) { - case Seq(Printf("%%", Seq())) => - } - } - it should "correctly emit tab" in { - class MyModule extends BasicTester { - printf(p"\t") - } - generateAndCheck(new MyModule) { - case Seq(Printf("\\t", Seq())) => - } - } - it should "support names of circuit elements including submodule IO" in { - // Submodule IO is a subtle issue because the Chisel element has a different - // parent module - class MySubModule extends Module { - val io = IO(new Bundle { - val fizz = UInt(32.W) - }) - } - class MyBundle extends Bundle { - val foo = UInt(32.W) - } - class MyModule extends BasicTester { - override def desiredName: String = "MyModule" - val myWire = Wire(new MyBundle) - val myInst = Module(new MySubModule) - printf(p"${Name(myWire.foo)}") - printf(p"${FullName(myWire.foo)}") - printf(p"${FullName(myInst.io.fizz)}") - } - generateAndCheck(new MyModule) { - case Seq(Printf("foo", Seq()), Printf("myWire.foo", Seq()), Printf("myInst.io.fizz", Seq())) => - } - } - it should "handle printing ports of submodules" in { - class MySubModule extends Module { - val io = IO(new Bundle { - val fizz = UInt(32.W) - }) - } - class MyModule extends BasicTester { - val myInst = Module(new MySubModule) - printf(p"${myInst.io.fizz}") - } - generateAndCheck(new MyModule) { - case Seq(Printf("%d", Seq("myInst.io.fizz"))) => - } - } - it should "print UInts and SInts as Decimal by default" in { - class MyModule extends BasicTester { - val myUInt = WireDefault(0.U) - val mySInt = WireDefault(-1.S) - printf(p"$myUInt & $mySInt") - } - generateAndCheck(new MyModule) { - case Seq(Printf("%d & %d", Seq("myUInt", "mySInt"))) => - } - } - it should "print Vecs like Scala Seqs by default" in { - class MyModule extends BasicTester { - val myVec = Wire(Vec(4, UInt(32.W))) - myVec.foreach(_ := 0.U) - printf(p"$myVec") - } - generateAndCheck(new MyModule) { - case Seq(Printf("Vec(%d, %d, %d, %d)", Seq("myVec[0]", "myVec[1]", "myVec[2]", "myVec[3]"))) => - } - } - it should "print Bundles like Scala Maps by default" in { - class MyModule extends BasicTester { - val myBun = Wire(new Bundle { - val foo = UInt(32.W) - val bar = UInt(32.W) - }) - myBun.foo := 0.U - myBun.bar := 0.U - printf(p"$myBun") - } - generateAndCheck(new MyModule) { - case Seq(Printf("AnonymousBundle(foo -> %d, bar -> %d)", Seq("myBun.foo", "myBun.bar"))) => - } - } - 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>printf") - 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>("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) : printf""" - ) - exactly(1, firLines) should include( - """printf(clock, UInt<1>("h1"), "adieu AnonymousBundle(foo -> %d, bar -> %d)", myBun.foo, myBun.bar) : farewell""" - ) - } - - // Unit tests for cf - it should "print regular scala variables with cf format specifier" in { - - class MyModule extends BasicTester { - val f1 = 20.4517 - val i1 = 10 - val str1 = "String!" - printf( - cf"F1 = $f1 D1 = $i1 F1 formatted = $f1%2.2f str1 = $str1%s i1_str = $i1%s i1_hex=$i1%x" - ) - - } - - generateAndCheck(new MyModule) { - case Seq(Printf("F1 = 20.4517 D1 = 10 F1 formatted = 20.45 str1 = String! i1_str = 10 i1_hex=a", Seq())) => - } - } - - it should "print chisel bits with cf format specifier" in { - - class MyBundle extends Bundle { - val foo = UInt(32.W) - val bar = UInt(32.W) - override def toPrintable: Printable = { - cf"Bundle : " + - cf"Foo : $foo%x Bar : $bar%x" - } - } - class MyModule extends BasicTester { - val b1 = 10.U - val w1 = Wire(new MyBundle) - w1.foo := 5.U - w1.bar := 10.U - printf(cf"w1 = $w1") - } - generateAndCheck(new MyModule) { - case Seq(Printf("w1 = Bundle : Foo : %x Bar : %x", Seq("w1.foo", "w1.bar"))) => - } - } - - it should "support names of circuit elements using format specifier including submodule IO with cf format specifier" in { - // Submodule IO is a subtle issue because the Chisel element has a different - // parent module - class MySubModule extends Module { - val io = IO(new Bundle { - val fizz = UInt(32.W) - }) - } - class MyBundle extends Bundle { - val foo = UInt(32.W) - } - class MyModule extends BasicTester { - override def desiredName: String = "MyModule" - val myWire = Wire(new MyBundle) - val myInst = Module(new MySubModule) - printf(cf"${myWire.foo}%n") - printf(cf"${myWire.foo}%N") - printf(cf"${myInst.io.fizz}%N") - } - generateAndCheck(new MyModule) { - case Seq(Printf("foo", Seq()), Printf("myWire.foo", Seq()), Printf("myInst.io.fizz", Seq())) => - } - } - - it should "correctly print strings after modifier" in { - class MyModule extends BasicTester { - val b1 = 10.U - printf(cf"This is here $b1%x!!!! And should print everything else") - } - generateAndCheck(new MyModule) { - case Seq(Printf("This is here %x!!!! And should print everything else", Seq("UInt<4>(\"ha\")"))) => - } - } - - it should "correctly print strings with a lot of literal %% and different format specifiers for Wires" in { - class MyModule extends BasicTester { - val b1 = 10.U - val b2 = 20.U - printf(cf"%% $b1%x%%$b2%b = ${b1 % b2}%d %%%% Tail String") - } - - generateAndCheck(new MyModule) { - case Seq(Printf("%% %x%%%b = %d %%%% Tail String", Seq(lita, litb, _))) => - assert(lita.contains("UInt<4>") && litb.contains("UInt<5>")) - } - } - - it should "not allow unescaped % in the message" in { - class MyModule extends BasicTester { - printf(cf"This should error out for sure because of % - it should be %%") - } - a[java.util.UnknownFormatConversionException] should be thrownBy { - extractCause[java.util.UnknownFormatConversionException] { - ChiselStage.elaborate { new MyModule } - } - } - } - - it should "allow Printables to be expanded and used" in { - class MyModule extends BasicTester { - val w1 = 20.U - val f1 = 30.2 - val i1 = 14 - val pable = cf"w1 = $w1%b f1 = $f1%2.2f" - printf(cf"Trying to expand printable $pable and mix with i1 = $i1%d") - } - generateAndCheck(new MyModule) { - case Seq(Printf("Trying to expand printable w1 = %b f1 = 30.20 and mix with i1 = 14", Seq(lit))) => - assert(lit.contains("UInt<5>")) - } - } - - it should "fail with a single % in the message" in { - class MyModule extends BasicTester { - printf(cf"%") - } - a[java.util.UnknownFormatConversionException] should be thrownBy { - extractCause[java.util.UnknownFormatConversionException] { - ChiselStage.elaborate { new MyModule } - } - } - } - - it should "fail when passing directly to StirngContext.cf a string with literal \\ correctly escaped " in { - a[StringContext.InvalidEscapeException] should be thrownBy { - extractCause[StringContext.InvalidEscapeException] { - val s_seq = Seq("Test with literal \\ correctly escaped") - StringContext(s_seq: _*).cf(Seq(): _*) - } - } - } - - it should "pass correctly escaped \\ when using Printable.pack" in { - class MyModule extends BasicTester { - printf(Printable.pack("\\ \\]")) - } - generateAndCheck(new MyModule) { - case Seq(Printf("\\\\ \\\\]", Seq())) => - } - } -} |
