diff --git a/src/main/scala/xiangshan/backend/CtrlBlock.scala b/src/main/scala/xiangshan/backend/CtrlBlock.scala index 59fa350810d4c9362bac9ab935006ca042e4b4d5..7f1891aaf6fe88e69df665d6cced66cc7e952dfa 100644 --- a/src/main/scala/xiangshan/backend/CtrlBlock.scala +++ b/src/main/scala/xiangshan/backend/CtrlBlock.scala @@ -292,6 +292,7 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper { rename.io.roqCommits <> roq.io.commits rename.io.out <> dispatch.io.fromRename rename.io.renameBypass <> dispatch.io.renameBypass + rename.io.dispatchInfo <> dispatch.io.preDpInfo dispatch.io.redirect <> backendRedirect dispatch.io.flush := flushReg diff --git a/src/main/scala/xiangshan/backend/dispatch/Dispatch.scala b/src/main/scala/xiangshan/backend/dispatch/Dispatch.scala index 352c8e414b731a8d1a9778563d2c3b1ef88a1a1e..7f1a0e2bc28d8498e3553ad5c925a62dc543161c 100644 --- a/src/main/scala/xiangshan/backend/dispatch/Dispatch.scala +++ b/src/main/scala/xiangshan/backend/dispatch/Dispatch.scala @@ -28,6 +28,7 @@ class Dispatch extends XSModule { // from rename val fromRename = Vec(RenameWidth, Flipped(DecoupledIO(new MicroOp))) val renameBypass = Input(new RenameBypassInfo) + val preDpInfo = Input(new PreDispatchInfo) // to busytable: set pdest to busy (not ready) when they are dispatched val allocPregs = Vec(RenameWidth, Output(new ReplayPregReq)) // enq Roq @@ -66,6 +67,7 @@ class Dispatch extends XSModule { // dispatch 1: accept uops from rename and dispatch them to the three dispatch queues // dispatch1.io.redirect <> io.redirect dispatch1.io.renameBypass := RegEnable(io.renameBypass, io.fromRename(0).valid && dispatch1.io.fromRename(0).ready) + dispatch1.io.preDpInfo := RegEnable(io.preDpInfo, io.fromRename(0).valid && dispatch1.io.fromRename(0).ready) dispatch1.io.enqRoq <> io.enqRoq dispatch1.io.enqLsq <> io.enqLsq dispatch1.io.toIntDq <> intDq.io.enq diff --git a/src/main/scala/xiangshan/backend/dispatch/Dispatch1.scala b/src/main/scala/xiangshan/backend/dispatch/Dispatch1.scala index 786bd66c3a5563e8bd144fe61cc58af1b5998348..9c9a3d9b054b0486826156c7952a5bb61c79a2e6 100644 --- a/src/main/scala/xiangshan/backend/dispatch/Dispatch1.scala +++ b/src/main/scala/xiangshan/backend/dispatch/Dispatch1.scala @@ -10,12 +10,18 @@ import xiangshan.backend.rename.RenameBypassInfo import xiangshan.mem.LsqEnqIO import xiangshan.backend.fu.HasExceptionNO + +class PreDispatchInfo extends XSBundle { + val lsqNeedAlloc = Vec(RenameWidth, UInt(2.W)) +} + // read rob and enqueue class Dispatch1 extends XSModule with HasExceptionNO { val io = IO(new Bundle() { // from rename val fromRename = Vec(RenameWidth, Flipped(DecoupledIO(new MicroOp))) val renameBypass = Input(new RenameBypassInfo) + val preDpInfo = Input(new PreDispatchInfo) val recv = Output(Vec(RenameWidth, Bool())) // enq Roq val enqRoq = Flipped(new RoqEnqIO) @@ -147,7 +153,7 @@ class Dispatch1 extends XSModule with HasExceptionNO { io.enqRoq.req(i).bits := updatedUop(i) XSDebug(io.enqRoq.req(i).valid, p"pc 0x${Hexadecimal(io.fromRename(i).bits.cf.pc)} receives nroq ${io.enqRoq.resp(i)}\n") - io.enqLsq.needAlloc(i) := io.fromRename(i).valid && isLs(i) + io.enqLsq.needAlloc(i) := Mux(io.fromRename(i).valid, io.preDpInfo.lsqNeedAlloc(i), 0.U) io.enqLsq.req(i).valid := io.fromRename(i).valid && isLs(i) && thisCanActualOut(i) && io.enqRoq.canAccept && io.toIntDq.canAccept && io.toFpDq.canAccept && io.toLsDq.canAccept io.enqLsq.req(i).bits := updatedUop(i) io.enqLsq.req(i).bits.roqIdx := io.enqRoq.resp(i) diff --git a/src/main/scala/xiangshan/backend/rename/Rename.scala b/src/main/scala/xiangshan/backend/rename/Rename.scala index 1552d7b534b0f8177fead08d8d6a0517759e7a39..8a242ab2f6c03d8ba1fe54231d5a1b34562fbdce 100644 --- a/src/main/scala/xiangshan/backend/rename/Rename.scala +++ b/src/main/scala/xiangshan/backend/rename/Rename.scala @@ -5,6 +5,7 @@ import chisel3.util._ import xiangshan._ import utils._ import xiangshan.backend.roq.RoqPtr +import xiangshan.backend.dispatch.PreDispatchInfo class RenameBypassInfo extends XSBundle { val lsrc1_bypass = MixedVec(List.tabulate(RenameWidth-1)(i => UInt((i+1).W))) @@ -23,6 +24,7 @@ class Rename extends XSModule with HasCircularQueuePtrHelper { // to dispatch1 val out = Vec(RenameWidth, DecoupledIO(new MicroOp)) val renameBypass = Output(new RenameBypassInfo) + val dispatchInfo = Output(new PreDispatchInfo) }) def printRenameInfo(in: DecoupledIO[CfCtrl], out: DecoupledIO[MicroOp]) = { @@ -202,6 +204,12 @@ class Rename extends XSModule with HasCircularQueuePtrHelper { }).reverse) } + val isLs = VecInit(uops.map(uop => FuType.isLoadStore(uop.ctrl.fuType))) + val isStore = VecInit(uops.map(uop => FuType.isStoreExu(uop.ctrl.fuType))) + val isAMO = VecInit(uops.map(uop => FuType.isAMO(uop.ctrl.fuType))) + io.dispatchInfo.lsqNeedAlloc := VecInit((0 until RenameWidth).map(i => + Mux(isLs(i), Mux(isStore(i) && !isAMO(i), 2.U, 1.U), 0.U))) + /** * Instructions commit: update freelist and rename table */ diff --git a/src/main/scala/xiangshan/mem/lsqueue/LSQWrapper.scala b/src/main/scala/xiangshan/mem/lsqueue/LSQWrapper.scala index bbbab1edb0cf772733b2c067015bde180661c9b5..a5046075aa84865fe4738c04619e0f836a4bd2b7 100644 --- a/src/main/scala/xiangshan/mem/lsqueue/LSQWrapper.scala +++ b/src/main/scala/xiangshan/mem/lsqueue/LSQWrapper.scala @@ -29,7 +29,7 @@ class InflightBlockInfo extends XSBundle { class LsqEnqIO extends XSBundle { val canAccept = Output(Bool()) - val needAlloc = Vec(RenameWidth, Input(Bool())) + val needAlloc = Vec(RenameWidth, Input(UInt(2.W))) val req = Vec(RenameWidth, Flipped(ValidIO(new MicroOp))) val resp = Vec(RenameWidth, Output(new LSIdx)) } @@ -75,15 +75,13 @@ class LsqWrappper extends XSModule with HasDCacheParameters { loadQueue.io.enq.sqCanAccept := storeQueue.io.enq.canAccept storeQueue.io.enq.lqCanAccept := loadQueue.io.enq.canAccept for (i <- 0 until RenameWidth) { - val isStore = CommitType.lsInstIsStore(io.enq.req(i).bits.ctrl.commitType) - - loadQueue.io.enq.needAlloc(i) := io.enq.needAlloc(i) && !isStore - loadQueue.io.enq.req(i).valid := !isStore && io.enq.req(i).valid + loadQueue.io.enq.needAlloc(i) := io.enq.needAlloc(i)(0) + loadQueue.io.enq.req(i).valid := io.enq.needAlloc(i)(0) && io.enq.req(i).valid loadQueue.io.enq.req(i).bits := io.enq.req(i).bits - storeQueue.io.enq.needAlloc(i) := io.enq.needAlloc(i) && isStore - storeQueue.io.enq.req(i).valid := isStore && io.enq.req(i).valid - storeQueue.io.enq.req(i).bits := io.enq.req(i).bits + storeQueue.io.enq.needAlloc(i) := io.enq.needAlloc(i)(1) + storeQueue.io.enq.req(i).valid := io.enq.needAlloc(i)(1) && io.enq.req(i).valid + storeQueue.io.enq.req(i).bits := io.enq.req(i).bits io.enq.resp(i).lqIdx := loadQueue.io.enq.resp(i) io.enq.resp(i).sqIdx := storeQueue.io.enq.resp(i)