summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/chisel3/aop/Select.scala4
-rw-r--r--src/main/scala/chisel3/internal/firrtl/Emitter.scala4
-rw-r--r--src/test/scala/chiselTests/PrintableSpec.scala66
-rw-r--r--src/test/scala/chiselTests/aop/SelectSpec.scala11
4 files changed, 77 insertions, 8 deletions
diff --git a/src/main/scala/chisel3/aop/Select.scala b/src/main/scala/chisel3/aop/Select.scala
index a16c415c..078422bb 100644
--- a/src/main/scala/chisel3/aop/Select.scala
+++ b/src/main/scala/chisel3/aop/Select.scala
@@ -281,7 +281,7 @@ object Select {
val printfs = mutable.ArrayBuffer[Printf]()
searchWhens(module, (cmd: Command, preds: Seq[Predicate]) => {
cmd match {
- case chisel3.internal.firrtl.Printf(_, clock, pable) => printfs += Printf(preds, pable, getId(clock).asInstanceOf[Clock])
+ case chisel3.internal.firrtl.Printf(id, _, clock, pable) => printfs += Printf(id, preds, pable, getId(clock).asInstanceOf[Clock])
case other =>
}
})
@@ -418,7 +418,7 @@ object Select {
* @param pable
* @param clock
*/
- case class Printf(preds: Seq[Predicate], pable: Printable, clock: Clock) extends Serializeable {
+ case class Printf(id: printf.Printf, preds: Seq[Predicate], pable: Printable, clock: Clock) extends Serializeable {
def serialize: String = {
s"printf when(${preds.map(_.serialize).mkString(" & ")}) on ${getName(clock)}: $pable"
}
diff --git a/src/main/scala/chisel3/internal/firrtl/Emitter.scala b/src/main/scala/chisel3/internal/firrtl/Emitter.scala
index 53d5c6ce..47849d91 100644
--- a/src/main/scala/chisel3/internal/firrtl/Emitter.scala
+++ b/src/main/scala/chisel3/internal/firrtl/Emitter.scala
@@ -75,11 +75,11 @@ private class Emitter(circuit: Circuit) {
case e: BulkConnect => s"${e.loc1.fullName(ctx)} <- ${e.loc2.fullName(ctx)}"
case e: Attach => e.locs.map(_.fullName(ctx)).mkString("attach (", ", ", ")")
case e: Stop => s"stop(${e.clock.fullName(ctx)}, UInt<1>(1), ${e.ret})"
- case e: Printf =>
+ case e: chisel3.internal.firrtl.Printf =>
val (fmt, args) = e.pable.unpack(ctx)
val printfArgs = Seq(e.clock.fullName(ctx), "UInt<1>(1)",
"\"" + printf.format(fmt) + "\"") ++ args
- printfArgs mkString ("printf(", ", ", ")")
+ (printfArgs mkString ("printf(", ", ", ")")) + s": ${e.name}"
case e: Verification[_] =>
s"""${e.op}(${e.clock.fullName(ctx)}, ${e.predicate.fullName(ctx)}, UInt<1>(1), "${printf.format(e.message)}") : ${e.name}"""
case e: DefInvalid => s"${e.arg.fullName(ctx)} is invalid"
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""")
+ }
}
diff --git a/src/test/scala/chiselTests/aop/SelectSpec.scala b/src/test/scala/chiselTests/aop/SelectSpec.scala
index 14ae202d..46c62d67 100644
--- a/src/test/scala/chiselTests/aop/SelectSpec.scala
+++ b/src/test/scala/chiselTests/aop/SelectSpec.scala
@@ -22,14 +22,16 @@ class SelectTester(results: Seq[Int]) extends BasicTester {
val nreset = reset.asBool() === false.B
val selected = values(counter)
val zero = 0.U + 0.U
+ var p: printf.Printf = null
when(overflow) {
counter := zero
stop()
}.otherwise {
when(nreset) {
assert(counter === values(counter))
- printf("values(%d) = %d\n", counter, selected)
+ p = printf("values(%d) = %d\n", counter, selected)
}
+
}
}
@@ -81,17 +83,18 @@ class SelectSpec extends ChiselFlatSpec {
"Test" should "pass if selecting correct printfs" in {
execute(
() => new SelectTester(Seq(0, 1, 2)),
- { dut: SelectTester => Seq(Select.printfs(dut).last) },
+ { dut: SelectTester => Seq(Select.printfs(dut).last.toString) },
{ dut: SelectTester =>
Seq(Select.Printf(
+ dut.p,
Seq(
When(Select.ops("eq")(dut).last.asInstanceOf[Bool]),
When(dut.nreset),
WhenNot(dut.overflow)
),
- Printable.pack("values(%d) = %d\n", dut.counter, dut.selected),
+ dut.p.pable,
dut.clock
- ))
+ ).toString)
}
)
}