diff --git a/src/main/scala/xiangshan/backend/CtrlBlock.scala b/src/main/scala/xiangshan/backend/CtrlBlock.scala index 50f0ae52ca69975eba7e4b628fa47ee19faeafa3..d1de6ca1867c6ee0a8a4e07fbf16bce7f5a47288 100644 --- a/src/main/scala/xiangshan/backend/CtrlBlock.scala +++ b/src/main/scala/xiangshan/backend/CtrlBlock.scala @@ -2,6 +2,7 @@ package xiangshan.backend import chisel3._ import chisel3.util._ +import utils._ import xiangshan._ import xiangshan.backend.decode.{DecodeBuffer, DecodeStage} import xiangshan.backend.rename.{Rename, BusyTable} @@ -37,7 +38,7 @@ class CtrlToLsBlockIO extends XSBundle { val redirect = ValidIO(new Redirect) } -class CtrlBlock extends XSModule { +class CtrlBlock extends XSModule with HasCircularQueuePtrHelper { val io = IO(new Bundle { val frontend = Flipped(new FrontendToBackendIO) val fromIntBlock = Flipped(new IntBlockToCtrlIO) @@ -70,18 +71,14 @@ class CtrlBlock extends XSModule { val roq = Module(new Roq(roqWbSize)) - val redirect = Mux( - roq.io.redirect.valid, - roq.io.redirect, - Mux( - brq.io.redirect.valid, - brq.io.redirect, - io.fromLsBlock.replay - ) - ) + val lsqIsAfterBrq = isAfter(io.fromLsBlock.replay.bits.roqIdx, brq.io.redirect.bits.roqIdx) + val redirectArb = Mux(brq.io.redirect.valid && (!io.fromLsBlock.replay.valid || lsqIsAfterBrq), + brq.io.redirect.bits, io.fromLsBlock.replay.bits) + val redirectValid = roq.io.redirect.valid || brq.io.redirect.valid || io.fromLsBlock.replay.valid + val redirect = Mux(roq.io.redirect.valid, roq.io.redirect.bits, redirectArb) - io.frontend.redirect.valid := roq.io.redirect.valid || brq.io.redirect.valid - io.frontend.redirect.bits := Mux(brq.io.redirect.valid, brq.io.redirect.bits.target, roq.io.redirect.bits.target) + io.frontend.redirect.valid := redirectValid + io.frontend.redirect.bits := Mux(roq.io.redirect.valid, roq.io.redirect.bits.target, redirectArb.target) io.frontend.outOfOrderBrInfo <> brq.io.outOfOrderBrInfo io.frontend.inOrderBrInfo <> brq.io.inOrderBrInfo @@ -97,15 +94,18 @@ class CtrlBlock extends XSModule { brq.io.exuRedirect <> io.fromIntBlock.exuRedirect decBuf.io.isWalking := roq.io.commits(0).valid && roq.io.commits(0).bits.isWalk - decBuf.io.redirect <> redirect + decBuf.io.redirect.valid <> redirectValid + decBuf.io.redirect.bits <> redirect decBuf.io.out <> rename.io.in - rename.io.redirect <> redirect + rename.io.redirect.valid <> redirectValid + rename.io.redirect.bits <> redirect rename.io.roqCommits <> roq.io.commits rename.io.out <> dispatch.io.fromRename rename.io.renameBypass <> dispatch.io.renameBypass - dispatch.io.redirect <> redirect + dispatch.io.redirect.valid <> redirectValid + dispatch.io.redirect.bits <> redirect dispatch.io.enqRoq <> roq.io.enq dispatch.io.enqLsq <> io.toLsBlock.enqLsq dispatch.io.dequeueRoqIndex.valid := roq.io.commitRoqIndex.valid || io.oldestStore.valid @@ -126,7 +126,7 @@ class CtrlBlock extends XSModule { dispatch.io.enqIQData <> io.toIntBlock.enqIqData ++ io.toFpBlock.enqIqData ++ io.toLsBlock.enqIqData - val flush = redirect.valid && (redirect.bits.isException || redirect.bits.isFlushPipe) + val flush = redirectValid && (redirect.isException || redirect.isFlushPipe) fpBusyTable.io.flush := flush intBusyTable.io.flush := flush for((wb, setPhyRegRdy) <- io.fromIntBlock.wbRegs.zip(intBusyTable.io.wbPregs)){ @@ -148,8 +148,10 @@ class CtrlBlock extends XSModule { fpBusyTable.io.replayPregs(i).bits := dispatch.io.replayPregReq(i).preg } - roq.io.memRedirect <> io.fromLsBlock.replay - roq.io.brqRedirect <> brq.io.redirect + roq.io.memRedirect := DontCare + roq.io.memRedirect.valid := false.B + roq.io.brqRedirect.valid := brq.io.redirect.valid || io.fromLsBlock.replay.valid + roq.io.brqRedirect.bits <> redirectArb roq.io.exeWbResults.take(roqWbSize-1).zip( io.fromIntBlock.wbRegs ++ io.fromFpBlock.wbRegs ++ io.fromLsBlock.stOut ).foreach{ @@ -159,9 +161,12 @@ class CtrlBlock extends XSModule { } roq.io.exeWbResults.last := brq.io.out - io.toIntBlock.redirect := redirect - io.toFpBlock.redirect := redirect - io.toLsBlock.redirect := redirect + io.toIntBlock.redirect.valid := redirectValid + io.toIntBlock.redirect.bits := redirect + io.toFpBlock.redirect.valid := redirectValid + io.toFpBlock.redirect.bits := redirect + io.toLsBlock.redirect.valid := redirectValid + io.toLsBlock.redirect.bits := redirect // roq to int block io.roqio.toCSR <> roq.io.csr diff --git a/src/main/scala/xiangshan/backend/brq/Brq.scala b/src/main/scala/xiangshan/backend/brq/Brq.scala index a596434360dffd30181f29c4dcc3fffa7854cb3e..29bc6098a1bdb607de8eb4820f9737a805dd55b9 100644 --- a/src/main/scala/xiangshan/backend/brq/Brq.scala +++ b/src/main/scala/xiangshan/backend/brq/Brq.scala @@ -224,16 +224,21 @@ class Brq extends XSModule with HasCircularQueuePtrHelper { // misprediction or replay stateQueue.zipWithIndex.foreach({case(s, i) => val ptr = BrqPtr(brQueue(i).ptrFlag, i.U) - when(s.isWb && brQueue(i).exuOut.uop.roqIdx.needFlush(io.memRedirect)){ + when(io.memRedirect.valid && ptr.needBrFlush(io.memRedirect.bits.brTag)){ s := s_idle } when(io.redirect.valid && ptr.needBrFlush(io.redirect.bits.brTag)){ s := s_invalid } }) - when(io.redirect.valid){ // Only Br Mispred reset tailPtr, replay does not - tailPtr := io.redirect.bits.brTag + true.B + when(io.redirect.valid || io.memRedirect.valid){ + when (!io.memRedirect.valid || isAfter(io.memRedirect.bits.brTag, io.redirect.bits.brTag)) { + tailPtr := io.redirect.bits.brTag + 1.U + }.otherwise { + tailPtr := io.memRedirect.bits.brTag + 1.U + } } + } diff --git a/src/main/scala/xiangshan/backend/decode/DecodeBuffer.scala b/src/main/scala/xiangshan/backend/decode/DecodeBuffer.scala index 4da6641f234e957d3c151305ffaa177e732461c3..4bc1e3d03b24471d600f7343a2609e08c532d4bc 100644 --- a/src/main/scala/xiangshan/backend/decode/DecodeBuffer.scala +++ b/src/main/scala/xiangshan/backend/decode/DecodeBuffer.scala @@ -24,7 +24,7 @@ class DecodeBuffer extends XSModule { }) ) - val flush = io.redirect.valid && !io.redirect.bits.isReplay + val flush = io.redirect.valid// && !io.redirect.bits.isReplay for( i <- 0 until RenameWidth){ when(io.out(i).fire()){ diff --git a/src/main/scala/xiangshan/backend/dispatch/Dispatch.scala b/src/main/scala/xiangshan/backend/dispatch/Dispatch.scala index 81ec93929d96aedb9de4867523657188e681bc07..015f9a2b5e383213f8542aed81645510d8d3a427 100644 --- a/src/main/scala/xiangshan/backend/dispatch/Dispatch.scala +++ b/src/main/scala/xiangshan/backend/dispatch/Dispatch.scala @@ -67,7 +67,7 @@ class Dispatch extends XSModule { // pipeline between rename and dispatch // accepts all at once - val redirectValid = io.redirect.valid && !io.redirect.bits.isReplay + val redirectValid = io.redirect.valid// && !io.redirect.bits.isReplay for (i <- 0 until RenameWidth) { PipelineConnect(io.fromRename(i), dispatch1.io.fromRename(i), dispatch1.io.recv(i), redirectValid) } diff --git a/src/main/scala/xiangshan/backend/dispatch/Dispatch1.scala b/src/main/scala/xiangshan/backend/dispatch/Dispatch1.scala index e1ec9dbf9982d069eaf281cd01e2423cbbaf8960..e1634e92e490474d3489bce8fa905d3223804699 100644 --- a/src/main/scala/xiangshan/backend/dispatch/Dispatch1.scala +++ b/src/main/scala/xiangshan/backend/dispatch/Dispatch1.scala @@ -122,7 +122,7 @@ class Dispatch1 extends XSModule { * acquire ROQ (all), LSQ (load/store only) and dispatch queue slots * only set valid when all of them provides enough entries */ - val redirectValid = io.redirect.valid && !io.redirect.bits.isReplay + val redirectValid = io.redirect.valid// && !io.redirect.bits.isReplay val allResourceReady = io.enqLsq.canAccept && io.enqRoq.canAccept && io.toIntDqReady && io.toFpDqReady && io.toLsDqReady // Instructions should enter dispatch queues in order. diff --git a/src/main/scala/xiangshan/backend/dispatch/DispatchQueue.scala b/src/main/scala/xiangshan/backend/dispatch/DispatchQueue.scala index f0b305f1e1507c7f73f3b35e3981fb1b20fa65e5..d549935a40ac75986bdd7beaeb1246f2b5ed9d19 100644 --- a/src/main/scala/xiangshan/backend/dispatch/DispatchQueue.scala +++ b/src/main/scala/xiangshan/backend/dispatch/DispatchQueue.scala @@ -62,7 +62,7 @@ class DispatchQueue(size: Int, enqnum: Int, deqnum: Int, replayWidth: Int) exten val allWalkDone = !io.inReplayWalk && io.otherWalkDone val canEnqueue = validEntries <= (size - enqnum).U && allWalkDone - val canActualEnqueue = canEnqueue && !(io.redirect.valid && !io.redirect.bits.isReplay) + val canActualEnqueue = canEnqueue && !(io.redirect.valid /*&& !io.redirect.bits.isReplay*/) /** * Part 1: update states and uops when enqueue, dequeue, commit, redirect/replay @@ -109,7 +109,7 @@ class DispatchQueue(size: Int, enqnum: Int, deqnum: Int, replayWidth: Int) exten } // redirect: cancel uops currently in the queue - val mispredictionValid = io.redirect.valid && io.redirect.bits.isMisPred + val mispredictionValid = io.redirect.valid //&& io.redirect.bits.isMisPred val exceptionValid = io.redirect.valid && io.redirect.bits.isException val flushPipeValid = io.redirect.valid && io.redirect.bits.isFlushPipe val roqNeedFlush = Wire(Vec(size, Bool())) @@ -128,7 +128,7 @@ class DispatchQueue(size: Int, enqnum: Int, deqnum: Int, replayWidth: Int) exten } // replay: from s_dispatched to s_valid - val replayValid = io.redirect.valid && io.redirect.bits.isReplay + val replayValid = false.B//io.redirect.valid && io.redirect.bits.isReplay val needReplay = Wire(Vec(size, Bool())) for (i <- 0 until size) { needReplay(i) := roqNeedFlush(i) && stateEntries(i) === s_dispatched && replayValid diff --git a/src/main/scala/xiangshan/backend/roq/Roq.scala b/src/main/scala/xiangshan/backend/roq/Roq.scala index 55e419015959020525496dd6211ff3b9b40ff249..9b120597b035c3b30e84099e925ff12a71403b2e 100644 --- a/src/main/scala/xiangshan/backend/roq/Roq.scala +++ b/src/main/scala/xiangshan/backend/roq/Roq.scala @@ -425,14 +425,14 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper { } // rollback: write all // when rollback, reset writebacked entry to valid - when(io.memRedirect.valid) { // TODO: opt timing - for (i <- 0 until RoqSize) { - val recRoqIdx = RoqPtr(flagBkup(i), i.U) - when (valid(i) && isAfter(recRoqIdx, io.memRedirect.bits.roqIdx)) { - writebacked(i) := false.B - } - } - } + // when(io.memRedirect.valid) { // TODO: opt timing + // for (i <- 0 until RoqSize) { + // val recRoqIdx = RoqPtr(flagBkup(i), i.U) + // when (valid(i) && isAfter(recRoqIdx, io.memRedirect.bits.roqIdx)) { + // writebacked(i) := false.B + // } + // } + // } // read // deqPtrWritebacked diff --git a/src/main/scala/xiangshan/mem/lsqueue/LoadQueue.scala b/src/main/scala/xiangshan/mem/lsqueue/LoadQueue.scala index e1db86e16b83f3d4777b0508291d7c7e7755ba9e..324c6c567aa6efdbe8411c6437acf83b7c77d10c 100644 --- a/src/main/scala/xiangshan/mem/lsqueue/LoadQueue.scala +++ b/src/main/scala/xiangshan/mem/lsqueue/LoadQueue.scala @@ -433,6 +433,8 @@ class LoadQueue extends XSModule with HasDCacheParameters with HasCircularQueueP rollback(i).bits.isMisPred := false.B rollback(i).bits.isException := false.B rollback(i).bits.isFlushPipe := false.B + rollback(i).bits.target := rollbackUop.cf.pc + rollback(i).bits.brTag := rollbackUop.brTag XSDebug( l1Violation, @@ -529,15 +531,15 @@ class LoadQueue extends XSModule with HasDCacheParameters with HasCircularQueueP for (i <- 0 until LoadQueueSize) { needCancel(i) := uop(i).roqIdx.needFlush(io.brqRedirect) && allocated(i) && !commited(i) when(needCancel(i)) { - when(io.brqRedirect.bits.isReplay){ - valid(i) := false.B - writebacked(i) := false.B - listening(i) := false.B - miss(i) := false.B - pending(i) := false.B - }.otherwise{ + // when(io.brqRedirect.bits.isReplay){ + // valid(i) := false.B + // writebacked(i) := false.B + // listening(i) := false.B + // miss(i) := false.B + // pending(i) := false.B + // }.otherwise{ allocated(i) := false.B - } + // } } } when (io.brqRedirect.valid && io.brqRedirect.bits.isMisPred) { diff --git a/src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala b/src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala index f31e32db0f3e41e79292c0c9cc8405fd5dc992ef..93d4972157349cff9b46368ac3f22ae357bb4cb5 100644 --- a/src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala +++ b/src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala @@ -340,13 +340,13 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue for (i <- 0 until StoreQueueSize) { needCancel(i) := uop(i).roqIdx.needFlush(io.brqRedirect) && allocated(i) && !commited(i) when(needCancel(i)) { - when(io.brqRedirect.bits.isReplay){ - datavalid(i) := false.B - writebacked(i) := false.B - pending(i) := false.B - }.otherwise{ + // when(io.brqRedirect.bits.isReplay){ + // datavalid(i) := false.B + // writebacked(i) := false.B + // pending(i) := false.B + // }.otherwise{ allocated(i) := false.B - } + // } } } when (io.brqRedirect.valid && io.brqRedirect.bits.isMisPred) {