aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Lawson2017-12-20 16:16:13 -0800
committerJack Koenig2017-12-20 16:16:13 -0800
commit19abcb04ad005a21319354550e87bfd428ec5597 (patch)
tree098d52697b40d58c36decd1670d6430b2bce9a93
parentc12e3b22cc3487906a265fe02b28ad1ac05be9f2 (diff)
Verify shl/shr amount is > 0 (#710)
Fixes #527
-rw-r--r--src/main/scala/firrtl/passes/Checks.scala10
-rw-r--r--src/test/scala/firrtlTests/CheckSpec.scala23
2 files changed, 31 insertions, 2 deletions
diff --git a/src/main/scala/firrtl/passes/Checks.scala b/src/main/scala/firrtl/passes/Checks.scala
index 09c818bd..454cdb90 100644
--- a/src/main/scala/firrtl/passes/Checks.scala
+++ b/src/main/scala/firrtl/passes/Checks.scala
@@ -49,6 +49,8 @@ object CheckHighForm extends Pass {
s"$info: [module $mname] Has instance loop $loop")
class NoTopModuleException(info: Info, name: String) extends PassException(
s"$info: A single module must be named $name.")
+ class NegArgException(info: Info, mname: String, op: String, value: Int) extends PassException(
+ s"$info: [module $mname] Primop $op argument $value < 0.")
// TODO FIXME
// - Do we need to check for uniquness on port names?
@@ -74,8 +76,14 @@ object CheckHighForm extends Pass {
correctNum(Option(2), 0)
case AsUInt | AsSInt | AsClock | Cvt | Neq | Not =>
correctNum(Option(1), 0)
- case AsFixedPoint | Pad | Shl | Shr | Head | Tail | BPShl | BPShr | BPSet =>
+ case AsFixedPoint | Pad | Head | Tail | BPShl | BPShr | BPSet =>
correctNum(Option(1), 1)
+ case Shl | Shr =>
+ correctNum(Option(1), 1)
+ val amount = e.consts.head.toInt
+ if (amount < 0) {
+ errors.append(new NegArgException(info, mname, e.op.toString, amount))
+ }
case Bits =>
correctNum(Option(1), 2)
case Andr | Orr | Xorr | Neg =>
diff --git a/src/test/scala/firrtlTests/CheckSpec.scala b/src/test/scala/firrtlTests/CheckSpec.scala
index 0d0df020..50a28f80 100644
--- a/src/test/scala/firrtlTests/CheckSpec.scala
+++ b/src/test/scala/firrtlTests/CheckSpec.scala
@@ -7,7 +7,7 @@ import org.scalatest._
import org.scalatest.prop._
import firrtl.Parser
import firrtl.ir.Circuit
-import firrtl.passes.{Pass,ToWorkingIR,CheckHighForm,ResolveKinds,InferTypes,CheckTypes,PassExceptions,InferWidths,CheckWidths,ResolveGenders,CheckGenders}
+import firrtl.passes.{Pass,ToWorkingIR,CheckHighForm,ResolveKinds,InferTypes,CheckTypes,PassException,InferWidths,CheckWidths,ResolveGenders,CheckGenders}
class CheckSpec extends FlatSpec with Matchers {
"Connecting bundles of different types" should "throw an exception" in {
@@ -242,4 +242,25 @@ class CheckSpec extends FlatSpec with Matchers {
}
}
+ for (op <- List("shl", "shr")) {
+ s"$op by negative amount" should "result in an error" in {
+ val passes = Seq(
+ ToWorkingIR,
+ CheckHighForm
+ )
+ val amount = -1
+ val input =
+ s"""circuit Unit :
+ | module Unit :
+ | input x: UInt<3>
+ | output z: UInt
+ | z <= $op(x, $amount)""".stripMargin
+ val exception = intercept[PassException] {
+ passes.foldLeft(Parser.parse(input.split("\n").toIterator)) {
+ (c: Circuit, p: Pass) => p.run(c)
+ }
+ }
+ exception.getMessage should include (s"Primop $op argument $amount < 0")
+ }
+ }
}