2017-06-23 09:28:05 +02:00
|
|
|
// See LICENSE.SiFive for license details.
|
2017-06-23 04:43:20 +02:00
|
|
|
|
2017-07-07 19:48:16 +02:00
|
|
|
package freechips.rocketchip.util
|
|
|
|
|
2017-06-23 04:43:20 +02:00
|
|
|
import Chisel._
|
|
|
|
|
|
|
|
object ReduceOthers {
|
|
|
|
// Given a list of bools, create this output:
|
|
|
|
// out[i] = AND[j=0..out.size, j!=i] in[j]
|
|
|
|
def apply(x: Seq[Bool]): Seq[Bool] = {
|
2017-06-23 09:28:05 +02:00
|
|
|
val (literals, variables) = x.partition(_.isLit)
|
|
|
|
|
|
|
|
val falses = literals.count(_.litValue == 0)
|
|
|
|
if (falses > 2) {
|
|
|
|
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)
|
|
|
|
}
|
2017-06-23 04:43:20 +02:00
|
|
|
}
|
|
|
|
} else {
|
2017-06-23 09:28:05 +02:00
|
|
|
var (out, all) = helper(variables)
|
|
|
|
x.map { b =>
|
|
|
|
if (b.isLit) {
|
|
|
|
all
|
|
|
|
} else {
|
|
|
|
val sel = out.head
|
|
|
|
out = out.tail
|
|
|
|
sel
|
|
|
|
}
|
2017-06-23 04:43:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Take pairs of (output_wire, input_bool)
|
|
|
|
def apply(x: Seq[(Bool, Bool)]) {
|
|
|
|
(x.map(_._1) zip apply(x.map(_._2))) foreach { case (w, x) => w := x }
|
|
|
|
}
|
2017-06-23 09:28:05 +02:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
2017-06-23 04:43:20 +02:00
|
|
|
}
|