diff --git a/src/main/scala/xiangshan/backend/brq/Brq.scala b/src/main/scala/xiangshan/backend/brq/Brq.scala index 0bfeaf43434403068e91398d39a0dc11de524027..48e8fff748db789372d4595cde187409bcd22413 100644 --- a/src/main/scala/xiangshan/backend/brq/Brq.scala +++ b/src/main/scala/xiangshan/backend/brq/Brq.scala @@ -82,37 +82,11 @@ class Brq extends XSModule with HasCircularQueuePtrHelper { val stateQueue = RegInit(VecInit(Seq.fill(BrqSize)(s_invalid))) val headPtr, tailPtr = RegInit(BrqPtr(false.B, 0.U)) + val redirectPtr = RegInit(BrqPtr(false.B, 0.U)) - // dequeue val headIdx = headPtr.value - val skipMask = Cat(stateQueue.map(_.isCommit).reverse) - - /* - example: headIdx = 2 - headIdxMaskHi = 11111100 - headIdxMaskLo = 00000011 - commitIdxHi = 6 - commitIdxLo = 0 - commitIdx = 6 - */ - val headIdxMaskLo = UIntToMask(headIdx, BrqSize) - val headIdxMaskHi = ~headIdxMaskLo - - val commitIdxHi = PriorityEncoder((~skipMask).asUInt() & headIdxMaskHi) - val (commitIdxLo, findLo) = PriorityEncoderWithFlag((~skipMask).asUInt() & headIdxMaskLo) - - val skipHi = (skipMask | headIdxMaskLo) === Fill(BrqSize, 1.U(1.W)) - val useLo = skipHi && findLo - - - val commitIdx = Mux(stateQueue(commitIdxHi).isWb, - commitIdxHi, - Mux(useLo && stateQueue(commitIdxLo).isWb, - commitIdxLo, - headIdx - ) - ) + val commitIdx = redirectPtr.value val deqValid = stateQueue(headIdx).isCommit && brCommitCnt=/=0.U val commitValid = stateQueue(commitIdx).isWb @@ -148,7 +122,7 @@ class Brq extends XSModule with HasCircularQueuePtrHelper { } assert(!(commitIdx===headIdx && commitValid && deqValid), "Error: deq and commit a same entry!") - headPtr := headPtrNext + headPtr := Mux(deqValid, headPtr + 1.U, headPtr) io.redirect.valid := commitValid && commitIsMisPred //&& // !io.roqRedirect.valid && @@ -160,8 +134,8 @@ class Brq extends XSModule with HasCircularQueuePtrHelper { io.outOfOrderBrInfo.valid := commitValid io.outOfOrderBrInfo.bits := commitEntry.exuOut.brUpdate - when (io.redirect.valid) { - commitEntry.npc := io.redirect.bits.target + when (commitValid) { + redirectPtr := redirectPtr + 1.U } XSInfo(io.out.valid, @@ -209,6 +183,7 @@ class Brq extends XSModule with HasCircularQueuePtrHelper { stateQueue.foreach(_ := s_invalid) headPtr := BrqPtr(false.B, 0.U) tailPtr := BrqPtr(false.B, 0.U) + redirectPtr := BrqPtr(false.B, 0.U) brCommitCnt := 0.U }.elsewhen(io.memRedirect.valid){ // misprediction or replay @@ -216,14 +191,14 @@ class Brq extends XSModule with HasCircularQueuePtrHelper { // replay should flush brTag val ptr = BrqPtr(brQueue(i).ptrFlag, i.U) val replayMatch = io.memRedirect.bits.isReplay && ptr === io.memRedirect.bits.brTag - when(io.memRedirect.valid && (ptr.needBrFlush(io.memRedirect.bits.brTag) || replayMatch)){ + when(ptr.needBrFlush(io.memRedirect.bits.brTag) || replayMatch){ s := s_invalid } }) - when(io.memRedirect.valid){ - tailPtr := io.memRedirect.bits.brTag + Mux(io.memRedirect.bits.isReplay, 0.U, 1.U) + tailPtr := io.memRedirect.bits.brTag + Mux(io.memRedirect.bits.isReplay, 0.U, 1.U) + when (io.memRedirect.bits.isReplay && (redirectPtr.needBrFlush(io.memRedirect.bits.brTag) || redirectPtr === io.memRedirect.bits.brTag)) { + redirectPtr := io.memRedirect.bits.brTag } - } // Debug info