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

rob: optimize bits width in storage (#1155)

This PR optimizes out isFused and crossPageIPFFix usages in Rob's DispatchData. They will not be stored in ROB. Now DispatchData has only 38 bits.

* isFused is merged with commitType (2 bits reduced)
* crossPageIPFFix is used only in ExceptionGen (1 bit reduced)
* rename: reduce ldest usages
* decode: set isMove to false if ldest is zero
上级 a79fef67
......@@ -162,7 +162,6 @@ class CtrlSignals(implicit p: Parameters) extends XSBundle {
val fpu = new FPUCtrlSignals
val isMove = Bool()
val singleStep = Bool()
val isFused = UInt(3.W)
val isORI = Bool() //for softprefetch
val isSoftPrefetchRead = Bool() //for softprefetch
val isSoftPrefetchWrite = Bool() //for softprefetch
......@@ -333,7 +332,6 @@ class RobCommitInfo(implicit p: Parameters) extends XSBundle {
val old_pdest = UInt(PhyRegIdxWidth.W)
val ftqIdx = new FtqPtr
val ftqOffset = UInt(log2Up(PredictWidth).W)
val isFused = UInt(3.W)
// these should be optimized for synthesis verilog
val pc = UInt(VAddrBits.W)
......
......@@ -88,7 +88,7 @@ class DecodeStage(implicit p: Parameters) extends XSModule {
val cond2 = sameFtqPtr && ftqOffsetDiff === 2.U
val cond3 = !sameFtqPtr && ftqOffset1 === 0.U
val cond4 = !sameFtqPtr && ftqOffset1 === 1.U
out.bits.ctrl.isFused := Mux(cond1, 1.U, Mux(cond2, 2.U, Mux(cond3, 3.U, 4.U)))
out.bits.ctrl.commitType := Mux(cond1, 4.U, Mux(cond2, 5.U, Mux(cond3, 6.U, 7.U)))
XSError(!cond1 && !cond2 && !cond3 && !cond4, p"new condition $sameFtqPtr $ftqOffset0 $ftqOffset1\n")
}
}
......
......@@ -544,21 +544,19 @@ class DecodeUnit(implicit p: Parameters) extends XSModule with DecodeUnitConstan
cs.isSoftPrefetchRead := false.B
cs.isSoftPrefetchWrite := false.B
cs.isFused := 0.U
val fpDecoder = Module(new FPDecoder)
fpDecoder.io.instr := ctrl_flow.instr
cs.fpu := fpDecoder.io.fpCtrl
val isMove = BitPat("b000000000000_?????_000_?????_0010011") === ctrl_flow.instr
cs.isMove := isMove
cs.isMove := isMove && ctrl_flow.instr(RD_MSB, RD_LSB) =/= 0.U
// read src1~3 location
cs.lsrc(0) := Mux(ctrl_flow.instr === LUI, 0.U,ctrl_flow.instr(RS1_MSB,RS1_LSB))
cs.lsrc(1) := ctrl_flow.instr(RS2_MSB,RS2_LSB)
cs.lsrc(2) := ctrl_flow.instr(RS3_MSB,RS3_LSB)
cs.lsrc(0) := Mux(ctrl_flow.instr === LUI, 0.U, ctrl_flow.instr(RS1_MSB, RS1_LSB))
cs.lsrc(1) := ctrl_flow.instr(RS2_MSB, RS2_LSB)
cs.lsrc(2) := ctrl_flow.instr(RS3_MSB, RS3_LSB)
// read dest location
cs.ldest := Mux((cs.fpWen || cs.rfWen) && !(isMove && ctrl_flow.instr(RS1_MSB,RS1_LSB) === ctrl_flow.instr(RD_MSB,RD_LSB)), ctrl_flow.instr(RD_MSB,RD_LSB), 0.U)
cs.ldest := ctrl_flow.instr(RD_MSB, RD_LSB)
// fill in exception vector
cf_ctrl.cf.exceptionVec := io.enq.ctrl_flow.exceptionVec
......
......@@ -134,10 +134,12 @@ class Dispatch(implicit p: Parameters) extends XSModule with HasExceptionNO {
updatedUop(i) := io.fromRename(i).bits
updatedUop(i).debugInfo.eliminatedMove := io.fromRename(i).bits.eliminatedMove
// update commitType
updatedUop(i).ctrl.commitType := updatedCommitType(i)
when (!CommitType.isFused(io.fromRename(i).bits.ctrl.commitType)) {
updatedUop(i).ctrl.commitType := updatedCommitType(i)
}.otherwise {
XSError(io.fromRename(i).valid && updatedCommitType(i) =/= CommitType.NORMAL, "why fused?\n")
}
// update robIdx, lqIdx, sqIdx
// updatedUop(i).robIdx := io.enqRob.resp(i)
// XSError(io.fromRename(i).valid && updatedUop(i).robIdx.asUInt =/= io.enqRob.resp(i).asUInt, "they should equal")
updatedUop(i).lqIdx := io.enqLsq.resp(i).lqIdx
updatedUop(i).sqIdx := io.enqLsq.resp(i).sqIdx
......
......@@ -47,14 +47,11 @@ class Rename(implicit p: Parameters) extends XSModule {
val fpFreeList = Module(new StdFreeList(StdFreeListSize))
// decide if given instruction needs allocating a new physical register (CfCtrl: from decode; RobCommitInfo: from rob)
val isIntDest = io.in.map(in => in.bits.ctrl.rfWen && in.bits.ctrl.ldest =/= 0.U)
val isFpDest = io.in.map(_.bits.ctrl.fpWen)
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 <: RobCommitInfo](fp: Boolean, x: T): Bool = {
// TODO: why this ldest?
{if(fp) x.fpWen else x.rfWen && (x.ldest =/= 0.U)}
if(fp) x.fpWen else x.rfWen
}
// connect [redirect + walk] ports for __float point__ & __integer__ free list
......
......@@ -102,16 +102,18 @@ class RenameTableWrapper(implicit p: Parameters) extends XSModule {
intRat.io.debug_rdata <> io.debug_int_rat
intRat.io.readPorts <> io.intReadPorts.flatten
val intDestValid = io.robCommits.info.map(info => info.rfWen && info.ldest =/= 0.U)
val intDestValid = io.robCommits.info.map(_.rfWen)
for ((arch, i) <- intRat.io.archWritePorts.zipWithIndex) {
arch.wen := !io.robCommits.isWalk && io.robCommits.valid(i) && intDestValid(i)
arch.addr := io.robCommits.info(i).ldest
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")
}
for ((spec, i) <- intRat.io.specWritePorts.zipWithIndex) {
spec.wen := io.robCommits.isWalk && io.robCommits.valid(i) && intDestValid(i)
spec.addr := io.robCommits.info(i).ldest
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")
}
for ((spec, rename) <- intRat.io.specWritePorts.zip(io.intRenamePorts)) {
when (rename.wen) {
......
......@@ -76,9 +76,7 @@ class RobEnqIO(implicit p: Parameters) extends XSBundle {
val resp = Vec(RenameWidth, Output(new RobPtr))
}
class RobDispatchData(implicit p: Parameters) extends RobCommitInfo {
val crossPageIPFFix = Bool()
}
class RobDispatchData(implicit p: Parameters) extends RobCommitInfo
class RobDeqPtrWrapper(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelper {
val io = IO(new Bundle {
......@@ -164,6 +162,7 @@ class RobExceptionInfo(implicit p: Parameters) extends XSBundle {
val flushPipe = Bool()
val replayInst = Bool() // redirect to that inst itself
val singleStep = Bool()
val crossPageIPFFix = Bool()
def has_exception = exceptionVec.asUInt.orR || flushPipe || singleStep || replayInst
// only exceptions are allowed to writeback when enqueue
......@@ -440,7 +439,7 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
io.exception.bits.uop.ctrl.commitType := RegEnable(deqDispatchData.commitType, exceptionHappen)
io.exception.bits.uop.cf.exceptionVec := RegEnable(exceptionDataRead.bits.exceptionVec, exceptionHappen)
io.exception.bits.uop.ctrl.singleStep := RegEnable(exceptionDataRead.bits.singleStep, exceptionHappen)
io.exception.bits.uop.cf.crossPageIPFFix := RegEnable(deqDispatchData.crossPageIPFFix, exceptionHappen)
io.exception.bits.uop.cf.crossPageIPFFix := RegEnable(exceptionDataRead.bits.crossPageIPFFix, exceptionHappen)
io.exception.bits.isInterrupt := RegEnable(intrEnable, exceptionHappen)
XSDebug(io.flushOut.valid,
......@@ -734,9 +733,6 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
wdata.ftqIdx := req.cf.ftqPtr
wdata.ftqOffset := req.cf.ftqOffset
wdata.pc := req.cf.pc
wdata.crossPageIPFFix := req.cf.crossPageIPFFix
wdata.isFused := req.ctrl.isFused
// wdata.exceptionVec := req.cf.exceptionVec
}
dispatchData.io.raddr := commitReadAddr_next
......@@ -750,6 +746,7 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
exceptionGen.io.enq(i).bits.replayInst := io.enq.req(i).bits.ctrl.replayInst
assert(exceptionGen.io.enq(i).bits.replayInst === false.B)
exceptionGen.io.enq(i).bits.singleStep := io.enq.req(i).bits.ctrl.singleStep
exceptionGen.io.enq(i).bits.crossPageIPFFix := io.enq.req(i).bits.cf.crossPageIPFFix
}
// TODO: don't hard code these idxes
......@@ -778,10 +775,11 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
assert(store_wb_idxes.contains(wb_index))
selectStore _
}
exceptionGen.io.wb(index).bits.exceptionVec := selectFunc(io.exeWbResults(wb_index).bits.uop.cf.exceptionVec, false, true)
exceptionGen.io.wb(index).bits.flushPipe := io.exeWbResults(wb_index).bits.uop.ctrl.flushPipe
exceptionGen.io.wb(index).bits.replayInst := io.exeWbResults(wb_index).bits.uop.ctrl.replayInst
exceptionGen.io.wb(index).bits.singleStep := false.B
exceptionGen.io.wb(index).bits.exceptionVec := selectFunc(io.exeWbResults(wb_index).bits.uop.cf.exceptionVec, false, true)
exceptionGen.io.wb(index).bits.flushPipe := io.exeWbResults(wb_index).bits.uop.ctrl.flushPipe
exceptionGen.io.wb(index).bits.replayInst := io.exeWbResults(wb_index).bits.uop.ctrl.replayInst
exceptionGen.io.wb(index).bits.singleStep := false.B
exceptionGen.io.wb(index).bits.crossPageIPFFix := false.B
}
// 4 fmac + 2 fmisc + 1 i2f
......@@ -804,7 +802,7 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
val instrCnt = RegInit(0.U(64.W))
val fuseCommitCnt = PopCount(io.commits.valid.zip(io.commits.info).map{ case (v, i) => v && i.isFused =/= 0.U })
val fuseCommitCnt = PopCount(io.commits.valid.zip(io.commits.info).map{ case (v, i) => v && CommitType.isFused(i.commitType) })
val trueCommitCnt = commitCnt +& fuseCommitCnt
val retireCounter = Mux(state === s_idle, trueCommitCnt, 0.U)
instrCnt := instrCnt + retireCounter
......@@ -930,7 +928,7 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
difftest.io.valid := RegNext(io.commits.valid(i) && !io.commits.isWalk)
difftest.io.pc := RegNext(SignExt(uop.cf.pc, XLEN))
difftest.io.instr := RegNext(uop.cf.instr)
difftest.io.special := RegNext(uop.ctrl.isFused =/= 0.U)
difftest.io.special := RegNext(CommitType.isFused(uop.ctrl.commitType))
// when committing an eliminated move instruction,
// we must make sure that skip is properly set to false (output from EXU is random value)
difftest.io.skip := RegNext(Mux(uop.eliminatedMove, false.B, exuOut.isMMIO || exuOut.isPerfCnt))
......
......@@ -823,14 +823,14 @@ class Ftq(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelpe
commitStateQueue(c.bits.ftqIdx.value)(c.bits.ftqOffset) := c_commited
// TODO: remove this
// For instruction fusions, we also update the next instruction
when (c.bits.isFused === 1.U) {
when (c.bits.commitType === 4.U) {
commitStateQueue(c.bits.ftqIdx.value)(c.bits.ftqOffset + 1.U) := c_commited
}.elsewhen(c.bits.isFused === 2.U) {
}.elsewhen(c.bits.commitType === 5.U) {
commitStateQueue(c.bits.ftqIdx.value)(c.bits.ftqOffset + 2.U) := c_commited
}.elsewhen(c.bits.isFused === 3.U) {
}.elsewhen(c.bits.commitType === 6.U) {
val index = (c.bits.ftqIdx + 1.U).value
commitStateQueue(index)(0) := c_commited
}.elsewhen(c.bits.isFused === 4.U) {
}.elsewhen(c.bits.commitType === 7.U) {
val index = (c.bits.ftqIdx + 1.U).value
commitStateQueue(index)(1) := c_commited
}
......
......@@ -115,16 +115,17 @@ package object xiangshan {
}
object CommitType {
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 isStore(commitType: UInt) = isLoadStore(commitType) && lsInstIsStore(commitType)
def isBranch(commitType: UInt) = commitType(0) && !commitType(1)
def NORMAL = "b000".U // int/fp
def BRANCH = "b001".U // branch
def LOAD = "b010".U // load
def STORE = "b011".U // store
def apply() = UInt(3.W)
def isFused(commitType: UInt): Bool = commitType(2)
def isLoadStore(commitType: UInt): Bool = !isFused(commitType) && commitType(1)
def lsInstIsStore(commitType: UInt): Bool = commitType(0)
def isStore(commitType: UInt): Bool = isLoadStore(commitType) && lsInstIsStore(commitType)
def isBranch(commitType: UInt): Bool = commitType(0) && !commitType(1) && !isFused(commitType)
}
object RedirectLevel {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册