aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJack Koenig2017-07-18 10:10:18 -0700
committerGitHub2017-07-18 10:10:18 -0700
commita54e32ab20ef521d18080f1c02d77339118b95e2 (patch)
tree76de155cd5314bdee2cbac07066d829c85a63b6d /src
parent661147d84d8c27a5b4f051ced12ebf7efecb40dc (diff)
parent97642d6ddeca4e2109010ac5d6a0a199df01f28c (diff)
Merge pull request #626 from freechipsproject/fix-swap-bug
Fix ConstProp bug where multiple names would swap with one
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/firrtl/transforms/ConstantPropagation.scala6
-rw-r--r--src/test/scala/firrtlTests/ConstantPropagationTests.scala57
2 files changed, 61 insertions, 2 deletions
diff --git a/src/main/scala/firrtl/transforms/ConstantPropagation.scala b/src/main/scala/firrtl/transforms/ConstantPropagation.scala
index bf8b1a55..d5a4b7e1 100644
--- a/src/main/scala/firrtl/transforms/ConstantPropagation.scala
+++ b/src/main/scala/firrtl/transforms/ConstantPropagation.scala
@@ -304,7 +304,9 @@ class ConstantPropagation extends Transform {
// When propagating a reference, check if we want to keep the name that would be deleted
def propagateRef(lname: String, value: Expression): Unit = {
value match {
- case WRef(rname,_,_,_) if betterName(lname, rname) =>
+ case WRef(rname,_,_,_) if betterName(lname, rname) && !swapMap.contains(rname) =>
+ assert(!swapMap.contains(lname)) // <- Shouldn't be possible because lname is either a
+ // node declaration or the single connection to a wire or register
swapMap += (lname -> rname, rname -> lname)
case _ =>
}
@@ -315,7 +317,7 @@ class ConstantPropagation extends Transform {
val stmtx = s map constPropStmt map constPropExpression
stmtx match {
case x: DefNode if !dontTouches.contains(x.name) => propagateRef(x.name, x.value)
- case Connect(_, WRef(wname, wtpe, WireKind, _), expr) if !dontTouches.contains(wname) =>
+ case Connect(_, WRef(wname, wtpe, WireKind, _), expr: Literal) if !dontTouches.contains(wname) =>
val exprx = constPropExpression(pad(expr, wtpe))
propagateRef(wname, exprx)
// Const prop registers that are fed only a constant or a mux between and constant and the
diff --git a/src/test/scala/firrtlTests/ConstantPropagationTests.scala b/src/test/scala/firrtlTests/ConstantPropagationTests.scala
index 75c43cf2..e42ecfac 100644
--- a/src/test/scala/firrtlTests/ConstantPropagationTests.scala
+++ b/src/test/scala/firrtlTests/ConstantPropagationTests.scala
@@ -451,6 +451,63 @@ class ConstantPropagationSpec extends FirrtlFlatSpec {
"""
(parse(exec(input))) should be (parse(check))
}
+
+ // =============================
+ "ConstProp" should "only swap a given name with one other name" in {
+ val input =
+"""circuit Top :
+ module Top :
+ input x : UInt<1>
+ input y : UInt<1>
+ output z : UInt<3>
+ node _T_1 = add(x, y)
+ node n = _T_1
+ node m = _T_1
+ z <= add(n, m)
+"""
+ val check =
+"""circuit Top :
+ module Top :
+ input x : UInt<1>
+ input y : UInt<1>
+ output z : UInt<3>
+ node n = add(x, y)
+ node _T_1 = n
+ node m = n
+ z <= add(n, n)
+"""
+ (parse(exec(input))) should be (parse(check))
+ }
+
+ "ConstProp" should "NOT swap wire names with node names" in {
+ val input =
+"""circuit Top :
+ module Top :
+ input clock : Clock
+ input x : UInt<1>
+ input y : UInt<1>
+ output z : UInt<1>
+ wire hit : UInt<1>
+ node _T_1 = or(x, y)
+ node _T_2 = eq(_T_1, UInt<1>(1))
+ hit <= _T_2
+ z <= hit
+"""
+ val check =
+"""circuit Top :
+ module Top :
+ input clock : Clock
+ input x : UInt<1>
+ input y : UInt<1>
+ output z : UInt<1>
+ wire hit : UInt<1>
+ node _T_1 = or(x, y)
+ node _T_2 = _T_1
+ hit <= _T_1
+ z <= hit
+"""
+ (parse(exec(input))) should be (parse(check))
+ }
}
// More sophisticated tests of the full compiler