未验证 提交 6474c47f 编写于 作者: Y Yinan Xu 提交者: GitHub

rob: optimize timing for commit and walk (#1644)

* rob: separate walk and commit valid bits

* rob: optimize instrCnt timing

* rob: fix blockCommit condition when flushPipe

When flushPipe is enabled, it will block commits in ROB. However,
in the deqPtrModule, the commit is not blocked. This commit fixes
the issue.
上级 53b8f1a7
...@@ -371,15 +371,17 @@ class RobCommitInfo(implicit p: Parameters) extends XSBundle { ...@@ -371,15 +371,17 @@ class RobCommitInfo(implicit p: Parameters) extends XSBundle {
} }
class RobCommitIO(implicit p: Parameters) extends XSBundle { class RobCommitIO(implicit p: Parameters) extends XSBundle {
val isCommit = Output(Bool())
val commitValid = Vec(CommitWidth, Output(Bool()))
val isWalk = Output(Bool()) val isWalk = Output(Bool())
val valid = Vec(CommitWidth, Output(Bool()))
// valid bits optimized for walk // valid bits optimized for walk
val walkValid = Vec(CommitWidth, Output(Bool())) val walkValid = Vec(CommitWidth, Output(Bool()))
val info = Vec(CommitWidth, Output(new RobCommitInfo))
def hasWalkInstr = isWalk && valid.asUInt.orR val info = Vec(CommitWidth, Output(new RobCommitInfo))
def hasCommitInstr = !isWalk && valid.asUInt.orR def hasWalkInstr: Bool = isWalk && walkValid.asUInt.orR
def hasCommitInstr: Bool = isCommit && commitValid.asUInt.orR
} }
class RSFeedback(implicit p: Parameters) extends XSBundle { class RSFeedback(implicit p: Parameters) extends XSBundle {
......
...@@ -342,7 +342,9 @@ class CtrlBlockImp(outer: CtrlBlock)(implicit p: Parameters) extends LazyModuleI ...@@ -342,7 +342,9 @@ class CtrlBlockImp(outer: CtrlBlock)(implicit p: Parameters) extends LazyModuleI
// Flushes to frontend may be delayed by some cycles and commit before flush causes errors. // Flushes to frontend may be delayed by some cycles and commit before flush causes errors.
// Thus, we make all flush reasons to behave the same as exceptions for frontend. // Thus, we make all flush reasons to behave the same as exceptions for frontend.
for (i <- 0 until CommitWidth) { for (i <- 0 until CommitWidth) {
val is_commit = rob.io.commits.valid(i) && !rob.io.commits.isWalk && !rob.io.flushOut.valid // why flushOut: instructions with flushPipe are not commited to frontend
// If we commit them to frontend, it will cause flush after commit, which is not acceptable by frontend.
val is_commit = rob.io.commits.commitValid(i) && rob.io.commits.isCommit && !rob.io.flushOut.valid
io.frontend.toFtq.rob_commits(i).valid := RegNext(is_commit) io.frontend.toFtq.rob_commits(i).valid := RegNext(is_commit)
io.frontend.toFtq.rob_commits(i).bits := RegEnable(rob.io.commits.info(i), is_commit) io.frontend.toFtq.rob_commits(i).bits := RegEnable(rob.io.commits.info(i), is_commit)
} }
......
...@@ -253,12 +253,10 @@ class Rename(implicit p: Parameters) extends XSModule with HasPerfEvents { ...@@ -253,12 +253,10 @@ class Rename(implicit p: Parameters) extends XSModule with HasPerfEvents {
* Instructions commit: update freelist and rename table * Instructions commit: update freelist and rename table
*/ */
for (i <- 0 until CommitWidth) { for (i <- 0 until CommitWidth) {
val commitValid = io.robCommits.isCommit && io.robCommits.commitValid(i)
val walkValid = io.robCommits.isWalk && io.robCommits.walkValid(i)
Seq((io.intRenamePorts, false), (io.fpRenamePorts, true)) foreach { case (rat, fp) => Seq((io.intRenamePorts, false), (io.fpRenamePorts, true)) foreach { case (rat, fp) =>
// is valid commit req and given instruction has destination register
val commitDestValid = io.robCommits.valid(i) && needDestRegCommit(fp, io.robCommits.info(i))
XSDebug(p"isFp[${fp}]index[$i]-commitDestValid:$commitDestValid,isWalk:${io.robCommits.isWalk}\n")
/* /*
I. RAT Update I. RAT Update
*/ */
...@@ -279,14 +277,15 @@ class Rename(implicit p: Parameters) extends XSModule with HasPerfEvents { ...@@ -279,14 +277,15 @@ class Rename(implicit p: Parameters) extends XSModule with HasPerfEvents {
II. Free List Update II. Free List Update
*/ */
if (fp) { // Float Point free list if (fp) { // Float Point free list
fpFreeList.io.freeReq(i) := commitDestValid && !io.robCommits.isWalk fpFreeList.io.freeReq(i) := commitValid && needDestRegCommit(fp, io.robCommits.info(i))
fpFreeList.io.freePhyReg(i) := io.robCommits.info(i).old_pdest fpFreeList.io.freePhyReg(i) := io.robCommits.info(i).old_pdest
} else { // Integer free list } else { // Integer free list
intFreeList.io.freeReq(i) := intRefCounter.io.freeRegs(i).valid intFreeList.io.freeReq(i) := intRefCounter.io.freeRegs(i).valid
intFreeList.io.freePhyReg(i) := intRefCounter.io.freeRegs(i).bits intFreeList.io.freePhyReg(i) := intRefCounter.io.freeRegs(i).bits
} }
} }
intRefCounter.io.deallocate(i).valid := io.robCommits.valid(i) && needDestRegCommit(false, io.robCommits.info(i))
intRefCounter.io.deallocate(i).valid := (commitValid || walkValid) && needDestRegCommit(false, io.robCommits.info(i))
intRefCounter.io.deallocate(i).bits := Mux(io.robCommits.isWalk, io.robCommits.info(i).pdest, io.robCommits.info(i).old_pdest) intRefCounter.io.deallocate(i).bits := Mux(io.robCommits.isWalk, io.robCommits.info(i).pdest, io.robCommits.info(i).old_pdest)
} }
...@@ -308,10 +307,10 @@ class Rename(implicit p: Parameters) extends XSModule with HasPerfEvents { ...@@ -308,10 +307,10 @@ class Rename(implicit p: Parameters) extends XSModule with HasPerfEvents {
} }
XSDebug(io.robCommits.isWalk, p"Walk Recovery Enabled\n") XSDebug(io.robCommits.isWalk, p"Walk Recovery Enabled\n")
XSDebug(io.robCommits.isWalk, p"validVec:${Binary(io.robCommits.valid.asUInt)}\n") XSDebug(io.robCommits.isWalk, p"validVec:${Binary(io.robCommits.walkValid.asUInt)}\n")
for (i <- 0 until CommitWidth) { for (i <- 0 until CommitWidth) {
val info = io.robCommits.info(i) val info = io.robCommits.info(i)
XSDebug(io.robCommits.isWalk && io.robCommits.valid(i), p"[#$i walk info] pc:${Hexadecimal(info.pc)} " + XSDebug(io.robCommits.isWalk && io.robCommits.walkValid(i), p"[#$i walk info] pc:${Hexadecimal(info.pc)} " +
p"ldest:${info.ldest} rfWen:${info.rfWen} fpWen:${info.fpWen} " + p"ldest:${info.ldest} rfWen:${info.rfWen} fpWen:${info.fpWen} " +
p"pdest:${info.pdest} old_pdest:${info.old_pdest}\n") p"pdest:${info.pdest} old_pdest:${info.old_pdest}\n")
} }
......
...@@ -105,13 +105,13 @@ class RenameTableWrapper(implicit p: Parameters) extends XSModule { ...@@ -105,13 +105,13 @@ class RenameTableWrapper(implicit p: Parameters) extends XSModule {
intRat.io.readPorts <> io.intReadPorts.flatten intRat.io.readPorts <> io.intReadPorts.flatten
val intDestValid = io.robCommits.info.map(_.rfWen) val intDestValid = io.robCommits.info.map(_.rfWen)
for ((arch, i) <- intRat.io.archWritePorts.zipWithIndex) { for ((arch, i) <- intRat.io.archWritePorts.zipWithIndex) {
arch.wen := !io.robCommits.isWalk && io.robCommits.valid(i) && intDestValid(i) arch.wen := io.robCommits.isCommit && io.robCommits.commitValid(i) && intDestValid(i)
arch.addr := io.robCommits.info(i).ldest arch.addr := io.robCommits.info(i).ldest
arch.data := io.robCommits.info(i).pdest arch.data := io.robCommits.info(i).pdest
XSError(arch.wen && arch.addr === 0.U && arch.data =/= 0.U, "pdest for $0 should be 0\n") XSError(arch.wen && arch.addr === 0.U && arch.data =/= 0.U, "pdest for $0 should be 0\n")
} }
for ((spec, i) <- intRat.io.specWritePorts.zipWithIndex) { for ((spec, i) <- intRat.io.specWritePorts.zipWithIndex) {
spec.wen := io.robCommits.isWalk && io.robCommits.valid(i) && intDestValid(i) spec.wen := io.robCommits.isWalk && io.robCommits.walkValid(i) && intDestValid(i)
spec.addr := io.robCommits.info(i).ldest spec.addr := io.robCommits.info(i).ldest
spec.data := io.robCommits.info(i).old_pdest spec.data := io.robCommits.info(i).old_pdest
XSError(spec.wen && spec.addr === 0.U && spec.data =/= 0.U, "pdest for $0 should be 0\n") XSError(spec.wen && spec.addr === 0.U && spec.data =/= 0.U, "pdest for $0 should be 0\n")
...@@ -128,12 +128,12 @@ class RenameTableWrapper(implicit p: Parameters) extends XSModule { ...@@ -128,12 +128,12 @@ class RenameTableWrapper(implicit p: Parameters) extends XSModule {
fpRat.io.debug_rdata <> io.debug_fp_rat fpRat.io.debug_rdata <> io.debug_fp_rat
fpRat.io.readPorts <> io.fpReadPorts.flatten fpRat.io.readPorts <> io.fpReadPorts.flatten
for ((arch, i) <- fpRat.io.archWritePorts.zipWithIndex) { for ((arch, i) <- fpRat.io.archWritePorts.zipWithIndex) {
arch.wen := !io.robCommits.isWalk && io.robCommits.valid(i) && io.robCommits.info(i).fpWen arch.wen := io.robCommits.isCommit && io.robCommits.commitValid(i) && io.robCommits.info(i).fpWen
arch.addr := io.robCommits.info(i).ldest arch.addr := io.robCommits.info(i).ldest
arch.data := io.robCommits.info(i).pdest arch.data := io.robCommits.info(i).pdest
} }
for ((spec, i) <- fpRat.io.specWritePorts.zipWithIndex) { for ((spec, i) <- fpRat.io.specWritePorts.zipWithIndex) {
spec.wen := io.robCommits.isWalk && io.robCommits.valid(i) && io.robCommits.info(i).fpWen spec.wen := io.robCommits.isWalk && io.robCommits.walkValid(i) && io.robCommits.info(i).fpWen
spec.addr := io.robCommits.info(i).ldest spec.addr := io.robCommits.info(i).ldest
spec.data := io.robCommits.info(i).old_pdest spec.data := io.robCommits.info(i).old_pdest
} }
......
...@@ -90,9 +90,7 @@ class RobDeqPtrWrapper(implicit p: Parameters) extends XSModule with HasCircular ...@@ -90,9 +90,7 @@ class RobDeqPtrWrapper(implicit p: Parameters) extends XSModule with HasCircular
val intrBitSetReg = Input(Bool()) val intrBitSetReg = Input(Bool())
val hasNoSpecExec = Input(Bool()) val hasNoSpecExec = Input(Bool())
val interrupt_safe = Input(Bool()) val interrupt_safe = Input(Bool())
val misPredBlock = Input(Bool()) val blockCommit = Input(Bool())
val isReplaying = Input(Bool())
val hasWFI = Input(Bool())
// output: the CommitWidth deqPtr // output: the CommitWidth deqPtr
val out = Vec(CommitWidth, Output(new RobPtr)) val out = Vec(CommitWidth, Output(new RobPtr))
val next_out = Vec(CommitWidth, Output(new RobPtr)) val next_out = Vec(CommitWidth, Output(new RobPtr))
...@@ -109,7 +107,7 @@ class RobDeqPtrWrapper(implicit p: Parameters) extends XSModule with HasCircular ...@@ -109,7 +107,7 @@ class RobDeqPtrWrapper(implicit p: Parameters) extends XSModule with HasCircular
// for normal commits: only to consider when there're no exceptions // for normal commits: only to consider when there're no exceptions
// we don't need to consider whether the first instruction has exceptions since it wil trigger exceptions. // we don't need to consider whether the first instruction has exceptions since it wil trigger exceptions.
val commit_exception = io.exception_state.valid && !isAfter(io.exception_state.bits.robIdx, deqPtrVec.last) val commit_exception = io.exception_state.valid && !isAfter(io.exception_state.bits.robIdx, deqPtrVec.last)
val canCommit = VecInit((0 until CommitWidth).map(i => io.deq_v(i) && io.deq_w(i) && !io.misPredBlock && !io.isReplaying && !io.hasWFI)) val canCommit = VecInit((0 until CommitWidth).map(i => io.deq_v(i) && io.deq_w(i)))
val normalCommitCnt = PriorityEncoder(canCommit.map(c => !c) :+ true.B) val normalCommitCnt = PriorityEncoder(canCommit.map(c => !c) :+ true.B)
// when io.intrBitSetReg or there're possible exceptions in these instructions, // when io.intrBitSetReg or there're possible exceptions in these instructions,
// only one instruction is allowed to commit // only one instruction is allowed to commit
...@@ -117,7 +115,7 @@ class RobDeqPtrWrapper(implicit p: Parameters) extends XSModule with HasCircular ...@@ -117,7 +115,7 @@ class RobDeqPtrWrapper(implicit p: Parameters) extends XSModule with HasCircular
val commitCnt = Mux(allowOnlyOne, canCommit(0), normalCommitCnt) val commitCnt = Mux(allowOnlyOne, canCommit(0), normalCommitCnt)
val commitDeqPtrVec = VecInit(deqPtrVec.map(_ + commitCnt)) val commitDeqPtrVec = VecInit(deqPtrVec.map(_ + commitCnt))
val deqPtrVec_next = Mux(io.state === 0.U && !redirectOutValid, commitDeqPtrVec, deqPtrVec) val deqPtrVec_next = Mux(io.state === 0.U && !redirectOutValid && !io.blockCommit, commitDeqPtrVec, deqPtrVec)
deqPtrVec := deqPtrVec_next deqPtrVec := deqPtrVec_next
...@@ -138,22 +136,24 @@ class RobEnqPtrWrapper(implicit p: Parameters) extends XSModule with HasCircular ...@@ -138,22 +136,24 @@ class RobEnqPtrWrapper(implicit p: Parameters) extends XSModule with HasCircular
val allowEnqueue = Input(Bool()) val allowEnqueue = Input(Bool())
val hasBlockBackward = Input(Bool()) val hasBlockBackward = Input(Bool())
val enq = Vec(RenameWidth, Input(Bool())) val enq = Vec(RenameWidth, Input(Bool()))
val out = Output(new RobPtr) val out = Output(Vec(RenameWidth, new RobPtr))
}) })
val enqPtr = RegInit(0.U.asTypeOf(new RobPtr)) val enqPtrVec = RegInit(VecInit.tabulate(RenameWidth)(_.U.asTypeOf(new RobPtr)))
// enqueue // enqueue
val canAccept = io.allowEnqueue && !io.hasBlockBackward val canAccept = io.allowEnqueue && !io.hasBlockBackward
val dispatchNum = Mux(canAccept, PopCount(io.enq), 0.U) val dispatchNum = Mux(canAccept, PopCount(io.enq), 0.U)
when (io.redirect.valid) { for ((ptr, i) <- enqPtrVec.zipWithIndex) {
enqPtr := io.redirect.bits.robIdx + Mux(io.redirect.bits.flushItself(), 0.U, 1.U) when(io.redirect.valid) {
ptr := Mux(io.redirect.bits.flushItself(), io.redirect.bits.robIdx + i.U, io.redirect.bits.robIdx + (i + 1).U)
}.otherwise { }.otherwise {
enqPtr := enqPtr + dispatchNum ptr := ptr + dispatchNum
}
} }
io.out := enqPtr io.out := enqPtrVec
} }
...@@ -348,14 +348,14 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -348,14 +348,14 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
// pointers // pointers
// For enqueue ptr, we don't duplicate it since only enqueue needs it. // For enqueue ptr, we don't duplicate it since only enqueue needs it.
val enqPtr = Wire(new RobPtr) val enqPtrVec = Wire(Vec(RenameWidth, new RobPtr))
val deqPtrVec = Wire(Vec(CommitWidth, new RobPtr)) val deqPtrVec = Wire(Vec(CommitWidth, new RobPtr))
val walkPtrVec = Reg(Vec(CommitWidth, new RobPtr)) val walkPtrVec = Reg(Vec(CommitWidth, new RobPtr))
val validCounter = RegInit(0.U(log2Ceil(RobSize + 1).W)) val validCounter = RegInit(0.U(log2Ceil(RobSize + 1).W))
val allowEnqueue = RegInit(true.B) val allowEnqueue = RegInit(true.B)
val enqPtrVec = VecInit((0 until RenameWidth).map(i => enqPtr + PopCount(io.enq.needAlloc.take(i)))) val enqPtr = enqPtrVec.head
val deqPtr = deqPtrVec(0) val deqPtr = deqPtrVec(0)
val walkPtr = walkPtrVec(0) val walkPtr = walkPtrVec(0)
...@@ -399,7 +399,7 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -399,7 +399,7 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
// To reduce registers usage, for hasBlockBackward cases, we allow enqueue after ROB is empty. // To reduce registers usage, for hasBlockBackward cases, we allow enqueue after ROB is empty.
when (isEmpty) { hasBlockBackward:= false.B } when (isEmpty) { hasBlockBackward:= false.B }
// When any instruction commits, hasNoSpecExec should be set to false.B // When any instruction commits, hasNoSpecExec should be set to false.B
when (io.commits.valid.asUInt.orR && state =/= s_extrawalk) { hasNoSpecExec:= false.B } when ((io.commits.hasWalkInstr && state =/= s_extrawalk) || io.commits.hasCommitInstr) { hasNoSpecExec:= false.B }
// The wait-for-interrupt (WFI) instruction waits in the ROB until an interrupt might need servicing. // The wait-for-interrupt (WFI) instruction waits in the ROB until an interrupt might need servicing.
// io.csr.wfiEvent will be asserted if the WFI can resume execution, and we change the state to s_wfi_idle. // io.csr.wfiEvent will be asserted if the WFI can resume execution, and we change the state to s_wfi_idle.
...@@ -410,21 +410,23 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -410,21 +410,23 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
hasWFI := false.B hasWFI := false.B
} }
val allocatePtrVec = VecInit((0 until RenameWidth).map(i => enqPtrVec(PopCount(io.enq.needAlloc.take(i)))))
io.enq.canAccept := allowEnqueue && !hasBlockBackward io.enq.canAccept := allowEnqueue && !hasBlockBackward
io.enq.resp := enqPtrVec io.enq.resp := allocatePtrVec
val canEnqueue = VecInit(io.enq.req.map(_.valid && io.enq.canAccept)) val canEnqueue = VecInit(io.enq.req.map(_.valid && io.enq.canAccept))
val timer = GTimer() val timer = GTimer()
for (i <- 0 until RenameWidth) { for (i <- 0 until RenameWidth) {
// we don't check whether io.redirect is valid here since redirect has higher priority // we don't check whether io.redirect is valid here since redirect has higher priority
when (canEnqueue(i)) { when (canEnqueue(i)) {
val enqUop = io.enq.req(i).bits val enqUop = io.enq.req(i).bits
val enqIndex = allocatePtrVec(i).value
// store uop in data module and debug_microOp Vec // store uop in data module and debug_microOp Vec
debug_microOp(enqPtrVec(i).value) := enqUop debug_microOp(enqIndex) := enqUop
debug_microOp(enqPtrVec(i).value).debugInfo.dispatchTime := timer debug_microOp(enqIndex).debugInfo.dispatchTime := timer
debug_microOp(enqPtrVec(i).value).debugInfo.enqRsTime := timer debug_microOp(enqIndex).debugInfo.enqRsTime := timer
debug_microOp(enqPtrVec(i).value).debugInfo.selectTime := timer debug_microOp(enqIndex).debugInfo.selectTime := timer
debug_microOp(enqPtrVec(i).value).debugInfo.issueTime := timer debug_microOp(enqIndex).debugInfo.issueTime := timer
debug_microOp(enqPtrVec(i).value).debugInfo.writebackTime := timer debug_microOp(enqIndex).debugInfo.writebackTime := timer
when (enqUop.ctrl.blockBackward) { when (enqUop.ctrl.blockBackward) {
hasBlockBackward := true.B hasBlockBackward := true.B
} }
...@@ -557,16 +559,16 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -557,16 +559,16 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
// wiring to csr // wiring to csr
val (wflags, fpWen) = (0 until CommitWidth).map(i => { val (wflags, fpWen) = (0 until CommitWidth).map(i => {
val v = io.commits.valid(i) val v = io.commits.commitValid(i)
val info = io.commits.info(i) val info = io.commits.info(i)
(v & info.wflags, v & info.fpWen) (v & info.wflags, v & info.fpWen)
}).unzip }).unzip
val fflags = Wire(Valid(UInt(5.W))) val fflags = Wire(Valid(UInt(5.W)))
fflags.valid := Mux(io.commits.isWalk, false.B, Cat(wflags).orR) fflags.valid := io.commits.isCommit && VecInit(wflags).asUInt.orR
fflags.bits := wflags.zip(fflagsDataRead).map({ fflags.bits := wflags.zip(fflagsDataRead).map({
case (w, f) => Mux(w, f, 0.U) case (w, f) => Mux(w, f, 0.U)
}).reduce(_|_) }).reduce(_|_)
val dirty_fs = Mux(io.commits.isWalk, false.B, Cat(fpWen).orR) val dirty_fs = io.commits.isCommit && VecInit(fpWen).asUInt.orR
// when mispredict branches writeback, stop commit in the next 2 cycles // when mispredict branches writeback, stop commit in the next 2 cycles
// TODO: don't check all exu write back // TODO: don't check all exu write back
...@@ -579,9 +581,12 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -579,9 +581,12 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
misPredBlockCounter >> 1.U misPredBlockCounter >> 1.U
) )
val misPredBlock = misPredBlockCounter(0) val misPredBlock = misPredBlockCounter(0)
val blockCommit = misPredBlock || isReplaying || lastCycleFlush || hasWFI
io.commits.isWalk := state =/= s_idle io.commits.isWalk := state =/= s_idle
val commit_v = Mux(state === s_idle, VecInit(deqPtrVec.map(ptr => valid(ptr.value))), VecInit(walkPtrVec.map(ptr => valid(ptr.value)))) io.commits.isCommit := state === s_idle && !blockCommit
val walk_v = VecInit(walkPtrVec.map(ptr => valid(ptr.value)))
val commit_v = VecInit(deqPtrVec.map(ptr => valid(ptr.value)))
// store will be commited iff both sta & std have been writebacked // store will be commited iff both sta & std have been writebacked
val commit_w = VecInit(deqPtrVec.map(ptr => writebacked(ptr.value) && store_data_writebacked(ptr.value))) val commit_w = VecInit(deqPtrVec.map(ptr => writebacked(ptr.value) && store_data_writebacked(ptr.value)))
val commit_exception = exceptionDataRead.valid && !isAfter(exceptionDataRead.bits.robIdx, deqPtrVec.last) val commit_exception = exceptionDataRead.valid && !isAfter(exceptionDataRead.bits.robIdx, deqPtrVec.last)
...@@ -592,20 +597,24 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -592,20 +597,24 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
// defaults: state === s_idle and instructions commit // defaults: state === s_idle and instructions commit
// when intrBitSetReg, allow only one instruction to commit at each clock cycle // when intrBitSetReg, allow only one instruction to commit at each clock cycle
val isBlocked = if (i != 0) Cat(commit_block.take(i)).orR || allowOnlyOneCommit else intrEnable || deqHasException || deqHasReplayInst val isBlocked = if (i != 0) Cat(commit_block.take(i)).orR || allowOnlyOneCommit else intrEnable || deqHasException || deqHasReplayInst
io.commits.valid(i) := commit_v(i) && commit_w(i) && !isBlocked && !misPredBlock && !isReplaying && !lastCycleFlush && !hasWFI io.commits.commitValid(i) := commit_v(i) && commit_w(i) && !isBlocked
io.commits.walkValid(i) := DontCare
io.commits.info(i) := dispatchDataRead(i) io.commits.info(i) := dispatchDataRead(i)
when (state === s_walk) { io.commits.walkValid(i) := shouldWalkVec(i)
io.commits.valid(i) := commit_v(i) && shouldWalkVec(i) when (io.commits.isWalk && state === s_walk && shouldWalkVec(i)) {
io.commits.walkValid(i) := commit_v(i) && shouldWalkVec(i) XSError(!walk_v(i), s"why not $i???\n")
}.elsewhen(state === s_extrawalk) { }
io.commits.valid(i) := (if (i < RenameWidth) usedSpaceForMPR(RenameWidth-i-1) else false.B) when (state === s_extrawalk) {
io.commits.walkValid(i) := (if (i < RenameWidth) usedSpaceForMPR(RenameWidth-i-1) else false.B) if (i < RenameWidth) {
io.commits.info(i) := (if (i < RenameWidth) extraSpaceForMPR(RenameWidth-i-1) else DontCare) io.commits.walkValid(i) := usedSpaceForMPR(RenameWidth - i - 1)
io.commits.info(i) := extraSpaceForMPR(RenameWidth - i - 1)
}
else {
io.commits.walkValid(i) := false.B
}
} }
XSInfo(state === s_idle && io.commits.valid(i), XSInfo(io.commits.isCommit && io.commits.commitValid(i),
"retired pc %x wen %d ldest %d pdest %x old_pdest %x data %x fflags: %b\n", "retired pc %x wen %d ldest %d pdest %x old_pdest %x data %x fflags: %b\n",
debug_microOp(deqPtrVec(i).value).cf.pc, debug_microOp(deqPtrVec(i).value).cf.pc,
io.commits.info(i).rfWen, io.commits.info(i).rfWen,
...@@ -615,13 +624,13 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -615,13 +624,13 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
debug_exuData(deqPtrVec(i).value), debug_exuData(deqPtrVec(i).value),
fflagsDataRead(i) fflagsDataRead(i)
) )
XSInfo(state === s_walk && io.commits.valid(i), "walked pc %x wen %d ldst %d data %x\n", XSInfo(state === s_walk && io.commits.walkValid(i), "walked pc %x wen %d ldst %d data %x\n",
debug_microOp(walkPtrVec(i).value).cf.pc, debug_microOp(walkPtrVec(i).value).cf.pc,
io.commits.info(i).rfWen, io.commits.info(i).rfWen,
io.commits.info(i).ldest, io.commits.info(i).ldest,
debug_exuData(walkPtrVec(i).value) debug_exuData(walkPtrVec(i).value)
) )
XSInfo(state === s_extrawalk && io.commits.valid(i), "use extra space walked wen %d ldst %d\n", XSInfo(state === s_extrawalk && io.commits.walkValid(i), "use extra space walked wen %d ldst %d\n",
io.commits.info(i).rfWen, io.commits.info(i).rfWen,
io.commits.info(i).ldest io.commits.info(i).ldest
) )
...@@ -635,13 +644,14 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -635,13 +644,14 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
io.csr.dirty_fs := RegNext(dirty_fs) io.csr.dirty_fs := RegNext(dirty_fs)
// commit load/store to lsq // 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 ldCommitVec = VecInit((0 until CommitWidth).map(i => io.commits.commitValid(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)) val stCommitVec = VecInit((0 until CommitWidth).map(i => io.commits.commitValid(i) && io.commits.info(i).commitType === CommitType.STORE))
io.lsq.lcommit := RegNext(Mux(io.commits.isWalk, 0.U, PopCount(ldCommitVec))) io.lsq.lcommit := RegNext(Mux(io.commits.isCommit, PopCount(ldCommitVec), 0.U))
io.lsq.scommit := RegNext(Mux(io.commits.isWalk, 0.U, PopCount(stCommitVec))) io.lsq.scommit := RegNext(Mux(io.commits.isCommit, PopCount(stCommitVec), 0.U))
io.lsq.pendingld := RegNext(!io.commits.isWalk && io.commits.info(0).commitType === CommitType.LOAD && valid(deqPtr.value)) // indicate a pending load or store
io.lsq.pendingst := RegNext(!io.commits.isWalk && io.commits.info(0).commitType === CommitType.STORE && valid(deqPtr.value)) io.lsq.pendingld := RegNext(io.commits.isCommit && io.commits.info(0).commitType === CommitType.LOAD && valid(deqPtr.value))
io.lsq.commit := RegNext(!io.commits.isWalk && io.commits.valid(0)) io.lsq.pendingst := RegNext(io.commits.isCommit && io.commits.info(0).commitType === CommitType.STORE && valid(deqPtr.value))
io.lsq.commit := RegNext(io.commits.isCommit && io.commits.commitValid(0))
/** /**
* state changes * state changes
...@@ -650,11 +660,24 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -650,11 +660,24 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
* (3) walk: when walking comes to the end, switch to s_walk * (3) walk: when walking comes to the end, switch to s_walk
* (4) s_extrawalk to s_walk * (4) s_extrawalk to s_walk
*/ */
// state === s_idle: don't change when walk_no_need
// state === s_walk: don't change when walk_no_need && walkFinished
// state === s_extrawalk: always continue to walk (because it's not possible for walk_no_need)
val zeroWalkDistance = enqPtr - 1.U === io.redirect.bits.robIdx && !io.redirect.bits.flushItself()
val noNeedToWalk = zeroWalkDistance && (state === s_idle || (state === s_walk && walkFinished))
// update the state depending on whether there is a redirect
val state_next = Mux(io.redirect.valid, val state_next = Mux(io.redirect.valid,
Mux(io.enq.needAlloc.asUInt.orR, s_extrawalk, s_walk), Mux(io.enq.needAlloc.asUInt.orR,
s_extrawalk,
Mux(noNeedToWalk, s_idle, s_walk)
),
Mux(state === s_walk && walkFinished, Mux(state === s_walk && walkFinished,
s_idle, s_idle,
Mux(state === s_extrawalk, s_walk, state) Mux(state === s_extrawalk,
// if no more walk, switch to s_idle
Mux(walkCounter === 0.U, s_idle, s_walk),
state
)
) )
) )
state := state_next state := state_next
...@@ -670,9 +693,7 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -670,9 +693,7 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
deqPtrGenModule.io.intrBitSetReg := intrBitSetReg deqPtrGenModule.io.intrBitSetReg := intrBitSetReg
deqPtrGenModule.io.hasNoSpecExec := hasNoSpecExec deqPtrGenModule.io.hasNoSpecExec := hasNoSpecExec
deqPtrGenModule.io.interrupt_safe := interrupt_safe(deqPtr.value) deqPtrGenModule.io.interrupt_safe := interrupt_safe(deqPtr.value)
deqPtrGenModule.io.misPredBlock := misPredBlock deqPtrGenModule.io.blockCommit := blockCommit
deqPtrGenModule.io.isReplaying := isReplaying
deqPtrGenModule.io.hasWFI := hasWFI
deqPtrVec := deqPtrGenModule.io.out deqPtrVec := deqPtrGenModule.io.out
val deqPtrVec_next = deqPtrGenModule.io.next_out val deqPtrVec_next = deqPtrGenModule.io.next_out
...@@ -681,7 +702,7 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -681,7 +702,7 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
enqPtrGenModule.io.allowEnqueue := allowEnqueue enqPtrGenModule.io.allowEnqueue := allowEnqueue
enqPtrGenModule.io.hasBlockBackward := hasBlockBackward enqPtrGenModule.io.hasBlockBackward := hasBlockBackward
enqPtrGenModule.io.enq := VecInit(io.enq.req.map(_.valid)) enqPtrGenModule.io.enq := VecInit(io.enq.req.map(_.valid))
enqPtr := enqPtrGenModule.io.out enqPtrVec := enqPtrGenModule.io.out
val thisCycleWalkCount = Mux(walkFinished, walkCounter, CommitWidth.U) val thisCycleWalkCount = Mux(walkFinished, walkCounter, CommitWidth.U)
// next walkPtrVec: // next walkPtrVec:
...@@ -698,13 +719,13 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -698,13 +719,13 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
val lastCycleRedirect = RegNext(io.redirect.valid) val lastCycleRedirect = RegNext(io.redirect.valid)
val trueValidCounter = Mux(lastCycleRedirect, distanceBetween(enqPtr, deqPtr), validCounter) val trueValidCounter = Mux(lastCycleRedirect, distanceBetween(enqPtr, deqPtr), validCounter)
val commitCnt = PopCount(io.commits.valid) val commitCnt = PopCount(io.commits.commitValid)
validCounter := Mux(state === s_idle, validCounter := Mux(io.commits.isCommit,
(validCounter - commitCnt) + dispatchNum, (validCounter - commitCnt) + dispatchNum,
trueValidCounter trueValidCounter
) )
allowEnqueue := Mux(state === s_idle, allowEnqueue := Mux(io.commits.isCommit,
validCounter + dispatchNum <= (RobSize - RenameWidth).U, validCounter + dispatchNum <= (RobSize - RenameWidth).U,
trueValidCounter <= (RobSize - RenameWidth).U trueValidCounter <= (RobSize - RenameWidth).U
) )
...@@ -721,11 +742,13 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -721,11 +742,13 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
// Previously we use `+` to count the walk distance and it causes overflows // Previously we use `+` to count the walk distance and it causes overflows
// when RobSize is power of 2. We change it to `+&` to allow walkCounter to be RobSize. // when RobSize is power of 2. We change it to `+&` to allow walkCounter to be RobSize.
// The width of walkCounter also needs to be changed. // The width of walkCounter also needs to be changed.
redirectWalkDistance +& io.redirect.bits.flushItself() - commitCnt, redirectWalkDistance - (thisCycleWalkCount - io.redirect.bits.flushItself()),
redirectWalkDistance +& io.redirect.bits.flushItself() redirectWalkDistance + io.redirect.bits.flushItself()
) )
XSError(state === s_walk && thisCycleWalkCount < io.redirect.bits.flushItself(),
p"walk distance error ($thisCycleWalkCount < ${io.redirect.bits.flushItself()}\n")
}.elsewhen (state === s_walk) { }.elsewhen (state === s_walk) {
walkCounter := walkCounter - commitCnt walkCounter := walkCounter - thisCycleWalkCount
XSInfo(p"rolling back: $enqPtr $deqPtr walk $walkPtr walkcnt $walkCounter\n") XSInfo(p"rolling back: $enqPtr $deqPtr walk $walkPtr walkcnt $walkCounter\n")
} }
...@@ -742,12 +765,14 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -742,12 +765,14 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
// enqueue logic writes 6 valid // enqueue logic writes 6 valid
for (i <- 0 until RenameWidth) { for (i <- 0 until RenameWidth) {
when (canEnqueue(i) && !io.redirect.valid) { when (canEnqueue(i) && !io.redirect.valid) {
valid(enqPtrVec(i).value) := true.B valid(allocatePtrVec(i).value) := true.B
} }
} }
// dequeue/walk logic writes 6 valid, dequeue and walk will not happen at the same time // dequeue/walk logic writes 6 valid, dequeue and walk will not happen at the same time
for (i <- 0 until CommitWidth) { for (i <- 0 until CommitWidth) {
when (io.commits.valid(i) && state =/= s_extrawalk) { val commitValid = io.commits.isCommit && io.commits.commitValid(i)
val walkValid = io.commits.isWalk && io.commits.walkValid(i) && state =/= s_extrawalk
when (commitValid || walkValid) {
valid(commitReadAddr(i)) := false.B valid(commitReadAddr(i)) := false.B
} }
} }
...@@ -765,9 +790,9 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -765,9 +790,9 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
val enqHasException = ExceptionNO.selectFrontend(io.enq.req(i).bits.cf.exceptionVec).asUInt.orR val enqHasException = ExceptionNO.selectFrontend(io.enq.req(i).bits.cf.exceptionVec).asUInt.orR
val enqHasTriggerHit = io.enq.req(i).bits.cf.trigger.getHitFrontend val enqHasTriggerHit = io.enq.req(i).bits.cf.trigger.getHitFrontend
val enqIsWritebacked = io.enq.req(i).bits.eliminatedMove val enqIsWritebacked = io.enq.req(i).bits.eliminatedMove
writebacked(enqPtrVec(i).value) := enqIsWritebacked && !enqHasException && !enqHasTriggerHit writebacked(allocatePtrVec(i).value) := enqIsWritebacked && !enqHasException && !enqHasTriggerHit
val isStu = io.enq.req(i).bits.ctrl.fuType === FuType.stu val isStu = io.enq.req(i).bits.ctrl.fuType === FuType.stu
store_data_writebacked(enqPtrVec(i).value) := !isStu store_data_writebacked(allocatePtrVec(i).value) := !isStu
} }
} }
when (exceptionGen.io.out.valid) { when (exceptionGen.io.out.valid) {
...@@ -798,7 +823,7 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -798,7 +823,7 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
// enqueue logic set 6 flagBkup at most // enqueue logic set 6 flagBkup at most
for (i <- 0 until RenameWidth) { for (i <- 0 until RenameWidth) {
when (canEnqueue(i)) { when (canEnqueue(i)) {
flagBkup(enqPtrVec(i).value) := enqPtrVec(i).flag flagBkup(allocatePtrVec(i).value) := allocatePtrVec(i).flag
} }
} }
...@@ -814,7 +839,7 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -814,7 +839,7 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
// Thus, we don't allow load/store instructions to trigger an interrupt. // Thus, we don't allow load/store instructions to trigger an interrupt.
// TODO: support non-MMIO load-store instructions to trigger interrupts // TODO: support non-MMIO load-store instructions to trigger interrupts
val allow_interrupts = !CommitType.isLoadStore(io.enq.req(i).bits.ctrl.commitType) val allow_interrupts = !CommitType.isLoadStore(io.enq.req(i).bits.ctrl.commitType)
interrupt_safe(RegNext(enqPtrVec(i).value)) := RegNext(allow_interrupts) interrupt_safe(RegNext(allocatePtrVec(i).value)) := RegNext(allow_interrupts)
} }
} }
...@@ -826,7 +851,7 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -826,7 +851,7 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
VecInit(walkPtrVec_next.map(_.value)) VecInit(walkPtrVec_next.map(_.value))
) )
dispatchData.io.wen := canEnqueue dispatchData.io.wen := canEnqueue
dispatchData.io.waddr := enqPtrVec.map(_.value) dispatchData.io.waddr := allocatePtrVec.map(_.value)
dispatchData.io.wdata.zip(io.enq.req.map(_.bits)).foreach{ case (wdata, req) => dispatchData.io.wdata.zip(io.enq.req.map(_.bits)).foreach{ case (wdata, req) =>
wdata.ldest := req.ctrl.ldest wdata.ldest := req.ctrl.ldest
wdata.rfWen := req.ctrl.rfWen wdata.rfWen := req.ctrl.rfWen
...@@ -888,12 +913,13 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -888,12 +913,13 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
fflagsDataRead := fflagsDataModule.io.rdata fflagsDataRead := fflagsDataModule.io.rdata
val instrCnt = RegInit(0.U(64.W)) val instrCntReg = RegInit(0.U(64.W))
val fuseCommitCnt = PopCount(io.commits.valid.zip(io.commits.info).map{ case (v, i) => v && CommitType.isFused(i.commitType) }) val fuseCommitCnt = PopCount(io.commits.commitValid.zip(io.commits.info).map{ case (v, i) => RegNext(v && CommitType.isFused(i.commitType)) })
val trueCommitCnt = commitCnt +& fuseCommitCnt val trueCommitCnt = RegNext(commitCnt) +& fuseCommitCnt
val retireCounter = Mux(state === s_idle, trueCommitCnt, 0.U) val retireCounter = Mux(RegNext(io.commits.isCommit), trueCommitCnt, 0.U)
instrCnt := instrCnt + retireCounter val instrCnt = instrCntReg + retireCounter
io.csr.perfinfo.retiredInstr := RegNext(retireCounter) instrCntReg := instrCnt
io.csr.perfinfo.retiredInstr := retireCounter
io.robFull := !allowEnqueue io.robFull := !allowEnqueue
/** /**
...@@ -917,7 +943,7 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -917,7 +943,7 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
if(i % 4 == 3) XSDebug(false, true.B, "\n") if(i % 4 == 3) XSDebug(false, true.B, "\n")
} }
def ifCommit(counter: UInt): UInt = Mux(io.commits.isWalk, 0.U, counter) def ifCommit(counter: UInt): UInt = Mux(io.commits.isCommit, counter, 0.U)
val commitDebugUop = deqPtrVec.map(_.value).map(debug_microOp(_)) val commitDebugUop = deqPtrVec.map(_.value).map(debug_microOp(_))
XSPerfAccumulate("clock_cycle", 1.U) XSPerfAccumulate("clock_cycle", 1.U)
...@@ -925,24 +951,24 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -925,24 +951,24 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
XSPerfAccumulate("commitUop", ifCommit(commitCnt)) XSPerfAccumulate("commitUop", ifCommit(commitCnt))
XSPerfAccumulate("commitInstr", ifCommit(trueCommitCnt)) XSPerfAccumulate("commitInstr", ifCommit(trueCommitCnt))
val commitIsMove = commitDebugUop.map(_.ctrl.isMove) val commitIsMove = commitDebugUop.map(_.ctrl.isMove)
XSPerfAccumulate("commitInstrMove", ifCommit(PopCount(io.commits.valid.zip(commitIsMove).map{ case (v, m) => v && m }))) XSPerfAccumulate("commitInstrMove", ifCommit(PopCount(io.commits.commitValid.zip(commitIsMove).map{ case (v, m) => v && m })))
val commitMoveElim = commitDebugUop.map(_.debugInfo.eliminatedMove) val commitMoveElim = commitDebugUop.map(_.debugInfo.eliminatedMove)
XSPerfAccumulate("commitInstrMoveElim", ifCommit(PopCount(io.commits.valid zip commitMoveElim map { case (v, e) => v && e }))) XSPerfAccumulate("commitInstrMoveElim", ifCommit(PopCount(io.commits.commitValid zip commitMoveElim map { case (v, e) => v && e })))
XSPerfAccumulate("commitInstrFused", ifCommit(fuseCommitCnt)) XSPerfAccumulate("commitInstrFused", ifCommit(fuseCommitCnt))
val commitIsLoad = io.commits.info.map(_.commitType).map(_ === CommitType.LOAD) val commitIsLoad = io.commits.info.map(_.commitType).map(_ === CommitType.LOAD)
val commitLoadValid = io.commits.valid.zip(commitIsLoad).map{ case (v, t) => v && t } val commitLoadValid = io.commits.commitValid.zip(commitIsLoad).map{ case (v, t) => v && t }
XSPerfAccumulate("commitInstrLoad", ifCommit(PopCount(commitLoadValid))) XSPerfAccumulate("commitInstrLoad", ifCommit(PopCount(commitLoadValid)))
val commitIsBranch = io.commits.info.map(_.commitType).map(_ === CommitType.BRANCH) val commitIsBranch = io.commits.info.map(_.commitType).map(_ === CommitType.BRANCH)
val commitBranchValid = io.commits.valid.zip(commitIsBranch).map{ case (v, t) => v && t } val commitBranchValid = io.commits.commitValid.zip(commitIsBranch).map{ case (v, t) => v && t }
XSPerfAccumulate("commitInstrBranch", ifCommit(PopCount(commitBranchValid))) XSPerfAccumulate("commitInstrBranch", ifCommit(PopCount(commitBranchValid)))
val commitLoadWaitBit = commitDebugUop.map(_.cf.loadWaitBit) val commitLoadWaitBit = commitDebugUop.map(_.cf.loadWaitBit)
XSPerfAccumulate("commitInstrLoadWait", ifCommit(PopCount(commitLoadValid.zip(commitLoadWaitBit).map{ case (v, w) => v && w }))) XSPerfAccumulate("commitInstrLoadWait", ifCommit(PopCount(commitLoadValid.zip(commitLoadWaitBit).map{ case (v, w) => v && w })))
val commitIsStore = io.commits.info.map(_.commitType).map(_ === CommitType.STORE) val commitIsStore = io.commits.info.map(_.commitType).map(_ === CommitType.STORE)
XSPerfAccumulate("commitInstrStore", ifCommit(PopCount(io.commits.valid.zip(commitIsStore).map{ case (v, t) => v && t }))) XSPerfAccumulate("commitInstrStore", ifCommit(PopCount(io.commits.commitValid.zip(commitIsStore).map{ case (v, t) => v && t })))
XSPerfAccumulate("writeback", PopCount((0 until RobSize).map(i => valid(i) && writebacked(i)))) XSPerfAccumulate("writeback", PopCount((0 until RobSize).map(i => valid(i) && writebacked(i))))
// XSPerfAccumulate("enqInstr", PopCount(io.dp1Req.map(_.fire))) // XSPerfAccumulate("enqInstr", PopCount(io.dp1Req.map(_.fire)))
// XSPerfAccumulate("d2rVnR", PopCount(io.dp1Req.map(p => p.valid && !p.ready))) // XSPerfAccumulate("d2rVnR", PopCount(io.dp1Req.map(p => p.valid && !p.ready)))
XSPerfAccumulate("walkInstr", Mux(io.commits.isWalk, PopCount(io.commits.valid), 0.U)) XSPerfAccumulate("walkInstr", Mux(io.commits.isWalk, PopCount(io.commits.walkValid), 0.U))
XSPerfAccumulate("walkCycle", state === s_walk || state === s_extrawalk) XSPerfAccumulate("walkCycle", state === s_walk || state === s_extrawalk)
val deqNotWritebacked = valid(deqPtr.value) && !writebacked(deqPtr.value) val deqNotWritebacked = valid(deqPtr.value) && !writebacked(deqPtr.value)
val deqUopCommitType = io.commits.info(0).commitType val deqUopCommitType = io.commits.info(0).commitType
...@@ -963,7 +989,7 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -963,7 +989,7 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
} }
for (fuType <- FuType.functionNameMap.keys) { for (fuType <- FuType.functionNameMap.keys) {
val fuName = FuType.functionNameMap(fuType) val fuName = FuType.functionNameMap(fuType)
val commitIsFuType = io.commits.valid.zip(commitDebugUop).map(x => x._1 && x._2.ctrl.fuType === fuType.U ) val commitIsFuType = io.commits.commitValid.zip(commitDebugUop).map(x => x._1 && x._2.ctrl.fuType === fuType.U )
XSPerfAccumulate(s"${fuName}_instr_cnt", ifCommit(PopCount(commitIsFuType))) XSPerfAccumulate(s"${fuName}_instr_cnt", ifCommit(PopCount(commitIsFuType)))
XSPerfAccumulate(s"${fuName}_latency_dispatch", ifCommit(latencySum(commitIsFuType, dispatchLatency))) XSPerfAccumulate(s"${fuName}_latency_dispatch", ifCommit(latencySum(commitIsFuType, dispatchLatency)))
XSPerfAccumulate(s"${fuName}_latency_enq_rs", ifCommit(latencySum(commitIsFuType, enqRsLatency))) XSPerfAccumulate(s"${fuName}_latency_enq_rs", ifCommit(latencySum(commitIsFuType, enqRsLatency)))
...@@ -981,7 +1007,7 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -981,7 +1007,7 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
} }
//difftest signals //difftest signals
val firstValidCommit = (deqPtr + PriorityMux(io.commits.valid, VecInit(List.tabulate(CommitWidth)(_.U)))).value val firstValidCommit = (deqPtr + PriorityMux(io.commits.commitValid, VecInit(List.tabulate(CommitWidth)(_.U)))).value
val wdata = Wire(Vec(CommitWidth, UInt(XLEN.W))) val wdata = Wire(Vec(CommitWidth, UInt(XLEN.W)))
val wpc = Wire(Vec(CommitWidth, UInt(XLEN.W))) val wpc = Wire(Vec(CommitWidth, UInt(XLEN.W)))
...@@ -991,9 +1017,6 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -991,9 +1017,6 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
wdata(i) := debug_exuData(idx) wdata(i) := debug_exuData(idx)
wpc(i) := SignExt(commitDebugUop(i).cf.pc, XLEN) wpc(i) := SignExt(commitDebugUop(i).cf.pc, XLEN)
} }
val retireCounterFix = Mux(io.exception.valid, 1.U, retireCounter)
val retirePCFix = SignExt(Mux(io.exception.valid, io.exception.bits.uop.cf.pc, debug_microOp(firstValidCommit).cf.pc), XLEN)
val retireInstFix = Mux(io.exception.valid, io.exception.bits.uop.cf.instr, debug_microOp(firstValidCommit).cf.instr)
if (env.EnableDifftest) { if (env.EnableDifftest) {
for (i <- 0 until CommitWidth) { for (i <- 0 until CommitWidth) {
...@@ -1006,7 +1029,7 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -1006,7 +1029,7 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
val uop = commitDebugUop(i) val uop = commitDebugUop(i)
val exuOut = debug_exuDebug(ptr) val exuOut = debug_exuDebug(ptr)
val exuData = debug_exuData(ptr) val exuData = debug_exuData(ptr)
difftest.io.valid := RegNext(RegNext(RegNext(io.commits.valid(i) && !io.commits.isWalk))) difftest.io.valid := RegNext(RegNext(RegNext(io.commits.commitValid(i) && io.commits.isCommit)))
difftest.io.pc := RegNext(RegNext(RegNext(SignExt(uop.cf.pc, XLEN)))) difftest.io.pc := RegNext(RegNext(RegNext(SignExt(uop.cf.pc, XLEN))))
difftest.io.instr := RegNext(RegNext(RegNext(uop.cf.instr))) difftest.io.instr := RegNext(RegNext(RegNext(uop.cf.instr)))
difftest.io.special := RegNext(RegNext(RegNext(CommitType.isFused(io.commits.info(i).commitType)))) difftest.io.special := RegNext(RegNext(RegNext(CommitType.isFused(io.commits.info(i).commitType))))
...@@ -1014,8 +1037,8 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -1014,8 +1037,8 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
// we must make sure that skip is properly set to false (output from EXU is random value) // we must make sure that skip is properly set to false (output from EXU is random value)
difftest.io.skip := RegNext(RegNext(RegNext(Mux(uop.eliminatedMove, false.B, exuOut.isMMIO || exuOut.isPerfCnt)))) difftest.io.skip := RegNext(RegNext(RegNext(Mux(uop.eliminatedMove, false.B, exuOut.isMMIO || exuOut.isPerfCnt))))
difftest.io.isRVC := RegNext(RegNext(RegNext(uop.cf.pd.isRVC))) difftest.io.isRVC := RegNext(RegNext(RegNext(uop.cf.pd.isRVC)))
difftest.io.rfwen := RegNext(RegNext(RegNext(io.commits.valid(i) && io.commits.info(i).rfWen && io.commits.info(i).ldest =/= 0.U))) difftest.io.rfwen := RegNext(RegNext(RegNext(io.commits.commitValid(i) && io.commits.info(i).rfWen && io.commits.info(i).ldest =/= 0.U)))
difftest.io.fpwen := RegNext(RegNext(RegNext(io.commits.valid(i) && io.commits.info(i).fpWen))) difftest.io.fpwen := RegNext(RegNext(RegNext(io.commits.commitValid(i) && io.commits.info(i).fpWen)))
difftest.io.wpdest := RegNext(RegNext(RegNext(io.commits.info(i).pdest))) difftest.io.wpdest := RegNext(RegNext(RegNext(io.commits.info(i).pdest)))
difftest.io.wdest := RegNext(RegNext(RegNext(io.commits.info(i).ldest))) difftest.io.wdest := RegNext(RegNext(RegNext(io.commits.info(i).ldest)))
...@@ -1037,8 +1060,8 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -1037,8 +1060,8 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
val dt_exuDebug = Reg(Vec(RobSize, new DebugBundle)) val dt_exuDebug = Reg(Vec(RobSize, new DebugBundle))
for (i <- 0 until RenameWidth) { for (i <- 0 until RenameWidth) {
when (canEnqueue(i)) { when (canEnqueue(i)) {
dt_eliminatedMove(enqPtrVec(i).value) := io.enq.req(i).bits.eliminatedMove dt_eliminatedMove(allocatePtrVec(i).value) := io.enq.req(i).bits.eliminatedMove
dt_isRVC(enqPtrVec(i).value) := io.enq.req(i).bits.cf.pd.isRVC dt_isRVC(allocatePtrVec(i).value) := io.enq.req(i).bits.cf.pd.isRVC
} }
} }
for (wb <- exuWriteback) { for (wb <- exuWriteback) {
...@@ -1059,12 +1082,12 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -1059,12 +1082,12 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
difftest.io.clock := clock difftest.io.clock := clock
difftest.io.coreid := io.hartId difftest.io.coreid := io.hartId
difftest.io.index := i.U difftest.io.index := i.U
difftest.io.valid := RegNext(RegNext(RegNext(io.commits.valid(i) && !io.commits.isWalk))) difftest.io.valid := RegNext(RegNext(RegNext(io.commits.commitValid(i) && io.commits.isCommit)))
difftest.io.special := RegNext(RegNext(RegNext(CommitType.isFused(commitInfo.commitType)))) difftest.io.special := RegNext(RegNext(RegNext(CommitType.isFused(commitInfo.commitType))))
difftest.io.skip := RegNext(RegNext(RegNext(Mux(eliminatedMove, false.B, exuOut.isMMIO || exuOut.isPerfCnt)))) difftest.io.skip := RegNext(RegNext(RegNext(Mux(eliminatedMove, false.B, exuOut.isMMIO || exuOut.isPerfCnt))))
difftest.io.isRVC := RegNext(RegNext(RegNext(isRVC))) difftest.io.isRVC := RegNext(RegNext(RegNext(isRVC)))
difftest.io.rfwen := RegNext(RegNext(RegNext(io.commits.valid(i) && commitInfo.rfWen && commitInfo.ldest =/= 0.U))) difftest.io.rfwen := RegNext(RegNext(RegNext(io.commits.commitValid(i) && commitInfo.rfWen && commitInfo.ldest =/= 0.U)))
difftest.io.fpwen := RegNext(RegNext(RegNext(io.commits.valid(i) && commitInfo.fpWen))) difftest.io.fpwen := RegNext(RegNext(RegNext(io.commits.commitValid(i) && commitInfo.fpWen)))
difftest.io.wpdest := RegNext(RegNext(RegNext(commitInfo.pdest))) difftest.io.wpdest := RegNext(RegNext(RegNext(commitInfo.pdest)))
difftest.io.wdest := RegNext(RegNext(RegNext(commitInfo.ldest))) difftest.io.wdest := RegNext(RegNext(RegNext(commitInfo.ldest)))
} }
...@@ -1080,7 +1103,7 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -1080,7 +1103,7 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
val ptr = deqPtrVec(i).value val ptr = deqPtrVec(i).value
val uop = commitDebugUop(i) val uop = commitDebugUop(i)
val exuOut = debug_exuDebug(ptr) val exuOut = debug_exuDebug(ptr)
difftest.io.valid := RegNext(RegNext(RegNext(io.commits.valid(i) && !io.commits.isWalk))) difftest.io.valid := RegNext(RegNext(RegNext(io.commits.commitValid(i) && io.commits.isCommit)))
difftest.io.paddr := RegNext(RegNext(RegNext(exuOut.paddr))) difftest.io.paddr := RegNext(RegNext(RegNext(exuOut.paddr)))
difftest.io.opType := RegNext(RegNext(RegNext(uop.ctrl.fuOpType))) difftest.io.opType := RegNext(RegNext(RegNext(uop.ctrl.fuOpType)))
difftest.io.fuType := RegNext(RegNext(RegNext(uop.ctrl.fuType))) difftest.io.fuType := RegNext(RegNext(RegNext(uop.ctrl.fuType)))
...@@ -1092,10 +1115,10 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -1092,10 +1115,10 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
val dt_isXSTrap = Mem(RobSize, Bool()) val dt_isXSTrap = Mem(RobSize, Bool())
for (i <- 0 until RenameWidth) { for (i <- 0 until RenameWidth) {
when (canEnqueue(i)) { when (canEnqueue(i)) {
dt_isXSTrap(enqPtrVec(i).value) := io.enq.req(i).bits.ctrl.isXSTrap dt_isXSTrap(allocatePtrVec(i).value) := io.enq.req(i).bits.ctrl.isXSTrap
} }
} }
val trapVec = io.commits.valid.zip(deqPtrVec).map{ case (v, d) => state === s_idle && v && dt_isXSTrap(d.value) } val trapVec = io.commits.commitValid.zip(deqPtrVec).map{ case (v, d) => io.commits.isCommit && v && dt_isXSTrap(d.value) }
val hitTrap = trapVec.reduce(_||_) val hitTrap = trapVec.reduce(_||_)
val trapCode = PriorityMux(wdata.zip(trapVec).map(x => x._2 -> x._1)) val trapCode = PriorityMux(wdata.zip(trapVec).map(x => x._2 -> x._1))
val trapPC = SignExt(PriorityMux(wpc.zip(trapVec).map(x => x._2 ->x._1)), XLEN) val trapPC = SignExt(PriorityMux(wpc.zip(trapVec).map(x => x._2 ->x._1)), XLEN)
...@@ -1113,10 +1136,10 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -1113,10 +1136,10 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
val dt_isXSTrap = Mem(RobSize, Bool()) val dt_isXSTrap = Mem(RobSize, Bool())
for (i <- 0 until RenameWidth) { for (i <- 0 until RenameWidth) {
when (canEnqueue(i)) { when (canEnqueue(i)) {
dt_isXSTrap(enqPtrVec(i).value) := io.enq.req(i).bits.ctrl.isXSTrap dt_isXSTrap(allocatePtrVec(i).value) := io.enq.req(i).bits.ctrl.isXSTrap
} }
} }
val trapVec = io.commits.valid.zip(deqPtrVec).map{ case (v, d) => state === s_idle && v && dt_isXSTrap(d.value) } val trapVec = io.commits.commitValid.zip(deqPtrVec).map{ case (v, d) => io.commits.isCommit && v && dt_isXSTrap(d.value) }
val hitTrap = trapVec.reduce(_||_) val hitTrap = trapVec.reduce(_||_)
val difftest = Module(new DifftestBasicTrapEvent) val difftest = Module(new DifftestBasicTrapEvent)
difftest.io.clock := clock difftest.io.clock := clock
...@@ -1133,13 +1156,13 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer) ...@@ -1133,13 +1156,13 @@ class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
("rob_replay_inst_num ", io.flushOut.valid && isFlushPipe && deqHasReplayInst ), ("rob_replay_inst_num ", io.flushOut.valid && isFlushPipe && deqHasReplayInst ),
("rob_commitUop ", ifCommit(commitCnt) ), ("rob_commitUop ", ifCommit(commitCnt) ),
("rob_commitInstr ", ifCommit(trueCommitCnt) ), ("rob_commitInstr ", ifCommit(trueCommitCnt) ),
("rob_commitInstrMove ", ifCommit(PopCount(io.commits.valid.zip(commitIsMove).map{ case (v, m) => v && m })) ), ("rob_commitInstrMove ", ifCommit(PopCount(io.commits.commitValid.zip(commitIsMove).map{ case (v, m) => v && m })) ),
("rob_commitInstrFused ", ifCommit(fuseCommitCnt) ), ("rob_commitInstrFused ", ifCommit(fuseCommitCnt) ),
("rob_commitInstrLoad ", ifCommit(PopCount(commitLoadValid)) ), ("rob_commitInstrLoad ", ifCommit(PopCount(commitLoadValid)) ),
("rob_commitInstrLoad ", ifCommit(PopCount(commitBranchValid)) ), ("rob_commitInstrLoad ", ifCommit(PopCount(commitBranchValid)) ),
("rob_commitInstrLoadWait ", ifCommit(PopCount(commitLoadValid.zip(commitLoadWaitBit).map{ case (v, w) => v && w })) ), ("rob_commitInstrLoadWait ", ifCommit(PopCount(commitLoadValid.zip(commitLoadWaitBit).map{ case (v, w) => v && w })) ),
("rob_commitInstrStore ", ifCommit(PopCount(io.commits.valid.zip(commitIsStore).map{ case (v, t) => v && t })) ), ("rob_commitInstrStore ", ifCommit(PopCount(io.commits.commitValid.zip(commitIsStore).map{ case (v, t) => v && t })) ),
("rob_walkInstr ", Mux(io.commits.isWalk, PopCount(io.commits.valid), 0.U) ), ("rob_walkInstr ", Mux(io.commits.isWalk, PopCount(io.commits.walkValid), 0.U) ),
("rob_walkCycle ", (state === s_walk || state === s_extrawalk) ), ("rob_walkCycle ", (state === s_walk || state === s_extrawalk) ),
("rob_1_4_valid ", (PopCount((0 until RobSize).map(valid(_))) < (RobSize.U/4.U)) ), ("rob_1_4_valid ", (PopCount((0 until RobSize).map(valid(_))) < (RobSize.U/4.U)) ),
("rob_2_4_valid ", (PopCount((0 until RobSize).map(valid(_))) > (RobSize.U/4.U)) & (PopCount((0 until RobSize).map(valid(_))) <= (RobSize.U/2.U)) ), ("rob_2_4_valid ", (PopCount((0 until RobSize).map(valid(_))) > (RobSize.U/4.U)) & (PopCount((0 until RobSize).map(valid(_))) <= (RobSize.U/2.U)) ),
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册