ReduceOthers: remove constants from the balanced AND tree
This commit is contained in:
		| @@ -135,11 +135,12 @@ object RegMapper | |||||||
|       val data = if (field.write.combinational) back.bits.data else front.bits.data |       val data = if (field.write.combinational) back.bits.data else front.bits.data | ||||||
|       val (f_riready, f_rovalid, f_data) = field.read.fn(rivalid(i) && rimask, roready(i) && romask) |       val (f_riready, f_rovalid, f_data) = field.read.fn(rivalid(i) && rimask, roready(i) && romask) | ||||||
|       val (f_wiready, f_wovalid) = field.write.fn(wivalid(i) && wimask, woready(i) && womask, data(high, low)) |       val (f_wiready, f_wovalid) = field.write.fn(wivalid(i) && wimask, woready(i) && womask, data(high, low)) | ||||||
|  |       def litOR(x: Bool, y: Bool) = if (x.isLit && x.litValue == 1) Bool(true) else x || y | ||||||
|       // Add this field to the ready-valid signals for the register |       // Add this field to the ready-valid signals for the register | ||||||
|       rifire(reg) = (rivalid(i), f_riready || !rimask) +: rifire(reg) |       rifire(reg) = (rivalid(i), litOR(f_riready, !rimask)) +: rifire(reg) | ||||||
|       wifire(reg) = (wivalid(i), f_wiready || !wimask) +: wifire(reg) |       wifire(reg) = (wivalid(i), litOR(f_wiready, !wimask)) +: wifire(reg) | ||||||
|       rofire(reg) = (roready(i), f_rovalid || !romask) +: rofire(reg) |       rofire(reg) = (roready(i), litOR(f_rovalid, !romask)) +: rofire(reg) | ||||||
|       wofire(reg) = (woready(i), f_wovalid || !womask) +: wofire(reg) |       wofire(reg) = (woready(i), litOR(f_wovalid, !womask)) +: wofire(reg) | ||||||
|       dataOut(reg) = dataOut(reg) | ((f_data << low) & (~UInt(0, width = high+1))) |       dataOut(reg) = dataOut(reg) | ((f_data << low) & (~UInt(0, width = high+1))) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| // See LICENSE.Berkeley for license details. | // See LICENSE.SiFive for license details. | ||||||
|  |  | ||||||
| package util | package util | ||||||
| import Chisel._ | import Chisel._ | ||||||
| @@ -7,16 +7,29 @@ object ReduceOthers { | |||||||
|   // Given a list of bools, create this output: |   // Given a list of bools, create this output: | ||||||
|   //   out[i] = AND[j=0..out.size, j!=i] in[j] |   //   out[i] = AND[j=0..out.size, j!=i] in[j] | ||||||
|   def apply(x: Seq[Bool]): Seq[Bool] = { |   def apply(x: Seq[Bool]): Seq[Bool] = { | ||||||
|     if (x.size <= 1) { |     val (literals, variables) = x.partition(_.isLit) | ||||||
|       Seq.fill(x.size) { Bool(true) } |  | ||||||
|     } else if (x.size <= 3) { |     val falses = literals.count(_.litValue == 0) | ||||||
|       Seq.tabulate(x.size) { i => |     if (falses > 2) { | ||||||
|         (x.take(i) ++ x.drop(i+1)).reduce(_ && _) |       Seq.fill(x.size) { Bool(false) } | ||||||
|  |     } else if (falses == 1) { | ||||||
|  |       x.map { b => | ||||||
|  |         if (b.isLit && b.litValue == 0) { | ||||||
|  |           variables.foldLeft(Bool(true))(_ && _) | ||||||
|  |         } else { | ||||||
|  |           Bool(false) | ||||||
|  |         } | ||||||
|       } |       } | ||||||
|     } else { |     } else { | ||||||
|       val half = ReduceOthers(x.grouped(2).map(_.reduce(_ && _)).toList) |       var (out, all) = helper(variables) | ||||||
|       Seq.tabulate(x.size) { i => |       x.map { b => | ||||||
|         if ((i ^ 1) >= x.size) half(i/2) else x(i ^ 1) && half(i / 2) |         if (b.isLit) { | ||||||
|  |           all | ||||||
|  |         } else { | ||||||
|  |           val sel = out.head | ||||||
|  |           out = out.tail | ||||||
|  |           sel | ||||||
|  |         } | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @@ -24,4 +37,18 @@ object ReduceOthers { | |||||||
|   def apply(x: Seq[(Bool, Bool)]) { |   def apply(x: Seq[(Bool, Bool)]) { | ||||||
|     (x.map(_._1) zip apply(x.map(_._2))) foreach { case (w, x) => w := x } |     (x.map(_._1) zip apply(x.map(_._2))) foreach { case (w, x) => w := x } | ||||||
|   } |   } | ||||||
|  |   private def helper(x: Seq[Bool]): (Seq[Bool], Bool) = { | ||||||
|  |     if (x.size <= 1) { | ||||||
|  |       (Seq.fill(x.size) { Bool(true) }, x.headOption.getOrElse(Bool(true))) | ||||||
|  |     } else if (x.size <= 3) { | ||||||
|  |       (Seq.tabulate(x.size) { i => | ||||||
|  |         (x.take(i) ++ x.drop(i+1)).reduce(_ && _) | ||||||
|  |       }, x.reduce(_ && _)) | ||||||
|  |     } else { | ||||||
|  |       val (half, all) = helper(x.grouped(2).map(_.reduce(_ && _)).toList) | ||||||
|  |       (Seq.tabulate(x.size) { i => | ||||||
|  |         if ((i ^ 1) >= x.size) half(i/2) else x(i ^ 1) && half(i / 2) | ||||||
|  |       }, all) | ||||||
|  |     } | ||||||
|  |   } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user