提交 10aac6e7 编写于 作者: W William Wang

Lsq, Roq: ld/st commit logic refactor

上级 71aa513d
......@@ -451,8 +451,7 @@ class XSCoreImp(outer: XSCore) extends LazyModuleImp(outer)
floatBlock.io.frm <> integerBlock.io.csrio.frm
memBlock.io.lsqio.commits <> ctrlBlock.io.roqio.commits
memBlock.io.lsqio.roqDeqPtr <> ctrlBlock.io.roqio.roqDeqPtr
memBlock.io.lsqio.roq <> ctrlBlock.io.roqio.lsq
memBlock.io.lsqio.exceptionAddr.lsIdx.lqIdx := ctrlBlock.io.roqio.exception.bits.lqIdx
memBlock.io.lsqio.exceptionAddr.lsIdx.sqIdx := ctrlBlock.io.roqio.exception.bits.sqIdx
memBlock.io.lsqio.exceptionAddr.isStore := CommitType.lsInstIsStore(ctrlBlock.io.roqio.exception.bits.ctrl.commitType)
......
......@@ -11,7 +11,7 @@ import xiangshan.backend.dispatch.Dispatch
import xiangshan.backend.exu._
import xiangshan.backend.exu.Exu.exuConfigs
import xiangshan.backend.regfile.RfReadPort
import xiangshan.backend.roq.{Roq, RoqCSRIO, RoqPtr}
import xiangshan.backend.roq.{Roq, RoqCSRIO, RoqLsqIO, RoqPtr}
import xiangshan.mem.LsqEnqIO
class CtrlToIntBlockIO extends XSBundle {
......@@ -52,8 +52,7 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
val exception = ValidIO(new MicroOp)
val isInterrupt = Output(Bool())
// to mem block
val commits = new RoqCommitIO
val roqDeqPtr = Output(new RoqPtr)
val lsq = new RoqLsqIO
}
})
......@@ -161,6 +160,5 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
io.roqio.exception.bits := roq.io.exception
io.roqio.isInterrupt := roq.io.redirectOut.bits.interrupt
// roq to mem block
io.roqio.roqDeqPtr := roq.io.roqDeqPtr
io.roqio.commits := roq.io.commits
io.roqio.lsq <> roq.io.lsq
}
......@@ -7,7 +7,7 @@ import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp}
import freechips.rocketchip.tile.HasFPUParameters
import xiangshan._
import xiangshan.backend.exu.Exu.{loadExuConfigs, storeExuConfigs}
import xiangshan.backend.roq.RoqPtr
import xiangshan.backend.roq.{RoqPtr, RoqLsqIO}
import xiangshan.backend.exu._
import xiangshan.cache._
import xiangshan.mem._
......@@ -77,8 +77,7 @@ class MemBlockImp
val lsqio = new Bundle {
val exceptionAddr = new ExceptionAddrIO // to csr
val commits = Flipped(new RoqCommitIO) // to lsq
val roqDeqPtr = Input(new RoqPtr) // to lsq
val roq = Flipped(new RoqLsqIO) // roq to lsq
}
val toDCachePrefetch = DecoupledIO(new MissReq)
......@@ -240,10 +239,9 @@ class MemBlockImp
}
// Lsq
lsq.io.commits <> io.lsqio.commits
lsq.io.roq <> io.lsqio.roq
lsq.io.enq <> io.fromCtrlBlock.enqLsq
lsq.io.brqRedirect <> io.fromCtrlBlock.redirect
lsq.io.roqDeqPtr <> io.lsqio.roqDeqPtr
io.toCtrlBlock.replay <> lsq.io.rollback
lsq.io.dcache <> dcache.io.lsu.lsq
lsq.io.uncache <> uncache.io.lsq
......
......@@ -43,6 +43,14 @@ class RoqCSRIO extends XSBundle {
}
}
class RoqLsqIO extends XSBundle {
val lcommit = Output(UInt(3.W))
val scommit = Output(UInt(3.W))
val pendingld = Output(Bool())
val pendingst = Output(Bool())
val commit = Output(Bool())
}
class RoqEnqIO extends XSBundle {
val canAccept = Output(Bool())
val isEmpty = Output(Bool())
......@@ -204,6 +212,7 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
// exu + brq
val exeWbResults = Vec(numWbPorts, Flipped(ValidIO(new ExuOutput)))
val commits = new RoqCommitIO
val lsq = new RoqLsqIO
val bcommit = Output(UInt(BrTagWidth.W))
val roqDeqPtr = Output(new RoqPtr)
val csr = new RoqCSRIO
......@@ -442,12 +451,22 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
io.commits.info.map(info => dontTouch(info.pc))
}
// sync fflags/dirty_fs to csr
io.csr.fflags := fflags
io.csr.dirty_fs := dirty_fs
// commit branch to brq
val cfiCommitVec = VecInit(io.commits.valid.zip(io.commits.info.map(_.commitType)).map{case(v, t) => v && CommitType.isBranch(t)})
io.bcommit := Mux(io.commits.isWalk, 0.U, PopCount(cfiCommitVec))
// commit load/store to lsq
val ldCommitVec = VecInit((0 until CommitWidth).map(i => io.commits.valid(i) && io.commits.info(i).commitType === CommitType.LOAD))
val stCommitVec = VecInit((0 until CommitWidth).map(i => io.commits.valid(i) && io.commits.info(i).commitType === CommitType.STORE))
io.lsq.lcommit := Mux(io.commits.isWalk, 0.U, PopCount(ldCommitVec))
io.lsq.scommit := Mux(io.commits.isWalk, 0.U, PopCount(stCommitVec))
io.lsq.pendingld := !io.commits.isWalk && io.commits.info(0).commitType === CommitType.LOAD && valid(deqPtr.value)
io.lsq.pendingst := !io.commits.isWalk && io.commits.info(0).commitType === CommitType.STORE && valid(deqPtr.value)
io.lsq.commit := !io.commits.isWalk && io.commits.valid(0)
/**
* state changes
......
......@@ -8,7 +8,7 @@ import xiangshan.cache._
import xiangshan.cache.{DCacheWordIO, DCacheLineIO, TlbRequestIO, MemoryOpConstants}
import xiangshan.backend.LSUOpType
import xiangshan.mem._
import xiangshan.backend.roq.RoqPtr
import xiangshan.backend.roq.RoqLsqIO
class ExceptionAddrIO extends XSBundle {
val lsIdx = Input(new LSIdx)
......@@ -45,11 +45,10 @@ class LsqWrappper extends XSModule with HasDCacheParameters {
val ldout = Vec(2, DecoupledIO(new ExuOutput)) // writeback int load
val mmioStout = DecoupledIO(new ExuOutput) // writeback uncached store
val forward = Vec(LoadPipelineWidth, Flipped(new LoadForwardQueryIO))
val commits = Flipped(new RoqCommitIO)
val roq = Flipped(new RoqLsqIO)
val rollback = Output(Valid(new Redirect))
val dcache = Flipped(ValidIO(new Refill))
val uncache = new DCacheWordIO
val roqDeqPtr = Input(new RoqPtr)
val exceptionAddr = new ExceptionAddrIO
val sqempty = Output(Bool())
})
......@@ -83,10 +82,9 @@ class LsqWrappper extends XSModule with HasDCacheParameters {
loadQueue.io.loadIn <> io.loadIn
loadQueue.io.storeIn <> io.storeIn
loadQueue.io.ldout <> io.ldout
loadQueue.io.commits <> io.commits
loadQueue.io.roq <> io.roq
loadQueue.io.rollback <> io.rollback
loadQueue.io.dcache <> io.dcache
loadQueue.io.roqDeqPtr <> io.roqDeqPtr
loadQueue.io.exceptionAddr.lsIdx := io.exceptionAddr.lsIdx
loadQueue.io.exceptionAddr.isStore := DontCare
......@@ -96,8 +94,7 @@ class LsqWrappper extends XSModule with HasDCacheParameters {
storeQueue.io.storeIn <> io.storeIn
storeQueue.io.sbuffer <> io.sbuffer
storeQueue.io.mmioStout <> io.mmioStout
storeQueue.io.commits <> io.commits
storeQueue.io.roqDeqPtr <> io.roqDeqPtr
storeQueue.io.roq <> io.roq
storeQueue.io.exceptionAddr.lsIdx := io.exceptionAddr.lsIdx
storeQueue.io.exceptionAddr.isStore := DontCare
......@@ -110,22 +107,22 @@ class LsqWrappper extends XSModule with HasDCacheParameters {
// naive uncache arbiter
val s_idle :: s_load :: s_store :: Nil = Enum(3)
val uncacheState = RegInit(s_idle)
val pendingstate = RegInit(s_idle)
switch(uncacheState){
switch(pendingstate){
is(s_idle){
when(io.uncache.req.fire()){
uncacheState := Mux(loadQueue.io.uncache.req.valid, s_load, s_store)
pendingstate := Mux(loadQueue.io.uncache.req.valid, s_load, s_store)
}
}
is(s_load){
when(io.uncache.resp.fire()){
uncacheState := s_idle
pendingstate := s_idle
}
}
is(s_store){
when(io.uncache.resp.fire()){
uncacheState := s_idle
pendingstate := s_idle
}
}
}
......@@ -139,7 +136,7 @@ class LsqWrappper extends XSModule with HasDCacheParameters {
}.otherwise{
io.uncache.req <> storeQueue.io.uncache.req
}
when(uncacheState === s_load){
when(pendingstate === s_load){
io.uncache.resp <> loadQueue.io.uncache.resp
}.otherwise{
io.uncache.resp <> storeQueue.io.uncache.resp
......@@ -147,6 +144,6 @@ class LsqWrappper extends XSModule with HasDCacheParameters {
assert(!(loadQueue.io.uncache.req.valid && storeQueue.io.uncache.req.valid))
assert(!(loadQueue.io.uncache.resp.valid && storeQueue.io.uncache.resp.valid))
assert(!((loadQueue.io.uncache.resp.valid || storeQueue.io.uncache.resp.valid) && uncacheState === s_idle))
assert(!((loadQueue.io.uncache.resp.valid || storeQueue.io.uncache.resp.valid) && pendingstate === s_idle))
}
......@@ -9,7 +9,7 @@ import xiangshan.cache._
import xiangshan.cache.{DCacheLineIO, DCacheWordIO, MemoryOpConstants, TlbRequestIO}
import xiangshan.backend.LSUOpType
import xiangshan.mem._
import xiangshan.backend.roq.RoqPtr
import xiangshan.backend.roq.RoqLsqIO
import xiangshan.backend.fu.HasExceptionNO
......@@ -68,11 +68,10 @@ class LoadQueue extends XSModule
val storeIn = Vec(StorePipelineWidth, Flipped(Valid(new LsPipelineBundle)))
val ldout = Vec(2, DecoupledIO(new ExuOutput)) // writeback int load
val load_s1 = Vec(LoadPipelineWidth, Flipped(new LoadForwardQueryIO))
val commits = Flipped(new RoqCommitIO)
val roq = Flipped(new RoqLsqIO)
val rollback = Output(Valid(new Redirect)) // replay now starts from load instead of store
val dcache = Flipped(ValidIO(new Refill))
val uncache = new DCacheWordIO
val roqDeqPtr = Input(new RoqPtr)
val exceptionAddr = new ExceptionAddrIO
})
......@@ -100,17 +99,12 @@ class LoadQueue extends XSModule
val enqPtr = enqPtrExt(0).value
val deqPtr = deqPtrExt.value
val sameFlag = enqPtrExt(0).flag === deqPtrExt.flag
val isEmpty = enqPtr === deqPtr && sameFlag
val isFull = enqPtr === deqPtr && !sameFlag
val allowIn = !isFull
val loadCommit = (0 until CommitWidth).map(i => io.commits.valid(i) && !io.commits.isWalk && io.commits.info(i).commitType === CommitType.LOAD)
val mcommitIdx = (0 until CommitWidth).map(i => io.commits.info(i).lqIdx.value)
val deqMask = UIntToMask(deqPtr, LoadQueueSize)
val enqMask = UIntToMask(enqPtr, LoadQueueSize)
val commitCount = RegNext(io.roq.lcommit)
/**
* Enqueue at dispatch
*
......@@ -324,9 +318,8 @@ class LoadQueue extends XSModule
* When load commited, mark it as !allocated and move deqPtrExt forward.
*/
(0 until CommitWidth).map(i => {
when(loadCommit(i)) {
allocated(mcommitIdx(i)) := false.B
XSDebug("load commit %d: idx %d %x\n", i.U, mcommitIdx(i), uop(mcommitIdx(i)).cf.pc)
when(commitCount > i.U){
allocated(deqPtr+i.U) := false.B
}
})
......@@ -501,11 +494,39 @@ class LoadQueue extends XSModule
/**
* Memory mapped IO / other uncached operations
*
* States:
* (1) writeback from store units: mark as pending
* (2) when they reach ROB's head, they can be sent to uncache channel
* (3) response from uncache channel: mark as datavalid
* (4) writeback to ROB (and other units): mark as writebacked
* (5) ROB commits the instruction: same as normal instructions
*/
io.uncache.req.valid := pending(deqPtr) && allocated(deqPtr) &&
io.commits.info(0).commitType === CommitType.LOAD &&
io.roqDeqPtr === uop(deqPtr).roqIdx &&
!io.commits.isWalk
//(2) when they reach ROB's head, they can be sent to uncache channel
val s_idle :: s_req :: s_resp :: s_wait :: Nil = Enum(4)
val uncacheState = RegInit(s_idle)
switch(uncacheState) {
is(s_idle) {
when(io.roq.pendingld && pending(deqPtr) && allocated(deqPtr)) {
uncacheState := s_req
}
}
is(s_req) {
when(io.uncache.req.fire()) {
uncacheState := s_resp
}
}
is(s_resp) {
when(io.uncache.resp.fire()) {
uncacheState := s_wait
}
}
is(s_wait) {
when(io.roq.commit) {
uncacheState := s_idle // ready for next mmio
}
}
}
io.uncache.req.valid := uncacheState === s_req
dataModule.io.uncache.raddr := deqPtrExtNext.value
......@@ -537,6 +558,7 @@ class LoadQueue extends XSModule
)
}
// (3) response from uncache channel: mark as datavalid
dataModule.io.uncache.wen := false.B
when(io.uncache.resp.fire()){
datavalid(deqPtr) := true.B
......@@ -573,7 +595,6 @@ class LoadQueue extends XSModule
enqPtrExt := VecInit(enqPtrExt.map(_ + enqNumber))
}
val commitCount = PopCount(loadCommit)
deqPtrExtNext := deqPtrExt + commitCount
deqPtrExt := deqPtrExtNext
......
......@@ -7,7 +7,7 @@ import xiangshan._
import xiangshan.cache._
import xiangshan.cache.{DCacheWordIO, DCacheLineIO, TlbRequestIO, MemoryOpConstants}
import xiangshan.backend.LSUOpType
import xiangshan.backend.roq.RoqPtr
import xiangshan.backend.roq.RoqLsqIO
class SqPtr extends CircularQueuePtr(SqPtr.StoreQueueSize) { }
......@@ -38,9 +38,8 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
val sbuffer = Vec(StorePipelineWidth, Decoupled(new DCacheWordReq))
val mmioStout = DecoupledIO(new ExuOutput) // writeback uncached store
val forward = Vec(LoadPipelineWidth, Flipped(new LoadForwardQueryIO))
val commits = Flipped(new RoqCommitIO)
val roq = Flipped(new RoqLsqIO)
val uncache = new DCacheWordIO
val roqDeqPtr = Input(new RoqPtr)
// val refill = Flipped(Valid(new DCacheLineReq ))
val exceptionAddr = new ExceptionAddrIO
val sqempty = Output(Bool())
......@@ -66,14 +65,18 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
require(StoreQueueSize > RenameWidth)
val enqPtrExt = RegInit(VecInit((0 until RenameWidth).map(_.U.asTypeOf(new SqPtr))))
val deqPtrExt = RegInit(VecInit((0 until StorePipelineWidth).map(_.U.asTypeOf(new SqPtr))))
val cmtPtrExt = RegInit(VecInit((0 until CommitWidth).map(_.U.asTypeOf(new SqPtr))))
val validCounter = RegInit(0.U(log2Ceil(LoadQueueSize + 1).W))
val allowEnqueue = RegInit(true.B)
val enqPtr = enqPtrExt(0).value
val deqPtr = deqPtrExt(0).value
val cmtPtr = cmtPtrExt(0).value
val tailMask = UIntToMask(deqPtr, StoreQueueSize)
val headMask = UIntToMask(enqPtr, StoreQueueSize)
val deqMask = UIntToMask(deqPtr, StoreQueueSize)
val enqMask = UIntToMask(enqPtr, StoreQueueSize)
val commitCount = RegNext(io.roq.scommit)
// Read dataModule
// deqPtrExtNext and deqPtrExtNext+1 entry will be read from dataModule
......@@ -185,7 +188,7 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
for (j <- 0 until StoreQueueSize) {
storeWritebackedVec(j) := datavalid(j) && allocated(j) // all datavalid terms need to be checked
}
val needForward1 = Mux(differentFlag, ~tailMask, tailMask ^ forwardMask) & storeWritebackedVec.asUInt
val needForward1 = Mux(differentFlag, ~deqMask, deqMask ^ forwardMask) & storeWritebackedVec.asUInt
val needForward2 = Mux(differentFlag, forwardMask, 0.U(StoreQueueSize.W)) & storeWritebackedVec.asUInt
XSDebug(p"$i f1 ${Binary(needForward1)} f2 ${Binary(needForward2)} " +
......@@ -215,10 +218,31 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
* (5) ROB commits the instruction: same as normal instructions
*/
//(2) when they reach ROB's head, they can be sent to uncache channel
io.uncache.req.valid := pending(deqPtr) && allocated(deqPtr) &&
io.commits.info(0).commitType === CommitType.STORE &&
io.roqDeqPtr === uop(deqPtr).roqIdx &&
!io.commits.isWalk
val s_idle :: s_req :: s_resp :: s_wait :: Nil = Enum(4)
val uncacheState = RegInit(s_idle)
switch(uncacheState) {
is(s_idle) {
when(io.roq.pendingst && pending(deqPtr) && allocated(deqPtr)) {
uncacheState := s_req
}
}
is(s_req) {
when(io.uncache.req.fire()) {
uncacheState := s_resp
}
}
is(s_resp) {
when(io.uncache.resp.fire()) {
uncacheState := s_wait
}
}
is(s_wait) {
when(io.roq.commit) {
uncacheState := s_idle // ready for next mmio
}
}
}
io.uncache.req.valid := uncacheState === s_req
io.uncache.req.bits.cmd := MemoryOpConstants.M_XWR
io.uncache.req.bits.addr := dataModule.io.rdata(0).paddr // data(deqPtr) -> rdata(0)
......@@ -275,12 +299,11 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
* (2) They will not be cancelled and can be sent to lower level.
*/
for (i <- 0 until CommitWidth) {
val storeCommit = !io.commits.isWalk && io.commits.valid(i) && io.commits.info(i).commitType === CommitType.STORE
when (storeCommit) {
commited(io.commits.info(i).sqIdx.value) := true.B
XSDebug("store commit %d: idx %d\n", i.U, io.commits.info(i).sqIdx.value)
when (commitCount > i.U) {
commited(cmtPtrExt(i).value) := true.B
}
}
cmtPtrExt := cmtPtrExt.map(_ + commitCount)
// Commited stores will not be cancelled and can be sent to lower level.
// remove retired insts from sq, add retired store to sbuffer
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册