提交 fe6452fc 编写于 作者: Y Yinan Xu

roq: wrap data in RoqDataModule

上级 512e951d
......@@ -218,22 +218,18 @@ class CfCtrl extends XSBundle {
val brTag = new BrqPtr
}
// Load / Store Index
//
// while separated lq and sq is used, lsIdx consists of lqIdx, sqIdx and l/s type.
trait HasLSIdx { this: HasXSParameter =>
// Separate LSQ
class LSIdx extends XSBundle {
val lqIdx = new LqPtr
val sqIdx = new SqPtr
}
class LSIdx extends XSBundle with HasLSIdx {}
// CfCtrl -> MicroOp at Rename Stage
class MicroOp extends CfCtrl with HasLSIdx {
class MicroOp extends CfCtrl {
val psrc1, psrc2, psrc3, pdest, old_pdest = UInt(PhyRegIdxWidth.W)
val src1State, src2State, src3State = SrcState()
val roqIdx = new RoqPtr
val lqIdx = new LqPtr
val sqIdx = new SqPtr
val diffTestDebugLrScValid = Bool()
}
......@@ -295,19 +291,21 @@ class CSRSpecialIO extends XSBundle {
val interrupt = Output(Bool())
}
//class ExuIO extends XSBundle {
// val in = Flipped(DecoupledIO(new ExuInput))
// val redirect = Flipped(ValidIO(new Redirect))
// val out = DecoupledIO(new ExuOutput)
// // for csr
// val csrOnly = new CSRSpecialIO
// val mcommit = Input(UInt(3.W))
//}
class RoqCommitInfo extends XSBundle {
val ldest = UInt(5.W)
val rfWen = Bool()
val fpWen = Bool()
val commitType = CommitType()
val pdest = UInt(PhyRegIdxWidth.W)
val old_pdest = UInt(PhyRegIdxWidth.W)
val lqIdx = new LqPtr
val sqIdx = new SqPtr
}
class RoqCommitIO extends XSBundle {
val isWalk = Output(Bool())
val valid = Vec(CommitWidth, Output(Bool()))
val uop = Vec(CommitWidth, Output(new MicroOp))
val info = Vec(CommitWidth, Output(new RoqCommitInfo))
def hasWalkInstr = isWalk && valid.asUInt.orR
def hasCommitInstr = !isWalk && valid.asUInt.orR
......
......@@ -41,17 +41,18 @@ class Dispatch1 extends XSModule {
* Part 1: choose the target dispatch queue and the corresponding write ports
*/
// valid bits for different dispatch queues
val isInt = VecInit(io.fromRename.map(req => FuType.isIntExu(req.bits.ctrl.fuType)))
val isFp = VecInit(io.fromRename.map(req => FuType.isFpExu (req.bits.ctrl.fuType)))
val isLs = VecInit(io.fromRename.map(req => FuType.isMemExu(req.bits.ctrl.fuType)))
val isStore = VecInit(io.fromRename.map(req => FuType.isStoreExu(req.bits.ctrl.fuType)))
val isAMO = VecInit(io.fromRename.map(req => req.bits.ctrl.fuType === FuType.mou))
val isInt = VecInit(io.fromRename.map(req => FuType.isIntExu(req.bits.ctrl.fuType)))
val isBranch = VecInit(io.fromRename.map(req => !req.bits.cf.brUpdate.pd.notCFI))
val isFp = VecInit(io.fromRename.map(req => FuType.isFpExu (req.bits.ctrl.fuType)))
val isLs = VecInit(io.fromRename.map(req => FuType.isMemExu(req.bits.ctrl.fuType)))
val isStore = VecInit(io.fromRename.map(req => FuType.isStoreExu(req.bits.ctrl.fuType)))
val isAMO = VecInit(io.fromRename.map(req => req.bits.ctrl.fuType === FuType.mou))
val isBlockBackward = VecInit(io.fromRename.map(_.bits.ctrl.blockBackward))
val isNoSpecExec = VecInit(io.fromRename.map(_.bits.ctrl.noSpecExec))
/**
* Part 2:
* Update commitType, psrc1, psrc2, psrc3, old_pdest for the uops
* Update commitType, psrc1, psrc2, psrc3, old_pdest, roqIdx, lqIdx, sqIdx for the uops
*/
val updatedUop = Wire(Vec(RenameWidth, new MicroOp))
val updatedCommitType = Wire(Vec(RenameWidth, CommitType()))
......@@ -61,7 +62,7 @@ class Dispatch1 extends XSModule {
val updatedOldPdest = Wire(Vec(RenameWidth, UInt(PhyRegIdxWidth.W)))
for (i <- 0 until RenameWidth) {
updatedCommitType(i) := Cat(isLs(i) && !isAMO(i), isStore(i) | isFp(i))
updatedCommitType(i) := Cat(isLs(i) && !isAMO(i), isStore(i) | isBranch(i))
updatedPsrc1(i) := io.fromRename.take(i).map(_.bits.pdest)
.zip(if (i == 0) Seq() else io.renameBypass.lsrc1_bypass(i-1).asBools)
.foldLeft(io.fromRename(i).bits.psrc1) {
......@@ -91,6 +92,10 @@ class Dispatch1 extends XSModule {
updatedUop(i).old_pdest := updatedOldPdest(i)
// update commitType
updatedUop(i).ctrl.commitType := updatedCommitType(i)
// update roqIdx, lqIdx, sqIdx
updatedUop(i).roqIdx := io.enqRoq.resp(i)
updatedUop(i).lqIdx := io.enqLsq.resp(i).lqIdx
updatedUop(i).sqIdx := io.enqLsq.resp(i).sqIdx
}
......@@ -125,9 +130,7 @@ class Dispatch1 extends XSModule {
// (2) previous instructions are ready
val thisCanActualOut = (0 until RenameWidth).map(i => !thisIsBlocked(i) && notBlockedByPrevious(i))
// input for ROQ and LSQ
// (1) LSQ needs roqIdx; (2) DPQ needs roqIdx and lsIdx
val updateUopWithIndex = Wire(Vec(RenameWidth, new MicroOp))
// input for ROQ, LSQ, Dispatch Queue
for (i <- 0 until RenameWidth) {
io.enqRoq.needAlloc(i) := io.fromRename(i).valid
io.enqRoq.req(i).valid := io.fromRename(i).valid && thisCanActualOut(i) && io.enqLsq.canAccept && io.toIntDq.canAccept && io.toFpDq.canAccept && io.toLsDq.canAccept
......@@ -142,23 +145,18 @@ class Dispatch1 extends XSModule {
XSDebug(io.enqLsq.req(i).valid,
p"pc 0x${Hexadecimal(io.fromRename(i).bits.cf.pc)} receives lq ${io.enqLsq.resp(i).lqIdx} sq ${io.enqLsq.resp(i).sqIdx}\n")
updateUopWithIndex(i) := updatedUop(i)
updateUopWithIndex(i).roqIdx := io.enqRoq.resp(i)
updateUopWithIndex(i).lqIdx := io.enqLsq.resp(i).lqIdx
updateUopWithIndex(i).sqIdx := io.enqLsq.resp(i).sqIdx
// send uops to dispatch queues
// Note that if one of their previous instructions cannot enqueue, they should not enter dispatch queue.
// We use notBlockedByPrevious here.
io.toIntDq.req(i).bits := updateUopWithIndex(i)
io.toIntDq.req(i).bits := updatedUop(i)
io.toIntDq.req(i).valid := io.fromRename(i).valid && isInt(i) && thisCanActualOut(i) &&
io.enqLsq.canAccept && io.enqRoq.canAccept && io.toFpDq.canAccept && io.toLsDq.canAccept
io.toFpDq.req(i).bits := updateUopWithIndex(i)
io.toFpDq.req(i).bits := updatedUop(i)
io.toFpDq.req(i).valid := io.fromRename(i).valid && isFp(i) && thisCanActualOut(i) &&
io.enqLsq.canAccept && io.enqRoq.canAccept && io.toIntDq.canAccept && io.toLsDq.canAccept
io.toLsDq.req(i).bits := updateUopWithIndex(i)
io.toLsDq.req(i).bits := updatedUop(i)
io.toLsDq.req(i).valid := io.fromRename(i).valid && isLs(i) && thisCanActualOut(i) &&
io.enqLsq.canAccept && io.enqRoq.canAccept && io.toIntDq.canAccept && io.toFpDq.canAccept
......@@ -177,7 +175,7 @@ class Dispatch1 extends XSModule {
XSInfo(io.recv(i) && io.fromRename(i).valid,
p"pc 0x${Hexadecimal(io.fromRename(i).bits.cf.pc)}, type(${isInt(i)}, ${isFp(i)}, ${isLs(i)}), " +
p"roq ${updateUopWithIndex(i).roqIdx}, lq ${updateUopWithIndex(i).lqIdx}, sq ${updateUopWithIndex(i).sqIdx})\n"
p"roq ${updatedUop(i).roqIdx}, lq ${updatedUop(i).lqIdx}, sq ${updatedUop(i).sqIdx})\n"
)
io.allocPregs(i).isInt := io.fromRename(i).valid && io.fromRename(i).bits.ctrl.rfWen && (io.fromRename(i).bits.ctrl.ldest =/= 0.U)
......
......@@ -824,10 +824,6 @@ class CSR extends FunctionUnit with HasCSRConst
"MbpRRight" -> (0xb0c, "perfCntCondMbpRRight" ),
"MbpRWrong" -> (0xb0d, "perfCntCondMbpRWrong" ),
"RoqWalk" -> (0xb0f, "perfCntCondRoqWalk" ),
"RoqWaitInt" -> (0xb10, "perfCntCondRoqWaitInt" ),
"RoqWaitFp" -> (0xb11, "perfCntCondRoqWaitFp" ),
"RoqWaitLoad" -> (0xb12, "perfCntCondRoqWaitLoad" ),
"RoqWaitStore"-> (0xb13, "perfCntCondRoqWaitStore"),
"DTlbReqCnt0" -> (0xb15, "perfCntDtlbReqCnt0" ),
"DTlbReqCnt1" -> (0xb16, "perfCntDtlbReqCnt1" ),
"DTlbReqCnt2" -> (0xb17, "perfCntDtlbReqCnt2" ),
......
......@@ -55,10 +55,13 @@ class Rename extends XSModule {
def needDestReg[T <: CfCtrl](fp: Boolean, x: T): Bool = {
{if(fp) x.ctrl.fpWen else x.ctrl.rfWen && (x.ctrl.ldest =/= 0.U)}
}
def needDestRegCommit[T <: RoqCommitInfo](fp: Boolean, x: T): Bool = {
{if(fp) x.fpWen else x.rfWen && (x.ldest =/= 0.U)}
}
fpFreeList.walk.valid := io.roqCommits.isWalk
intFreeList.walk.valid := io.roqCommits.isWalk
fpFreeList.walk.bits := PopCount((0 until CommitWidth).map(i => io.roqCommits.valid(i) && needDestReg(true, io.roqCommits.uop(i))))
intFreeList.walk.bits := PopCount((0 until CommitWidth).map(i => io.roqCommits.valid(i) && needDestReg(false, io.roqCommits.uop(i))))
fpFreeList.walk.bits := PopCount((0 until CommitWidth).map(i => io.roqCommits.valid(i) && needDestRegCommit(true, io.roqCommits.info(i))))
intFreeList.walk.bits := PopCount((0 until CommitWidth).map(i => io.roqCommits.valid(i) && needDestRegCommit(false, io.roqCommits.info(i))))
// walk has higher priority than allocation and thus we don't use isWalk here
fpFreeList.req.doAlloc := intFreeList.req.canAlloc && io.out(0).ready
intFreeList.req.doAlloc := fpFreeList.req.canAlloc && io.out(0).ready
......@@ -120,21 +123,21 @@ class Rename extends XSModule {
// speculative inst write
val specWen = freeList.req.allocReqs(i) && freeList.req.canAlloc && freeList.req.doAlloc && !io.roqCommits.isWalk
// walk back write
val commitDestValid = io.roqCommits.valid(i) && needDestReg(fp, io.roqCommits.uop(i))
val commitDestValid = io.roqCommits.valid(i) && needDestRegCommit(fp, io.roqCommits.info(i))
val walkWen = commitDestValid && io.roqCommits.isWalk
rat.specWritePorts(i).wen := specWen || walkWen
rat.specWritePorts(i).addr := Mux(specWen, uops(i).ctrl.ldest, io.roqCommits.uop(i).ctrl.ldest)
rat.specWritePorts(i).wdata := Mux(specWen, freeList.req.pdests(i), io.roqCommits.uop(i).old_pdest)
rat.specWritePorts(i).addr := Mux(specWen, uops(i).ctrl.ldest, io.roqCommits.info(i).ldest)
rat.specWritePorts(i).wdata := Mux(specWen, freeList.req.pdests(i), io.roqCommits.info(i).old_pdest)
XSInfo(walkWen,
{if(fp) p"fp" else p"int "} + p"walk: pc:${Hexadecimal(io.roqCommits.uop(i).cf.pc)}" +
{if(fp) p"fp" else p"int "} + p"walk: " +
p" ldest:${rat.specWritePorts(i).addr} old_pdest:${rat.specWritePorts(i).wdata}\n"
)
rat.archWritePorts(i).wen := commitDestValid && !io.roqCommits.isWalk
rat.archWritePorts(i).addr := io.roqCommits.uop(i).ctrl.ldest
rat.archWritePorts(i).wdata := io.roqCommits.uop(i).pdest
rat.archWritePorts(i).addr := io.roqCommits.info(i).ldest
rat.archWritePorts(i).wdata := io.roqCommits.info(i).pdest
XSInfo(rat.archWritePorts(i).wen,
{if(fp) p"fp" else p"int "} + p" rat arch: ldest:${rat.archWritePorts(i).addr}" +
......@@ -142,7 +145,7 @@ class Rename extends XSModule {
)
freeList.deallocReqs(i) := rat.archWritePorts(i).wen
freeList.deallocPregs(i) := io.roqCommits.uop(i).old_pdest
freeList.deallocPregs(i) := io.roqCommits.info(i).old_pdest
}
......
......@@ -47,6 +47,26 @@ class RoqEnqIO extends XSBundle {
val resp = Vec(RenameWidth, Output(new RoqPtr))
}
class RoqDataModule(numRead: Int, numWrite: Int) extends XSModule {
val io = IO(new Bundle {
val raddr = Vec(numRead, Input(new RoqPtr))
val rdata = Vec(numRead, Output(new RoqCommitInfo))
val wen = Vec(numWrite, Input(Bool()))
val waddr = Vec(numWrite, Input(new RoqPtr))
val wdata = Vec(numWrite, Input(new RoqCommitInfo))
})
val data = Mem(RoqSize, new RoqCommitInfo)
for (i <- 0 until numRead) {
io.rdata(i) := data(io.raddr(i).value)
}
for (i <- 0 until numWrite) {
when (io.wen(i)) {
data(io.waddr(i).value) := io.wdata(i)
}
}
}
class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
val io = IO(new Bundle() {
val brqRedirect = Input(Valid(new Redirect))
......@@ -111,31 +131,59 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
io.roqDeqPtr := deqPtrExt
// common signal
val enqPtrVec = WireInit(VecInit((0 until RenameWidth).map(i => enqPtrExt + PopCount(io.enq.needAlloc.take(i)))))
val deqPtrExtPlus = Wire(Vec(RenameWidth, UInt(log2Up(RoqSize).W)))
for(i <- 0 until CommitWidth){
val roqIdxExt = deqPtrExt + i.U
deqPtrExtPlus(i) := roqIdxExt.value
val enqPtrVec = VecInit((0 until RenameWidth).map(i => enqPtrExt + PopCount(io.enq.needAlloc.take(i))))
val deqPtrVec = VecInit((0 until CommitWidth).map(i => deqPtrExt + i.U))
val walkPtrVec = VecInit((0 until CommitWidth).map(i => walkPtrExt - i.U))
val deqPtrExtPlus = VecInit(deqPtrVec.map(_.value))
/**
* CommitDataModule: store commit info separately
* (1) read: commits/walk
* (2) write: enqueue
*/
val commitData = Module(new RoqDataModule(CommitWidth, RenameWidth))
val deqCommitData = commitData.io.rdata(0)
for (i <- 0 until RenameWidth) {
commitData.io.wen(i) := false.B
commitData.io.waddr(i) := enqPtrVec(i)
commitData.io.wdata(i).ldest := io.enq.req(i).bits.ctrl.ldest
commitData.io.wdata(i).rfWen := io.enq.req(i).bits.ctrl.rfWen
commitData.io.wdata(i).fpWen := io.enq.req(i).bits.ctrl.fpWen
commitData.io.wdata(i).commitType := io.enq.req(i).bits.ctrl.commitType
commitData.io.wdata(i).pdest := io.enq.req(i).bits.pdest
commitData.io.wdata(i).old_pdest := io.enq.req(i).bits.old_pdest
commitData.io.wdata(i).lqIdx := io.enq.req(i).bits.lqIdx
commitData.io.wdata(i).sqIdx := io.enq.req(i).bits.sqIdx
}
for (i <- 0 until CommitWidth) {
commitData.io.raddr(i) := walkPtrVec(i)
when (state === s_idle) {
commitData.io.raddr(i) := deqPtrVec(i)
}
}
// Dispatch
/**
* Enqueue (from dispatch)
*/
// special cases
val hasBlockBackward = RegInit(false.B)
val hasNoSpecExec = RegInit(false.B)
// When blockBackward instruction leaves Roq (commit or walk), hasBlockBackward should be set to false.B
val blockBackwardLeave = Cat((0 until CommitWidth).map(i => io.commits.valid(i) && io.commits.uop(i).ctrl.blockBackward)).orR
when(blockBackwardLeave || io.redirect.valid) { hasBlockBackward:= false.B }
// val blockBackwardLeave = Cat((0 until CommitWidth).map(i => io.commits.valid(i) && io.commits.uop(i).ctrl.blockBackward)).orR
when (isEmpty) { hasBlockBackward:= false.B }
// When noSpecExec instruction commits (it should not be walked except when it has not entered Roq),
// hasNoSpecExec should be set to false.B
val noSpecExecCommit = !io.commits.isWalk && Cat((0 until CommitWidth).map(i => io.commits.valid(i) && io.commits.uop(i).ctrl.noSpecExec)).orR
when(noSpecExecCommit || io.redirect.valid) { hasNoSpecExec:= false.B }
// val noSpecExecCommit = !io.commits.isWalk && Cat((0 until CommitWidth).map(i => io.commits.valid(i) && io.commits.uop(i).ctrl.noSpecExec)).orR
when (io.commits.valid.asUInt.orR) { hasNoSpecExec:= false.B }
// Assertion on that noSpecExec should never be walked since it's the only instruction in Roq.
// Extra walk should be ok since noSpecExec has not enter Roq.
val walkNoSpecExec = io.commits.isWalk && Cat((0 until CommitWidth).map(i => io.commits.valid(i) && io.commits.uop(i).ctrl.noSpecExec)).orR
XSError(state =/= s_extrawalk && walkNoSpecExec, "noSpecExec should not walk\n")
// val walkNoSpecExec = io.commits.isWalk && Cat((0 until CommitWidth).map(i => io.commits.valid(i) && io.commits.uop(i).ctrl.noSpecExec)).orR
// XSError(state =/= s_extrawalk && walkNoSpecExec, "noSpecExec should not walk\n")
for (i <- 0 until RenameWidth) {
when(io.enq.req(i).valid && io.enq.canAccept) {
// store uop in data module and microOp Vec
commitData.io.wen(i) := true.B
microOp(enqPtrVec(i).value) := io.enq.req(i).bits
when(io.enq.req(i).bits.ctrl.blockBackward) {
hasBlockBackward := true.B
......@@ -158,7 +206,9 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
XSInfo("dispatched %d insts\n", firedDispatch)
}
// Writeback
/**
* Writeback (from execution units)
*/
val firedWriteback = io.exeWbResults.map(_.fire())
XSInfo(PopCount(firedWriteback) > 0.U, "writebacked %d insts\n", PopCount(firedWriteback))
for(i <- 0 until numWbPorts) {
......@@ -166,8 +216,6 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
val wbIdxExt = io.exeWbResults(i).bits.uop.roqIdx
val wbIdx = wbIdxExt.value
microOp(wbIdx).cf.exceptionVec := io.exeWbResults(i).bits.uop.cf.exceptionVec
microOp(wbIdx).lqIdx := io.exeWbResults(i).bits.uop.lqIdx
microOp(wbIdx).sqIdx := io.exeWbResults(i).bits.uop.sqIdx
microOp(wbIdx).ctrl.flushPipe := io.exeWbResults(i).bits.uop.ctrl.flushPipe
microOp(wbIdx).diffTestDebugLrScValid := io.exeWbResults(i).bits.uop.diffTestDebugLrScValid
debug_exuData(wbIdx) := io.exeWbResults(i).bits.data
......@@ -182,15 +230,17 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
}
}
// Interrupt
/**
* Interrupt and Exceptions
*/
val deqUop = microOp(deqPtr)
val deqPtrWritebacked = writebacked(deqPtr) && valid(deqPtr)
val intrEnable = io.csr.intrBitSet && !isEmpty && !hasNoSpecExec &&
deqUop.ctrl.commitType =/= CommitType.STORE && deqUop.ctrl.commitType =/= CommitType.LOAD// TODO: wanna check why has hasCsr(hasNoSpec)
deqCommitData.commitType =/= CommitType.STORE && deqCommitData.commitType =/= CommitType.LOAD
val exceptionEnable = deqPtrWritebacked && Cat(deqUop.cf.exceptionVec).orR()
val isFlushPipe = deqPtrWritebacked && deqUop.ctrl.flushPipe
io.redirect := DontCare
io.redirect.valid := (state === s_idle) && (intrEnable || exceptionEnable || isFlushPipe)// TODO: add fence flush to flush the whole pipe
io.redirect.valid := (state === s_idle) && (intrEnable || exceptionEnable || isFlushPipe)
io.redirect.bits.isException := intrEnable || exceptionEnable
// reuse isFlushPipe to represent interrupt for CSR
io.redirect.bits.isFlushPipe := isFlushPipe || intrEnable
......@@ -201,22 +251,22 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
io.exception.cf.pc, intrEnable, exceptionEnable, isFlushPipe, io.redirect.bits.target, io.csr.trapTarget,
Cat(microOp(deqPtr).cf.exceptionVec))
// Commit uop to Rename (walk)
/**
* Commits (and walk)
* They share the same width.
*/
val walkCounter = Reg(UInt(log2Up(RoqSize).W))
val shouldWalkVec = Wire(Vec(CommitWidth, Bool()))
val walkPtrVec = Wire(Vec(CommitWidth, new RoqPtr))
for(i <- shouldWalkVec.indices){
walkPtrVec(i) := walkPtrExt - i.U
shouldWalkVec(i) := i.U < walkCounter
}
val walkFinished = walkCounter <= CommitWidth.U //&& // walk finish in this cycle
//!io.brqRedirect.valid // no new redirect comes and update walkptr
val walkFinished = walkCounter <= CommitWidth.U
// extra space is used weh roq has no enough space, but mispredict recovery needs such info to walk regmap
val needExtraSpaceForMPR = WireInit(VecInit(
List.tabulate(RenameWidth)(i => io.brqRedirect.valid && io.enq.needAlloc(i))
))
val extraSpaceForMPR = Reg(Vec(RenameWidth, new MicroOp))
val extraSpaceForMPR = Reg(Vec(RenameWidth, new RoqCommitInfo))
val usedSpaceForMPR = Reg(Vec(RenameWidth, Bool()))
val storeCommitVec = WireInit(VecInit(Seq.fill(CommitWidth)(false.B)))
......@@ -228,24 +278,20 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
io.commits.isWalk := state =/= s_idle
for (i <- 0 until CommitWidth) {
io.commits.valid(i) := false.B
io.commits.uop(i) := DontCare
switch(state){
is(s_idle){
val commitIdx = deqPtr + i.U
val commitInfo = commitData.io.rdata(i)
io.commits.info(i) := commitInfo
switch (state) {
is (s_idle) {
val commitIdx = deqPtrVec(i).value
val commitUop = microOp(commitIdx)
val hasException = Cat(commitUop.cf.exceptionVec).orR() || intrEnable
val canCommit = if(i!=0) (io.commits.valid(i-1) && !io.commits.uop(i-1).ctrl.flushPipe) else true.B
val canCommit = if(i!=0) (io.commits.valid(i-1) && !microOp(deqPtrVec(i-1).value).ctrl.flushPipe) else true.B
val v = valid(commitIdx)
val w = writebacked(commitIdx)
io.commits.valid(i) := v && w && canCommit && !hasException
io.commits.uop(i) := commitUop
storeCommitVec(i) := io.commits.valid(i) &&
commitUop.ctrl.commitType === CommitType.STORE
cfiCommitVec(i) := io.commits.valid(i) &&
!commitUop.cf.brUpdate.pd.notCFI
storeCommitVec(i) := io.commits.valid(i) && CommitType.isLoadStore(commitInfo.commitType) && CommitType.lsInstIsStore(commitInfo.commitType)
cfiCommitVec(i) := io.commits.valid(i) && CommitType.isBranch(commitInfo.commitType)
val commitFflags = exuFflags(commitIdx)
when(io.commits.valid(i)){
......@@ -253,7 +299,7 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
// update fflags
fflags := exuFflags(commitIdx)
}
when(commitUop.ctrl.fpWen){
when(commitInfo.fpWen){
// set fs to dirty
dirty_fs := true.B
}
......@@ -262,46 +308,41 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
XSInfo(io.commits.valid(i),
"retired pc %x wen %d ldest %d pdest %x old_pdest %x data %x fflags: %b\n",
commitUop.cf.pc,
commitUop.ctrl.rfWen,
commitUop.ctrl.ldest,
commitUop.pdest,
commitUop.old_pdest,
commitInfo.rfWen,
commitInfo.ldest,
commitInfo.pdest,
commitInfo.old_pdest,
debug_exuData(commitIdx),
exuFflags(commitIdx).asUInt
)
XSInfo(io.commits.valid(i) && debug_exuDebug(commitIdx).isMMIO,
"difftest skiped pc0x%x\n",
commitUop.cf.pc
)
}
is(s_walk){
is (s_walk) {
val idx = walkPtrVec(i).value
val v = valid(idx)
val walkUop = microOp(idx)
io.commits.valid(i) := v && shouldWalkVec(i)
io.commits.uop(i) := walkUop
when(shouldWalkVec(i)){
when (shouldWalkVec(i)) {
v := false.B
}
XSInfo(io.commits.valid(i) && shouldWalkVec(i), "walked pc %x wen %d ldst %d data %x\n",
walkUop.cf.pc,
walkUop.ctrl.rfWen,
walkUop.ctrl.ldest,
commitInfo.rfWen,
commitInfo.ldest,
debug_exuData(idx)
)
}
is(s_extrawalk){
is (s_extrawalk) {
val idx = RenameWidth-i-1
val walkUop = extraSpaceForMPR(idx)
io.commits.valid(i) := usedSpaceForMPR(idx)
io.commits.uop(i) := walkUop
io.commits.info(i) := walkUop
state := s_walk
XSInfo(io.commits.valid(i), "use extra space walked pc %x wen %d ldst %d\n",
walkUop.cf.pc,
walkUop.ctrl.rfWen,
walkUop.ctrl.ldest
XSInfo(io.commits.valid(i), "use extra space walked wen %d ldst %d\n",
// walkUop.cf.pc,
commitInfo.rfWen,
commitInfo.ldest
)
}
}
......@@ -348,7 +389,7 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
// no enough space for walk, allocate extra space
when(needExtraSpaceForMPR.asUInt.orR && io.brqRedirect.valid){
usedSpaceForMPR := needExtraSpaceForMPR
(0 until RenameWidth).foreach(i => extraSpaceForMPR(i) := io.enq.req(i).bits)
(0 until RenameWidth).foreach(i => extraSpaceForMPR(i) := commitData.io.wdata(i))
state := s_extrawalk
XSDebug("roq full, switched to s_extrawalk. needExtraSpaceForMPR: %b\n", needExtraSpaceForMPR.asUInt)
}
......@@ -360,8 +401,13 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
deqPtrExt := 0.U.asTypeOf(new RoqPtr)
}
// instvalid field
/**
* States
* We put all the stage changes here.
* All events: (1) enqueue (dispatch); (2) writeback; (3) cancel; (4) dequeue (commit);
* All states: (1) valid; (2) writebacked;
*/
// write
// enqueue logic writes 6 valid
for (i <- 0 until RenameWidth) {
......@@ -492,8 +538,8 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
val isRVC = Wire(Vec(CommitWidth, Bool()))
for(i <- 0 until CommitWidth){
// io.commits(i).valid
val idx = deqPtr+i.U
val uop = io.commits.uop(i)
val idx = deqPtrVec(i).value
val uop = microOp(idx)
val DifftestSkipSC = false
if(!DifftestSkipSC){
skip(i) := debug_exuDebug(idx).isMMIO && io.commits.valid(i)
......@@ -514,8 +560,8 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
}
val scFailed = !diffTestDebugLrScValid(0) &&
io.commits.uop(0).ctrl.fuType === FuType.mou &&
(io.commits.uop(0).ctrl.fuOpType === LSUOpType.sc_d || io.commits.uop(0).ctrl.fuOpType === LSUOpType.sc_w)
microOp(deqPtr).ctrl.fuType === FuType.mou &&
(microOp(deqPtr).ctrl.fuOpType === LSUOpType.sc_d || microOp(deqPtr).ctrl.fuOpType === LSUOpType.sc_w)
val instrCnt = RegInit(0.U(64.W))
instrCnt := instrCnt + retireCounter
......@@ -548,12 +594,6 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
ExcitingUtils.addSource(RegNext(GTimer()), "trapCycleCnt")
ExcitingUtils.addSource(RegNext(instrCnt), "trapInstrCnt")
ExcitingUtils.addSource(state === s_walk || state === s_extrawalk, "perfCntCondRoqWalk", Perf)
val deqNotWritebacked = valid(deqPtr) && !writebacked(deqPtr)
val deqUopCommitType = deqUop.ctrl.commitType
ExcitingUtils.addSource(deqNotWritebacked && deqUopCommitType === CommitType.INT, "perfCntCondRoqWaitInt", Perf)
ExcitingUtils.addSource(deqNotWritebacked && deqUopCommitType === CommitType.FP, "perfCntCondRoqWaitFp", Perf)
ExcitingUtils.addSource(deqNotWritebacked && deqUopCommitType === CommitType.LOAD, "perfCntCondRoqWaitLoad", Perf)
ExcitingUtils.addSource(deqNotWritebacked && deqUopCommitType === CommitType.STORE, "perfCntCondRoqWaitStore", Perf)
if(EnableBPU){
ExcitingUtils.addSource(hitTrap, "XSTRAP", ConnectionType.Debug)
......
......@@ -68,8 +68,8 @@ class LoadQueue extends XSModule with HasDCacheParameters with HasCircularQueueP
val isFull = enqPtr === deqPtr && !sameFlag
val allowIn = !isFull
val loadCommit = (0 until CommitWidth).map(i => io.commits.valid(i) && !io.commits.isWalk && io.commits.uop(i).ctrl.commitType === CommitType.LOAD)
val mcommitIdx = (0 until CommitWidth).map(i => io.commits.uop(i).lqIdx.value)
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)
......@@ -496,9 +496,8 @@ class LoadQueue extends XSModule with HasDCacheParameters with HasCircularQueueP
* Memory mapped IO / other uncached operations
*
*/
val commitType = io.commits.uop(0).ctrl.commitType
io.uncache.req.valid := pending(deqPtr) && allocated(deqPtr) &&
commitType === CommitType.LOAD &&
io.commits.info(0).commitType === CommitType.LOAD &&
io.roqDeqPtr === uop(deqPtr).roqIdx &&
!io.commits.isWalk
......
......@@ -194,9 +194,8 @@ 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
val commitType = io.commits.uop(0).ctrl.commitType
io.uncache.req.valid := pending(deqPtr) && allocated(deqPtr) &&
commitType === CommitType.STORE &&
io.commits.info(0).commitType === CommitType.STORE &&
io.roqDeqPtr === uop(deqPtr).roqIdx &&
!io.commits.isWalk
......@@ -256,10 +255,10 @@ 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.uop(i).ctrl.commitType === CommitType.STORE
val storeCommit = !io.commits.isWalk && io.commits.valid(i) && io.commits.info(i).commitType === CommitType.STORE
when (storeCommit) {
commited(io.commits.uop(i).sqIdx.value) := true.B
XSDebug("store commit %d: idx %d %x\n", i.U, io.commits.uop(i).sqIdx.value, io.commits.uop(i).cf.pc)
commited(io.commits.info(i).sqIdx.value) := true.B
XSDebug("store commit %d: idx %d\n", i.U, io.commits.info(i).sqIdx.value)
}
}
......
......@@ -85,13 +85,14 @@ package object xiangshan {
}
object CommitType {
def INT = "b00".U // int
def FP = "b01".U // fp
def LOAD = "b10".U // load
def STORE = "b11".U // store
def NORMAL = "b00".U // int/fp
def BRANCH = "b01".U // branch
def LOAD = "b10".U // load
def STORE = "b11".U // store
def apply() = UInt(2.W)
def isLoadStore(commitType: UInt) = commitType(1)
def lsInstIsStore(commitType: UInt) = commitType(0)
def isBranch(commitType: UInt) = commitType(0) && !commitType(1)
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册