提交 282a07b1 编写于 作者: L LinJiawei

CtrlBlock: fix flush logic

上级 0df85908
......@@ -228,6 +228,8 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
}
ftq.io.redirect <> backendRedirect
ftq.io.flush := flush
ftq.io.flushIdx := roq.io.flushOut.bits.ftqIdx
ftq.io.flushOffset := roq.io.flushOut.bits.ftqOffset
ftq.io.frontendRedirect <> frontendRedirect
ftq.io.exuWriteback <> io.fromIntBlock.exuRedirect
......@@ -268,7 +270,7 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
// pipeline between decode and dispatch
for (i <- 0 until RenameWidth) {
PipelineConnect(decode.io.out(i), rename.io.in(i), rename.io.in(i).ready,
backendRedirect.valid || frontendRedirect.valid)
backendRedirect.valid || flush || io.frontend.redirect_cfiUpdate.valid)
}
rename.io.redirect <> backendRedirect
......
......@@ -48,6 +48,8 @@ class Ftq extends XSModule with HasCircularQueuePtrHelper {
// redirect, reset enq ptr
val redirect = Flipped(ValidIO(new Redirect))
val flush = Input(Bool())
val flushIdx = Input(new FtqPtr)
val flushOffset = Input(UInt(log2Up(PredictWidth).W))
// update mispredict target
val frontendRedirect = Flipped(ValidIO(new Redirect))
// exu write back, update info
......@@ -65,7 +67,10 @@ class Ftq extends XSModule with HasCircularQueuePtrHelper {
io.enq.ready := validEntries < FtqSize.U
io.enqPtr := tailPtr
val real_fire = io.enq.fire() && !io.redirect.valid && !io.frontendRedirect.valid && !io.flush
val stage2Flush = io.redirect.valid || io.flush
val stage3Flush = RegNext(stage2Flush)
val real_fire = io.enq.fire() && !stage2Flush && !stage3Flush
val dataModule = Module(new DataModuleTemplate(new FtqEntry, FtqSize, 4, 1, true))
dataModule.io.wen(0) := real_fire
......@@ -164,18 +169,13 @@ class Ftq extends XSModule with HasCircularQueuePtrHelper {
}
// redirect, reset ptr
when(io.flush) { // flush pipe / exception
// clear ftq
tailPtr := headPtr
commitStateQueue(headPtr.value).foreach(_ := s_invalid)
assert(headPtr === io.redirect.bits.ftqIdx)
}.elsewhen(io.redirect.valid) { // branch misprediction or load replay
val isReplay = RedirectLevel.flushItself(io.redirect.bits.level)
when(io.flush || io.redirect.valid){
val idx = Mux(io.flush, io.flushIdx, io.redirect.bits.ftqIdx)
val next = io.redirect.bits.ftqIdx + 1.U
tailPtr := next
val offset = io.redirect.bits.ftqOffset
commitStateQueue(io.redirect.bits.ftqIdx.value).zipWithIndex.foreach({ case (s, i) =>
when(i.U > offset || (isReplay && i.U === offset)) { // replay will not commit
val offset = Mux(io.flush, io.flushOffset, io.redirect.bits.ftqOffset)
commitStateQueue(idx.value).zipWithIndex.foreach({ case (s, i) =>
when(i.U > offset){
s := s_invalid
}
})
......
......@@ -438,8 +438,9 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
val dirty_fs = Mux(io.commits.isWalk, false.B, Cat(fpWen).orR())
// when mispredict branches writeback, stop commit in the next 2 cycles
// TODO: don't check all exu write back
val misPredWb = Cat(VecInit((0 until numWbPorts).map(i =>
io.exeWbResults(i).bits.redirect.cfiUpdate.isMisPred && io.exeWbResults(i).valid
io.exeWbResults(i).bits.redirect.cfiUpdate.isMisPred && io.exeWbResults(i).bits.redirectValid
))).orR()
val misPredBlockCounter = Reg(UInt(2.W))
misPredBlockCounter := Mux(misPredWb,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册