aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlbert Chen2020-07-23 14:31:11 -0700
committerGitHub2020-07-23 21:31:11 +0000
commite30c20d10ba47b11e06416e912ed89b6b6ce8e7b (patch)
treed64b76b035c22a924eca42b7c91e0db56b99e987 /src
parent1927dc6574b9eee315c8f24441df390f2ce793c7 (diff)
fix reduction op bug ConstantPropagation (#1746)
* add const prop bitwise reduction equivalence test * mask negative literals when propagating reduction * change widths * get rid of unnecessary if * add BigInt mask utility
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/firrtl/Utils.scala9
-rw-r--r--src/main/scala/firrtl/transforms/ConstantPropagation.scala3
-rw-r--r--src/test/scala/firrtlTests/ConstantPropagationTests.scala13
3 files changed, 24 insertions, 1 deletions
diff --git a/src/main/scala/firrtl/Utils.scala b/src/main/scala/firrtl/Utils.scala
index 2264a0e4..0a067c04 100644
--- a/src/main/scala/firrtl/Utils.scala
+++ b/src/main/scala/firrtl/Utils.scala
@@ -764,6 +764,15 @@ object Utils extends LazyLogging {
.toSeq
.foldLeft(Seq[String]()){ case (seq, id) => seq :+ name.splitAt(id)._1 }
}
+
+ /** Returns the value masked with the width.
+ *
+ * This supports truncating negative values as well as values that are too
+ * wide for the width
+ */
+ def maskBigInt(value: BigInt, width: Int): BigInt = {
+ value & ((BigInt(1) << width) - 1)
+ }
}
object MemoizedHash {
diff --git a/src/main/scala/firrtl/transforms/ConstantPropagation.scala b/src/main/scala/firrtl/transforms/ConstantPropagation.scala
index 8ad3489f..0ec4fe0b 100644
--- a/src/main/scala/firrtl/transforms/ConstantPropagation.scala
+++ b/src/main/scala/firrtl/transforms/ConstantPropagation.scala
@@ -160,7 +160,8 @@ class ConstantPropagation extends Transform with DependencyAPIMigration with Res
case IntWidth(b) => b
}
- val v: Seq[Boolean] = s"%${w}s".format(a.value.toString(2)).map(_ == '1')
+ val maskedValue = Utils.maskBigInt(a.value, w.toInt)
+ val v: Seq[Boolean] = s"%${w}s".format(maskedValue.toString(2)).map(_ == '1')
(BigInt(0) until w).zip(v).foldLeft(identityValue) {
case (acc, (_, x)) => reduce(acc, x)
diff --git a/src/test/scala/firrtlTests/ConstantPropagationTests.scala b/src/test/scala/firrtlTests/ConstantPropagationTests.scala
index d81f8687..653653d6 100644
--- a/src/test/scala/firrtlTests/ConstantPropagationTests.scala
+++ b/src/test/scala/firrtlTests/ConstantPropagationTests.scala
@@ -1629,6 +1629,19 @@ class ConstantPropagationEquivalenceSpec extends FirrtlFlatSpec {
firrtlEquivalenceTest(input, transforms)
}
+ "reduction of literals" should "be propagated" in {
+ val input =
+ s"""circuit ConstPropReductionTester :
+ | module ConstPropReductionTester :
+ | output out1 : UInt<1>
+ | output out2 : UInt<1>
+ | output out3 : UInt<1>
+ | out1 <= xorr(SInt<2>(-1))
+ | out2 <= andr(SInt<2>(-1))
+ | out3 <= orr(SInt<2>(-1))""".stripMargin
+ firrtlEquivalenceTest(input, transforms)
+ }
+
"addition of negative literals" should "be propagated" in {
val input =
s"""circuit AddTester :