Skip to content
Draft
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
3 changes: 2 additions & 1 deletion src/main/scala/coupledL2/CoupledL2.scala
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,8 @@ abstract class CoupledL2Base(implicit p: Parameters) extends LazyModule with Has
val sizeBytes = cacheParams.toCacheParams.capacity.toDouble
val sizeStr = sizeBytesToStr(sizeBytes)
println(s"====== Inclusive TL-${if (enableCHI) "CHI" else "TL"} ${cacheParams.name} ($sizeStr * $banks-bank) ======")
println(s"prefetch: ${cacheParams.prefetch}")
println(s"prefetch (sort by priority): ")
prefetchers.zipWithIndex.foreach { case (pft, i) => println(s"${i+1}. $pft") }
println(s"bankBits: ${bankBits}")
println(s"replacement: ${cacheParams.replacement}")
println(s"replace policy: ${cacheParams.releaseData}")
Expand Down
34 changes: 15 additions & 19 deletions src/main/scala/coupledL2/prefetch/BestOffsetPrefetch.scala
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ case class BOPParameters(
override val hasPrefetchBit: Boolean = true
override val hasPrefetchSrc: Boolean = true
override val inflightEntries: Int = 16
override def toString: String = {
// val fields = productIterator.zip(productElementNames).map {
// case (value, name) => s"$name = $value"
// }.mkString("\n\t")
// s"Best-offset prefetch (hybrid vbop and pbop)\n\t$fields"
s"Best-offset prefetch (hybrid vbop and pbop)"
}
}

