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 198891a219SYinan Xuimport org.chipsalliance.cde.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 xiangshan.cache._ 281d8f4dcbSJayimport utils._ 293c02ee8fSwakafaimport utility._ 3041cb8b61SJeniusimport difftest._ 311d8f4dcbSJay 321d8f4dcbSJay 331d8f4dcbSJayabstract class ICacheMissUnitModule(implicit p: Parameters) extends XSModule 341d8f4dcbSJay with HasICacheParameters 351d8f4dcbSJay 361d8f4dcbSJayabstract class ICacheMissUnitBundle(implicit p: Parameters) extends XSBundle 371d8f4dcbSJay with HasICacheParameters 381d8f4dcbSJay 391d8f4dcbSJay 40*b92f8445Sssszwicclass Demultiplexer[T <: Data](val gen: T, val n: Int) extends Module 41*b92f8445Sssszwic{ 42*b92f8445Sssszwic /** Hardware module that is used to sequence 1 producers into n consumer. 43*b92f8445Sssszwic * Priority is given to lower producer. 44*b92f8445Sssszwic */ 45*b92f8445Sssszwic require(n >= 2) 46*b92f8445Sssszwic val io = IO(new Bundle { 47*b92f8445Sssszwic val in = Flipped(DecoupledIO(gen)) 48*b92f8445Sssszwic val out = Vec(n, DecoupledIO(gen)) 49*b92f8445Sssszwic val chosen = Output(UInt(log2Ceil(n).W)) 50*b92f8445Sssszwic }) 51*b92f8445Sssszwic 52*b92f8445Sssszwic val grant = false.B +: (1 until n).map(i=> (0 until i).map(io.out(_).ready).reduce(_||_)) 53*b92f8445Sssszwic for (i <- 0 until n) { 54*b92f8445Sssszwic io.out(i).bits := io.in.bits 55*b92f8445Sssszwic io.out(i).valid := !grant(i) && io.in.valid 56*b92f8445Sssszwic } 57*b92f8445Sssszwic 58*b92f8445Sssszwic io.in.ready := grant.last || io.out.last.ready 59*b92f8445Sssszwic io.chosen := PriorityEncoder(VecInit(io.out.map(_.ready))) 601d8f4dcbSJay} 611d8f4dcbSJay 621d8f4dcbSJay 63*b92f8445Sssszwicclass MuxBundle[T <: Data](val gen: T, val n: Int) extends Module 641d8f4dcbSJay{ 65*b92f8445Sssszwic require(n >= 2) 66*b92f8445Sssszwic val io = IO(new Bundle { 67*b92f8445Sssszwic val sel = Input(UInt(log2Ceil(n).W)) 68*b92f8445Sssszwic val in = Flipped(Vec(n, DecoupledIO(gen))) 69*b92f8445Sssszwic val out = DecoupledIO(gen) 70*b92f8445Sssszwic }) 71*b92f8445Sssszwic 72*b92f8445Sssszwic io.in <> DontCare 73*b92f8445Sssszwic io.out <> DontCare 74*b92f8445Sssszwic for (i <- 0 until n) { 75*b92f8445Sssszwic when(io.sel === i.U) { 76*b92f8445Sssszwic io.out <> io.in(i) 77*b92f8445Sssszwic } 78*b92f8445Sssszwic io.in(i).ready := (io.sel === i.U) && io.out.ready 79*b92f8445Sssszwic } 80*b92f8445Sssszwic} 81*b92f8445Sssszwic 82*b92f8445Sssszwic 83*b92f8445Sssszwicclass ICacheMissReq(implicit p: Parameters) extends ICacheBundle { 84*b92f8445Sssszwic val blkPaddr = UInt((PAddrBits - blockOffBits).W) 85*b92f8445Sssszwic val vSetIdx = UInt(idxBits.W) 86*b92f8445Sssszwic} 87*b92f8445Sssszwic 88*b92f8445Sssszwic 89*b92f8445Sssszwicclass ICacheMissResp(implicit p: Parameters) extends ICacheBundle { 90*b92f8445Sssszwic val blkPaddr = UInt((PAddrBits - blockOffBits).W) 91*b92f8445Sssszwic val vSetIdx = UInt(idxBits.W) 92*b92f8445Sssszwic val waymask = UInt(nWays.W) 931d8f4dcbSJay val data = UInt(blockBits.W) 9458dbdfc2SJay val corrupt = Bool() 951d8f4dcbSJay} 961d8f4dcbSJay 97*b92f8445Sssszwic 98*b92f8445Sssszwicclass LookUpMSHR(implicit p: Parameters) extends ICacheBundle { 99*b92f8445Sssszwic val info = ValidIO(new ICacheMissReq) 100*b92f8445Sssszwic val hit = Input(Bool()) 1011d8f4dcbSJay} 1021d8f4dcbSJay 1031d8f4dcbSJay 104*b92f8445Sssszwicclass MSHRResp(implicit p: Parameters) extends ICacheBundle { 105*b92f8445Sssszwic val blkPaddr = UInt((PAddrBits - blockOffBits).W) 106*b92f8445Sssszwic val vSetIdx = UInt(idxBits.W) 107*b92f8445Sssszwic val waymask = UInt(log2Ceil(nWays).W) 108*b92f8445Sssszwic} 109*b92f8445Sssszwic 110*b92f8445Sssszwic 111*b92f8445Sssszwicclass MSHRAcquire(edge: TLEdgeOut)(implicit p: Parameters) extends ICacheBundle { 112*b92f8445Sssszwic val acquire = new TLBundleA(edge.bundle) 113*b92f8445Sssszwic val vSetIdx = UInt(idxBits.W) 114*b92f8445Sssszwic} 115*b92f8445Sssszwic 116*b92f8445Sssszwicclass ICacheMSHR(edge: TLEdgeOut, isFetch: Boolean, ID: Int)(implicit p: Parameters) extends ICacheMissUnitModule { 1171d8f4dcbSJay val io = IO(new Bundle { 1182a6078bfSguohongyu val fencei = Input(Bool()) 119*b92f8445Sssszwic val flush = Input(Bool()) 120*b92f8445Sssszwic val invalid = Input(Bool()) 121*b92f8445Sssszwic val req = Flipped(DecoupledIO(new ICacheMissReq)) 122*b92f8445Sssszwic val acquire = DecoupledIO(new MSHRAcquire(edge)) 123*b92f8445Sssszwic val lookUps = Flipped(Vec(2, new LookUpMSHR)) 124*b92f8445Sssszwic val resp = ValidIO(new MSHRResp) 125*b92f8445Sssszwic val victimWay = Input(UInt(log2Ceil(nWays).W)) 1261d8f4dcbSJay }) 1271d8f4dcbSJay 128*b92f8445Sssszwic val valid = RegInit(Bool(), false.B) 129*b92f8445Sssszwic // this MSHR doesn't respones to fetch and sram 130*b92f8445Sssszwic val flush = RegInit(Bool(), false.B) 131*b92f8445Sssszwic val fencei = RegInit(Bool(), false.B) 132*b92f8445Sssszwic // this MSHR has been issued 133*b92f8445Sssszwic val issue = RegInit(Bool(), false.B) 1341d8f4dcbSJay 135*b92f8445Sssszwic val blkPaddr = RegInit(UInt((PAddrBits - blockOffBits).W), 0.U) 136*b92f8445Sssszwic val vSetIdx = RegInit(UInt(idxBits.W), 0.U) 137*b92f8445Sssszwic val waymask = RegInit(UInt(log2Ceil(nWays).W), 0.U) 1381d8f4dcbSJay 139*b92f8445Sssszwic // look up and return result at the same cycle 140*b92f8445Sssszwic val hits = io.lookUps.map(lookup => valid && !fencei && !flush && (lookup.info.bits.vSetIdx === vSetIdx) && 141*b92f8445Sssszwic (lookup.info.bits.blkPaddr === blkPaddr)) 142*b92f8445Sssszwic // Decoupling valid and bits 143*b92f8445Sssszwic (0 until 2).foreach { i => 144*b92f8445Sssszwic io.lookUps(i).hit := hits(i) 145*b92f8445Sssszwic } 1461d8f4dcbSJay 147*b92f8445Sssszwic // disable wake up when hit MSHR (fencei is low) 148*b92f8445Sssszwic // when(hit) { 149*b92f8445Sssszwic // flush := false.B 150*b92f8445Sssszwic // } 1512a6078bfSguohongyu 152*b92f8445Sssszwic // invalid when the req hasn't been issued 153*b92f8445Sssszwic when(io.fencei || io.flush) { 154*b92f8445Sssszwic fencei := true.B 155*b92f8445Sssszwic flush := true.B 156*b92f8445Sssszwic when(!issue) { 157*b92f8445Sssszwic valid := false.B 158*b92f8445Sssszwic } 159*b92f8445Sssszwic } 1601d8f4dcbSJay 161*b92f8445Sssszwic // receive request and register 162*b92f8445Sssszwic io.req.ready := !valid && !io.flush && !io.fencei 163935edac4STang Haojin when(io.req.fire) { 164*b92f8445Sssszwic valid := true.B 165*b92f8445Sssszwic flush := false.B 166*b92f8445Sssszwic issue := false.B 167*b92f8445Sssszwic fencei := false.B 168*b92f8445Sssszwic blkPaddr := io.req.bits.blkPaddr 169*b92f8445Sssszwic vSetIdx := io.req.bits.vSetIdx 1701d8f4dcbSJay } 1711d8f4dcbSJay 172*b92f8445Sssszwic // send request to L2 173*b92f8445Sssszwic io.acquire.valid := valid && !issue && !io.flush && !io.fencei 17438160951Sguohongyu val getBlock = edge.Get( 175*b92f8445Sssszwic fromSource = ID.U, 176*b92f8445Sssszwic toAddress = Cat(blkPaddr, 0.U(blockOffBits.W)), 17738160951Sguohongyu lgSize = (log2Up(cacheParams.blockBytes)).U 17838160951Sguohongyu )._2 179*b92f8445Sssszwic io.acquire.bits.acquire := getBlock 180*b92f8445Sssszwic io.acquire.bits.acquire.user.lift(ReqSourceKey).foreach(_ := MemReqSource.CPUInst.id.U) 181*b92f8445Sssszwic io.acquire.bits.vSetIdx := vSetIdx 18238160951Sguohongyu 183*b92f8445Sssszwic // get victim way when acquire fire 184*b92f8445Sssszwic when(io.acquire.fire) { 185*b92f8445Sssszwic issue := true.B 186*b92f8445Sssszwic waymask := io.victimWay 187*b92f8445Sssszwic } 1881d8f4dcbSJay 189*b92f8445Sssszwic // invalid request when grant finish 190*b92f8445Sssszwic when(io.invalid) { 191*b92f8445Sssszwic valid := false.B 192*b92f8445Sssszwic } 1932a25dbb4SJay 194*b92f8445Sssszwic // offer the information other than data for write sram and response fetch 195*b92f8445Sssszwic io.resp.valid := valid && (!flush && !fencei) 196*b92f8445Sssszwic io.resp.bits.blkPaddr := blkPaddr 197*b92f8445Sssszwic io.resp.bits.vSetIdx := vSetIdx 198*b92f8445Sssszwic io.resp.bits.waymask := waymask 199*b92f8445Sssszwic} 200131aa97cSssszwic 201*b92f8445Sssszwicclass ICacheMissBundle(edge: TLEdgeOut)(implicit p: Parameters) extends ICacheBundle{ 202*b92f8445Sssszwic // difftest 203*b92f8445Sssszwic val hartId = Input(Bool()) 204*b92f8445Sssszwic // control 205*b92f8445Sssszwic val fencei = Input(Bool()) 206*b92f8445Sssszwic val flush = Input(Bool()) 207*b92f8445Sssszwic // fetch 208*b92f8445Sssszwic val fetch_req = Flipped(DecoupledIO(new ICacheMissReq)) 209*b92f8445Sssszwic val fetch_resp = ValidIO(new ICacheMissResp) 210*b92f8445Sssszwic // prefetch 211*b92f8445Sssszwic val prefetch_req = Flipped(DecoupledIO(new ICacheMissReq)) 212*b92f8445Sssszwic // SRAM Write Req 213*b92f8445Sssszwic val meta_write = DecoupledIO(new ICacheMetaWriteBundle) 214*b92f8445Sssszwic val data_write = DecoupledIO(new ICacheDataWriteBundle) 215*b92f8445Sssszwic // get victim from replacer 216*b92f8445Sssszwic val victim = new ReplacerVictim 217*b92f8445Sssszwic // Tilelink 218*b92f8445Sssszwic val mem_acquire = DecoupledIO(new TLBundleA(edge.bundle)) 219*b92f8445Sssszwic val mem_grant = Flipped(DecoupledIO(new TLBundleD(edge.bundle))) 2201d8f4dcbSJay} 2211d8f4dcbSJay 2221d8f4dcbSJay 2231d8f4dcbSJayclass ICacheMissUnit(edge: TLEdgeOut)(implicit p: Parameters) extends ICacheMissUnitModule 2241d8f4dcbSJay{ 225*b92f8445Sssszwic val io = IO(new ICacheMissBundle(edge)) 2261d8f4dcbSJay 227*b92f8445Sssszwic /** 228*b92f8445Sssszwic ****************************************************************************** 229*b92f8445Sssszwic * fetch have higher priority 230*b92f8445Sssszwic * fetch MSHR: lower index have a higher priority 231*b92f8445Sssszwic * prefetch MSHR: the prefetchMSHRs earlier have a higher priority 232*b92f8445Sssszwic * --------- -------------- ----------- 233*b92f8445Sssszwic * ---fetch reg--->| Demux |-----> | fetch MSHR |------>| Arbiter |---acquire---> 234*b92f8445Sssszwic * --------- -------------- ----------- 235*b92f8445Sssszwic * | fetch MSHR | ^ 236*b92f8445Sssszwic * -------------- | 237*b92f8445Sssszwic * | 238*b92f8445Sssszwic * ----------------- | 239*b92f8445Sssszwic * | prefetch MSHR | | 240*b92f8445Sssszwic * --------- ----------------- ----------- 241*b92f8445Sssszwic * ---fetch reg--->| Demux |----> | prefetch MSHR |---->| Arbiter | 242*b92f8445Sssszwic * --------- ----------------- ----------- 243*b92f8445Sssszwic * | ....... | 244*b92f8445Sssszwic * ----------------- 245*b92f8445Sssszwic ****************************************************************************** 246*b92f8445Sssszwic */ 2471d8f4dcbSJay 248*b92f8445Sssszwic val fetchDemux = Module(new Demultiplexer(new ICacheMissReq, nFetchMshr)) 249*b92f8445Sssszwic val prefetchDemux = Module(new Demultiplexer(new ICacheMissReq, nPrefetchMshr)) 250*b92f8445Sssszwic val prefetchArb = Module(new MuxBundle(new MSHRAcquire(edge), nPrefetchMshr)) 251*b92f8445Sssszwic val acquireArb = Module(new Arbiter(new MSHRAcquire(edge), nFetchMshr + 1)) 252cb6e5d3cSssszwic 253*b92f8445Sssszwic // To avoid duplicate request reception. 254*b92f8445Sssszwic val fetchHit, prefetchHit = Wire(Bool()) 255*b92f8445Sssszwic fetchDemux.io.in <> io.fetch_req 256*b92f8445Sssszwic fetchDemux.io.in.valid := io.fetch_req.valid && !fetchHit 257*b92f8445Sssszwic io.fetch_req.ready := fetchDemux.io.in.ready || fetchHit 258*b92f8445Sssszwic prefetchDemux.io.in <> io.prefetch_req 259*b92f8445Sssszwic prefetchDemux.io.in.valid := io.prefetch_req.valid && !prefetchHit 260*b92f8445Sssszwic io.prefetch_req.ready := prefetchDemux.io.in.ready || prefetchHit 261*b92f8445Sssszwic acquireArb.io.in.last <> prefetchArb.io.out 2621d8f4dcbSJay 263*b92f8445Sssszwic // mem_acquire connect 264*b92f8445Sssszwic io.mem_acquire.valid := acquireArb.io.out.valid 265*b92f8445Sssszwic io.mem_acquire.bits := acquireArb.io.out.bits.acquire 266*b92f8445Sssszwic acquireArb.io.out.ready := io.mem_acquire.ready 2671d8f4dcbSJay 268*b92f8445Sssszwic val fetchMSHRs = (0 until nFetchMshr).map { i => 269*b92f8445Sssszwic val mshr = Module(new ICacheMSHR(edge, true, i)) 270*b92f8445Sssszwic mshr.io.flush := false.B 271*b92f8445Sssszwic mshr.io.fencei := io.fencei 272*b92f8445Sssszwic mshr.io.req <> fetchDemux.io.out(i) 273*b92f8445Sssszwic mshr.io.lookUps(0).info.valid := io.fetch_req.valid 274*b92f8445Sssszwic mshr.io.lookUps(0).info.bits := io.fetch_req.bits 275*b92f8445Sssszwic mshr.io.lookUps(1).info.valid := io.prefetch_req.valid 276*b92f8445Sssszwic mshr.io.lookUps(1).info.bits := io.prefetch_req.bits 277*b92f8445Sssszwic mshr.io.victimWay := io.victim.way 278*b92f8445Sssszwic acquireArb.io.in(i) <> mshr.io.acquire 279*b92f8445Sssszwic mshr 2801d8f4dcbSJay } 2811d8f4dcbSJay 282*b92f8445Sssszwic val prefetchMSHRs = (0 until nPrefetchMshr).map { i => 283*b92f8445Sssszwic val mshr = Module(new ICacheMSHR(edge, false, nFetchMshr + i)) 284*b92f8445Sssszwic mshr.io.flush := io.flush 285*b92f8445Sssszwic mshr.io.fencei := io.fencei 286*b92f8445Sssszwic mshr.io.req <> prefetchDemux.io.out(i) 287*b92f8445Sssszwic mshr.io.lookUps(0).info.valid := io.fetch_req.valid 288*b92f8445Sssszwic mshr.io.lookUps(0).info.bits := io.fetch_req.bits 289*b92f8445Sssszwic mshr.io.lookUps(1).info.valid := io.prefetch_req.valid 290*b92f8445Sssszwic mshr.io.lookUps(1).info.bits := io.prefetch_req.bits 291*b92f8445Sssszwic mshr.io.victimWay := io.victim.way 292*b92f8445Sssszwic prefetchArb.io.in(i) <> mshr.io.acquire 293*b92f8445Sssszwic mshr 2947052722fSJay } 2957052722fSJay 29658c354d0Sssszwic /** 29758c354d0Sssszwic ****************************************************************************** 298*b92f8445Sssszwic * MSHR look up 299*b92f8445Sssszwic * - look up all mshr 30058c354d0Sssszwic ****************************************************************************** 30158c354d0Sssszwic */ 302*b92f8445Sssszwic val allMSHRs = (fetchMSHRs ++ prefetchMSHRs) 303*b92f8445Sssszwic val prefetchHitFetchReq = (io.prefetch_req.bits.blkPaddr === io.fetch_req.bits.blkPaddr) && 304*b92f8445Sssszwic (io.prefetch_req.bits.vSetIdx === io.fetch_req.bits.vSetIdx) && 305*b92f8445Sssszwic io.fetch_req.valid 306*b92f8445Sssszwic fetchHit := allMSHRs.map(mshr => mshr.io.lookUps(0).hit).reduce(_||_) 307*b92f8445Sssszwic prefetchHit := allMSHRs.map(mshr => mshr.io.lookUps(1).hit).reduce(_||_) || prefetchHitFetchReq 30858c354d0Sssszwic 309*b92f8445Sssszwic /** 310*b92f8445Sssszwic ****************************************************************************** 311*b92f8445Sssszwic * prefetchMSHRs priority 312*b92f8445Sssszwic * - The requests that enter the prefetchMSHRs earlier have a higher priority in issuing. 313*b92f8445Sssszwic * - The order of enqueuing is recorded in FIFO when requset enters MSHRs. 314*b92f8445Sssszwic * - The requests are dispatched in the order they are recorded in FIFO. 315*b92f8445Sssszwic ****************************************************************************** 316*b92f8445Sssszwic */ 317*b92f8445Sssszwic // When the FIFO is full, enqueue and dequeue operations do not occur at the same cycle. 318*b92f8445Sssszwic // So the depth of the FIFO is set to match the number of MSHRs. 319*b92f8445Sssszwic // val priorityFIFO = Module(new Queue(UInt(log2Ceil(nPrefetchMshr).W), nPrefetchMshr, hasFlush=true)) 320*b92f8445Sssszwic val priorityFIFO = Module(new FIFOReg(UInt(log2Ceil(nPrefetchMshr).W), nPrefetchMshr, hasFlush=true)) 321*b92f8445Sssszwic priorityFIFO.io.flush.get := io.flush || io.fencei 322*b92f8445Sssszwic priorityFIFO.io.enq.valid := prefetchDemux.io.in.fire 323*b92f8445Sssszwic priorityFIFO.io.enq.bits := prefetchDemux.io.chosen 324*b92f8445Sssszwic priorityFIFO.io.deq.ready := prefetchArb.io.out.fire 325*b92f8445Sssszwic prefetchArb.io.sel := priorityFIFO.io.deq.bits 326*b92f8445Sssszwic assert(!(priorityFIFO.io.enq.fire ^ prefetchDemux.io.in.fire), "priorityFIFO.io.enq and io.prefetch_req must fire at the same cycle") 327*b92f8445Sssszwic assert(!(priorityFIFO.io.deq.fire ^ prefetchArb.io.out.fire), "priorityFIFO.io.deq and prefetchArb.io.out must fire at the same cycle") 3287052722fSJay 329*b92f8445Sssszwic /** 330*b92f8445Sssszwic ****************************************************************************** 331*b92f8445Sssszwic * Tilelink D channel (grant) 332*b92f8445Sssszwic ****************************************************************************** 333*b92f8445Sssszwic */ 334*b92f8445Sssszwic //cacheline register 335*b92f8445Sssszwic val readBeatCnt = RegInit(UInt(log2Up(refillCycles).W), 0.U) 336*b92f8445Sssszwic val respDataReg = RegInit(VecInit(Seq.fill(refillCycles)(0.U(beatBits.W)))) 3371d8f4dcbSJay 338*b92f8445Sssszwic val wait_last = readBeatCnt === (refillCycles - 1).U 339*b92f8445Sssszwic when(io.mem_grant.fire && edge.hasData(io.mem_grant.bits)) { 340*b92f8445Sssszwic respDataReg(readBeatCnt) := io.mem_grant.bits.data 341*b92f8445Sssszwic readBeatCnt := Mux(wait_last || io.mem_grant.bits.corrupt, 0.U, readBeatCnt + 1.U) 342*b92f8445Sssszwic } 343*b92f8445Sssszwic 344*b92f8445Sssszwic // last transition finsh or corrupt 345*b92f8445Sssszwic val last_fire = io.mem_grant.fire && edge.hasData(io.mem_grant.bits) && 346*b92f8445Sssszwic (wait_last || io.mem_grant.bits.corrupt) 347*b92f8445Sssszwic 348*b92f8445Sssszwic val (_, _, refill_done, _) = edge.addr_inc(io.mem_grant) 349*b92f8445Sssszwic assert(!(refill_done ^ last_fire), "refill not done!") 350*b92f8445Sssszwic io.mem_grant.ready := true.B 351*b92f8445Sssszwic 352*b92f8445Sssszwic val last_fire_r = RegNext(last_fire) 353*b92f8445Sssszwic val id_r = RegNext(io.mem_grant.bits.source) 354*b92f8445Sssszwic val corrupt_r = RegNext(io.mem_grant.bits.corrupt) 355*b92f8445Sssszwic 356*b92f8445Sssszwic /** 357*b92f8445Sssszwic ****************************************************************************** 358*b92f8445Sssszwic * invalid mshr when finish transition 359*b92f8445Sssszwic ****************************************************************************** 360*b92f8445Sssszwic */ 361*b92f8445Sssszwic (0 until (nFetchMshr + nPrefetchMshr)).foreach{ i => 362*b92f8445Sssszwic allMSHRs(i).io.invalid := last_fire_r && (id_r === i.U) 363*b92f8445Sssszwic } 364*b92f8445Sssszwic 365*b92f8445Sssszwic /** 366*b92f8445Sssszwic ****************************************************************************** 367*b92f8445Sssszwic * response fetch and write SRAM 368*b92f8445Sssszwic ****************************************************************************** 369*b92f8445Sssszwic */ 370*b92f8445Sssszwic // get request information from MSHRs 371*b92f8445Sssszwic val allMSHRs_resp = VecInit(allMSHRs.map(mshr => mshr.io.resp)) 372*b92f8445Sssszwic val mshr_resp = allMSHRs_resp(id_r) 373*b92f8445Sssszwic 374*b92f8445Sssszwic // get waymask from replacer when acquire fire 375*b92f8445Sssszwic io.victim.vSetIdx.valid := acquireArb.io.out.valid 376*b92f8445Sssszwic io.victim.vSetIdx.bits := acquireArb.io.out.bits.vSetIdx 377*b92f8445Sssszwic val waymask = UIntToOH(mshr_resp.bits.waymask) 378*b92f8445Sssszwic val fetch_resp_valid = mshr_resp.valid && last_fire_r && !io.flush && !io.fencei 379*b92f8445Sssszwic val write_sram_valid = fetch_resp_valid && !corrupt_r 380*b92f8445Sssszwic 381*b92f8445Sssszwic // write SRAM 382*b92f8445Sssszwic io.meta_write.bits.generate(tag = getPhyTagFromBlk(mshr_resp.bits.blkPaddr), 383*b92f8445Sssszwic idx = mshr_resp.bits.vSetIdx, 384*b92f8445Sssszwic waymask = waymask, 385*b92f8445Sssszwic bankIdx = mshr_resp.bits.vSetIdx(0)) 386*b92f8445Sssszwic io.data_write.bits.generate(data = respDataReg.asUInt, 387*b92f8445Sssszwic idx = mshr_resp.bits.vSetIdx, 388*b92f8445Sssszwic waymask = waymask, 389*b92f8445Sssszwic bankIdx = mshr_resp.bits.vSetIdx(0)) 390*b92f8445Sssszwic 391*b92f8445Sssszwic io.meta_write.valid := write_sram_valid 392*b92f8445Sssszwic io.data_write.valid := write_sram_valid 393*b92f8445Sssszwic 394*b92f8445Sssszwic // response fetch 395*b92f8445Sssszwic io.fetch_resp.valid := fetch_resp_valid 396*b92f8445Sssszwic io.fetch_resp.bits.blkPaddr := mshr_resp.bits.blkPaddr 397*b92f8445Sssszwic io.fetch_resp.bits.vSetIdx := mshr_resp.bits.vSetIdx 398*b92f8445Sssszwic io.fetch_resp.bits.waymask := waymask 399*b92f8445Sssszwic io.fetch_resp.bits.data := respDataReg.asUInt 400*b92f8445Sssszwic io.fetch_resp.bits.corrupt := corrupt_r 401*b92f8445Sssszwic 402*b92f8445Sssszwic /** 403*b92f8445Sssszwic ****************************************************************************** 404*b92f8445Sssszwic * performance counter 405*b92f8445Sssszwic ****************************************************************************** 406*b92f8445Sssszwic */ 407*b92f8445Sssszwic // Duplicate requests will be excluded. 408*b92f8445Sssszwic XSPerfAccumulate("enq_fetch_req", fetchDemux.io.in.fire) 409*b92f8445Sssszwic XSPerfAccumulate("enq_prefetch_req", prefetchDemux.io.in.fire) 410*b92f8445Sssszwic 411*b92f8445Sssszwic /** 412*b92f8445Sssszwic ****************************************************************************** 413*b92f8445Sssszwic * ChiselDB: record ICache SRAM write log 414*b92f8445Sssszwic ****************************************************************************** 415*b92f8445Sssszwic */ 416*b92f8445Sssszwic class ICacheSRAMDB(implicit p: Parameters) extends ICacheBundle{ 417*b92f8445Sssszwic val blkPaddr = UInt((PAddrBits - blockOffBits).W) 418*b92f8445Sssszwic val vSetIdx = UInt(idxBits.W) 419*b92f8445Sssszwic val waymask = UInt(log2Ceil(nWays).W) 420*b92f8445Sssszwic } 421*b92f8445Sssszwic 422*b92f8445Sssszwic val isWriteICacheSRAMTable = WireInit(Constantin.createRecord("isWriteICacheSRAMTable" + p(XSCoreParamsKey).HartId.toString)) 423*b92f8445Sssszwic val ICacheSRAMTable = ChiselDB.createTable("ICacheSRAMTable" + p(XSCoreParamsKey).HartId.toString, new ICacheSRAMDB) 424*b92f8445Sssszwic 425*b92f8445Sssszwic val ICacheSRAMDBDumpData = Wire(new ICacheSRAMDB) 426*b92f8445Sssszwic ICacheSRAMDBDumpData.blkPaddr := mshr_resp.bits.blkPaddr 427*b92f8445Sssszwic ICacheSRAMDBDumpData.vSetIdx := mshr_resp.bits.vSetIdx 428*b92f8445Sssszwic ICacheSRAMDBDumpData.waymask := OHToUInt(waymask) 429*b92f8445Sssszwic ICacheSRAMTable.log( 430*b92f8445Sssszwic data = ICacheSRAMDBDumpData, 431*b92f8445Sssszwic en = write_sram_valid, 432*b92f8445Sssszwic clock = clock, 433*b92f8445Sssszwic reset = reset 434*b92f8445Sssszwic ) 435*b92f8445Sssszwic 436*b92f8445Sssszwic /** 437*b92f8445Sssszwic ****************************************************************************** 438*b92f8445Sssszwic * Difftest 439*b92f8445Sssszwic ****************************************************************************** 440*b92f8445Sssszwic */ 441afa866b1Sguohongyu if (env.EnableDifftest) { 442a0c65233SYinan Xu val difftest = DifftestModule(new DiffRefillEvent, dontCare = true) 4437d45a146SYinan Xu difftest.coreid := io.hartId 4447d45a146SYinan Xu difftest.index := 0.U 445*b92f8445Sssszwic difftest.valid := write_sram_valid 446*b92f8445Sssszwic difftest.addr := Cat(mshr_resp.bits.blkPaddr, 0.U(blockOffBits.W)) 447*b92f8445Sssszwic difftest.data := respDataReg.asTypeOf(difftest.data) 448935edac4STang Haojin difftest.idtfr := DontCare 44941cb8b61SJenius } 4501d8f4dcbSJay}