xref: /XiangShan/src/main/scala/xiangshan/frontend/icache/ICacheMissUnit.scala (revision 381609512aeee0f0cc54f512988386c435091bb6)
11d8f4dcbSJay/***************************************************************************************
21d8f4dcbSJay* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
31d8f4dcbSJay* Copyright (c) 2020-2021 Peng Cheng Laboratory
41d8f4dcbSJay*
51d8f4dcbSJay* XiangShan is licensed under Mulan PSL v2.
61d8f4dcbSJay* You can use this software according to the terms and conditions of the Mulan PSL v2.
71d8f4dcbSJay* You may obtain a copy of Mulan PSL v2 at:
81d8f4dcbSJay*          http://license.coscl.org.cn/MulanPSL2
91d8f4dcbSJay*
101d8f4dcbSJay* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
111d8f4dcbSJay* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
121d8f4dcbSJay* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
131d8f4dcbSJay*
141d8f4dcbSJay* See the Mulan PSL v2 for more details.
151d8f4dcbSJay***************************************************************************************/
161d8f4dcbSJay
171d8f4dcbSJaypackage xiangshan.frontend.icache
181d8f4dcbSJay
191d8f4dcbSJayimport chipsalliance.rocketchip.config.Parameters
201d8f4dcbSJayimport chisel3._
211d8f4dcbSJayimport chisel3.util._
221d8f4dcbSJayimport freechips.rocketchip.diplomacy.IdRange
231d8f4dcbSJayimport freechips.rocketchip.tilelink.ClientStates._
241d8f4dcbSJayimport freechips.rocketchip.tilelink.TLPermissions._
251d8f4dcbSJayimport freechips.rocketchip.tilelink._
261d8f4dcbSJayimport xiangshan._
271d8f4dcbSJayimport huancun.{AliasKey, DirtyKey}
281d8f4dcbSJayimport xiangshan.cache._
291d8f4dcbSJayimport utils._
303c02ee8fSwakafaimport utility._
3141cb8b61SJeniusimport difftest._
321d8f4dcbSJay
331d8f4dcbSJay
341d8f4dcbSJayabstract class ICacheMissUnitModule(implicit p: Parameters) extends XSModule
351d8f4dcbSJay  with HasICacheParameters
361d8f4dcbSJay
371d8f4dcbSJayabstract class ICacheMissUnitBundle(implicit p: Parameters) extends XSBundle
381d8f4dcbSJay  with HasICacheParameters
391d8f4dcbSJay
401d8f4dcbSJayclass ICacheMissReq(implicit p: Parameters) extends ICacheBundle
411d8f4dcbSJay{
421d8f4dcbSJay    val paddr      = UInt(PAddrBits.W)
431d8f4dcbSJay    val vaddr      = UInt(VAddrBits.W)
441d8f4dcbSJay    val waymask   = UInt(nWays.W)
451d8f4dcbSJay    val coh       = new ClientMetadata
461d8f4dcbSJay
471d8f4dcbSJay    def getVirSetIdx = get_idx(vaddr)
481d8f4dcbSJay    def getPhyTag    = get_phy_tag(paddr)
491d8f4dcbSJay}
501d8f4dcbSJay
511d8f4dcbSJay
521d8f4dcbSJayclass ICacheMissResp(implicit p: Parameters) extends ICacheBundle
531d8f4dcbSJay{
541d8f4dcbSJay    val data     = UInt(blockBits.W)
5558dbdfc2SJay    val corrupt  = Bool()
561d8f4dcbSJay}
571d8f4dcbSJay
581d8f4dcbSJayclass ICacheMissBundle(implicit p: Parameters) extends ICacheBundle{
591d8f4dcbSJay    val req       =   Vec(2, Flipped(DecoupledIO(new ICacheMissReq)))
601d8f4dcbSJay    val resp      =   Vec(2,ValidIO(new ICacheMissResp))
611d8f4dcbSJay    val flush     =   Input(Bool())
621d8f4dcbSJay}
631d8f4dcbSJay
641d8f4dcbSJay
651d8f4dcbSJayclass ICacheMissEntry(edge: TLEdgeOut, id: Int)(implicit p: Parameters) extends ICacheMissUnitModule
661d8f4dcbSJay  with MemoryOpConstants
671d8f4dcbSJay{
681d8f4dcbSJay  val io = IO(new Bundle {
697052722fSJay    val id = Input(UInt(log2Ceil(PortNumber).W))
701d8f4dcbSJay
711d8f4dcbSJay    val req = Flipped(DecoupledIO(new ICacheMissReq))
721d8f4dcbSJay    val resp = ValidIO(new ICacheMissResp)
731d8f4dcbSJay
741d8f4dcbSJay    //tilelink channel
751d8f4dcbSJay    val mem_acquire = DecoupledIO(new TLBundleA(edge.bundle))
761d8f4dcbSJay    val mem_grant = Flipped(DecoupledIO(new TLBundleD(edge.bundle)))
771d8f4dcbSJay    val mem_finish = DecoupledIO(new TLBundleE(edge.bundle))
781d8f4dcbSJay
791d8f4dcbSJay    val meta_write = DecoupledIO(new ICacheMetaWriteBundle)
801d8f4dcbSJay    val data_write = DecoupledIO(new ICacheDataWriteBundle)
811d8f4dcbSJay
822a25dbb4SJay    val release_req    =  DecoupledIO(new ReplacePipeReq)
832a25dbb4SJay    val release_resp   =  Flipped(ValidIO(UInt(ReplaceIdWid.W)))
842a25dbb4SJay    val victimInfor    =  Output(new ICacheVictimInfor())
857052722fSJay
8600240ba6SJay    val toPrefetch    = ValidIO(UInt(PAddrBits.W))
8700240ba6SJay
881d8f4dcbSJay  })
891d8f4dcbSJay
901d8f4dcbSJay  /** default value for control signals */
911d8f4dcbSJay  io.resp := DontCare
921d8f4dcbSJay  io.mem_acquire.bits := DontCare
931d8f4dcbSJay  io.mem_grant.ready := true.B
941d8f4dcbSJay  io.meta_write.bits := DontCare
951d8f4dcbSJay  io.data_write.bits := DontCare
961d8f4dcbSJay
97*38160951Sguohongyu  val s_idle  :: s_send_mem_aquire :: s_wait_mem_grant :: s_write_back :: s_wait_resp :: Nil = Enum(5)
981d8f4dcbSJay  val state = RegInit(s_idle)
991d8f4dcbSJay  /** control logic transformation */
1001d8f4dcbSJay  //request register
1011d8f4dcbSJay  val req = Reg(new ICacheMissReq)
1021d8f4dcbSJay  val req_idx = req.getVirSetIdx //virtual index
1031d8f4dcbSJay  val req_tag = req.getPhyTag //physical tag
1041d8f4dcbSJay  val req_waymask = req.waymask
1057052722fSJay  val release_id  = Cat(MainPipeKey.U, id.U)
10658dbdfc2SJay  val req_corrupt = RegInit(false.B)
1071d8f4dcbSJay
108*38160951Sguohongyu  io.victimInfor.valid := false.B // state === s_send_replace || state === s_wait_replace || state === s_wait_resp
109*38160951Sguohongyu  io.victimInfor.vidx  := false.B // req_idx
1101d8f4dcbSJay
1111d8f4dcbSJay  val (_, _, refill_done, refill_address_inc) = edge.addr_inc(io.mem_grant)
1121d8f4dcbSJay
1131d8f4dcbSJay  //cacheline register
1141d8f4dcbSJay  val readBeatCnt = Reg(UInt(log2Up(refillCycles).W))
1151d8f4dcbSJay  val respDataReg = Reg(Vec(refillCycles, UInt(beatBits.W)))
1161d8f4dcbSJay
1171d8f4dcbSJay  //initial
1181d8f4dcbSJay  io.resp.bits := DontCare
1191d8f4dcbSJay  io.mem_acquire.bits := DontCare
1201d8f4dcbSJay  io.mem_grant.ready := true.B
1211d8f4dcbSJay  io.meta_write.bits := DontCare
1221d8f4dcbSJay  io.data_write.bits := DontCare
1231d8f4dcbSJay
1242a25dbb4SJay  io.release_req.bits.paddr := req.paddr
1252a25dbb4SJay  io.release_req.bits.vaddr := req.vaddr
1262a25dbb4SJay  io.release_req.bits.voluntary := true.B
1272a25dbb4SJay  io.release_req.bits.waymask   := req.waymask
1280bebd829SJay  io.release_req.bits.needData   := false.B
1292a25dbb4SJay  io.release_req.bits.id   := release_id
1302a25dbb4SJay  io.release_req.bits.param := DontCare //release will not care tilelink param
1311d8f4dcbSJay
1321d8f4dcbSJay  io.req.ready := (state === s_idle)
1332a25dbb4SJay  io.mem_acquire.valid := (state === s_send_mem_aquire)
134*38160951Sguohongyu  io.release_req.valid := false.B // (state === s_send_replace)
1351d8f4dcbSJay
13600240ba6SJay  io.toPrefetch.valid := (state =/= s_idle)
13700240ba6SJay  io.toPrefetch.bits  :=  addrAlign(req.paddr, blockBytes, PAddrBits)
13800240ba6SJay
1391d8f4dcbSJay  val grantack = RegEnable(edge.GrantAck(io.mem_grant.bits), io.mem_grant.fire())
1401d8f4dcbSJay  val grant_param = Reg(UInt(TLPermissions.bdWidth.W))
1411d8f4dcbSJay  val is_dirty = RegInit(false.B)
1421d8f4dcbSJay  val is_grant = RegEnable(edge.isRequest(io.mem_grant.bits), io.mem_grant.fire())
1431d8f4dcbSJay
1441d8f4dcbSJay  //state change
1451d8f4dcbSJay  switch(state) {
1461d8f4dcbSJay    is(s_idle) {
1471d8f4dcbSJay      when(io.req.fire()) {
1481d8f4dcbSJay        readBeatCnt := 0.U
1491d8f4dcbSJay        state := s_send_mem_aquire
1501d8f4dcbSJay        req := io.req.bits
1511d8f4dcbSJay      }
1521d8f4dcbSJay    }
1531d8f4dcbSJay
1541d8f4dcbSJay    // memory request
1551d8f4dcbSJay    is(s_send_mem_aquire) {
1561d8f4dcbSJay      when(io.mem_acquire.fire()) {
1571d8f4dcbSJay        state := s_wait_mem_grant
1581d8f4dcbSJay      }
1591d8f4dcbSJay    }
1601d8f4dcbSJay
1611d8f4dcbSJay    is(s_wait_mem_grant) {
1621d8f4dcbSJay      when(edge.hasData(io.mem_grant.bits)) {
1631d8f4dcbSJay        when(io.mem_grant.fire()) {
1641d8f4dcbSJay          readBeatCnt := readBeatCnt + 1.U
1651d8f4dcbSJay          respDataReg(readBeatCnt) := io.mem_grant.bits.data
166*38160951Sguohongyu          req_corrupt := io.mem_grant.bits.corrupt // TODO: seems has bug
167*38160951Sguohongyu//          grant_param := io.mem_grant.bits.param
168*38160951Sguohongyu//          is_dirty    := io.mem_grant.bits.echo.lift(DirtyKey).getOrElse(false.B)
1691d8f4dcbSJay          when(readBeatCnt === (refillCycles - 1).U) {
1701d8f4dcbSJay            assert(refill_done, "refill not done!")
171*38160951Sguohongyu            state := s_write_back // s_send_grant_ack
1721d8f4dcbSJay          }
1731d8f4dcbSJay        }
1741d8f4dcbSJay      }
1751d8f4dcbSJay    }
1761d8f4dcbSJay
177*38160951Sguohongyu//    is(s_send_grant_ack) {
178*38160951Sguohongyu//      when(io.mem_finish.fire()) {
179*38160951Sguohongyu//        state := s_send_replace
180*38160951Sguohongyu//      }
181*38160951Sguohongyu//    }
1821d8f4dcbSJay
183*38160951Sguohongyu//    is(s_send_replace){
184*38160951Sguohongyu//      when(io.release_req.fire()){
185*38160951Sguohongyu//        state := s_wait_replace
186*38160951Sguohongyu//      }
187*38160951Sguohongyu//    }
1882a25dbb4SJay
189*38160951Sguohongyu//    is(s_wait_replace){
190*38160951Sguohongyu//      when(io.release_resp.valid && io.release_resp.bits === release_id){
191*38160951Sguohongyu//        state := s_write_back
192*38160951Sguohongyu//      }
193*38160951Sguohongyu//    }
1942a25dbb4SJay
1952a25dbb4SJay    is(s_write_back) {
1962a25dbb4SJay      state := Mux(io.meta_write.fire() && io.data_write.fire(), s_wait_resp, s_write_back)
1972a25dbb4SJay    }
1982a25dbb4SJay
1991d8f4dcbSJay    is(s_wait_resp) {
2001d8f4dcbSJay      io.resp.bits.data := respDataReg.asUInt
20158dbdfc2SJay      io.resp.bits.corrupt := req_corrupt
2021d8f4dcbSJay      when(io.resp.fire()) {
2031d8f4dcbSJay        state := s_idle
2041d8f4dcbSJay      }
2051d8f4dcbSJay    }
2061d8f4dcbSJay  }
2071d8f4dcbSJay
2081d8f4dcbSJay  /** refill write and meta write */
2091d8f4dcbSJay  val missCoh    = ClientMetadata(Nothing)
2101d8f4dcbSJay  val grow_param = missCoh.onAccess(M_XRD)._2
2111d8f4dcbSJay  val acquireBlock = edge.AcquireBlock(
2121d8f4dcbSJay    fromSource = io.id,
2131d8f4dcbSJay    toAddress = addrAlign(req.paddr, blockBytes, PAddrBits),
2141d8f4dcbSJay    lgSize = (log2Up(cacheParams.blockBytes)).U,
2151d8f4dcbSJay    growPermissions = grow_param
2161d8f4dcbSJay  )._2
217*38160951Sguohongyu
218*38160951Sguohongyu  val getBlock = edge.Get(
219*38160951Sguohongyu    fromSource = io.id,
220*38160951Sguohongyu    toAddress = addrAlign(req.paddr, blockBytes, PAddrBits),
221*38160951Sguohongyu    lgSize = (log2Up(cacheParams.blockBytes)).U
222*38160951Sguohongyu  )._2
223*38160951Sguohongyu
224*38160951Sguohongyu  io.mem_acquire.bits := getBlock // acquireBlock
2251d8f4dcbSJay  // resolve cache alias by L2
226*38160951Sguohongyu//  io.mem_acquire.bits.user.lift(AliasKey).foreach(_ := req.vaddr(13, 12))
2271d8f4dcbSJay  require(nSets <= 256) // icache size should not be more than 128KB
2281d8f4dcbSJay
2291d8f4dcbSJay  /** Grant ACK */
230*38160951Sguohongyu  io.mem_finish.valid := false.B // (state === s_send_grant_ack) && is_grant
2311d8f4dcbSJay  io.mem_finish.bits := grantack
2321d8f4dcbSJay
2331d8f4dcbSJay  //resp to ifu
2341d8f4dcbSJay  io.resp.valid := state === s_wait_resp
2352a25dbb4SJay  /** update coh meta */
2362a25dbb4SJay  def missCohGen(param: UInt, dirty: Bool): UInt = {
2372a25dbb4SJay    MuxLookup(Cat(param, dirty), Nothing, Seq(
2382a25dbb4SJay      Cat(toB, false.B) -> Branch,
2392a25dbb4SJay      Cat(toB, true.B)  -> Branch,
2402a25dbb4SJay      Cat(toT, false.B) -> Trunk,
2412a25dbb4SJay      Cat(toT, true.B)  -> Dirty))
2422a25dbb4SJay  }
2432a25dbb4SJay
244*38160951Sguohongyu  val miss_new_coh = ClientMetadata(ClientStates.Branch) // ClientMetadata(missCohGen(grant_param, is_dirty))
2452a25dbb4SJay
2462a25dbb4SJay  io.meta_write.valid := (state === s_write_back)
2472a25dbb4SJay  io.meta_write.bits.generate(tag = req_tag, coh = miss_new_coh, idx = req_idx, waymask = req_waymask, bankIdx = req_idx(0))
2482a25dbb4SJay
2492a25dbb4SJay  io.data_write.valid := (state === s_write_back)
25041cb8b61SJenius  io.data_write.bits.generate(data = respDataReg.asUInt,
25141cb8b61SJenius                              idx  = req_idx,
25241cb8b61SJenius                              waymask = req_waymask,
25341cb8b61SJenius                              bankIdx = req_idx(0),
25441cb8b61SJenius                              paddr = req.paddr)
2551d8f4dcbSJay
2561d8f4dcbSJay  XSPerfAccumulate(
2571d8f4dcbSJay    "entryPenalty" + Integer.toString(id, 10),
2581d8f4dcbSJay    BoolStopWatch(
2591d8f4dcbSJay      start = io.req.fire(),
2601d8f4dcbSJay      stop = io.resp.valid,
2611d8f4dcbSJay      startHighPriority = true)
2621d8f4dcbSJay  )
2631d8f4dcbSJay  XSPerfAccumulate("entryReq" + Integer.toString(id, 10), io.req.fire())
2641d8f4dcbSJay
2651d8f4dcbSJay}
2661d8f4dcbSJay
2671d8f4dcbSJay
2681d8f4dcbSJayclass ICacheMissUnit(edge: TLEdgeOut)(implicit p: Parameters) extends ICacheMissUnitModule
2691d8f4dcbSJay{
2701d8f4dcbSJay  val io = IO(new Bundle{
27141cb8b61SJenius    val hartId      = Input(UInt(8.W))
2721d8f4dcbSJay    val req         = Vec(2, Flipped(DecoupledIO(new ICacheMissReq)))
2731d8f4dcbSJay    val resp        = Vec(2, ValidIO(new ICacheMissResp))
2741d8f4dcbSJay
2751d8f4dcbSJay    val mem_acquire = DecoupledIO(new TLBundleA(edge.bundle))
2761d8f4dcbSJay    val mem_grant   = Flipped(DecoupledIO(new TLBundleD(edge.bundle)))
2771d8f4dcbSJay    val mem_finish  = DecoupledIO(new TLBundleE(edge.bundle))
2781d8f4dcbSJay
2791d8f4dcbSJay    val meta_write  = DecoupledIO(new ICacheMetaWriteBundle)
2801d8f4dcbSJay    val data_write  = DecoupledIO(new ICacheDataWriteBundle)
2811d8f4dcbSJay
2822a25dbb4SJay    val release_req    =  DecoupledIO(new ReplacePipeReq)
2832a25dbb4SJay    val release_resp   =  Flipped(ValidIO(UInt(ReplaceIdWid.W)))
2841d8f4dcbSJay
2852a25dbb4SJay    val victimInfor = Vec(PortNumber, Output(new ICacheVictimInfor()))
2862a25dbb4SJay
2877052722fSJay    val prefetch_req          =  Flipped(DecoupledIO(new PIQReq))
28800240ba6SJay    val prefetch_check        =  Vec(PortNumber,ValidIO(UInt(PAddrBits.W)))
28900240ba6SJay
2907052722fSJay
2911d8f4dcbSJay  })
2921d8f4dcbSJay  // assign default values to output signals
2931d8f4dcbSJay  io.mem_grant.ready := false.B
2941d8f4dcbSJay
2951d8f4dcbSJay  val meta_write_arb = Module(new Arbiter(new ICacheMetaWriteBundle,  PortNumber))
2961d8f4dcbSJay  val refill_arb     = Module(new Arbiter(new ICacheDataWriteBundle,  PortNumber))
2972a25dbb4SJay  val release_arb    = Module(new Arbiter(new ReplacePipeReq,  PortNumber))
2981d8f4dcbSJay
2991d8f4dcbSJay  io.mem_grant.ready := true.B
3001d8f4dcbSJay
3012a25dbb4SJay  val entries = (0 until PortNumber) map { i =>
3021d8f4dcbSJay    val entry = Module(new ICacheMissEntry(edge, i))
3031d8f4dcbSJay
3041d8f4dcbSJay    entry.io.id := i.U
3051d8f4dcbSJay
3061d8f4dcbSJay    // entry req
3071d8f4dcbSJay    entry.io.req.valid := io.req(i).valid
3081d8f4dcbSJay    entry.io.req.bits  := io.req(i).bits
3091d8f4dcbSJay    io.req(i).ready    := entry.io.req.ready
3101d8f4dcbSJay
3111d8f4dcbSJay    // entry resp
3121d8f4dcbSJay    meta_write_arb.io.in(i)     <>  entry.io.meta_write
3131d8f4dcbSJay    refill_arb.io.in(i)         <>  entry.io.data_write
3142a25dbb4SJay    release_arb.io.in(i)        <>  entry.io.release_req
3151d8f4dcbSJay
3161d8f4dcbSJay    entry.io.mem_grant.valid := false.B
3171d8f4dcbSJay    entry.io.mem_grant.bits  := DontCare
3181d8f4dcbSJay    when (io.mem_grant.bits.source === i.U) {
3191d8f4dcbSJay      entry.io.mem_grant <> io.mem_grant
3201d8f4dcbSJay    }
3211d8f4dcbSJay
3221d8f4dcbSJay    io.resp(i) <> entry.io.resp
3231d8f4dcbSJay
3242a25dbb4SJay    io.victimInfor(i) := entry.io.victimInfor
32500240ba6SJay    io.prefetch_check(i) <> entry.io.toPrefetch
3262a25dbb4SJay
3272a25dbb4SJay    entry.io.release_resp <> io.release_resp
3282a25dbb4SJay
3291d8f4dcbSJay    XSPerfAccumulate(
3301d8f4dcbSJay      "entryPenalty" + Integer.toString(i, 10),
3311d8f4dcbSJay      BoolStopWatch(
3321d8f4dcbSJay        start = entry.io.req.fire(),
3331d8f4dcbSJay        stop = entry.io.resp.fire(),
3341d8f4dcbSJay        startHighPriority = true)
3351d8f4dcbSJay    )
3361d8f4dcbSJay    XSPerfAccumulate("entryReq" + Integer.toString(i, 10), entry.io.req.fire())
3371d8f4dcbSJay
3381d8f4dcbSJay    entry
3391d8f4dcbSJay  }
3401d8f4dcbSJay
3417052722fSJay  val alloc = Wire(UInt(log2Ceil(nPrefetchEntries).W))
3427052722fSJay
343de7689fcSJay  val prefEntries = (PortNumber until PortNumber + nPrefetchEntries) map { i =>
3447052722fSJay    val prefetchEntry = Module(new IPrefetchEntry(edge, PortNumber))
3457052722fSJay
3467052722fSJay    prefetchEntry.io.mem_hint_ack.valid := false.B
3477052722fSJay    prefetchEntry.io.mem_hint_ack.bits := DontCare
3487052722fSJay
3497052722fSJay    when(io.mem_grant.bits.source === PortNumber.U) {
3507052722fSJay      prefetchEntry.io.mem_hint_ack <> io.mem_grant
3517052722fSJay    }
3527052722fSJay
353de7689fcSJay    prefetchEntry.io.req.valid := io.prefetch_req.valid && ((i-PortNumber).U === alloc)
3547052722fSJay    prefetchEntry.io.req.bits  := io.prefetch_req.bits
3557052722fSJay
3567052722fSJay    prefetchEntry.io.id := i.U
3577052722fSJay
3587052722fSJay    prefetchEntry
3597052722fSJay  }
3607052722fSJay
3617052722fSJay  alloc := PriorityEncoder(prefEntries.map(_.io.req.ready))
3627052722fSJay  io.prefetch_req.ready := ParallelOR(prefEntries.map(_.io.req.ready))
3637052722fSJay  val tl_a_chanel = entries.map(_.io.mem_acquire) ++ prefEntries.map(_.io.mem_hint)
3647052722fSJay  TLArbiter.lowest(edge, io.mem_acquire, tl_a_chanel:_*)
3657052722fSJay
3661d8f4dcbSJay  TLArbiter.lowest(edge, io.mem_finish,  entries.map(_.io.mem_finish):_*)
3671d8f4dcbSJay
3681d8f4dcbSJay  io.meta_write     <> meta_write_arb.io.out
3691d8f4dcbSJay  io.data_write     <> refill_arb.io.out
3702a25dbb4SJay  io.release_req    <> release_arb.io.out
3711d8f4dcbSJay
37241cb8b61SJenius  if (env.EnableDifftest) {
37341cb8b61SJenius    val difftest = Module(new DifftestRefillEvent)
37441cb8b61SJenius    difftest.io.clock := clock
37541cb8b61SJenius    difftest.io.coreid := io.hartId
37641cb8b61SJenius    difftest.io.cacheid := 0.U
37741cb8b61SJenius    difftest.io.valid := refill_arb.io.out.valid
37841cb8b61SJenius    difftest.io.addr := refill_arb.io.out.bits.paddr
37941cb8b61SJenius    difftest.io.data := refill_arb.io.out.bits.data.asTypeOf(difftest.io.data)
38041cb8b61SJenius  }
38141cb8b61SJenius
3821d8f4dcbSJay  (0 until nWays).map{ w =>
3831d8f4dcbSJay    XSPerfAccumulate("line_0_refill_way_" + Integer.toString(w, 10),  entries(0).io.meta_write.valid && OHToUInt(entries(0).io.meta_write.bits.waymask)  === w.U)
3841d8f4dcbSJay    XSPerfAccumulate("line_1_refill_way_" + Integer.toString(w, 10),  entries(1).io.meta_write.valid && OHToUInt(entries(1).io.meta_write.bits.waymask)  === w.U)
3851d8f4dcbSJay  }
3861d8f4dcbSJay
3871d8f4dcbSJay}
3881d8f4dcbSJay
3891d8f4dcbSJay
3901d8f4dcbSJay
391