Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fdip: limit prefetchPtr range in ftq #2395

Merged
merged 1 commit into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading