From ea741d6154addf0e258d21334c458e6c14c8006f Mon Sep 17 00:00:00 2001 From: Anzooooo Date: Fri, 13 Dec 2024 11:37:49 +0800 Subject: [PATCH] fix(st-ld forward): modify misaligned `forward fault` detection --- .../xiangshan/mem/lsqueue/LoadQueueReplay.scala | 4 ++-- .../scala/xiangshan/mem/lsqueue/StoreQueue.scala | 15 ++++++--------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/main/scala/xiangshan/mem/lsqueue/LoadQueueReplay.scala b/src/main/scala/xiangshan/mem/lsqueue/LoadQueueReplay.scala index 9eab647d8d0..f81ab9b0ae5 100644 --- a/src/main/scala/xiangshan/mem/lsqueue/LoadQueueReplay.scala +++ b/src/main/scala/xiangshan/mem/lsqueue/LoadQueueReplay.scala @@ -305,8 +305,8 @@ class LoadQueueReplay(implicit p: Parameters) extends XSModule for (i <- 0 until LoadQueueReplaySize) { // dequeue // FIXME: store*Ptr is not accurate - dataNotBlockVec(i) := isNotBefore(io.stDataReadySqPtr, blockSqIdx(i)) || stDataReadyVec(blockSqIdx(i).value) || io.sqEmpty // for better timing - addrNotBlockVec(i) := isNotBefore(io.stAddrReadySqPtr, blockSqIdx(i)) || !strict(i) && stAddrReadyVec(blockSqIdx(i).value) || io.sqEmpty // for better timing + dataNotBlockVec(i) := isAfter(io.stDataReadySqPtr, blockSqIdx(i)) || stDataReadyVec(blockSqIdx(i).value) || io.sqEmpty // for better timing + addrNotBlockVec(i) := isAfter(io.stAddrReadySqPtr, blockSqIdx(i)) || !strict(i) && stAddrReadyVec(blockSqIdx(i).value) || io.sqEmpty // for better timing // store address execute storeAddrInSameCycleVec(i) := VecInit((0 until StorePipelineWidth).map(w => { io.storeAddrIn(w).valid && diff --git a/src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala b/src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala index e98b7c7836d..1978d0091d2 100644 --- a/src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala +++ b/src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala @@ -674,19 +674,16 @@ class StoreQueue(implicit p: Parameters) extends XSModule // Forward result will be generated 1 cycle later (load_s2) io.forward(i).forwardMask := dataModule.io.forwardMask(i) io.forward(i).forwardData := dataModule.io.forwardData(i) + + //TODO If the previous store appears out of alignment, then simply FF, this is a very unreasonable way to do it. + //TODO But for the time being, this is the way to ensure correctness. Such a suitable opportunity to support unaligned forward. // If addr match, data not ready, mark it as dataInvalid // load_s1: generate dataInvalid in load_s1 to set fastUop - val dataInvalidMask1 = (addrValidVec.asUInt & ~dataValidVec.asUInt & vaddrModule.io.forwardMmask(i).asUInt & forwardMask1.asUInt) - val dataInvalidMask2 = (addrValidVec.asUInt & ~dataValidVec.asUInt & vaddrModule.io.forwardMmask(i).asUInt & forwardMask2.asUInt) + val dataInvalidMask1 = ((addrValidVec.asUInt & ~dataValidVec.asUInt & vaddrModule.io.forwardMmask(i).asUInt) | unaligned.asUInt & allocated.asUInt) & forwardMask1.asUInt) + val dataInvalidMask2 = ((addrValidVec.asUInt & ~dataValidVec.asUInt & vaddrModule.io.forwardMmask(i).asUInt) | unaligned.asUInt & allocated.asUInt) & forwardMask2.asUInt) val dataInvalidMask = dataInvalidMask1 | dataInvalidMask2 io.forward(i).dataInvalidFast := dataInvalidMask.orR - //TODO If the previous store appears out of alignment, then simply FF, this is a very unreasonable way to do it. - //TODO But for the time being, this is the way to ensure correctness. Such a suitable opportunity to support unaligned forward. - val unalignedMask1 = unaligned.asUInt & forwardMask1.asUInt & allocated.asUInt - val unalignedMask2 = unaligned.asUInt & forwardMask2.asUInt & allocated.asUInt - val forwardPreWithUnaligned = (unalignedMask1 | unalignedMask2).asUInt.orR - // make chisel happy val dataInvalidMask1Reg = Wire(UInt(StoreQueueSize.W)) dataInvalidMask1Reg := RegNext(dataInvalidMask1) @@ -708,7 +705,7 @@ class StoreQueue(implicit p: Parameters) extends XSModule val addrInvalidMaskReg = addrInvalidMask1Reg | addrInvalidMask2Reg // load_s2 - io.forward(i).dataInvalid := RegNext(io.forward(i).dataInvalidFast) || RegNext(forwardPreWithUnaligned) + io.forward(i).dataInvalid := RegNext(io.forward(i).dataInvalidFast) // check if vaddr forward mismatched io.forward(i).matchInvalid := vaddrMatchFailed