aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/passes/Passes.scala
diff options
context:
space:
mode:
authorAndrew Waterman2016-04-07 21:39:40 -0700
committerAndrew Waterman2016-04-07 21:44:02 -0700
commit456b1c2c408a764eaa0f90c02487669a21e1d552 (patch)
tree2aac449b2be27b957706012d4013ae0cd30d8b86 /src/main/scala/firrtl/passes/Passes.scala
parentb3874120be90f194b39eee78b74b045146b74b31 (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.scala140
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")