diff options
| author | Andrew Waterman | 2016-04-07 21:39:40 -0700 |
|---|---|---|
| committer | Andrew Waterman | 2016-04-07 21:44:02 -0700 |
| commit | 456b1c2c408a764eaa0f90c02487669a21e1d552 (patch) | |
| tree | 2aac449b2be27b957706012d4013ae0cd30d8b86 /src/main/scala/firrtl/passes/Passes.scala | |
| parent | b3874120be90f194b39eee78b74b045146b74b31 (diff) | |
Split ConstProp pass into own file; propagate lits through nodes
Diffstat (limited to 'src/main/scala/firrtl/passes/Passes.scala')
| -rw-r--r-- | src/main/scala/firrtl/passes/Passes.scala | 140 |
1 files changed, 0 insertions, 140 deletions
diff --git a/src/main/scala/firrtl/passes/Passes.scala b/src/main/scala/firrtl/passes/Passes.scala index 4f947202..ef9380d3 100644 --- a/src/main/scala/firrtl/passes/Passes.scala +++ b/src/main/scala/firrtl/passes/Passes.scala @@ -1163,146 +1163,6 @@ object Legalize extends Pass { } } -object ConstProp extends Pass { - def name = "Constant Propogation" - - trait FoldLogicalOp { - def fold(c1: UIntValue, c2: UIntValue): UIntValue - def simplify(e: Expression, lhs: UIntValue, rhs: Expression): Expression - - def apply(e: DoPrim): Expression = (e.args(0), e.args(1)) match { - case (lhs: UIntValue, rhs: UIntValue) => fold(lhs, rhs) - case (lhs: UIntValue, rhs) => simplify(e, lhs, rhs) - case (lhs, rhs: UIntValue) => simplify(e, rhs, lhs) - case _ => e - } - } - - object FoldAND extends FoldLogicalOp { - def fold(c1: UIntValue, c2: UIntValue) = UIntValue(c1.value & c2.value, c1.width max c2.width) - def simplify(e: Expression, lhs: UIntValue, rhs: Expression) = lhs.width match { - case IntWidth(w) if long_BANG(tpe(rhs)) == w => - if (lhs.value == 0) lhs // and(x, 0) => 0 - else if (lhs.value == (BigInt(1) << w.toInt) - 1) rhs // and(x, 1) => x - else e - case _ => e - } - } - - object FoldOR extends FoldLogicalOp { - def fold(c1: UIntValue, c2: UIntValue) = UIntValue(c1.value | c2.value, c1.width max c2.width) - def simplify(e: Expression, lhs: UIntValue, rhs: Expression) = lhs.width match { - case IntWidth(w) if long_BANG(tpe(rhs)) == w => - if (lhs.value == 0) rhs // or(x, 0) => x - else if (lhs.value == (BigInt(1) << w.toInt) - 1) lhs // or(x, 1) => 1 - else e - case _ => e - } - } - - object FoldXOR extends FoldLogicalOp { - def fold(c1: UIntValue, c2: UIntValue) = UIntValue(c1.value ^ c2.value, c1.width max c2.width) - def simplify(e: Expression, lhs: UIntValue, rhs: Expression) = lhs.width match { - case IntWidth(w) if long_BANG(tpe(rhs)) == w => - if (lhs.value == 0) rhs // xor(x, 0) => x - else e - case _ => e - } - } - - object FoldEqual extends FoldLogicalOp { - def fold(c1: UIntValue, c2: UIntValue) = UIntValue(if (c1.value == c2.value) 1 else 0, IntWidth(1)) - def simplify(e: Expression, lhs: UIntValue, rhs: Expression) = lhs.width match { - case IntWidth(w) if w == 1 && long_BANG(tpe(rhs)) == 1 => - if (lhs.value == 1) rhs // eq(x, 1) => x - else e - case _ => e - } - } - - object FoldNotEqual extends FoldLogicalOp { - def fold(c1: UIntValue, c2: UIntValue) = UIntValue(if (c1.value != c2.value) 1 else 0, IntWidth(1)) - def simplify(e: Expression, lhs: UIntValue, rhs: Expression) = lhs.width match { - case IntWidth(w) if w == 1 && long_BANG(tpe(rhs)) == w => - if (lhs.value == 0) rhs // neq(x, 0) => x - else e - case _ => e - } - } - - private def constPropPrim(e: DoPrim): Expression = e.op match { - case SHIFT_RIGHT_OP => { - val amount = e.consts(0).toInt - def shiftWidth(w: Width) = (w - IntWidth(amount)) max IntWidth(1) - e.args(0) match { - // TODO when amount >= x.width, return a zero-width wire - case UIntValue(v, w) => UIntValue(v >> amount, shiftWidth(w)) - // take sign bit if shift amount is larger than arg width - case SIntValue(v, w) => SIntValue(v >> amount, shiftWidth(w)) - case _ => e - } - } - case AND_OP => FoldAND(e) - case OR_OP => FoldOR(e) - case XOR_OP => FoldXOR(e) - case EQUAL_OP => FoldEqual(e) - case NEQUAL_OP => FoldNotEqual(e) - case NOT_OP => e.args(0) match { - case UIntValue(v, IntWidth(w)) => UIntValue(v ^ ((BigInt(1) << w.toInt) - 1), IntWidth(w)) - case _ => e - } - case BITS_SELECT_OP => e.args(0) match { - case UIntValue(v, w) => { - val hi = e.consts(0).toInt - val lo = e.consts(1).toInt - require(hi >= lo) - UIntValue((v >> lo) & ((BigInt(1) << (hi - lo + 1)) - 1), w) - } - case x if long_BANG(tpe(e)) == long_BANG(tpe(x)) => tpe(x) match { - case t: UIntType => x - case _ => DoPrim(AS_UINT_OP, Seq(x), Seq(), tpe(e)) - } - case _ => e - } - case _ => e - } - - private def constPropMuxCond(m: Mux) = (m.cond, tpe(m.tval), tpe(m.fval), m.tpe) match { - case (c: UIntValue, ttpe: UIntType, ftpe: UIntType, mtpe: UIntType) => - if (c.value == 1 && ttpe == mtpe) m.tval - else if (c.value == 0 && ftpe == mtpe) m.fval - else m - case _ => m - } - - private def constPropMux(m: Mux): Expression = (m.tval, m.fval) match { - case (t: UIntValue, f: UIntValue) => - if (t == f) t - else if (t.value == 1 && f.value == 0 && long_BANG(m.tpe) == 1) m.cond - else constPropMuxCond(m) - case _ => constPropMuxCond(m) - } - - private def constPropExpression(e: Expression): Expression = { - e map constPropExpression match { - case p: DoPrim => constPropPrim(p) - case m: Mux => constPropMux(m) - case x => x - } - } - - private def constPropStmt(s: Stmt): Stmt = - s map constPropStmt map constPropExpression - - def run(c: Circuit): Circuit = { - val modulesx = c.modules.map { - case m: ExModule => m - case m: InModule => InModule(m.info, m.name, m.ports, constPropStmt(m.body)) - } - Circuit(c.info, modulesx, c.main) - } -} - object LoToVerilog extends Pass with StanzaPass { def name = "Lo To Verilog" def run (c:Circuit): Circuit = stanzaPass(c, "lo-to-verilog") |
