ReduceOthers: remove constants from the balanced AND tree
This commit is contained in:
parent
48611266fa
commit
2d8b2f4edd
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user