Skip to content

Commit

Permalink
fdip: limit prefetchPtr range in ftq (#2395)
Browse files Browse the repository at this point in the history
  • Loading branch information
ssszwic authored Oct 23, 2023
1 parent b21f711 commit f9c5154
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 62 deletions.
1 change: 1 addition & 0 deletions src/main/scala/utils/PerfCounterUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ object XSPerfHistogram extends HasRegularPerfName {
}

when (perfDump) {
XSPerfPrint(p"${perfName}_sum, ${sum}\n")(helper.io)
XSPerfPrint(p"${perfName}_mean, ${sum/nSamples}\n")(helper.io)
XSPerfPrint(p"${perfName}_sampled, ${nSamples}\n")(helper.io)
XSPerfPrint(p"${perfName}_underflow, ${underflow}\n")(helper.io)
Expand Down
106 changes: 51 additions & 55 deletions src/main/scala/xiangshan/frontend/NewFtq.scala
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,10 @@ class Ftq_pd_Entry(implicit p: Parameters) extends XSBundle {
}
}


class PrefetchPtrDB(implicit p: Parameters) extends Bundle {
val fromFtqPtr = UInt(log2Up(p(XSCoreParamsKey).FtqSize).W)
val fromIfuPtr = UInt(log2Up(p(XSCoreParamsKey).FtqSize).W)
}

class Ftq_Redirect_SRAMEntry(implicit p: Parameters) extends SpeculativeInfo {
val sc_disagree = Vec(numBr, Bool())
Expand Down Expand Up @@ -1261,65 +1264,58 @@ class Ftq(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelpe
// ****************************************************************
// *********************** to prefetch ****************************
// ****************************************************************

ftq_pc_mem.io.other_raddrs(0) := DontCare
if(cacheParams.enableICachePrefetch){
val prefetchPtr = RegInit(FtqPtr(false.B, 0.U))
val diff_prefetch_addr = WireInit(update_target(prefetchPtr.value)) //TODO: remove this
// TODO : MUST WIDER
prefetchPtr := prefetchPtr + io.toPrefetch.req.fire

val prefetch_too_late = (isBefore(prefetchPtr, ifuPtr) && !isFull(ifuPtr, prefetchPtr)) || (prefetchPtr === ifuPtr)
when(prefetch_too_late){
when(prefetchPtr =/= bpuPtr){
prefetchPtr := bpuPtr - 1.U
}.otherwise{
prefetchPtr := ifuPtr
}
}

ftq_pc_mem.io.other_raddrs(0) := prefetchPtr.value

when (bpu_s2_redirect && !isBefore(prefetchPtr, bpu_s2_resp.ftq_idx)) {
prefetchPtr := bpu_s2_resp.ftq_idx
}

when (bpu_s3_redirect && !isBefore(prefetchPtr, bpu_s3_resp.ftq_idx)) {
prefetchPtr := bpu_s3_resp.ftq_idx
// XSError(true.B, "\ns3_redirect mechanism not implemented!\n")
/**
******************************************************************************
* prefetchPtr control
* - 1. prefetchPtr plus 1 when toPrefetch fire and keep distance from bpuPtr more than 2
* - 2. limit range of prefetchPtr is in [ifuPtr + minRange, ifuPtr + maxRange]
* - 3. flush prefetchPtr when receive redirect from ifu or backend
******************************************************************************
*/
val prefetchPtr = RegInit(FtqPtr(false.B, 0.U))
val nextPrefetchPtr = WireInit(prefetchPtr)

prefetchPtr := nextPrefetchPtr

// TODO: consider req which cross cacheline
when(io.toPrefetch.req.fire) {
when(prefetchPtr < bpuPtr - 2.U) {
nextPrefetchPtr := prefetchPtr + 1.U
}
}

when(prefetchPtr < ifuPtr + minRangeFromIFUptr.U) {
nextPrefetchPtr := ifuPtr + minRangeFromIFUptr.U
}.elsewhen(prefetchPtr > ifuPtr + maxRangeFromIFUptr.U) {
nextPrefetchPtr := ifuPtr + maxRangeFromIFUptr.U
}

val prefetch_is_to_send = WireInit(entry_fetch_status(prefetchPtr.value) === f_to_send)
val prefetch_addr = Wire(UInt(VAddrBits.W))

when (last_cycle_bpu_in && bpu_in_bypass_ptr === prefetchPtr) {
prefetch_is_to_send := true.B
prefetch_addr := last_cycle_bpu_target
diff_prefetch_addr := last_cycle_bpu_target // TODO: remove this
}.otherwise{
prefetch_addr := RegNext( ftq_pc_mem.io.other_rdatas(0).startAddr)
}
io.toPrefetch.req.valid := prefetchPtr =/= bpuPtr && prefetch_is_to_send
io.toPrefetch.req.bits.target := prefetch_addr

when(redirectVec.map(r => r.valid).reduce(_||_)){
val r = PriorityMux(redirectVec.map(r => (r.valid -> r.bits)))
val next = r.ftqIdx + 1.U
prefetchPtr := next
}

// TODO: remove this
// XSError(io.toPrefetch.req.valid && diff_prefetch_addr =/= prefetch_addr,
// f"\nprefetch_req_target wrong! prefetchPtr: ${prefetchPtr}, prefetch_addr: ${Hexadecimal(prefetch_addr)} diff_prefetch_addr: ${Hexadecimal(diff_prefetch_addr)}\n")
when(redirectVec.map(r => r.valid).reduce(_||_)){
val r = PriorityMux(redirectVec.map(r => (r.valid -> r.bits)))
val next = r.ftqIdx + minRangeFromIFUptr.U
nextPrefetchPtr := next
}

// data from ftq_pc_mem has 1 cycle delay
io.toPrefetch.req.valid := RegNext(entry_fetch_status(nextPrefetchPtr.value) === f_to_send)
ftq_pc_mem.io.other_raddrs(0) := nextPrefetchPtr.value
io.toPrefetch.req.bits.target := RegNext(ftq_pc_mem.io.other_rdatas(0).startAddr)

// record position relationship between ifuPtr, pfPtr and bpuPtr
val isWritePrefetchPtrTable = WireInit(Constantin.createRecord("isWritePrefetchPtrTable" + p(XSCoreParamsKey).HartId.toString))
val prefetchPtrTable = ChiselDB.createTable("PrefetchPtrTable" + p(XSCoreParamsKey).HartId.toString, new PrefetchPtrDB)
val prefetchPtrDumpData = Wire(new PrefetchPtrDB)
prefetchPtrDumpData.fromFtqPtr := distanceBetween(bpuPtr, prefetchPtr)
prefetchPtrDumpData.fromIfuPtr := distanceBetween(prefetchPtr, ifuPtr)

prefetchPtrTable.log(
data = prefetchPtrDumpData,
en = isWritePrefetchPtrTable.orR && io.toPrefetch.req.fire,
site = "FTQ" + p(XSCoreParamsKey).HartId.toString,
clock = clock,
reset = reset
)

XSError(isBefore(bpuPtr, prefetchPtr) && !isFull(bpuPtr, prefetchPtr), "\nprefetchPtr is before bpuPtr!\n")
// XSError(isBefore(prefetchPtr, ifuPtr) && !isFull(ifuPtr, prefetchPtr), "\nifuPtr is before prefetchPtr!\n")
}
else {
io.toPrefetch.req <> DontCare
}

// ******************************************************************************
// **************************** commit perf counters ****************************
Expand Down
6 changes: 5 additions & 1 deletion src/main/scala/xiangshan/frontend/icache/ICache.scala
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ case class ICacheParameters(
nPrefetchEntries: Int = 12,
nPrefBufferEntries: Int = 32,
maxIPFMoveConf: Int = 1, // temporary use small value to cause more "move" operation
minRangeFromIFUptr: Int = 2,
maxRangeFromIFUptr: Int = 32,

nMMIOs: Int = 1,
blockBytes: Int = 64
Expand Down Expand Up @@ -97,6 +99,8 @@ trait HasICacheParameters extends HasL1CacheParameters with HasInstrMMIOConst wi
def nPrefetchEntries = cacheParams.nPrefetchEntries
def nPrefBufferEntries = cacheParams.nPrefBufferEntries
def maxIPFMoveConf = cacheParams.maxIPFMoveConf
def minRangeFromIFUptr = cacheParams.minRangeFromIFUptr
def maxRangeFromIFUptr = cacheParams.maxRangeFromIFUptr

def getBits(num: Int) = log2Ceil(num).W

Expand Down Expand Up @@ -132,7 +136,7 @@ trait HasICacheParameters extends HasL1CacheParameters with HasInstrMMIOConst wi
return RegInit(VecInit(Seq.fill(size)(0.U.asTypeOf(entry.cloneType))))
}

def getBlkPaddr(addr: UInt) = addr(PAddrBits-1, log2Ceil(blockBytes))
def getBlkAddr(addr: UInt) = addr >> log2Ceil(blockBytes)

require(isPow2(nSets), s"nSets($nSets) must be pow2")
require(isPow2(nWays), s"nWays($nWays) must be pow2")
Expand Down
32 changes: 32 additions & 0 deletions src/main/scala/xiangshan/frontend/icache/ICacheMainPipe.scala
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@ class ICacheMainPipeInterface(implicit p: Parameters) extends ICacheBundle {
val csr_parity_enable = Input(Bool())
}

class ICacheDB(implicit p: Parameters) extends ICacheBundle {
val blk_vaddr = UInt((VAddrBits - blockOffBits).W)
val blk_paddr = UInt((PAddrBits - blockOffBits).W)
val hit = Bool()
}

class ICacheMainPipe(implicit p: Parameters) extends ICacheModule
{
val io = IO(new ICacheMainPipeInterface)
Expand Down Expand Up @@ -374,6 +380,32 @@ class ICacheMainPipe(implicit p: Parameters) extends ICacheModule
}
}

// record cacheline log
val isWriteICacheTable = WireInit(Constantin.createRecord("isWriteICacheTable" + p(XSCoreParamsKey).HartId.toString))
val ICacheTable = ChiselDB.createTable("ICacheTable" + p(XSCoreParamsKey).HartId.toString, new ICacheDB)

val ICacheDumpData_req0 = Wire(new ICacheDB)
ICacheDumpData_req0.blk_paddr := getBlkAddr(s1_req_paddr(0))
ICacheDumpData_req0.blk_vaddr := getBlkAddr(s1_req_vaddr(0))
ICacheDumpData_req0.hit := s1_port_hit(0) || s1_prefetch_hit(0)
ICacheTable.log(
data = ICacheDumpData_req0,
en = isWriteICacheTable.orR && s1_fire,
clock = clock,
reset = reset
)

val ICacheDumpData_req1 = Wire(new ICacheDB)
ICacheDumpData_req1.blk_paddr := getBlkAddr(s1_req_paddr(1))
ICacheDumpData_req1.blk_vaddr := getBlkAddr(s1_req_vaddr(1))
ICacheDumpData_req1.hit := s1_port_hit(1) || s1_prefetch_hit(1)
ICacheTable.log(
data = ICacheDumpData_req1,
en = isWriteICacheTable.orR && s1_fire && s1_double_line,
clock = clock,
reset = reset
)

/** <PERF> replace victim way number */

(0 until nWays).map{ w =>
Expand Down
12 changes: 6 additions & 6 deletions src/main/scala/xiangshan/frontend/icache/IPrefetch.scala
Original file line number Diff line number Diff line change
Expand Up @@ -439,22 +439,22 @@ class IPrefetchPipe(implicit p: Parameters) extends IPrefetchModule

/** 5. Prefetch Buffer Recently write chcek */
val p2_check_ipf_info = VecInit(fromIPFInfo.map(info =>
info.valid && getBlkPaddr(info.paddr) === getBlkPaddr(p2_paddr))).reduce(_||_)
info.valid && getBlkAddr(info.paddr) === getBlkAddr(p2_paddr))).reduce(_||_)

/** 6. MainPipeInfo chcek */
val check_mp_s1 = VecInit(fromMainPipeInfo.s1Info.map(info =>
info.valid && getBlkPaddr(info.paddr) === getBlkPaddr(p2_paddr))).reduce(_||_)
info.valid && getBlkAddr(info.paddr) === getBlkAddr(p2_paddr))).reduce(_||_)
val check_mp_s2 = VecInit(fromMainPipeInfo.s2Info.map(info =>
info.valid && getBlkPaddr(info.paddr) === getBlkPaddr(p2_paddr))).reduce(_||_)
info.valid && getBlkAddr(info.paddr) === getBlkAddr(p2_paddr))).reduce(_||_)
val check_mp_missSlot = VecInit(fromMainPipeInfo.missSlot.map(info =>
info.valid && info.ptag === get_phy_tag(p2_paddr) && info.vSetIdx === p2_vidx)).reduce(_||_)
val p2_check_mp_info = check_mp_s1 || check_mp_s2 || check_mp_missSlot

