summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDeborah Soung2021-07-06 14:40:59 -0700
committerGitHub2021-07-06 14:40:59 -0700
commit503ae520e7f997bcbc639b79869c9a4214d402ed (patch)
tree7e72d44b7e023fac04fdbe8d95d5bfdc01001988
parent4b7499f7c6287c696111bd7c6ee060f33f667419 (diff)
Make printf return BaseSim subclass so it can be named/annotated (#1992)
-rw-r--r--core/src/main/scala/chisel3/Printf.scala22
-rw-r--r--core/src/main/scala/chisel3/experimental/verification/package.scala17
-rw-r--r--core/src/main/scala/chisel3/internal/firrtl/Converter.scala4
-rw-r--r--core/src/main/scala/chisel3/internal/firrtl/IR.scala2
-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
8 files changed, 103 insertions, 27 deletions
diff --git a/core/src/main/scala/chisel3/Printf.scala b/core/src/main/scala/chisel3/Printf.scala
index 7cbd1918..cf7821b8 100644
--- a/core/src/main/scala/chisel3/Printf.scala
+++ b/core/src/main/scala/chisel3/Printf.scala
@@ -3,11 +3,10 @@
package chisel3
import scala.language.experimental.macros
-
import chisel3.internal._
import chisel3.internal.Builder.pushCommand
-import chisel3.internal.firrtl._
import chisel3.internal.sourceinfo.SourceInfo
+import chisel3.experimental.BaseSim
/** Prints a message in simulation
*
@@ -34,6 +33,9 @@ object printf {
formatIn map escaped mkString ""
}
+ /** Named class for [[printf]]s. */
+ final class Printf(val pable: Printable) extends BaseSim
+
/** Prints a message in simulation
*
* Prints a message every cycle. If defined within the scope of a [[when]] block, the message
@@ -71,7 +73,7 @@ object printf {
* @param fmt printf format string
* @param data format string varargs containing data to print
*/
- def apply(fmt: String, data: Bits*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit =
+ def apply(fmt: String, data: Bits*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Printf =
apply(Printable.pack(fmt, data:_*))
/** Prints a message in simulation
*
@@ -87,16 +89,20 @@ object printf {
* @see [[Printable]] documentation
* @param pable [[Printable]] to print
*/
- def apply(pable: Printable)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit = {
+ def apply(pable: Printable)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Printf = {
+ var printfId: Printf = null
when (!Module.reset.asBool) {
- printfWithoutReset(pable)
+ printfId = printfWithoutReset(pable)
}
+ printfId
}
- private[chisel3] def printfWithoutReset(pable: Printable)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit = {
+ private[chisel3] def printfWithoutReset(pable: Printable)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Printf = {
val clock = Builder.forcedClock
- pushCommand(Printf(sourceInfo, clock.ref, pable))
+ val printfId = new Printf(pable)
+ pushCommand(chisel3.internal.firrtl.Printf(printfId, sourceInfo, clock.ref, pable))
+ printfId
}
- private[chisel3] def printfWithoutReset(fmt: String, data: Bits*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit =
+ private[chisel3] def printfWithoutReset(fmt: String, data: Bits*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Printf =
printfWithoutReset(Printable.pack(fmt, data:_*))
}
diff --git a/core/src/main/scala/chisel3/experimental/verification/package.scala b/core/src/main/scala/chisel3/experimental/verification/package.scala
index ca15a5c4..190083fd 100644
--- a/core/src/main/scala/chisel3/experimental/verification/package.scala
+++ b/core/src/main/scala/chisel3/experimental/verification/package.scala
@@ -9,16 +9,11 @@ import chisel3.internal.sourceinfo.SourceInfo
package object verification {
- /** Named class for assertions. */
- final class Assert(val predicate: Bool) extends BaseSim
-
- /** Named class for assumes. */
- final class Assume(val predicate: Bool) extends BaseSim
+ object assert {
+ /** Named class for assertions. */
+ final class Assert(private[chisel3] val predicate: Bool) extends BaseSim
- /** Named class for covers. */
- final class Cover(val predicate: Bool) extends BaseSim
- object assert {
def apply(predicate: Bool, msg: String = "")(
implicit sourceInfo: SourceInfo,
compileOptions: CompileOptions): Assert = {
@@ -32,6 +27,9 @@ package object verification {
}
object assume {
+ /** Named class for assumes. */
+ final class Assume(private[chisel3] val predicate: Bool) extends BaseSim
+
def apply(predicate: Bool, msg: String = "")(
implicit sourceInfo: SourceInfo,
compileOptions: CompileOptions): Assume = {
@@ -45,6 +43,9 @@ package object verification {
}
object cover {
+ /** Named class for covers. */
+ final class Cover(private[chisel3] val predicate: Bool) extends BaseSim
+
def apply(predicate: Bool, msg: String = "")(
implicit sourceInfo: SourceInfo,
compileOptions: CompileOptions): Cover = {
diff --git a/core/src/main/scala/chisel3/internal/firrtl/Converter.scala b/core/src/main/scala/chisel3/internal/firrtl/Converter.scala
index 093d4848..8efb2abc 100644
--- a/core/src/main/scala/chisel3/internal/firrtl/Converter.scala
+++ b/core/src/main/scala/chisel3/internal/firrtl/Converter.scala
@@ -143,10 +143,10 @@ private[chisel3] object Converter {
Some(fir.DefInstance(convert(info), e.name, id.name))
case Stop(info, clock, ret) =>
Some(fir.Stop(convert(info), ret, convert(clock, ctx, info), firrtl.Utils.one))
- case Printf(info, clock, pable) =>
+ case e @ Printf(_, info, clock, pable) =>
val (fmt, args) = unpack(pable, ctx)
Some(fir.Print(convert(info), fir.StringLit(fmt),
- args.map(a => convert(a, ctx, info)), convert(clock, ctx, info), firrtl.Utils.one))
+ args.map(a => convert(a, ctx, info)), convert(clock, ctx, info), firrtl.Utils.one, e.name))
case e @ Verification(_, op, info, clk, pred, msg) =>
val firOp = op match {
case Formal.Assert => fir.Formal.Assert
diff --git a/core/src/main/scala/chisel3/internal/firrtl/IR.scala b/core/src/main/scala/chisel3/internal/firrtl/IR.scala
index a4f6d26d..5796522c 100644
--- a/core/src/main/scala/chisel3/internal/firrtl/IR.scala
+++ b/core/src/main/scala/chisel3/internal/firrtl/IR.scala
@@ -773,7 +773,7 @@ case class Attach(sourceInfo: SourceInfo, locs: Seq[Node]) extends Command
case class ConnectInit(sourceInfo: SourceInfo, loc: Node, exp: Arg) extends Command
case class Stop(sourceInfo: SourceInfo, clock: Arg, ret: Int) extends Command
case class Port(id: Data, dir: SpecifiedDirection)
-case class Printf(sourceInfo: SourceInfo, clock: Arg, pable: Printable) extends Command
+case class Printf(id: printf.Printf, sourceInfo: SourceInfo, clock: Arg, pable: Printable) extends Definition
object Formal extends Enumeration {
val Assert = Value("assert")
val Assume = Value("assume")
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)
}
)
}