trait HasBOPParams extends HasPrefetcherHelper {
Expand Down Expand Up @@ -667,23 +674,17 @@ class DelayQueue(name: String = "")(implicit p: Parameters) extends BOPModule{
}

class VBestOffsetPrefetch(implicit p: Parameters) extends BOPModule {
val io = IO(new Bundle() {
val enable = Input(Bool())
val train = Flipped(DecoupledIO(new PrefetchTrain))
val pbopCrossPage = Input(Bool())
val tlb_req = new L2ToL1TlbIO(nRespDups= 1)
val req = DecoupledIO(new PrefetchReq)
val resp = Flipped(DecoupledIO(new PrefetchResp))
})
val io_enable = IO(Input(Bool()))
val io = IO(new L2PrefetchIO())
// 0 / 1: whether to enable
private val cstEnable = Constantin.createRecord("vbop_enable"+cacheParams.hartId.toString, initValue = 1)
val enable = io.enable && cstEnable.orR
val enable = io_enable && cstEnable.orR

val delayQueue = Module(new DelayQueue("vbop"))
val rrTable = Module(new RecentRequestTable("vbop"))
val scoreTable = Module(new OffsetScoreTable("vbop"))

val s0_fire = scoreTable.io.req.fire && io.pbopCrossPage
val s0_fire = scoreTable.io.req.fire
val s1_fire = WireInit(false.B)
val s0_ready, s1_ready = WireInit(false.B)

Expand Down Expand Up @@ -795,17 +796,12 @@ class VBestOffsetPrefetch(implicit p: Parameters) extends BOPModule {
}

class PBestOffsetPrefetch(implicit p: Parameters) extends BOPModule {
val io = IO(new Bundle() {
val enable = Input(Bool())
val train = Flipped(DecoupledIO(new PrefetchTrain))
val pbopCrossPage = Output(Bool())
val req = DecoupledIO(new PrefetchReq)
val resp = Flipped(DecoupledIO(new PrefetchResp))
})
val io_enable = IO(Input(Bool()))
val io = IO(new L2PrefetchIO())

// 0 / 1: whether to enable
private val cstEnable = Constantin.createRecord("pbop_enable"+cacheParams.hartId.toString, initValue = 1)
val enable = io.enable && cstEnable.orR
val enable = io_enable && cstEnable.orR

val delayQueue = Module(new DelayQueue("pbop"))
val rrTable = Module(new RecentRequestTable("pbop"))
Expand Down Expand Up @@ -838,12 +834,12 @@ class PBestOffsetPrefetch(implicit p: Parameters) extends BOPModule {
req_valid := !crossPage && !prefetchDisable // stop prefetch when prefetch req crosses pages
}

io.pbopCrossPage := crossPage
io.req.valid := enable && req_valid
io.req.bits := req
io.req.bits.pfSource := MemReqSource.Prefetch2L2PBOP.id.U
io.train.ready := delayQueue.io.in.ready && scoreTable.io.req.ready && (!req_valid || io.req.ready)
io.resp.ready := rrTable.io.w.ready
io.tlb_req <> DontCare

for (off <- offsetList) {
if (off < 0) {
Expand Down
1 change: 1 addition & 0 deletions src/main/scala/coupledL2/prefetch/PrefetchReceiver.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ case class PrefetchReceiverParams(n: Int = 32) extends PrefetchParameters {
override val hasPrefetchBit: Boolean = true
override val hasPrefetchSrc: Boolean = true
override val inflightEntries: Int = n
override def toString: String = s"Receiver for prefetches from L1"
}

class PrefetchReceiver()(implicit p: Parameters) extends PrefetchModule {
Expand Down
53 changes: 53 additions & 0 deletions src/main/scala/coupledL2/prefetch/PrefetchTemplate.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/** *************************************************************************************
* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
* Copyright (c) 2020-2021 Peng Cheng Laboratory
*
* XiangShan is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*
* See the Mulan PSL v2 for more details.
* *************************************************************************************
*/

package coupledL2.prefetch

import chisel3._
import chisel3.util._
import org.chipsalliance.cde.config.Parameters

case class MyPrefetchParameters(
// TODO
) extends PrefetchParameters {
override val hasPrefetchBit: Boolean = true
override val hasPrefetchSrc: Boolean = true
override val inflightEntries: Int = 16 // TODO
override def toString: String = s"My prefetch :)"
}

trait HasMyPrefetchParams extends HasPrefetcherHelper {
def params = prefetchers.find {
case p: MyPrefetchParameters => true
case _ => false
}.get.asInstanceOf[MyPrefetchParameters]
// TODO
}

abstract class MyPrefetchModule(implicit val p: Parameters) extends Module with HasMyPrefetchParams

class MyPrefetch(implicit p: Parameters) extends MyPrefetchModule {
val io = IO(new L2PrefetchIO())

val addr = io.train.bits.addr + (1 << offsetBits).U

io <> DontCare
io.req.valid := io.train.valid
io.req.bits.tag := parseFullAddress(addr)._1
io.req.bits.set := parseFullAddress(addr)._2
io.train.ready := true.B
}
39 changes: 25 additions & 14 deletions src/main/scala/coupledL2/prefetch/Prefetcher.scala
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,14 @@ class PrefetchTrain(implicit p: Parameters) extends PrefetchBundle {
def addr: UInt = Cat(tag, set, 0.U(offsetBits.W))
}

class PrefetchIO(implicit p: Parameters) extends PrefetchBundle {
class L2PrefetchIO(implicit p: Parameters) extends PrefetchBundle {
val train = Flipped(DecoupledIO(new PrefetchTrain))
val tlb_req = new L2ToL1TlbIO(nRespDups= 1)
val req = DecoupledIO(new PrefetchReq)
val resp = Flipped(DecoupledIO(new PrefetchResp))
}

class PrefetchIO(implicit p: Parameters) extends L2PrefetchIO {
val recv_addr = Flipped(ValidIO(new Bundle() {
val addr = UInt(64.W)
val pfSource = UInt(MemReqSource.reqSourceBits.W)
Expand Down Expand Up @@ -288,27 +291,29 @@ class Prefetcher(implicit p: Parameters) extends PrefetchModule {
val tp = if (hasTPPrefetcher) Some(Module(new TemporalPrefetch())) else None
// prefetch from upper level
val pfRcv = if (hasReceiver) Some(Module(new PrefetchReceiver())) else None
val hasMyPrefetch = prefetchers.exists(_.isInstanceOf[MyPrefetchParameters])
val myPrefetch = if (hasMyPrefetch) Some(Module(new MyPrefetch())) else None

// =================== Connection for each Prefetcher =====================
// Rcv > VBOP > PBOP > TP
if (hasBOP) {
vbop.get.io.enable := vbop_en
vbop.get.io_enable := vbop_en
vbop.get.io.req.ready := (if(hasReceiver) !pfRcv.get.io.req.valid else true.B)
vbop.get.io.train <> io.train
vbop.get.io.train.valid := io.train.valid && (io.train.bits.reqsource =/= MemReqSource.L1DataPrefetch.id.U)
vbop.get.io.resp <> io.resp
vbop.get.io.resp.valid := io.resp.valid && io.resp.bits.isBOP
vbop.get.io.tlb_req <> io.tlb_req
vbop.get.io.pbopCrossPage := true.B // pbop.io.pbopCrossPage // let vbop have noting to do with pbop

pbop.get.io.enable := pbop_en
pbop.get.io_enable := pbop_en
pbop.get.io.req.ready :=
(if(hasReceiver) !pfRcv.get.io.req.valid else true.B) &&
(if(hasBOP) !vbop.get.io.req.valid else true.B)
pbop.get.io.train <> io.train
pbop.get.io.train.valid := io.train.valid && (io.train.bits.reqsource =/= MemReqSource.L1DataPrefetch.id.U)
pbop.get.io.resp <> io.resp
pbop.get.io.resp.valid := io.resp.valid && io.resp.bits.isPBOP
pbop.get.io.tlb_req <> DontCare
}
if (hasReceiver) {
pfRcv.get.io_enable := pfRcv_en
Expand Down Expand Up @@ -338,6 +343,10 @@ class Prefetcher(implicit p: Parameters) extends PrefetchModule {

tp.get.io.tpmeta_port <> tpio.tpmeta_port.get
}
if (hasMyPrefetch) {
myPrefetch.get.io <> DontCare
myPrefetch.get.io.train <> io.train
}
private val mbistPl = MbistPipeline.PlaceMbistPipeline(2, "MbistPipeL2Prefetcher", cacheParams.hasMbist && (hasBOP || hasTPPrefetcher))

// =================== Connection of all Prefetchers =====================
Expand All @@ -346,16 +355,18 @@ class Prefetcher(implicit p: Parameters) extends PrefetchModule {
val pftQueue = Module(new PrefetchQueue)
val pipe = Module(new Pipeline(io.req.bits.cloneType, 1))

pftQueue.io.enq.valid :=
(if (hasReceiver) pfRcv.get.io.req.valid else false.B) ||
(if (hasBOP) vbop.get.io.req.valid || pbop.get.io.req.valid else false.B) ||
(if (hasTPPrefetcher) tp.get.io.req.valid else false.B)
pftQueue.io.enq.bits := ParallelPriorityMux(Seq(
if (hasReceiver) pfRcv.get.io.req.valid -> pfRcv.get.io.req.bits else false.B -> 0.U.asTypeOf(io.req.bits),
if (hasBOP) vbop.get.io.req.valid -> vbop.get.io.req.bits else false.B -> 0.U.asTypeOf(io.req.bits),
if (hasBOP) pbop.get.io.req.valid -> pbop.get.io.req.bits else false.B -> 0.U.asTypeOf(io.req.bits),
if (hasTPPrefetcher) tp.get.io.req.valid -> tp.get.io.req.bits else false.B -> 0.U.asTypeOf(io.req.bits)
))
val bopReq = Wire(DecoupledIO(new PrefetchReq()))
if (hasBOP) { arb(Seq(vbop.get.io.req, pbop.get.io.req), bopReq) }
arb(
in = prefetchers.map {
case _: PrefetchReceiverParams => pfRcv.get.io.req
case _: BOPParameters => bopReq
case _: TPParameters => tp.get.io.req
case _: MyPrefetchParameters => myPrefetch.get.io.req
},
out = pftQueue.io.enq,
name = Some("pftQueue")
)

pipe.io.in <> pftQueue.io.deq
io.req <> pipe.io.out
Expand Down
6 changes: 6 additions & 0 deletions src/main/scala/coupledL2/prefetch/TemporalPrefetch.scala
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ case class TPParameters(
override val hasPrefetchBit: Boolean = true
override val hasPrefetchSrc: Boolean = true
override val inflightEntries: Int = 16 // changed in sv48
override def toString: String = {
val fields = productIterator.zip(productElementNames).map {
case (value, name) => s"$name = $value"
}.mkString("\n\t")
s"Temporal prefetch\n\t$fields"
}
}

trait HasTPParams extends HasCoupledL2Parameters {
Expand Down