aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJack Koenig2019-01-13 16:11:22 -0800
committerJack Koenig2019-01-13 22:10:22 -0800
commitf961bfca704c9095309e110ff3a546a40b1a2dc5 (patch)
treeda30d0db11c934800e18f59782cb53dac0e6ccb2 /src
parentf5a42ce22193a038008a1c4f80618e38f72b40f1 (diff)
Constant Propagate dshl and dshr with constant amounts
Fixes #990 h/t @pentin-as and @abejgonzalez
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/firrtl/transforms/ConstantPropagation.scala17
-rw-r--r--src/test/scala/firrtlTests/ConstantPropagationTests.scala71
2 files changed, 88 insertions, 0 deletions
diff --git a/src/main/scala/firrtl/transforms/ConstantPropagation.scala b/src/main/scala/firrtl/transforms/ConstantPropagation.scala
index ed4ecd96..16960b34 100644
--- a/src/main/scala/firrtl/transforms/ConstantPropagation.scala
+++ b/src/main/scala/firrtl/transforms/ConstantPropagation.scala
@@ -137,6 +137,13 @@ class ConstantPropagation extends Transform with ResolvedAnnotationPaths {
}
}
+ private def foldDynamicShiftLeft(e: DoPrim) = e.args.last match {
+ case UIntLiteral(v, IntWidth(w)) =>
+ val shl = DoPrim(Shl, Seq(e.args.head), Seq(v), UnknownType)
+ pad(PrimOps.set_primop_type(shl), e.tpe)
+ case _ => e
+ }
+
private def foldShiftRight(e: DoPrim) = e.consts.head.toInt match {
case 0 => e.args.head
case x => e.args.head match {
@@ -148,6 +155,14 @@ class ConstantPropagation extends Transform with ResolvedAnnotationPaths {
}
}
+ private def foldDynamicShiftRight(e: DoPrim) = e.args.last match {
+ case UIntLiteral(v, IntWidth(w)) =>
+ val shr = DoPrim(Shr, Seq(e.args.head), Seq(v), UnknownType)
+ pad(PrimOps.set_primop_type(shr), e.tpe)
+ case _ => e
+ }
+
+
private def foldComparison(e: DoPrim) = {
def foldIfZeroedArg(x: Expression): Expression = {
def isUInt(e: Expression): Boolean = e.tpe match {
@@ -221,7 +236,9 @@ class ConstantPropagation extends Transform with ResolvedAnnotationPaths {
private def constPropPrim(e: DoPrim): Expression = e.op match {
case Shl => foldShiftLeft(e)
+ case Dshl => foldDynamicShiftLeft(e)
case Shr => foldShiftRight(e)
+ case Dshr => foldDynamicShiftRight(e)
case Cat => foldConcat(e)
case Add => FoldADD(e)
case And => FoldAND(e)
diff --git a/src/test/scala/firrtlTests/ConstantPropagationTests.scala b/src/test/scala/firrtlTests/ConstantPropagationTests.scala
index a6df1a3b..8a69fcaa 100644
--- a/src/test/scala/firrtlTests/ConstantPropagationTests.scala
+++ b/src/test/scala/firrtlTests/ConstantPropagationTests.scala
@@ -1122,6 +1122,77 @@ class ConstantPropagationIntegrationSpec extends LowTransformSpec {
| z <= _T_61""".stripMargin
execute(input, check, Seq.empty)
}
+
+ behavior of "ConstProp"
+
+ it should "optimize shl of constants" in {
+ val input =
+ """circuit Top :
+ | module Top :
+ | output z : UInt<7>
+ | z <= shl(UInt(5), 4)
+ """.stripMargin
+ val check =
+ """circuit Top :
+ | module Top :
+ | output z : UInt<7>
+ | z <= UInt<7>("h50")
+ """.stripMargin
+ execute(input, check, Seq.empty)
+ }
+
+ it should "optimize shr of constants" in {
+ val input =
+ """circuit Top :
+ | module Top :
+ | output z : UInt<1>
+ | z <= shr(UInt(5), 2)
+ """.stripMargin
+ val check =
+ """circuit Top :
+ | module Top :
+ | output z : UInt<1>
+ | z <= UInt<1>("h1")
+ """.stripMargin
+ execute(input, check, Seq.empty)
+ }
+
+ // Due to #866, we need dshl optimized away or it'll become a dshlw and error in parsing
+ // Include cat to verify width is correct
+ it should "optimize dshl of constant" in {
+ val input =
+ """circuit Top :
+ | module Top :
+ | output z : UInt<8>
+ | node n = dshl(UInt<1>(0), UInt<2>(0))
+ | z <= cat(UInt<4>("hf"), n)
+ """.stripMargin
+ val check =
+ """circuit Top :
+ | module Top :
+ | output z : UInt<8>
+ | z <= UInt<8>("hf0")
+ """.stripMargin
+ execute(input, check, Seq.empty)
+ }
+
+ // Include cat and constants to verify width is correct
+ it should "optimize dshr of constant" in {
+ val input =
+ """circuit Top :
+ | module Top :
+ | output z : UInt<8>
+ | node n = dshr(UInt<4>(0), UInt<2>(2))
+ | z <= cat(UInt<4>("hf"), n)
+ """.stripMargin
+ val check =
+ """circuit Top :
+ | module Top :
+ | output z : UInt<8>
+ | z <= UInt<8>("hf0")
+ """.stripMargin
+ execute(input, check, Seq.empty)
+ }
}