/** 7. MissUnitInfo chcek */
val check_mu_mshr = VecInit(fromMissUnitInfo.mshr.map(info =>
info.valid && getBlkPaddr(info.paddr) === getBlkPaddr(p2_paddr))).reduce(_||_)
info.valid && getBlkAddr(info.paddr) === getBlkAddr(p2_paddr))).reduce(_||_)
val check_mu_recent_write = VecInit(fromMissUnitInfo.recentWrite.map(info =>
info.valid && getBlkPaddr(info.paddr) === getBlkPaddr(p2_paddr))).reduce(_||_)
info.valid && getBlkAddr(info.paddr) === getBlkAddr(p2_paddr))).reduce(_||_)
val p2_check_mu_info = check_mu_mshr || check_mu_recent_write

/** 8. send req to piq */
Expand Down Expand Up @@ -542,7 +542,7 @@ class PrefetchQueueIO(edge: TLEdgeOut)(implicit p: Parameters) extends IPrefetch

class PrefetchQueue(edge: TLEdgeOut)(implicit p: Parameters) extends IPrefetchModule with HasCircularQueuePtrHelper {
val io = IO(new PrefetchQueueIO(edge))

val enqueReq = io.prefetchReq
val fromIPrefetch = io.PIQFilterRead.req
val toIPrefetch = io.PIQFilterRead.resp
Expand Down

0 comments on commit f9c5154

Please sign in to comment.