提交 45a56a29 编写于 作者: Z ZhangZifei

Roq: add flush pipe logic for fence instr

上级 a6dfd373
......@@ -122,6 +122,7 @@ class CtrlSignals extends XSBundle {
val isXSTrap = Bool()
val noSpecExec = Bool() // This inst can not be speculated
val isBlocked = Bool() // This inst requires pipeline to be blocked
val flushPipe = Bool() // This inst will flush all the pipe when commit, like exception but can commit
val isRVF = Bool()
val imm = UInt(XLEN.W)
val commitType = CommitType()
......@@ -164,6 +165,7 @@ class Redirect extends XSBundle with HasRoqIdx {
val isException = Bool()
val isMisPred = Bool()
val isReplay = Bool()
val isFlushPipe = Bool()
val pc = UInt(VAddrBits.W)
val target = UInt(VAddrBits.W)
val brTag = new BrqPtr
......
......@@ -174,7 +174,7 @@ class Backend extends XSModule
io.mem.commits <> roq.io.commits
io.mem.ldin <> issueQueues.filter(_.exuCfg == Exu.ldExeUnitCfg).map(_.io.deq)
io.mem.stin <> issueQueues.filter(_.exuCfg == Exu.stExeUnitCfg).map(_.io.deq)
jmpExeUnit.io.exception.valid := roq.io.redirect.valid
jmpExeUnit.io.exception.valid := roq.io.redirect.valid && roq.io.redirect.bits.isException
jmpExeUnit.io.exception.bits := roq.io.exception
io.frontend.outOfOrderBrInfo <> brq.io.outOfOrderBrInfo
......
......@@ -34,7 +34,7 @@ class BrqPtr extends XSBundle {
def needBrFlush(redirectTag: BrqPtr): Bool = this < redirectTag
def needFlush(redirect: Valid[Redirect]): Bool = {
redirect.valid && (redirect.bits.isException || needBrFlush(redirect.bits.brTag))
redirect.valid && (redirect.bits.isException || redirect.bits.isFlushPipe || needBrFlush(redirect.bits.brTag)) //TODO: discuss if (isException || isFlushPipe) need here?
}
override def toPrintable: Printable = p"f:$flag v:$value"
......
......@@ -144,13 +144,13 @@ class Decoder extends XSModule with HasInstrType {
io.out.ctrl.lsrc1 := 10.U // a0
}
io.out.ctrl.noSpecExec := io.out.ctrl.isXSTrap || io.out.ctrl.fuType===FuType.csr || io.out.ctrl.fuType===FuType.mou || io.out.ctrl.fuType===FuType.fence/*noSpecExec make it sent to alu0,for roq is empty*/
//io.out.ctrl.isBlocked := (io.out.ctrl.fuType===FuType.alu && io.out.ctrl.fuOpType===ALUOpType.sfence) // TOOD: check it
io.out.ctrl.flushPipe := io.out.ctrl.fuType===FuType.fence
XSDebug("in: instr=%x pc=%x excepVec=%b intrVec=%b crossPageIPFFix=%d\n",
io.in.instr, io.in.pc, io.in.exceptionVec.asUInt, io.in.intrVec.asUInt, io.in.crossPageIPFFix)
XSDebug("out: src1Type=%b src2Type=%b src3Type=%b lsrc1=%d lsrc2=%d lsrc3=%d ldest=%d fuType=%b fuOpType=%b\n",
io.out.ctrl.src1Type, io.out.ctrl.src2Type, io.out.ctrl.src3Type, io.out.ctrl.lsrc1, io.out.ctrl.lsrc2, io.out.ctrl.lsrc3, io.out.ctrl.ldest, io.out.ctrl.fuType, io.out.ctrl.fuOpType)
XSDebug("out: rfWen=%d fpWen=%d isXSTrap=%d noSpecExec=%d isBlocked=%d isRVF=%d imm=%x\n",
io.out.ctrl.rfWen, io.out.ctrl.fpWen, io.out.ctrl.isXSTrap, io.out.ctrl.noSpecExec, io.out.ctrl.isBlocked, io.out.ctrl.isRVF, io.out.ctrl.imm)
XSDebug("out: rfWen=%d fpWen=%d isXSTrap=%d noSpecExec=%d isBlocked=%d flushPipe=%d isRVF=%d imm=%x\n",
io.out.ctrl.rfWen, io.out.ctrl.fpWen, io.out.ctrl.isXSTrap, io.out.ctrl.noSpecExec, io.out.ctrl.isBlocked, io.out.ctrl.flushPipe, io.out.ctrl.isRVF, io.out.ctrl.imm)
}
......@@ -118,11 +118,12 @@ 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 exceptionValid = io.redirect.valid && io.redirect.bits.isException
val flushPipeValid = io.redirect.valid && io.redirect.bits.isFlushPipe
val roqNeedFlush = Wire(Vec(size, Bool()))
val needCancel = Wire(Vec(size, Bool()))
for (i <- 0 until size) {
roqNeedFlush(i) := uopEntries(i.U).needFlush(io.redirect)
needCancel(i) := stateEntries(i) =/= s_invalid && ((roqNeedFlush(i) && mispredictionValid) || exceptionValid)
needCancel(i) := stateEntries(i) =/= s_invalid && ((roqNeedFlush(i) && mispredictionValid) || exceptionValid || flushPipeValid)
when (needCancel(i)) {
stateEntries(i) := s_invalid
}
......
......@@ -59,6 +59,7 @@ class AluExeUnit extends Exu(Exu.aluExeUnitCfg) {
io.out.bits.redirect.brTag := uop.brTag
io.out.bits.redirect.isException := false.B
io.out.bits.redirect.isMisPred := DontCare // check this in brq
io.out.bits.redirect.isFlushPipe := false.B
io.out.bits.redirect.isReplay := false.B
io.out.bits.redirect.roqIdx := uop.roqIdx
......@@ -77,13 +78,14 @@ class AluExeUnit extends Exu(Exu.aluExeUnitCfg) {
io.out.bits.data := aluRes
XSDebug(io.in.valid,
"In(%d %d) Out(%d %d) Redirect:(%d %d %d) brTag:f:%d v:%d\n",
"In(%d %d) Out(%d %d) Redirect:(%d %d %d %d) brTag:f:%d v:%d\n",
io.in.valid,
io.in.ready,
io.out.valid,
io.out.ready,
io.redirect.valid,
io.redirect.bits.isException,
io.redirect.bits.isFlushPipe,
redirectHit,
io.redirect.bits.brTag.flag,
io.redirect.bits.brTag.value
......
......@@ -47,11 +47,12 @@ class DivExeUnit extends Exu(Exu.divExeUnitCfg) {
io.dmem <> DontCare
io.out.bits.debug <> DontCare
XSDebug(io.in.valid || io.redirect.valid, "In(%d %d) Out(%d %d) Redirect:(%d %d) brTag:%x\n",
XSDebug(io.in.valid || io.redirect.valid, "In(%d %d) Out(%d %d) Redirect:(%d %d %d) brTag:%x\n",
io.in.valid, io.in.ready,
io.out.valid, io.out.ready,
io.redirect.valid,
io.redirect.bits.isException,
io.redirect.bits.isFlushPipe,
io.redirect.bits.brTag.value
)
XSDebug(io.in.valid, "src1:%x src2:%x func:%b pc:%x roqIdx:%d\n", src1, src2, func, io.in.bits.uop.cf.pc, io.in.bits.uop.roqIdx)
......
......@@ -38,6 +38,7 @@ class JmpExeUnit extends Exu(Exu.jmpExeUnitCfg) {
csrExuOut.redirect.brTag := uop.brTag
csrExuOut.redirect.isException := false.B
csrExuOut.redirect.isMisPred := false.B
csrExuOut.redirect.isFlushPipe := false.B
csrExuOut.redirect.isReplay := false.B
csrExuOut.redirect.roqIdx := uop.roqIdx
csrExuOut.redirect.target := csr.io.redirect.target
......
......@@ -181,7 +181,7 @@
// rdata := dataBackVec.asUInt
//
// val expRedirect = io.redirect.valid && io.redirect.bits.isException
// val brRedirect = io.redirect.valid && !io.redirect.bits.isException
// val brRedirect = io.redirect.valid && io.redirect.bits.isMisPred
// for(i <- 0 until 8){
// when((i.U >= stqCommited && i.U < stqHead) && (expRedirect || brRedirect && stqData(stqPtr(i)).brTag.needBrFlush(io.redirect.bits.brTag) && stqValid(stqPtr(i)))){
// stqValid(stqPtr(i)) := false.B
......
......@@ -45,11 +45,12 @@ class MulDivFenceExeUnit extends Exu(Exu.mulDivFenceExeUnitCfg){
io.out <> arb.io.out
XSDebug(io.in.valid || io.redirect.valid, "In(%d %d) Out(%d %d) Redirect:(%d %d) brTag:%x\n",
XSDebug(io.in.valid || io.redirect.valid, "In(%d %d) Out(%d %d) Redirect:(%d %d %d) brTag:%x\n",
io.in.valid, io.in.ready,
io.out.valid, io.out.ready,
io.redirect.valid,
io.redirect.bits.isException,
io.redirect.bits.isFlushPipe,
io.redirect.bits.brTag.value
)
XSDebug(io.in.valid, "src1:%x src2:%x pc:%x fuType:%b fuOpType:%b roqIdx:%d (%d%d%d)\n", src1, src2, io.in.bits.uop.cf.pc, io.in.bits.uop.ctrl.fuType, io.in.bits.uop.ctrl.fuOpType, io.in.bits.uop.roqIdx, isMul, isDiv, isFence)
......@@ -90,11 +91,12 @@ class MulDivExeUnit extends Exu(Exu.mulDivExeUnitCfg){
io.out <> arb.io.out
XSDebug(io.in.valid, "In(%d %d) Out(%d %d) Redirect:(%d %d) brTag:%x\n",
XSDebug(io.in.valid, "In(%d %d) Out(%d %d) Redirect:(%d %d %d) brTag:%x\n",
io.in.valid, io.in.ready,
io.out.valid, io.out.ready,
io.redirect.valid,
io.redirect.bits.isException,
io.redirect.bits.isFlushPipe,
io.redirect.bits.brTag.value
)
XSDebug(io.in.valid, "src1:%x src2:%x pc:%x\n", src1, src2, io.in.bits.uop.cf.pc)
......
......@@ -51,11 +51,12 @@ class MulExeUnit extends Exu(Exu.mulExeUnitCfg){
io.out.bits.redirectValid := false.B
io.out.bits.redirect <> DontCare
XSDebug(io.in.valid, "In(%d %d) Out(%d %d) Redirect:(%d %d) brTag:%x\n",
XSDebug(io.in.valid, "In(%d %d) Out(%d %d) Redirect:(%d %d %d) brTag:%x\n",
io.in.valid, io.in.ready,
io.out.valid, io.out.ready,
io.redirect.valid,
io.redirect.bits.isException,
io.redirect.bits.isFlushPipe,
io.redirect.bits.brTag.value
)
XSDebug(io.in.valid, "src1:%x src2:%x pc:%x\n", src1, src2, io.in.bits.uop.cf.pc)
......
......@@ -25,6 +25,7 @@ class Jump extends FunctionUnit(jmpCfg){
io.out.bits.redirect.target := target
io.out.bits.redirect.brTag := uop.brTag
io.out.bits.redirect.isException := false.B
io.out.bits.redirect.isFlushPipe := false.B
io.out.bits.redirect.isMisPred := DontCare // check this in brq
io.out.bits.redirect.isReplay := false.B
io.out.bits.redirect.roqIdx := uop.roqIdx
......@@ -49,13 +50,14 @@ class Jump extends FunctionUnit(jmpCfg){
io.out.bits.debug <> DontCare
// NOTE: the debug info is for one-cycle exec, if FMV needs multi-cycle, may needs change it
XSDebug(io.in.valid, "In(%d %d) Out(%d %d) Redirect:(%d %d %d) brTag:%x\n",
XSDebug(io.in.valid, "In(%d %d) Out(%d %d) Redirect:(%d %d %d %d) brTag:%x\n",
io.in.valid,
io.in.ready,
io.out.valid,
io.out.ready,
io.redirect.valid,
io.redirect.bits.isException,
io.redirect.bits.isFlushPipe,
redirectHit,
io.redirect.bits.brTag.value
)
......
......@@ -363,7 +363,7 @@ class ReservationStation
sel.bits.ctrl.rfWen := issQue(deqSelIq).uop.ctrl.rfWen
sel.bits.ctrl.fpWen := issQue(deqSelIq).uop.ctrl.fpWen
}
XSInfo(io.redirect.valid, "Redirect: valid:%d isExp:%d brTag:%d redHitVec:%b redIdHitVec:%b enqHit:%d selIsRed:%d\n", io.redirect.valid, io.redirect.bits.isException, io.redirect.bits.brTag.value, VecInit(redHitVec).asUInt, VecInit(redIdHitVec).asUInt, enqRedHit, selIsRed)
XSInfo(io.redirect.valid, "Redirect: valid:%d isExp:%d isFpp:%d brTag:%d redHitVec:%b redIdHitVec:%b enqHit:%d selIsRed:%d\n", io.redirect.valid, io.redirect.bits.isException, io.redirect.bits.isFlushPipe, io.redirect.bits.brTag.value, VecInit(redHitVec).asUInt, VecInit(redIdHitVec).asUInt, enqRedHit, selIsRed)
XSInfo(enqFire, s"EnqCtrl(%d %d) enqSelIq:%d Psrc/Rdy(%d:%d %d:%d %d:%d) Dest:%d oldDest:%d pc:%x roqIdx:%x\n", io.enqCtrl.valid, io.enqCtrl.ready, enqSelIq
, io.enqCtrl.bits.psrc1, io.enqCtrl.bits.src1State, io.enqCtrl.bits.psrc2, io.enqCtrl.bits.src2State, io.enqCtrl.bits.psrc3, io.enqCtrl.bits.src3State, io.enqCtrl.bits.pdest, io.enqCtrl.bits.old_pdest, io.enqCtrl.bits.cf.pc, io.enqCtrl.bits.roqIdx)
XSInfo(enqFireNext, "EnqData: src1:%x src2:%x src3:%x pc:%x roqIdx:%x(for last cycle's Ctrl)\n", io.enqData.src1, io.enqData.src2, io.enqData.src3, issQue(enqSelIqNext).uop.cf.pc, issQue(enqSelIqNext).uop.roqIdx)
......
......@@ -98,7 +98,7 @@ class FreeList extends XSModule with HasFreeListConsts {
}
headPtr := Mux(io.redirect.valid, // mispredict or exception happen
Mux(io.redirect.bits.isException,
Mux(io.redirect.bits.isException || io.redirect.bits.isFlushPipe, // TODO: need check by JiaWei
FreeListPtr(!tailPtr.flag, tailPtr.value),
Mux(io.redirect.bits.isMisPred,
checkPoints(io.redirect.bits.brTag.value),
......
......@@ -49,7 +49,7 @@ class Rename extends XSModule {
fpFreeList.redirect := io.redirect
intFreeList.redirect := io.redirect
val flush = io.redirect.valid && io.redirect.bits.isException
val flush = io.redirect.valid && (io.redirect.bits.isException || io.redirect.bits.isFlushPipe) // TODO: need check by JiaWei
fpRat.flush := flush
intRat.flush := flush
fpBusyTable.flush := flush
......
......@@ -114,14 +114,16 @@ class Roq extends XSModule {
val deqUop = microOp(deqPtr)
val intrEnable = intrBitSet && (state === s_idle) && !isEmpty && !hasCsr
val exceptionEnable = Cat(deqUop.cf.exceptionVec).orR() && (state === s_idle) && !isEmpty
// TODO: need check if writebacked needed
val isEcall = deqUop.cf.exceptionVec(ecallM) ||
deqUop.cf.exceptionVec(ecallS) ||
deqUop.cf.exceptionVec(ecallU)
val isFlushPipe = (deqUop.ctrl.flushPipe && writebacked(deqPtr))
io.redirect := DontCare
io.redirect.valid := intrEnable || exceptionEnable // TODO: add fence flush to flush the whol pipe
io.redirect.bits.isException := true.B
io.redirect.bits.target := trapTarget
io.redirect.valid := intrEnable || exceptionEnable || isFlushPipe// TODO: add fence flush to flush the whole pipe
io.redirect.bits.isException := intrEnable || exceptionEnable
io.redirect.bits.isFlushPipe := isFlushPipe
io.redirect.bits.target := Mux(isFlushPipe, deqUop.cf.pc + 4.U, trapTarget)
io.exception := deqUop
XSDebug(io.redirect.valid, "generate exception: pc 0x%x target 0x%x exceptionVec %b\n", io.exception.cf.pc, trapTarget, Cat(microOp(deqPtr).cf.exceptionVec))
......@@ -153,7 +155,7 @@ class Roq extends XSModule {
val commitIdx = deqPtr + i.U
val commitUop = microOp(commitIdx)
val hasException = Cat(commitUop.cf.exceptionVec).orR() || intrEnable
val canCommit = if(i!=0) io.commits(i-1).valid else true.B
val canCommit = if(i!=0) (io.commits(i-1).valid && io.commits(i-1).bits.uop.ctrl.flushPipe) else true.B
val v = valid(commitIdx)
val w = writebacked(commitIdx)
io.commits(i).valid := v && w && canCommit && !hasException
......@@ -235,7 +237,7 @@ class Roq extends XSModule {
io.bcommit := PopCount(cfiCommitVec)
// when redirect, walk back roq entries
when(io.brqRedirect.valid){
when(io.brqRedirect.valid){ // TODO: need check if consider exception redirect?
state := s_walk
walkPtrExt := Mux(state === s_walk && !walkFinished, walkPtrExt - CommitWidth.U, Mux(state === s_extrawalk, walkPtrExt, enqPtrExt - 1.U + dispatchCnt))
walkTgtExt := io.brqRedirect.bits.roqIdx
......
......@@ -285,8 +285,8 @@ class IFU extends XSModule with HasIFUConst
XSDebug(RegNext(reset.asBool) && !reset.asBool, "Reseting...\n")
XSDebug(io.icacheFlush(0).asBool, "Flush icache stage2...\n")
XSDebug(io.icacheFlush(1).asBool, "Flush icache stage3...\n")
XSDebug(io.redirect.valid, "Redirect from backend! isExcp=%d isMisPred=%d isReplay=%d pc=%x\n",
io.redirect.bits.isException, io.redirect.bits.isMisPred, io.redirect.bits.isReplay, io.redirect.bits.pc)
XSDebug(io.redirect.valid, "Redirect from backend! isExcp=%d isFpp:%d isMisPred=%d isReplay=%d pc=%x\n",
io.redirect.bits.isException, io.redirect.bits.isFlushPipe, io.redirect.bits.isMisPred, io.redirect.bits.isReplay, io.redirect.bits.pc)
XSDebug(io.redirect.valid, p"Redirect from backend! target=${Hexadecimal(io.redirect.bits.target)} brTag=${io.redirect.bits.brTag}\n")
XSDebug("[IF1] v=%d fire=%d flush=%d pc=%x ptr=%d mask=%b\n", if1_valid, if1_fire, if1_flush, if1_npc, ptr, mask(if1_npc))
......
......@@ -212,7 +212,7 @@ class LoadUnit extends XSModule {
XSDebug(l4_valid, "l4: lsroq forwardData: 0x%x forwardMask: %x\n",
io.lsroq.forward.forwardData.asUInt, io.lsroq.forward.forwardMask.asUInt)
XSDebug(io.redirect.valid, p"Redirect: excp:${io.redirect.bits.isException} misp:${io.redirect.bits.isMisPred} replay:${io.redirect.bits.isReplay} pc:0x${Hexadecimal(io.redirect.bits.pc)} target:0x${Hexadecimal(io.redirect.bits.target)} brTag:${io.redirect.bits.brTag} l2:${io.ldin.bits.uop.needFlush(io.redirect)} l3:${l3_uop.needFlush(io.redirect)} l4:${l4_out.bits.uop.needFlush(io.redirect)}\n")
XSDebug(io.redirect.valid, p"Redirect: excp:${io.redirect.bits.isException} flushPipe:${io.redirect.bits.isFlushPipe} misp:${io.redirect.bits.isMisPred} replay:${io.redirect.bits.isReplay} pc:0x${Hexadecimal(io.redirect.bits.pc)} target:0x${Hexadecimal(io.redirect.bits.target)} brTag:${io.redirect.bits.brTag} l2:${io.ldin.bits.uop.needFlush(io.redirect)} l3:${l3_uop.needFlush(io.redirect)} l4:${l4_out.bits.uop.needFlush(io.redirect)}\n")
//-------------------------------------------------------
// LD Pipeline Stage 5
// Do data ecc check, merge result and write back to LS ROQ
......
......@@ -542,6 +542,7 @@ class Lsroq extends XSModule {
rollback(i).bits.isReplay := true.B
rollback(i).bits.isMisPred := false.B
rollback(i).bits.isException := false.B
rollback(i).bits.isFlushPipe := false.B
XSDebug(
lsroqViolation,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册