xref: /XiangShan/src/main/scala/xiangshan/cache/wpu/WPUWrapper.scala (revision bb2f3f51dd67f6e16e0cc1ffe43368c9fc7e4aef)
104665835SMaxpicca-Lipackage xiangshan.cache.wpu
204665835SMaxpicca-Li
38891a219SYinan Xuimport org.chipsalliance.cde.config.Parameters
404665835SMaxpicca-Liimport chisel3._
504665835SMaxpicca-Liimport chisel3.util._
6*bb2f3f51STang Haojinimport utility.XSPerfAccumulate
704665835SMaxpicca-Liimport xiangshan._
804665835SMaxpicca-Liimport xiangshan.cache.{DCacheModule, HasDCacheParameters}
904665835SMaxpicca-Liimport xiangshan.frontend.icache.HasICacheParameters
1004665835SMaxpicca-Li
1104665835SMaxpicca-Liclass ReplayCarry(nWays: Int)(implicit p: Parameters) extends XSBundle {
1204665835SMaxpicca-Li  val real_way_en = UInt(nWays.W)
1304665835SMaxpicca-Li  val valid = Bool()
1404665835SMaxpicca-Li}
1504665835SMaxpicca-Li
1604665835SMaxpicca-Liobject ReplayCarry{
1704665835SMaxpicca-Li  def apply(nWays: Int, rwe: UInt = 0.U, v: Bool = false.B)(implicit p: Parameters): ReplayCarry = {
1804665835SMaxpicca-Li    val rcry = Wire(new ReplayCarry(nWays))
1904665835SMaxpicca-Li    rcry.real_way_en := rwe
2004665835SMaxpicca-Li    rcry.valid := v
2104665835SMaxpicca-Li    rcry
2204665835SMaxpicca-Li  }
2304665835SMaxpicca-Li
2404665835SMaxpicca-Li  def init(nWays: Int)(implicit p: Parameters): ReplayCarry = {
2504665835SMaxpicca-Li    val rcry = Wire(new ReplayCarry(nWays))
2604665835SMaxpicca-Li    rcry.real_way_en := 0.U
2704665835SMaxpicca-Li    rcry.valid := false.B
2804665835SMaxpicca-Li    rcry
2904665835SMaxpicca-Li  }
3004665835SMaxpicca-Li}
3104665835SMaxpicca-Li
3204665835SMaxpicca-Liclass WPUBaseReq(implicit p: Parameters) extends BaseWPUBundle{
3304665835SMaxpicca-Li  val vaddr = UInt(VAddrBits.W)
3404665835SMaxpicca-Li}
3504665835SMaxpicca-Li
3604665835SMaxpicca-Liclass WPUReplayedReq(nWays: Int)(implicit p: Parameters) extends WPUBaseReq {
3704665835SMaxpicca-Li  val replayCarry = new ReplayCarry(nWays)
3804665835SMaxpicca-Li}
3904665835SMaxpicca-Li
4004665835SMaxpicca-Liclass WPUResp(nWays:Int)(implicit p:Parameters) extends BaseWPUBundle{
4104665835SMaxpicca-Li  val s0_pred_way_en = UInt(nWays.W)
4204665835SMaxpicca-Li}
4304665835SMaxpicca-Li
4404665835SMaxpicca-Liclass WPUUpdate(nWays:Int)(implicit p:Parameters) extends BaseWPUBundle{
4504665835SMaxpicca-Li  val vaddr = UInt(VAddrBits.W)
4604665835SMaxpicca-Li  val s1_real_way_en = UInt(nWays.W)
4704665835SMaxpicca-Li}
4804665835SMaxpicca-Li
4904665835SMaxpicca-Liclass WPUUpdateLookup(nWays:Int)(implicit p:Parameters) extends WPUUpdate(nWays){
5004665835SMaxpicca-Li  val s1_pred_way_en = UInt(nWays.W)
5104665835SMaxpicca-Li}
5204665835SMaxpicca-Li
5304665835SMaxpicca-Liclass ConflictPredictIO(nWays:Int)(implicit p:Parameters) extends BaseWPUBundle{
5404665835SMaxpicca-Li  // pred
5504665835SMaxpicca-Li  val s0_vaddr = Input(UInt(VAddrBits.W))
5604665835SMaxpicca-Li  // update
5704665835SMaxpicca-Li  val s1_vaddr = Input(UInt(VAddrBits.W))
5804665835SMaxpicca-Li  val s1_dm_hit = Input(Bool())
5904665835SMaxpicca-Li}
6004665835SMaxpicca-Li
6104665835SMaxpicca-Liclass IwpuBaseIO(nWays:Int, nPorts: Int)(implicit p:Parameters) extends BaseWPUBundle{
6204665835SMaxpicca-Li  val req = Vec(nPorts, Flipped(Decoupled(new WPUBaseReq)))
6304665835SMaxpicca-Li  val resp = Vec(nPorts, ValidIO(new WPUResp(nWays)))
6404665835SMaxpicca-Li  val lookup_upd = Vec(nPorts, Flipped(ValidIO(new WPUUpdateLookup(nWays))))
6504665835SMaxpicca-Li}
6604665835SMaxpicca-Li
6704665835SMaxpicca-Liclass IwpuIO(nWays:Int, nPorts: Int)(implicit p:Parameters) extends IwpuBaseIO(nWays, nPorts){
6804665835SMaxpicca-Li  val tagwrite_upd = Flipped(ValidIO(new WPUUpdate(nWays)))
6904665835SMaxpicca-Li}
7004665835SMaxpicca-Li
7104665835SMaxpicca-Liclass DwpuBaseIO(nWays:Int, nPorts: Int)(implicit p:Parameters) extends BaseWPUBundle{
7204665835SMaxpicca-Li  val req = Vec(nPorts, Flipped(Decoupled(new WPUReplayedReq(nWays))))
7304665835SMaxpicca-Li  val resp = Vec(nPorts, ValidIO(new WPUResp(nWays)))
7404665835SMaxpicca-Li  val lookup_upd = Vec(nPorts, Flipped(ValidIO(new WPUUpdateLookup(nWays))))
7504665835SMaxpicca-Li  val cfpred = Vec(nPorts, new ConflictPredictIO(nWays))
7604665835SMaxpicca-Li}
7704665835SMaxpicca-Li
7804665835SMaxpicca-Liclass DwpuIO(nWays:Int, nPorts:Int)(implicit p:Parameters) extends DwpuBaseIO(nWays, nPorts){
7904665835SMaxpicca-Li  val tagwrite_upd = Flipped(ValidIO(new WPUUpdate(nWays)))
8004665835SMaxpicca-Li}
8104665835SMaxpicca-Li
8204665835SMaxpicca-Liclass DCacheWpuWrapper (nPorts: Int = 1) (implicit p:Parameters) extends DCacheModule with HasWPUParameters  {
8304665835SMaxpicca-Li  val wpu = AlgoWPUMap(dwpuParam, nPorts)
8404665835SMaxpicca-Li  val wayConflictPredictor = Module(new WayConflictPredictor(nPorts))
8504665835SMaxpicca-Li  val io = IO(new DwpuIO(nWays, nPorts))
8604665835SMaxpicca-Li
8704665835SMaxpicca-Li  /** pred */
8804665835SMaxpicca-Li  val s0_dmSel = Wire(Vec(nPorts, Bool()))
8904665835SMaxpicca-Li  val s0_pred_way_conflict = Wire(Vec(nPorts, Bool()))
9004665835SMaxpicca-Li  val s0_pred_way_en = Wire(Vec(nPorts, UInt(nWays.W)))
9104665835SMaxpicca-Li  val s1_lookup_valid = Wire(Vec(nPorts, Bool()))
9204665835SMaxpicca-Li  val s1_dmSel = Wire(Vec(nPorts, Bool()))
9304665835SMaxpicca-Li  val s1_pred_way_en = Wire(Vec(nPorts, UInt(nWays.W)))
9404665835SMaxpicca-Li  val s1_pred_fail = Wire(Vec(nPorts, Bool()))
9504665835SMaxpicca-Li  val s1_hit = Wire(Vec(nPorts, Bool()))
9604665835SMaxpicca-Li
9704665835SMaxpicca-Li  for(i <- 0 until nPorts){
9804665835SMaxpicca-Li    wayConflictPredictor.io.pred(i).en := io.req(i).valid
9904665835SMaxpicca-Li    wayConflictPredictor.io.pred(i).vaddr := io.cfpred(i).s0_vaddr
10004665835SMaxpicca-Li    s0_pred_way_conflict(i) := wayConflictPredictor.io.pred(i).way_conflict
10104665835SMaxpicca-Li
10204665835SMaxpicca-Li    s0_dmSel(i) := false.B
10304665835SMaxpicca-Li    wpu.io.predVec(i).en := io.req(i).valid
10404665835SMaxpicca-Li    wpu.io.predVec(i).vaddr := io.req(i).bits.vaddr
10504665835SMaxpicca-Li    when(io.req(i).bits.replayCarry.valid) {
10604665835SMaxpicca-Li      // replay carry
10704665835SMaxpicca-Li      s0_pred_way_en(i) := io.req(i).bits.replayCarry.real_way_en
10804665835SMaxpicca-Li    }.otherwise {
10904665835SMaxpicca-Li      // way prediction
11004665835SMaxpicca-Li      s0_pred_way_en(i) := wpu.io.predVec(i).way_en
11104665835SMaxpicca-Li
11204665835SMaxpicca-Li      if (dwpuParam.enCfPred) {
11304665835SMaxpicca-Li        // selective direct mapping
11404665835SMaxpicca-Li        when(!s0_pred_way_conflict(i)) {
11504665835SMaxpicca-Li          s0_pred_way_en(i) := UIntToOH(get_direct_map_way(io.req(i).bits.vaddr))
11604665835SMaxpicca-Li          s0_dmSel(i) := true.B
11704665835SMaxpicca-Li        }
11804665835SMaxpicca-Li      }
11904665835SMaxpicca-Li    }
12004665835SMaxpicca-Li
12104665835SMaxpicca-Li    /** check and update in s1 */
12204665835SMaxpicca-Li    s1_lookup_valid(i) := io.lookup_upd(i).valid
12304665835SMaxpicca-Li    s1_dmSel(i) := RegNext(s0_dmSel(i))
12404665835SMaxpicca-Li    s1_pred_way_en(i) := io.lookup_upd(i).bits.s1_pred_way_en
12504665835SMaxpicca-Li    s1_pred_fail(i) := io.lookup_upd(i).valid && s1_pred_way_en(i) =/= io.lookup_upd(i).bits.s1_real_way_en
12604665835SMaxpicca-Li    s1_hit(i) := !s1_pred_fail(i) && s1_pred_way_en(i).orR
12704665835SMaxpicca-Li
12804665835SMaxpicca-Li    val s0_replay_upd = Wire(new BaseWpuUpdateBundle(nWays))
12904665835SMaxpicca-Li    s0_replay_upd.en := io.req(i).valid && io.req(i).bits.replayCarry.valid
13004665835SMaxpicca-Li    s0_replay_upd.vaddr := io.req(i).bits.vaddr
13104665835SMaxpicca-Li    s0_replay_upd.way_en := io.req(i).bits.replayCarry.real_way_en
13204665835SMaxpicca-Li    val s1_replay_upd = RegNext(s0_replay_upd)
13304665835SMaxpicca-Li
13404665835SMaxpicca-Li    wayConflictPredictor.io.update(i).en := io.lookup_upd(i).valid
13504665835SMaxpicca-Li    wayConflictPredictor.io.update(i).vaddr := io.cfpred(i).s1_vaddr
13604665835SMaxpicca-Li    wayConflictPredictor.io.update(i).dm_hit := s1_dmSel(i) && io.cfpred(i).s1_dm_hit
13704665835SMaxpicca-Li    wayConflictPredictor.io.update(i).sa_hit := !s1_dmSel(i) && s1_hit(i)
13804665835SMaxpicca-Li
13904665835SMaxpicca-Li    // look up res
14004665835SMaxpicca-Li    wpu.io.updLookup(i).en := io.lookup_upd(i).valid
14104665835SMaxpicca-Li    wpu.io.updLookup(i).vaddr := io.lookup_upd(i).bits.vaddr
14204665835SMaxpicca-Li    wpu.io.updLookup(i).way_en := io.lookup_upd(i).bits.s1_real_way_en
14304665835SMaxpicca-Li    wpu.io.updLookup(i).pred_way_en := io.lookup_upd(i).bits.s1_pred_way_en
14404665835SMaxpicca-Li
14504665835SMaxpicca-Li    // which will update in look up pred fail
14604665835SMaxpicca-Li    wpu.io.updReplaycarry(i) := s1_replay_upd
14704665835SMaxpicca-Li
14804665835SMaxpicca-Li    // replace / tag write
14904665835SMaxpicca-Li    wpu.io.updTagwrite(i) := DontCare
15004665835SMaxpicca-Li
15104665835SMaxpicca-Li    /** predict and response in s0 */
15204665835SMaxpicca-Li    io.req(i).ready := true.B
15304665835SMaxpicca-Li    if (dwpuParam.enWPU) {
15404665835SMaxpicca-Li      io.resp(i).valid := io.req(i).valid
15504665835SMaxpicca-Li    } else {
15604665835SMaxpicca-Li      io.resp(i).valid := false.B
15704665835SMaxpicca-Li    }
15804665835SMaxpicca-Li    io.resp(i).bits.s0_pred_way_en := s0_pred_way_en(i)
15904665835SMaxpicca-Li    assert(PopCount(io.resp(i).bits.s0_pred_way_en) <= 1.U, "tag should not match with more than 1 way")
16004665835SMaxpicca-Li  }
16104665835SMaxpicca-Li  wpu.io.updTagwrite(0).en := io.tagwrite_upd.valid
16204665835SMaxpicca-Li  wpu.io.updTagwrite(0).vaddr := io.tagwrite_upd.bits.vaddr
16304665835SMaxpicca-Li  wpu.io.updTagwrite(0).way_en := io.tagwrite_upd.bits.s1_real_way_en
16404665835SMaxpicca-Li
16504665835SMaxpicca-Li  // PerfLog
16604665835SMaxpicca-Li  // pred situation
16704665835SMaxpicca-Li  XSPerfAccumulate("wpu_pred_total", PopCount((0 until nPorts).map(i => RegNext(io.req(i).valid) && s1_lookup_valid(i))))
16804665835SMaxpicca-Li  XSPerfAccumulate("wpu_pred_succ", PopCount((0 until nPorts).map(i => RegNext(io.req(i).valid) && s1_lookup_valid(i) && !s1_pred_fail(i))))
16904665835SMaxpicca-Li  XSPerfAccumulate("wpu_pred_fail", PopCount((0 until nPorts).map(i => RegNext(io.req(i).valid) && s1_lookup_valid(i) && s1_pred_fail(i))))
17004665835SMaxpicca-Li  XSPerfAccumulate("wpu_pred_miss", PopCount((0 until nPorts).map(i => RegNext(io.req(i).valid) && s1_lookup_valid(i) && !s1_pred_way_en(i).orR)))
17104665835SMaxpicca-Li  XSPerfAccumulate("wpu_real_miss", PopCount((0 until nPorts).map(i => RegNext(io.req(i).valid) && s1_lookup_valid(i) && !io.lookup_upd(i).bits.s1_real_way_en.orR)))
17204665835SMaxpicca-Li  // pred component
17304665835SMaxpicca-Li  XSPerfAccumulate("wpu_pred_replayCarry", PopCount((0 until nPorts).map(i => io.req(i).valid && io.req(i).bits.replayCarry.valid)))
17404665835SMaxpicca-Li  if(!dwpuParam.enCfPred){
17504665835SMaxpicca-Li    XSPerfAccumulate("wpu_pred_wayPrediction", PopCount((0 until nPorts).map(i => io.req(i).valid && !io.req(i).bits.replayCarry.valid)))
17604665835SMaxpicca-Li  }else{
17704665835SMaxpicca-Li    XSPerfAccumulate("wpu_pred_wayPrediction", PopCount((0 until nPorts).map(i => io.req(i).valid && !io.req(i).bits.replayCarry.valid && s0_pred_way_conflict(i))))
17804665835SMaxpicca-Li    XSPerfAccumulate("wpu_pred_directMap", PopCount((0 until nPorts).map(i => io.req(i).valid && !io.req(i).bits.replayCarry.valid && !s0_pred_way_conflict(i))))
17904665835SMaxpicca-Li    // dm situation
18004665835SMaxpicca-Li    XSPerfAccumulate("direct_map_all", PopCount((0 until nPorts).map(i => io.lookup_upd(i).valid)))
18104665835SMaxpicca-Li    XSPerfAccumulate("direct_map_ok", PopCount((0 until nPorts).map(i => io.lookup_upd(i).valid && io.cfpred(i).s1_dm_hit)))
18204665835SMaxpicca-Li  }
18304665835SMaxpicca-Li}
18404665835SMaxpicca-Li
18504665835SMaxpicca-Li
18604665835SMaxpicca-Liclass ICacheWpuWrapper (nPorts: Int) (implicit p:Parameters) extends WPUModule with HasICacheParameters {
18704665835SMaxpicca-Li  val wpu = AlgoWPUMap(iwpuParam, nPorts)
18804665835SMaxpicca-Li  val io = IO(new IwpuIO(nWays, nPorts))
18904665835SMaxpicca-Li
19004665835SMaxpicca-Li  val s1_pred_fail = Wire(Vec(nPorts, Bool()))
19104665835SMaxpicca-Li  val s0_pred_way_en = Wire(Vec(nPorts, UInt(nWays.W)))
19204665835SMaxpicca-Li  val s1_pred_way_en = Wire(Vec(nPorts, UInt(nWays.W)))
19304665835SMaxpicca-Li  val s1_real_way_en = Wire(Vec(nPorts, UInt(nWays.W)))
19404665835SMaxpicca-Li  /** pred in s0*/
19504665835SMaxpicca-Li  for (i <- 0 until nPorts){
19604665835SMaxpicca-Li    wpu.io.predVec(i).en := io.req(i).valid
19704665835SMaxpicca-Li    wpu.io.predVec(i).vaddr := io.req(i).bits.vaddr
19804665835SMaxpicca-Li    s0_pred_way_en(i) := wpu.io.predVec(i).way_en
19904665835SMaxpicca-Li    // io
20004665835SMaxpicca-Li    io.req(i).ready := true.B
20104665835SMaxpicca-Li    if (iwpuParam.enWPU) {
20204665835SMaxpicca-Li      io.resp(i).valid := io.req(i).valid
20304665835SMaxpicca-Li    } else {
20404665835SMaxpicca-Li      io.resp(i).valid := false.B
20504665835SMaxpicca-Li    }
20604665835SMaxpicca-Li    io.resp(i).bits.s0_pred_way_en := s0_pred_way_en(i)
20704665835SMaxpicca-Li    assert(PopCount(io.resp(i).bits.s0_pred_way_en) <= 1.U, "tag should not match with more than 1 way")
20804665835SMaxpicca-Li
20904665835SMaxpicca-Li    /** update in s1 */
21004665835SMaxpicca-Li    s1_pred_way_en(i) := io.lookup_upd(i).bits.s1_pred_way_en
21104665835SMaxpicca-Li    s1_real_way_en(i) := io.lookup_upd(i).bits.s1_real_way_en
21204665835SMaxpicca-Li    s1_pred_fail(i) := io.lookup_upd(i).valid && s1_pred_way_en(i) =/= s1_real_way_en(i)
21304665835SMaxpicca-Li    // look up res
21404665835SMaxpicca-Li    wpu.io.updLookup(i).en := io.lookup_upd(i).valid
21504665835SMaxpicca-Li    wpu.io.updLookup(i).vaddr := io.lookup_upd(i).bits.vaddr
21604665835SMaxpicca-Li    wpu.io.updLookup(i).way_en := io.lookup_upd(i).bits.s1_real_way_en
21704665835SMaxpicca-Li    wpu.io.updLookup(i).pred_way_en := io.lookup_upd(i).bits.s1_pred_way_en
21804665835SMaxpicca-Li    // which will update in look up pred fail
21904665835SMaxpicca-Li    wpu.io.updReplaycarry := DontCare
22004665835SMaxpicca-Li    // replace / tag write
22104665835SMaxpicca-Li    wpu.io.updTagwrite := DontCare
22204665835SMaxpicca-Li  }
22304665835SMaxpicca-Li  wpu.io.updTagwrite.head.en := io.tagwrite_upd.valid
22404665835SMaxpicca-Li  wpu.io.updTagwrite.head.vaddr := io.tagwrite_upd.bits.vaddr
22504665835SMaxpicca-Li  wpu.io.updTagwrite.head.way_en := io.tagwrite_upd.bits.s1_real_way_en
22604665835SMaxpicca-Li
22704665835SMaxpicca-Li  XSPerfAccumulate("wpu_pred_total", PopCount((0 until nPorts).map{i => RegNext(io.req(i).valid) && io.lookup_upd(i).valid}))
22804665835SMaxpicca-Li  XSPerfAccumulate("wpu_pred_succ",  PopCount((0 until nPorts).map{i => RegNext(io.req(i).valid) && io.lookup_upd(i).valid && !s1_pred_fail(i)}))
22904665835SMaxpicca-Li  XSPerfAccumulate("wpu_pred_fail",  PopCount((0 until nPorts).map{i => RegNext(io.req(i).valid) && io.lookup_upd(i).valid && s1_pred_fail(i)}))
23004665835SMaxpicca-Li  XSPerfAccumulate("wpu_pred_miss",  PopCount((0 until nPorts).map{i => RegNext(io.req(i).valid) && io.lookup_upd(i).valid && !RegNext(s0_pred_way_en(i)).orR}))
23104665835SMaxpicca-Li  XSPerfAccumulate("wpu_real_miss",  PopCount((0 until nPorts).map{i => RegNext(io.req(i).valid) && io.lookup_upd(i).valid && !RegNext(s1_real_way_en(i)).orR}))
23204665835SMaxpicca-Li}
23304665835SMaxpicca-Li
23404665835SMaxpicca-Li/** IdealWPU:
23504665835SMaxpicca-Li  * req in s1 and resp in s1
23604665835SMaxpicca-Li  */
23704665835SMaxpicca-Liclass IdealWPU(implicit p:Parameters) extends WPUModule with HasDCacheParameters {
23804665835SMaxpicca-Li  val io = IO(new Bundle{
23904665835SMaxpicca-Li    val req = Output(new Bundle {
24004665835SMaxpicca-Li      val valid = Bool()
24104665835SMaxpicca-Li      val s1_real_way_en = UInt(nWays.W)
24204665835SMaxpicca-Li    })
24304665835SMaxpicca-Li    val resp = Output(new Bundle{
24404665835SMaxpicca-Li      val valid = Bool()
24504665835SMaxpicca-Li      val s1_pred_way_en = UInt(nWays.W)
24604665835SMaxpicca-Li    })
24704665835SMaxpicca-Li  })
24804665835SMaxpicca-Li
24904665835SMaxpicca-Li  val s1_pred_way_en = io.req.s1_real_way_en
25004665835SMaxpicca-Li
25104665835SMaxpicca-Li  if(dwpuParam.enWPU){
25204665835SMaxpicca-Li    io.resp.valid := io.req.valid
25304665835SMaxpicca-Li  }else{
25404665835SMaxpicca-Li    io.resp.valid := false.B
25504665835SMaxpicca-Li  }
25604665835SMaxpicca-Li  io.resp.s1_pred_way_en := s1_pred_way_en
25704665835SMaxpicca-Li}