aboutsummaryrefslogtreecommitdiff
path: root/src/test/scala/firrtlTests/CheckSpec.scala
diff options
context:
space:
mode:
authorJack Koenig2021-04-16 11:41:07 -0700
committerGitHub2021-04-16 11:41:07 -0700
commitbf1cf3d2db49195d031f89594baebcc9f307659e (patch)
tree4a13e03f64c49295dc9cb620f76737d25df08419 /src/test/scala/firrtlTests/CheckSpec.scala
parente9b2946c962f91a04611e32b1a9d03f78e7edf2b (diff)
Make InferTypes error on enable conditions > 1-bit wide (#2182)
Diffstat (limited to 'src/test/scala/firrtlTests/CheckSpec.scala')
-rw-r--r--src/test/scala/firrtlTests/CheckSpec.scala100
1 files changed, 100 insertions, 0 deletions
diff --git a/src/test/scala/firrtlTests/CheckSpec.scala b/src/test/scala/firrtlTests/CheckSpec.scala
index a3efc784..547639d6 100644
--- a/src/test/scala/firrtlTests/CheckSpec.scala
+++ b/src/test/scala/firrtlTests/CheckSpec.scala
@@ -86,6 +86,106 @@ class CheckSpec extends AnyFlatSpec with Matchers {
}
}
+ behavior.of("Check Types")
+
+ def runCheckTypes(input: String) = {
+ val passes = List(InferTypes, CheckTypes)
+ val wrapped = "circuit test:\n module test:\n " + input.replaceAll("\n", "\n ")
+ passes.foldLeft(Parser.parse(wrapped)) { case (c, p) => p.run(c) }
+ }
+
+ it should "disallow mux enable conditions that are not 1-bit UInts (or unknown width)" in {
+ def mk(tpe: String) =
+ s"""|input en : $tpe
+ |input foo : UInt<8>
+ |input bar : UInt<8>
+ |node x = mux(en, foo, bar)""".stripMargin
+ a[CheckTypes.MuxCondUInt] shouldBe thrownBy { runCheckTypes(mk("SInt<1>")) }
+ a[CheckTypes.MuxCondUInt] shouldBe thrownBy { runCheckTypes(mk("SInt")) }
+ a[CheckTypes.MuxCondUInt] shouldBe thrownBy { runCheckTypes(mk("UInt<3>")) }
+ a[CheckTypes.MuxCondUInt] shouldBe thrownBy { runCheckTypes(mk("Clock")) }
+ a[CheckTypes.MuxCondUInt] shouldBe thrownBy { runCheckTypes(mk("AsyncReset")) }
+ runCheckTypes(mk("UInt"))
+ runCheckTypes(mk("UInt<1>"))
+ }
+
+ it should "disallow when predicates that are not 1-bit UInts (or unknown width)" in {
+ def mk(tpe: String) =
+ s"""|input en : $tpe
+ |input foo : UInt<8>
+ |input bar : UInt<8>
+ |output out : UInt<8>
+ |when en :
+ | out <= foo
+ |else:
+ | out <= bar""".stripMargin
+ a[CheckTypes.PredNotUInt] shouldBe thrownBy { runCheckTypes(mk("SInt<1>")) }
+ a[CheckTypes.PredNotUInt] shouldBe thrownBy { runCheckTypes(mk("SInt")) }
+ a[CheckTypes.PredNotUInt] shouldBe thrownBy { runCheckTypes(mk("UInt<3>")) }
+ a[CheckTypes.PredNotUInt] shouldBe thrownBy { runCheckTypes(mk("Clock")) }
+ a[CheckTypes.PredNotUInt] shouldBe thrownBy { runCheckTypes(mk("AsyncReset")) }
+ runCheckTypes(mk("UInt"))
+ runCheckTypes(mk("UInt<1>"))
+ }
+
+ it should "disallow print enables that are not 1-bit UInts (or unknown width)" in {
+ def mk(tpe: String) =
+ s"""|input en : $tpe
+ |input clock : Clock
+ |printf(clock, en, "Hello World!\\n")""".stripMargin
+ a[CheckTypes.EnNotUInt] shouldBe thrownBy { runCheckTypes(mk("SInt<1>")) }
+ a[CheckTypes.EnNotUInt] shouldBe thrownBy { runCheckTypes(mk("SInt")) }
+ a[CheckTypes.EnNotUInt] shouldBe thrownBy { runCheckTypes(mk("UInt<3>")) }
+ a[CheckTypes.EnNotUInt] shouldBe thrownBy { runCheckTypes(mk("Clock")) }
+ a[CheckTypes.EnNotUInt] shouldBe thrownBy { runCheckTypes(mk("AsyncReset")) }
+ runCheckTypes(mk("UInt"))
+ runCheckTypes(mk("UInt<1>"))
+ }
+
+ it should "disallow stop enables that are not 1-bit UInts (or unknown width)" in {
+ def mk(tpe: String) =
+ s"""|input en : $tpe
+ |input clock : Clock
+ |stop(clock, en, 0)""".stripMargin
+ a[CheckTypes.EnNotUInt] shouldBe thrownBy { runCheckTypes(mk("SInt<1>")) }
+ a[CheckTypes.EnNotUInt] shouldBe thrownBy { runCheckTypes(mk("SInt")) }
+ a[CheckTypes.EnNotUInt] shouldBe thrownBy { runCheckTypes(mk("UInt<3>")) }
+ a[CheckTypes.EnNotUInt] shouldBe thrownBy { runCheckTypes(mk("Clock")) }
+ a[CheckTypes.EnNotUInt] shouldBe thrownBy { runCheckTypes(mk("AsyncReset")) }
+ runCheckTypes(mk("UInt"))
+ runCheckTypes(mk("UInt<1>"))
+ }
+
+ it should "disallow verif node predicates that are not 1-bit UInts (or unknown width)" in {
+ def mk(tpe: String) =
+ s"""|input en : $tpe
+ |input cond : UInt<1>
+ |input clock : Clock
+ |assert(clock, en, cond, "Howdy!")""".stripMargin
+ a[CheckTypes.PredNotUInt] shouldBe thrownBy { runCheckTypes(mk("SInt<1>")) }
+ a[CheckTypes.PredNotUInt] shouldBe thrownBy { runCheckTypes(mk("SInt")) }
+ a[CheckTypes.PredNotUInt] shouldBe thrownBy { runCheckTypes(mk("UInt<3>")) }
+ a[CheckTypes.PredNotUInt] shouldBe thrownBy { runCheckTypes(mk("Clock")) }
+ a[CheckTypes.PredNotUInt] shouldBe thrownBy { runCheckTypes(mk("AsyncReset")) }
+ runCheckTypes(mk("UInt"))
+ runCheckTypes(mk("UInt<1>"))
+ }
+
+ it should "disallow verif node enables that are not 1-bit UInts (or unknown width)" in {
+ def mk(tpe: String) =
+ s"""|input en : UInt<1>
+ |input cond : $tpe
+ |input clock : Clock
+ |assert(clock, en, cond, "Howdy!")""".stripMargin
+ a[CheckTypes.EnNotUInt] shouldBe thrownBy { runCheckTypes(mk("SInt<1>")) }
+ a[CheckTypes.EnNotUInt] shouldBe thrownBy { runCheckTypes(mk("SInt")) }
+ a[CheckTypes.EnNotUInt] shouldBe thrownBy { runCheckTypes(mk("UInt<3>")) }
+ a[CheckTypes.EnNotUInt] shouldBe thrownBy { runCheckTypes(mk("Clock")) }
+ a[CheckTypes.EnNotUInt] shouldBe thrownBy { runCheckTypes(mk("AsyncReset")) }
+ runCheckTypes(mk("UInt"))
+ runCheckTypes(mk("UInt<1>"))
+ }
+
"Instance loops a -> b -> a" should "be detected" in {
val input =
"""