提交 105e5703 编写于 作者: Y Yinan Xu

Merge remote-tracking branch 'origin/master' into ifu-timing

......@@ -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,24 @@ 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
// these should be optimized for synthesis verilog
val pc = UInt(VAddrBits.W)
}
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
}
......
......@@ -262,6 +262,8 @@ class LsqWrappper extends XSModule with HasDCacheParameters {
// LSQ: send out canAccept when both load queue and store queue are ready
// Dispatch: send instructions to LSQ only when they are ready
io.enq.canAccept := loadQueue.io.enq.canAccept && storeQueue.io.enq.canAccept
loadQueue.io.enq.sqCanAccept := storeQueue.io.enq.canAccept
storeQueue.io.enq.lqCanAccept := loadQueue.io.enq.canAccept
for (i <- 0 until RenameWidth) {
val isStore = CommitType.lsInstIsStore(io.enq.req(i).bits.ctrl.commitType)
......
......@@ -25,6 +25,7 @@ object LqPtr extends HasXSParameter {
class LqEnqIO extends XSBundle {
val canAccept = Output(Bool())
val sqCanAccept = Input(Bool())
val needAlloc = Vec(RenameWidth, Input(Bool()))
val req = Vec(RenameWidth, Flipped(ValidIO(new MicroOp)))
val resp = Vec(RenameWidth, Output(new LqPtr))
......@@ -68,8 +69,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)
......@@ -87,7 +88,7 @@ class LoadQueue extends XSModule with HasDCacheParameters with HasCircularQueueP
val offset = if (i == 0) 0.U else PopCount(io.enq.needAlloc.take(i))
val lqIdx = enqPtrExt(offset)
val index = lqIdx.value
when (io.enq.req(i).valid && io.enq.canAccept && !io.brqRedirect.valid) {
when (io.enq.req(i).valid && io.enq.canAccept && io.enq.sqCanAccept && !io.brqRedirect.valid) {
uop(index) := io.enq.req(i).bits
allocated(index) := true.B
datavalid(index) := false.B
......@@ -101,7 +102,7 @@ class LoadQueue extends XSModule with HasDCacheParameters with HasCircularQueueP
}
// when io.brqRedirect.valid, we don't allow eneuque even though it may fire.
when (Cat(firedDispatch).orR && io.enq.canAccept && !io.brqRedirect.valid) {
when (Cat(firedDispatch).orR && io.enq.canAccept && io.enq.sqCanAccept && !io.brqRedirect.valid) {
val enqNumber = PopCount(firedDispatch)
enqPtrExt := VecInit(enqPtrExt.map(_ + enqNumber))
XSInfo("dispatched %d insts to lq\n", enqNumber)
......@@ -496,9 +497,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
......
......@@ -23,6 +23,7 @@ object SqPtr extends HasXSParameter {
class SqEnqIO extends XSBundle {
val canAccept = Output(Bool())
val lqCanAccept = Input(Bool())
val needAlloc = Vec(RenameWidth, Input(Bool()))
val req = Vec(RenameWidth, Flipped(ValidIO(new MicroOp)))
val resp = Vec(RenameWidth, Output(new SqPtr))
......@@ -76,7 +77,7 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
val offset = if (i == 0) 0.U else PopCount(io.enq.needAlloc.take(i))
val sqIdx = enqPtrExt(offset)
val index = sqIdx.value
when (io.enq.req(i).valid && io.enq.canAccept && !io.brqRedirect.valid) {
when (io.enq.req(i).valid && io.enq.canAccept && io.enq.lqCanAccept && !io.brqRedirect.valid) {
uop(index) := io.enq.req(i).bits
allocated(index) := true.B
datavalid(index) := false.B
......@@ -87,7 +88,7 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
io.enq.resp(i) := sqIdx
}
when (Cat(firedDispatch).orR && io.enq.canAccept && !io.brqRedirect.valid) {
when (Cat(firedDispatch).orR && io.enq.canAccept && io.enq.lqCanAccept && !io.brqRedirect.valid) {
val enqNumber = PopCount(firedDispatch)
enqPtrExt := VecInit(enqPtrExt.map(_ + enqNumber))
XSInfo("dispatched %d insts to sq\n", enqNumber)
......@@ -194,9 +195,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 +256,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.
先完成此消息的编辑!
想要评论请 注册