Skip to content

Commit e1e73e9

Browse files
authored
feat(RequestBuffer): throttle prefetch hints based on MSHR pressure (#21)
1 parent 98e7110 commit e1e73e9

2 files changed

Lines changed: 14 additions & 5 deletions

File tree

src/main/scala/coupledL2/RequestBuffer.scala

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ class RequestBuffer(flow: Boolean = true, entries: Int = 4)(implicit p: Paramete
7979
/* Snoop task from arbiter at stage 2 */
8080
val taskFromArb_s2 = Flipped(ValidIO(new TaskBundle()))
8181

82+
/* status of s2 and s3 */
83+
val pipeStatusVec = Flipped(Vec(2, ValidIO(new PipeStatus)))
84+
8285
val ATag = Output(UInt(tagBits.W))
8386
val ASet = Output(UInt(setBits.W))
8487

@@ -172,8 +175,12 @@ class RequestBuffer(flow: Boolean = true, entries: Int = 4)(implicit p: Paramete
172175
}
173176
def noFreeWay(task: TaskBundle): Bool = noFreeWayForSet(task.set)
174177

178+
val pfThrottleByMSHR = RegNext(PopCount(io.pipeStatusVec.map(_.valid) ++ io.mshrInfo.map(_.valid)) >= (mshrsAll - 3).U)
179+
180+
def prefetchBlocked(task: TaskBundle): Bool = task.fromA && task.opcode === Hint && pfThrottleByMSHR
181+
175182
// flow not allowed when full, or entries might starve
176-
val canFlow = flow.B && !full && !conflict(in) && !chosenQValid && !Cat(io.mainPipeBlock).orR && !noFreeWay(in)
183+
val canFlow = flow.B && !full && !conflict(in) && !chosenQValid && !Cat(io.mainPipeBlock).orR && !noFreeWay(in) && !prefetchBlocked(in)
177184
val doFlow = canFlow && io.out.ready
178185

179186
// val depMask = buffer.map(e => e.valid && sameAddr(io.in.bits, e.task))
@@ -203,10 +210,10 @@ class RequestBuffer(flow: Boolean = true, entries: Int = 4)(implicit p: Paramete
203210
//!! TODO: we can also remove those that duplicate with mainPipe
204211

205212
/* ======== Alloc ======== */
206-
io.in.ready := !full || doFlow || mergeA || dup
213+
io.in.ready := !prefetchBlocked(in) && (!full || doFlow) || mergeA || dup
207214

208215
val insertOH = MaskToOH(buffer.map(!_.valid))
209-
val alloc = !full && io.in.valid && !doFlow && !dup && !mergeA
216+
val alloc = !full && io.in.valid && !prefetchBlocked(in) && !doFlow && !dup && !mergeA
210217
buffer.zip(insertOH.asBools).foreach { case (entry, sel) =>
211218
when(alloc && sel){
212219
val mpBlock = Cat(io.mainPipeBlock).orR
@@ -231,7 +238,7 @@ class RequestBuffer(flow: Boolean = true, entries: Int = 4)(implicit p: Paramete
231238
/* ======== Issue ======== */
232239
issueArb.io.in zip buffer foreach {
233240
case(in, e) =>
234-
in.valid := e.valid && e.rdy
241+
in.valid := e.valid && e.rdy && !prefetchBlocked(e.task)
235242
in.bits := e
236243
}
237244

@@ -290,7 +297,7 @@ class RequestBuffer(flow: Boolean = true, entries: Int = 4)(implicit p: Paramete
290297
// when entry.rdy is no longer true,
291298
// we cancel req in chosenQ, with the entry still held in buffer to issue later
292299
// val cancel = (canFlow && sameSet(chosenQ.io.deq.bits.bits.task, io.in.bits)) || !buffer(chosenQ.io.deq.bits.id).rdy
293-
val cancel = !Mux1H(chosenQ.io.deq.bits.idOH, buffer.map(_.rdy))
300+
val cancel = !Mux1H(chosenQ.io.deq.bits.idOH, buffer.map(e => e.rdy && !prefetchBlocked(e.task)))
294301

295302
chosenQ.io.deq.ready := io.out.ready || cancel
296303
io.out.valid := chosenQValid && !cancel || io.in.valid && canFlow

src/main/scala/coupledL2/Slice.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ class Slice()(implicit p: Parameters) extends BaseSlice[OuterBundle]
108108
reqBuf.io.in <> sinkA.io.task
109109
reqBuf.io.mshrInfo := mshrCtl.io.msInfo
110110
reqBuf.io.mainPipeBlock := mainPipe.io.toReqBuf
111+
reqBuf.io.pipeStatusVec(0) := reqArb.io.status_vec(1) // s2 status
112+
reqBuf.io.pipeStatusVec(1) := mainPipe.io.status_vec_toD(0) // s3 status
111113
reqBuf.io.s1Entrance := reqArb.io.s1Entrance
112114
reqBuf.io.taskFromArb_s2 := reqArb.io.taskToPipe_s2
113115

0 commit comments

Comments
 (0)