未验证 提交 cba0c52f 编写于 作者: Y Yinan Xu 提交者: GitHub

Merge pull request #162 from RISCVERS/brq-opt

Optimize brq
...@@ -17,4 +17,27 @@ object PriorityEncoderDefault { ...@@ -17,4 +17,27 @@ object PriorityEncoderDefault {
def apply(in: Seq[Bool], default: UInt): UInt = { def apply(in: Seq[Bool], default: UInt): UInt = {
PriorityMuxDefault(in.zipWithIndex.map(x => x._1 -> x._2.U), default) PriorityMuxDefault(in.zipWithIndex.map(x => x._1 -> x._2.U), default)
} }
}
object PriorityMuxWithFlag {
def apply[T <: Data](in: Seq[(Bool, T)]): (T, Bool) = {
in.size match {
case 1 =>
(in.head._2, in.head._1)
case _ =>
val (d_tail, f_tail) = PriorityMuxWithFlag(in.tail)
val d_head = in.head._2
val f_head = in.head._1
(Mux(f_head, d_head, d_tail), f_head || f_tail)
}
}
}
object PriorityEncoderWithFlag {
def apply(in: Seq[Bool]): (UInt, Bool) = {
PriorityMuxWithFlag(in.zipWithIndex.map(x => x._1 -> x._2.U))
}
def apply(in: Bits): (UInt, Bool) = {
PriorityEncoderWithFlag(in.asBools())
}
} }
\ No newline at end of file
...@@ -72,9 +72,6 @@ class BrqIO extends XSBundle{ ...@@ -72,9 +72,6 @@ class BrqIO extends XSBundle{
class Brq extends XSModule { class Brq extends XSModule {
val io = IO(new BrqIO) val io = IO(new BrqIO)
def redirctWindowSize: Int = BrqSize/2
require(redirctWindowSize <= BrqSize && redirctWindowSize > 0)
class BrqEntry extends Bundle { class BrqEntry extends Bundle {
val ptrFlag = Bool() val ptrFlag = Bool()
val npc = UInt(VAddrBits.W) val npc = UInt(VAddrBits.W)
...@@ -103,23 +100,42 @@ class Brq extends XSModule { ...@@ -103,23 +100,42 @@ class Brq extends XSModule {
// dequeue // dequeue
val headIdx = headPtr.value val headIdx = headPtr.value
var commitIdx = WireInit(headIdx)
def needCheckNext(idx: UInt): Bool = { val skipMask = Cat(stateQueue.zipWithIndex.map({
(stateQueue(idx).isWb && !brQueue(idx).misPred) || stateQueue(idx).isCommit case (s, i) => (s.isWb && !brQueue(i).misPred) || s.isCommit
}).reverse)
/*
example: headIdx = 2
headIdxOH = 00000100
headIdxMaskHI = 11111100
headIdxMaskLo = 00000011
skipMask = 00111101
commitIdxHi = 6
commitIdxLo = 0
commitIdx = 6
*/
val headIdxOH = UIntToOH(headIdx)
val headIdxMaskHiVec = Wire(Vec(BrqSize, Bool()))
for(i <- headIdxMaskHiVec.indices){
headIdxMaskHiVec(i) := { if(i==0) headIdxOH(i) else headIdxMaskHiVec(i-1) || headIdxOH(i) }
} }
val headIdxMaskHi = headIdxMaskHiVec.asUInt()
val headIdxMaskLo = (~headIdxMaskHi).asUInt()
val commitIdxHi = PriorityEncoder((~skipMask).asUInt() & headIdxMaskHi)
val (commitIdxLo, findLo) = PriorityEncoderWithFlag((~skipMask).asUInt() & headIdxMaskLo)
var checkNext = WireInit(needCheckNext(headIdx)) val skipHi = (skipMask | headIdxMaskLo) === Fill(BrqSize, 1.U(1.W))
val useLo = skipHi && findLo
for(i <- 1 until redirctWindowSize){ val commitIdx = Mux(stateQueue(commitIdxHi).isWb && brQueue(commitIdxHi).misPred,
val idx = commitIdx + i.U commitIdxHi,
val commitThis = checkNext && stateQueue(idx).isWb && brQueue(idx).misPred Mux(useLo && stateQueue(commitIdxLo).isWb && brQueue(commitIdxLo).misPred,
commitIdx = Mux(commitThis, commitIdxLo,
idx, headIdx
commitIdx
) )
checkNext = checkNext && needCheckNext(idx) )
}
val commitIsHead = commitIdx===headIdx val commitIsHead = commitIdx===headIdx
val deqValid = !stateQueue(headIdx).isIdle && commitIsHead && brCommitCnt=/=0.U val deqValid = !stateQueue(headIdx).isIdle && commitIsHead && brCommitCnt=/=0.U
...@@ -134,10 +150,16 @@ class Brq extends XSModule { ...@@ -134,10 +150,16 @@ class Brq extends XSModule {
io.inOrderBrInfo.misPred := commitEntry.misPred io.inOrderBrInfo.misPred := commitEntry.misPred
io.inOrderBrInfo.redirect := commitEntry.exuOut.redirect io.inOrderBrInfo.redirect := commitEntry.exuOut.redirect
// XSDebug(
// p"commitIdxHi:$commitIdxHi ${Binary(headIdxMaskHi)} ${Binary(skipMask)}\n"
// )
// XSDebug(
// p"commitIdxLo:$commitIdxLo ${Binary(headIdxMaskLo)} ${Binary(skipMask)}\n"
// )
XSDebug(p"headIdx:$headIdx commitIdx:$commitIdx\n") XSDebug(p"headIdx:$headIdx commitIdx:$commitIdx\n")
XSDebug(p"headPtr:$headPtr tailPtr:$tailPtr\n") XSDebug(p"headPtr:$headPtr tailPtr:$tailPtr\n")
XSDebug("") XSDebug("")
stateQueue.map(s =>{ stateQueue.reverse.map(s =>{
XSDebug(false, s.isIdle, "-") XSDebug(false, s.isIdle, "-")
XSDebug(false, s.isWb, "w") XSDebug(false, s.isWb, "w")
XSDebug(false, s.isCommit, "c") XSDebug(false, s.isCommit, "c")
......
...@@ -20,11 +20,11 @@ class BrqTest extends FlatSpec ...@@ -20,11 +20,11 @@ class BrqTest extends FlatSpec
with ParallelTestExecution with ParallelTestExecution
with HasPartialDecoupledDriver { with HasPartialDecoupledDriver {
it should "redirect out-of-order, dequeue in-order" in { it should "redirect out-of-order, dequeue in-order" in {
XSLog.generateLog = false XSLog.generateLog = true
test(new Brq { test(new Brq {
AddSinks() AddSinks()
}).withAnnotations(Seq(VerilatorBackendAnnotation)) { c => }).withAnnotations(Seq()) { c =>
def genEnqReq(x: => DecoupledIO[CfCtrl], pc: Long) = { def genEnqReq(x: => DecoupledIO[CfCtrl], pc: Long) = {
chiselTypeOf(x.bits).Lit( chiselTypeOf(x.bits).Lit(
...@@ -51,7 +51,7 @@ class BrqTest extends FlatSpec ...@@ -51,7 +51,7 @@ class BrqTest extends FlatSpec
} }
var enqTags = List.tabulate(10)(i => i) var enqTags = List.tabulate(10)(i => i)
val misPred = Random.nextInt(10) val misPred = 6
println(s"enqTags:$enqTags misPredTag:$misPred") println(s"enqTags:$enqTags misPredTag:$misPred")
enqTags = enqTags.take(misPred + 1) enqTags = enqTags.take(misPred + 1)
var commitTags, deqTags = List[Int]() var commitTags, deqTags = List[Int]()
...@@ -91,6 +91,8 @@ class BrqTest extends FlatSpec ...@@ -91,6 +91,8 @@ class BrqTest extends FlatSpec
} }
} }
c.io.bcommit.poke((misPred+1).U) c.io.bcommit.poke((misPred+1).U)
c.clock.step(1)
c.io.bcommit.poke(0.U)
while (deqTags.size != misPred+1) { while (deqTags.size != misPred+1) {
checkCommit checkCommit
checkDeq checkDeq
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册