summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormergify[bot]2022-09-29 18:53:44 +0000
committerGitHub2022-09-29 18:53:44 +0000
commit5a79814631bdc8c71c5a7b4722cd43712f7ff445 (patch)
tree6a42aceb9b6002bcbeb3070c7bb98d1b17db91b4
parent9f1eae19445e110bb743176767f59970ce1d36b5 (diff)
Add lexical scope checks to Assert, Assume and Printf (#2706) (#2753)
(cherry picked from commit f462c9f9307bebf3012da52432c3729cd752321c) Co-authored-by: Aditya Naik <91489422+adkian-sifive@users.noreply.github.com>
-rw-r--r--core/src/main/scala/chisel3/Data.scala2
-rw-r--r--core/src/main/scala/chisel3/Printable.scala13
-rw-r--r--core/src/main/scala/chisel3/Printf.scala3
-rw-r--r--core/src/main/scala/chisel3/VerificationStatement.scala2
-rw-r--r--src/test/scala/chiselTests/Assert.scala77
-rw-r--r--src/test/scala/chiselTests/Printf.scala39
6 files changed, 135 insertions, 1 deletions
diff --git a/core/src/main/scala/chisel3/Data.scala b/core/src/main/scala/chisel3/Data.scala
index 7c8ec1a9..f52f99de 100644
--- a/core/src/main/scala/chisel3/Data.scala
+++ b/core/src/main/scala/chisel3/Data.scala
@@ -662,7 +662,7 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc {
*/
private[chisel3] def typeEquivalent(that: Data): Boolean
- private def requireVisible(): Unit = {
+ private[chisel3] def requireVisible(): Unit = {
val mod = topBindingOpt.flatMap(_.location)
topBindingOpt match {
case Some(tb: TopBinding) if (mod == Builder.currentModule) =>
diff --git a/core/src/main/scala/chisel3/Printable.scala b/core/src/main/scala/chisel3/Printable.scala
index 78655517..82054ee1 100644
--- a/core/src/main/scala/chisel3/Printable.scala
+++ b/core/src/main/scala/chisel3/Printable.scala
@@ -134,6 +134,19 @@ object Printable {
val bufEscapeBackSlash = buf.map(_.replace("\\", "\\\\"))
StringContext(bufEscapeBackSlash.toSeq: _*).cf(data: _*)
}
+
+ private[chisel3] def checkScope(message: Printable): Unit = {
+ def getData(x: Printable): Seq[Data] = {
+ x match {
+ case y: FirrtlFormat => Seq(y.bits)
+ case Name(d) => Seq(d)
+ case FullName(d) => Seq(d)
+ case Printables(p) => p.flatMap(getData(_)).toSeq
+ case _ => Seq() // Handles subtypes PString and Percent
+ }
+ }
+ getData(message).foreach(_.requireVisible())
+ }
}
case class Printables(pables: Iterable[Printable]) extends Printable {
diff --git a/core/src/main/scala/chisel3/Printf.scala b/core/src/main/scala/chisel3/Printf.scala
index bdcca8e1..9410a409 100644
--- a/core/src/main/scala/chisel3/Printf.scala
+++ b/core/src/main/scala/chisel3/Printf.scala
@@ -108,6 +108,9 @@ object printf {
): Printf = {
val clock = Builder.forcedClock
val printfId = new Printf(pable)
+
+ Printable.checkScope(pable)
+
pushCommand(chisel3.internal.firrtl.Printf(printfId, sourceInfo, clock.ref, pable))
printfId
}
diff --git a/core/src/main/scala/chisel3/VerificationStatement.scala b/core/src/main/scala/chisel3/VerificationStatement.scala
index 1b13b86c..10cece60 100644
--- a/core/src/main/scala/chisel3/VerificationStatement.scala
+++ b/core/src/main/scala/chisel3/VerificationStatement.scala
@@ -178,6 +178,7 @@ object assert extends VerifPrintMacrosDoc {
compileOptions: CompileOptions
): Assert = {
val id = new Assert()
+ message.foreach(Printable.checkScope(_))
when(!Module.reset.asBool()) {
failureMessage("Assertion", line, cond, message)
Builder.pushCommand(Verification(id, Formal.Assert, sourceInfo, Module.clock.ref, cond.ref, ""))
@@ -343,6 +344,7 @@ object assume extends VerifPrintMacrosDoc {
compileOptions: CompileOptions
): Assume = {
val id = new Assume()
+ message.foreach(Printable.checkScope(_))
when(!Module.reset.asBool()) {
failureMessage("Assumption", line, cond, message)
Builder.pushCommand(Verification(id, Formal.Assume, sourceInfo, Module.clock.ref, cond.ref, ""))
diff --git a/src/test/scala/chiselTests/Assert.scala b/src/test/scala/chiselTests/Assert.scala
index d7885a3b..5e7b6496 100644
--- a/src/test/scala/chiselTests/Assert.scala
+++ b/src/test/scala/chiselTests/Assert.scala
@@ -84,6 +84,64 @@ class PrintableAssumeTester extends Module {
out := in
}
+class PrintableScopeTester extends Module {
+ val in = IO(Input(UInt(8.W)))
+ val out = IO(Output(UInt(8.W)))
+ out := in
+
+ val w = Wire(UInt(8.W))
+ w := 255.U
+
+ val printableWire = cf"$w"
+ val printablePort = cf"$in"
+}
+
+class AssertPrintableWireScope extends BasicTester {
+ val mod = Module(new PrintableScopeTester)
+ assert(1.U === 2.U, mod.printableWire)
+ stop()
+}
+
+class AssertPrintablePortScope extends BasicTester {
+ val mod = Module(new PrintableScopeTester)
+ mod.in := 255.U
+ assert(1.U === 1.U, mod.printablePort)
+ stop()
+}
+
+class AssertPrintableFailingWhenScope extends BasicTester {
+ val mod = Module(new PrintableWhenScopeTester)
+ assert(1.U === 1.U, mod.printable)
+ stop()
+}
+
+class AssumePrintableWireScope extends BasicTester {
+ val mod = Module(new PrintableScopeTester)
+ assume(1.U === 1.U, mod.printableWire)
+ stop()
+}
+
+class AssumePrintablePortScope extends BasicTester {
+ val mod = Module(new PrintableScopeTester)
+ mod.in := 255.U
+ assume(1.U === 1.U, mod.printablePort)
+ stop()
+}
+
+class PrintableWhenScopeTester extends Module {
+ val in = IO(Input(UInt(8.W)))
+ val out = IO(Output(UInt(8.W)))
+
+ out := in
+
+ val w = Wire(UInt(8.W))
+ w := 255.U
+ var printable = cf""
+ when(true.B) {
+ printable = cf"$w"
+ }
+}
+
class AssertSpec extends ChiselFlatSpec with Utils {
"A failing assertion" should "fail the testbench" in {
assert(!runTester { new FailingAssertTester })
@@ -94,6 +152,25 @@ class AssertSpec extends ChiselFlatSpec with Utils {
"An assertion" should "not assert until we come out of reset" in {
assertTesterPasses { new PipelinedResetTester }
}
+
+ "Assert Printables" should "respect port scoping" in {
+ assertTesterPasses { new AssertPrintablePortScope }
+ }
+ "Assert Printables" should "respect wire scoping" in {
+ a[ChiselException] should be thrownBy { ChiselStage.elaborate(new AssertPrintableWireScope) }
+ }
+ "Assume Printables" should "respect port scoping" in {
+ assertTesterPasses { new AssumePrintablePortScope }
+ }
+
+ "Assume Printables" should "respect wire scoping" in {
+ a[ChiselException] should be thrownBy { ChiselStage.elaborate(new AssumePrintableWireScope) }
+ }
+
+ "Assert Printables" should "respect when scope" in {
+ a[ChiselException] should be thrownBy { ChiselStage.elaborate(new AssertPrintableFailingWhenScope) }
+ }
+
"Assertions" should "allow the modulo operator % in the message" in {
assertTesterPasses { new ModuloAssertTester }
}
diff --git a/src/test/scala/chiselTests/Printf.scala b/src/test/scala/chiselTests/Printf.scala
index 4171f97f..6c9f05f0 100644
--- a/src/test/scala/chiselTests/Printf.scala
+++ b/src/test/scala/chiselTests/Printf.scala
@@ -4,6 +4,7 @@ package chiselTests
import chisel3._
import chisel3.testers.BasicTester
+import chisel3.stage.ChiselStage
class SinglePrintfTester() extends BasicTester {
val x = 254.U
@@ -28,6 +29,38 @@ class ASCIIPrintableTester extends BasicTester {
stop()
}
+class ScopeTesterModule extends Module {
+ val in = IO(Input(UInt(8.W)))
+ val out = IO(Output(UInt(8.W)))
+ out := in
+
+ val w = Wire(UInt(8.W))
+ w := 125.U
+
+ val p = cf"$in"
+ val wp = cf"$w"
+}
+
+class PrintablePrintfScopeTester extends BasicTester {
+ ChiselStage.elaborate {
+ new Module {
+ val mod = Module(new ScopeTesterModule)
+ printf(mod.p)
+ }
+ }
+ stop()
+}
+
+class PrintablePrintfWireScopeTester extends BasicTester {
+ ChiselStage.elaborate {
+ new Module {
+ val mod = Module(new ScopeTesterModule)
+ printf(mod.wp)
+ }
+ }
+ stop()
+}
+
class PrintfSpec extends ChiselFlatSpec {
"A printf with a single argument" should "run" in {
assertTesterPasses { new SinglePrintfTester }
@@ -41,4 +74,10 @@ class PrintfSpec extends ChiselFlatSpec {
"A printf with Printable ASCII characters 1-127" should "run" in {
assertTesterPasses { new ASCIIPrintableTester }
}
+ "A printf with Printable" should "respect port scopes" in {
+ assertTesterPasses { new PrintablePrintfScopeTester }
+ }
+ "A printf with Printable" should "respect wire scopes" in {
+ a[ChiselException] should be thrownBy { assertTesterPasses { new PrintablePrintfWireScopeTester } }
+ }
}