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 chisel3._ 201d8f4dcbSJayimport chisel3.util._ 21*cf7d6b7aSMuziimport difftest._ 221d8f4dcbSJayimport freechips.rocketchip.diplomacy.IdRange 23*cf7d6b7aSMuziimport freechips.rocketchip.tilelink._ 241d8f4dcbSJayimport freechips.rocketchip.tilelink.ClientStates._ 251d8f4dcbSJayimport freechips.rocketchip.tilelink.TLPermissions._ 26*cf7d6b7aSMuziimport org.chipsalliance.cde.config.Parameters 27*cf7d6b7aSMuziimport utility._ 28*cf7d6b7aSMuziimport utils._ 291d8f4dcbSJayimport xiangshan._ 301d8f4dcbSJayimport xiangshan.cache._ 311d8f4dcbSJay 321d8f4dcbSJayabstract class ICacheMissUnitModule(implicit p: Parameters) extends XSModule 331d8f4dcbSJay with HasICacheParameters 341d8f4dcbSJay 351d8f4dcbSJayabstract class ICacheMissUnitBundle(implicit p: Parameters) extends XSBundle 361d8f4dcbSJay with HasICacheParameters 371d8f4dcbSJay 38*cf7d6b7aSMuziclass Demultiplexer[T <: Data](val gen: T, val n: Int) extends Module { 391d8f4dcbSJay 40b92f8445Sssszwic /** Hardware module that is used to sequence 1 producers into n consumer. 41b92f8445Sssszwic * Priority is given to lower producer. 42b92f8445Sssszwic */ 43b92f8445Sssszwic require(n >= 2) 44b92f8445Sssszwic val io = IO(new Bundle { 45b92f8445Sssszwic val in = Flipped(DecoupledIO(gen)) 46b92f8445Sssszwic val out = Vec(n, DecoupledIO(gen)) 47b92f8445Sssszwic val chosen = Output(UInt(log2Ceil(n).W)) 48b92f8445Sssszwic }) 49b92f8445Sssszwic 50b92f8445Sssszwic val grant = false.B +: (1 until n).map(i => (0 until i).map(io.out(_).ready).reduce(_ || _)) 51b92f8445Sssszwic for (i <- 0 until n) { 52b92f8445Sssszwic io.out(i).bits := io.in.bits 53b92f8445Sssszwic io.out(i).valid := !grant(i) && io.in.valid 54b92f8445Sssszwic } 55b92f8445Sssszwic 56b92f8445Sssszwic io.in.ready := grant.last || io.out.last.ready 57b92f8445Sssszwic io.chosen := PriorityEncoder(VecInit(io.out.map(_.ready))) 581d8f4dcbSJay} 591d8f4dcbSJay 60*cf7d6b7aSMuziclass MuxBundle[T <: Data](val gen: T, val n: Int) extends Module { 61b92f8445Sssszwic require(n >= 2) 62b92f8445Sssszwic val io = IO(new Bundle { 63b92f8445Sssszwic val sel = Input(UInt(log2Ceil(n).W)) 64b92f8445Sssszwic val in = Flipped(Vec(n, DecoupledIO(gen))) 65b92f8445Sssszwic val out = DecoupledIO(gen) 66b92f8445Sssszwic }) 67b92f8445Sssszwic 68b92f8445Sssszwic io.in <> DontCare 69b92f8445Sssszwic io.out <> DontCare 70b92f8445Sssszwic for (i <- 0 until n) { 71b92f8445Sssszwic when(io.sel === i.U) { 72b92f8445Sssszwic io.out <> io.in(i) 73b92f8445Sssszwic } 74b92f8445Sssszwic io.in(i).ready := (io.sel === i.U) && io.out.ready 75b92f8445Sssszwic } 76b92f8445Sssszwic} 77b92f8445Sssszwic 78b92f8445Sssszwicclass ICacheMissReq(implicit p: Parameters) extends ICacheBundle { 79b92f8445Sssszwic val blkPaddr = UInt((PAddrBits - blockOffBits).W) 80b92f8445Sssszwic val vSetIdx = UInt(idxBits.W) 81b92f8445Sssszwic} 82b92f8445Sssszwic 83b92f8445Sssszwicclass ICacheMissResp(implicit p: Parameters) extends ICacheBundle { 84b92f8445Sssszwic val blkPaddr = UInt((PAddrBits - blockOffBits).W) 85b92f8445Sssszwic val vSetIdx = UInt(idxBits.W) 86b92f8445Sssszwic val waymask = UInt(nWays.W) 871d8f4dcbSJay val data = UInt(blockBits.W) 8858dbdfc2SJay val corrupt = Bool() 891d8f4dcbSJay} 901d8f4dcbSJay 91b92f8445Sssszwicclass LookUpMSHR(implicit p: Parameters) extends ICacheBundle { 92b92f8445Sssszwic val info = ValidIO(new ICacheMissReq) 93b92f8445Sssszwic val hit = Input(Bool()) 941d8f4dcbSJay} 951d8f4dcbSJay 96b92f8445Sssszwicclass MSHRResp(implicit p: Parameters) extends ICacheBundle { 97b92f8445Sssszwic val blkPaddr = UInt((PAddrBits - blockOffBits).W) 98b92f8445Sssszwic val vSetIdx = UInt(idxBits.W) 99b92f8445Sssszwic val waymask = UInt(log2Ceil(nWays).W) 100b92f8445Sssszwic} 101b92f8445Sssszwic 102b92f8445Sssszwicclass MSHRAcquire(edge: TLEdgeOut)(implicit p: Parameters) extends ICacheBundle { 103b92f8445Sssszwic val acquire = new TLBundleA(edge.bundle) 104b92f8445Sssszwic val vSetIdx = UInt(idxBits.W) 105b92f8445Sssszwic} 106b92f8445Sssszwic 107b92f8445Sssszwicclass ICacheMSHR(edge: TLEdgeOut, isFetch: Boolean, ID: Int)(implicit p: Parameters) extends ICacheMissUnitModule { 1081d8f4dcbSJay val io = IO(new Bundle { 1092a6078bfSguohongyu val fencei = Input(Bool()) 110b92f8445Sssszwic val flush = Input(Bool()) 111b92f8445Sssszwic val invalid = Input(Bool()) 112b92f8445Sssszwic val req = Flipped(DecoupledIO(new ICacheMissReq)) 113b92f8445Sssszwic val acquire = DecoupledIO(new MSHRAcquire(edge)) 114b92f8445Sssszwic val lookUps = Flipped(Vec(2, new LookUpMSHR)) 115b92f8445Sssszwic val resp = ValidIO(new MSHRResp) 116b92f8445Sssszwic val victimWay = Input(UInt(log2Ceil(nWays).W)) 1171d8f4dcbSJay }) 1181d8f4dcbSJay 119b92f8445Sssszwic val valid = RegInit(Bool(), false.B) 120b92f8445Sssszwic // this MSHR doesn't respones to fetch and sram 121b92f8445Sssszwic val flush = RegInit(Bool(), false.B) 122b92f8445Sssszwic val fencei = RegInit(Bool(), false.B) 123b92f8445Sssszwic // this MSHR has been issued 124b92f8445Sssszwic val issue = RegInit(Bool(), false.B) 1251d8f4dcbSJay 126b92f8445Sssszwic val blkPaddr = RegInit(UInt((PAddrBits - blockOffBits).W), 0.U) 127b92f8445Sssszwic val vSetIdx = RegInit(UInt(idxBits.W), 0.U) 128b92f8445Sssszwic val waymask = RegInit(UInt(log2Ceil(nWays).W), 0.U) 1291d8f4dcbSJay 130b92f8445Sssszwic // look up and return result at the same cycle 131*cf7d6b7aSMuzi val hits = io.lookUps.map(lookup => 132*cf7d6b7aSMuzi valid && !fencei && !flush && (lookup.info.bits.vSetIdx === vSetIdx) && 133*cf7d6b7aSMuzi (lookup.info.bits.blkPaddr === blkPaddr) 134*cf7d6b7aSMuzi ) 135b92f8445Sssszwic // Decoupling valid and bits 136*cf7d6b7aSMuzi (0 until 2).foreach(i => io.lookUps(i).hit := hits(i)) 1371d8f4dcbSJay 138b92f8445Sssszwic // disable wake up when hit MSHR (fencei is low) 139b92f8445Sssszwic // when(hit) { 140b92f8445Sssszwic // flush := false.B 141b92f8445Sssszwic // } 1422a6078bfSguohongyu 143b92f8445Sssszwic // invalid when the req hasn't been issued 144b92f8445Sssszwic when(io.fencei || io.flush) { 145b92f8445Sssszwic fencei := true.B 146b92f8445Sssszwic flush := true.B 147b92f8445Sssszwic when(!issue) { 148b92f8445Sssszwic valid := false.B 149b92f8445Sssszwic } 150b92f8445Sssszwic } 1511d8f4dcbSJay 152b92f8445Sssszwic // receive request and register 153b92f8445Sssszwic io.req.ready := !valid && !io.flush && !io.fencei 154935edac4STang Haojin when(io.req.fire) { 155b92f8445Sssszwic valid := true.B 156b92f8445Sssszwic flush := false.B 157b92f8445Sssszwic issue := false.B 158b92f8445Sssszwic fencei := false.B 159b92f8445Sssszwic blkPaddr := io.req.bits.blkPaddr 160b92f8445Sssszwic vSetIdx := io.req.bits.vSetIdx 1611d8f4dcbSJay } 1621d8f4dcbSJay 163b92f8445Sssszwic // send request to L2 164b92f8445Sssszwic io.acquire.valid := valid && !issue && !io.flush && !io.fencei 16538160951Sguohongyu val getBlock = edge.Get( 166b92f8445Sssszwic fromSource = ID.U, 167b92f8445Sssszwic toAddress = Cat(blkPaddr, 0.U(blockOffBits.W)), 168*cf7d6b7aSMuzi lgSize = log2Up(cacheParams.blockBytes).U 16938160951Sguohongyu )._2 170b92f8445Sssszwic io.acquire.bits.acquire := getBlock 171b92f8445Sssszwic io.acquire.bits.acquire.user.lift(ReqSourceKey).foreach(_ := MemReqSource.CPUInst.id.U) 172b92f8445Sssszwic io.acquire.bits.vSetIdx := vSetIdx 17338160951Sguohongyu 174b92f8445Sssszwic // get victim way when acquire fire 175b92f8445Sssszwic when(io.acquire.fire) { 176b92f8445Sssszwic issue := true.B 177b92f8445Sssszwic waymask := io.victimWay 178b92f8445Sssszwic } 1791d8f4dcbSJay 180b92f8445Sssszwic // invalid request when grant finish 181b92f8445Sssszwic when(io.invalid) { 182b92f8445Sssszwic valid := false.B 183b92f8445Sssszwic } 1842a25dbb4SJay 185b92f8445Sssszwic // offer the information other than data for write sram and response fetch 186b92f8445Sssszwic io.resp.valid := valid && (!flush && !fencei) 187b92f8445Sssszwic io.resp.bits.blkPaddr := blkPaddr 188b92f8445Sssszwic io.resp.bits.vSetIdx := vSetIdx 189b92f8445Sssszwic io.resp.bits.waymask := waymask 190b92f8445Sssszwic} 191131aa97cSssszwic 192b92f8445Sssszwicclass ICacheMissBundle(edge: TLEdgeOut)(implicit p: Parameters) extends ICacheBundle { 193b92f8445Sssszwic // difftest 194b92f8445Sssszwic val hartId = Input(Bool()) 195b92f8445Sssszwic // control 196b92f8445Sssszwic val fencei = Input(Bool()) 197b92f8445Sssszwic val flush = Input(Bool()) 198b92f8445Sssszwic // fetch 199b92f8445Sssszwic val fetch_req = Flipped(DecoupledIO(new ICacheMissReq)) 200b92f8445Sssszwic val fetch_resp = ValidIO(new ICacheMissResp) 201b92f8445Sssszwic // prefetch 202b92f8445Sssszwic val prefetch_req = Flipped(DecoupledIO(new ICacheMissReq)) 203b92f8445Sssszwic // SRAM Write Req 204b92f8445Sssszwic val meta_write = DecoupledIO(new ICacheMetaWriteBundle) 205b92f8445Sssszwic val data_write = DecoupledIO(new ICacheDataWriteBundle) 206b92f8445Sssszwic // get victim from replacer 207b92f8445Sssszwic val victim = new ReplacerVictim 208b92f8445Sssszwic // Tilelink 209b92f8445Sssszwic val mem_acquire = DecoupledIO(new TLBundleA(edge.bundle)) 210b92f8445Sssszwic val mem_grant = Flipped(DecoupledIO(new TLBundleD(edge.bundle))) 2111d8f4dcbSJay} 2121d8f4dcbSJay 213*cf7d6b7aSMuziclass ICacheMissUnit(edge: TLEdgeOut)(implicit p: Parameters) extends ICacheMissUnitModule { 214b92f8445Sssszwic val io = IO(new ICacheMissBundle(edge)) 2151d8f4dcbSJay 216b92f8445Sssszwic /** 217b92f8445Sssszwic ****************************************************************************** 218b92f8445Sssszwic * fetch have higher priority 219b92f8445Sssszwic * fetch MSHR: lower index have a higher priority 220b92f8445Sssszwic * prefetch MSHR: the prefetchMSHRs earlier have a higher priority 221b92f8445Sssszwic * --------- -------------- ----------- 222b92f8445Sssszwic * ---fetch reg--->| Demux |-----> | fetch MSHR |------>| Arbiter |---acquire---> 223b92f8445Sssszwic * --------- -------------- ----------- 224b92f8445Sssszwic * | fetch MSHR | ^ 225b92f8445Sssszwic * -------------- | 226b92f8445Sssszwic * | 227b92f8445Sssszwic * ----------------- | 228b92f8445Sssszwic * | prefetch MSHR | | 229b92f8445Sssszwic * --------- ----------------- ----------- 230b92f8445Sssszwic * ---fetch reg--->| Demux |----> | prefetch MSHR |---->| Arbiter | 231b92f8445Sssszwic * --------- ----------------- ----------- 232b92f8445Sssszwic * | ....... | 233b92f8445Sssszwic * ----------------- 234b92f8445Sssszwic ****************************************************************************** 235b92f8445Sssszwic */ 2361d8f4dcbSJay 237b92f8445Sssszwic val fetchDemux = Module(new Demultiplexer(new ICacheMissReq, nFetchMshr)) 238b92f8445Sssszwic val prefetchDemux = Module(new Demultiplexer(new ICacheMissReq, nPrefetchMshr)) 239b92f8445Sssszwic val prefetchArb = Module(new MuxBundle(new MSHRAcquire(edge), nPrefetchMshr)) 240b92f8445Sssszwic val acquireArb = Module(new Arbiter(new MSHRAcquire(edge), nFetchMshr + 1)) 241cb6e5d3cSssszwic 242b92f8445Sssszwic // To avoid duplicate request reception. 243b92f8445Sssszwic val fetchHit, prefetchHit = Wire(Bool()) 244b92f8445Sssszwic fetchDemux.io.in <> io.fetch_req 245b92f8445Sssszwic fetchDemux.io.in.valid := io.fetch_req.valid && !fetchHit 246b92f8445Sssszwic io.fetch_req.ready := fetchDemux.io.in.ready || fetchHit 247b92f8445Sssszwic prefetchDemux.io.in <> io.prefetch_req 248b92f8445Sssszwic prefetchDemux.io.in.valid := io.prefetch_req.valid && !prefetchHit 249b92f8445Sssszwic io.prefetch_req.ready := prefetchDemux.io.in.ready || prefetchHit 250b92f8445Sssszwic acquireArb.io.in.last <> prefetchArb.io.out 2511d8f4dcbSJay 252b92f8445Sssszwic // mem_acquire connect 253b92f8445Sssszwic io.mem_acquire.valid := acquireArb.io.out.valid 254b92f8445Sssszwic io.mem_acquire.bits := acquireArb.io.out.bits.acquire 255b92f8445Sssszwic acquireArb.io.out.ready := io.mem_acquire.ready 2561d8f4dcbSJay 257b92f8445Sssszwic val fetchMSHRs = (0 until nFetchMshr).map { i => 258b92f8445Sssszwic val mshr = Module(new ICacheMSHR(edge, true, i)) 259b92f8445Sssszwic mshr.io.flush := false.B 260b92f8445Sssszwic mshr.io.fencei := io.fencei 261b92f8445Sssszwic mshr.io.req <> fetchDemux.io.out(i) 262b92f8445Sssszwic mshr.io.lookUps(0).info.valid := io.fetch_req.valid 263b92f8445Sssszwic mshr.io.lookUps(0).info.bits := io.fetch_req.bits 264b92f8445Sssszwic mshr.io.lookUps(1).info.valid := io.prefetch_req.valid 265b92f8445Sssszwic mshr.io.lookUps(1).info.bits := io.prefetch_req.bits 266b92f8445Sssszwic mshr.io.victimWay := io.victim.way 267b92f8445Sssszwic acquireArb.io.in(i) <> mshr.io.acquire 268b92f8445Sssszwic mshr 2691d8f4dcbSJay } 2701d8f4dcbSJay 271b92f8445Sssszwic val prefetchMSHRs = (0 until nPrefetchMshr).map { i => 272b92f8445Sssszwic val mshr = Module(new ICacheMSHR(edge, false, nFetchMshr + i)) 273b92f8445Sssszwic mshr.io.flush := io.flush 274b92f8445Sssszwic mshr.io.fencei := io.fencei 275b92f8445Sssszwic mshr.io.req <> prefetchDemux.io.out(i) 276b92f8445Sssszwic mshr.io.lookUps(0).info.valid := io.fetch_req.valid 277b92f8445Sssszwic mshr.io.lookUps(0).info.bits := io.fetch_req.bits 278b92f8445Sssszwic mshr.io.lookUps(1).info.valid := io.prefetch_req.valid 279b92f8445Sssszwic mshr.io.lookUps(1).info.bits := io.prefetch_req.bits 280b92f8445Sssszwic mshr.io.victimWay := io.victim.way 281b92f8445Sssszwic prefetchArb.io.in(i) <> mshr.io.acquire 282b92f8445Sssszwic mshr 2837052722fSJay } 2847052722fSJay 28558c354d0Sssszwic /** 28658c354d0Sssszwic ****************************************************************************** 287b92f8445Sssszwic * MSHR look up 288b92f8445Sssszwic * - look up all mshr 28958c354d0Sssszwic ****************************************************************************** 29058c354d0Sssszwic */ 291*cf7d6b7aSMuzi val allMSHRs = fetchMSHRs ++ prefetchMSHRs 292b92f8445Sssszwic val prefetchHitFetchReq = (io.prefetch_req.bits.blkPaddr === io.fetch_req.bits.blkPaddr) && 293b92f8445Sssszwic (io.prefetch_req.bits.vSetIdx === io.fetch_req.bits.vSetIdx) && 294b92f8445Sssszwic io.fetch_req.valid 295b92f8445Sssszwic fetchHit := allMSHRs.map(mshr => mshr.io.lookUps(0).hit).reduce(_ || _) 296b92f8445Sssszwic prefetchHit := allMSHRs.map(mshr => mshr.io.lookUps(1).hit).reduce(_ || _) || prefetchHitFetchReq 29758c354d0Sssszwic 298b92f8445Sssszwic /** 299b92f8445Sssszwic ****************************************************************************** 300b92f8445Sssszwic * prefetchMSHRs priority 301b92f8445Sssszwic * - The requests that enter the prefetchMSHRs earlier have a higher priority in issuing. 302b92f8445Sssszwic * - The order of enqueuing is recorded in FIFO when requset enters MSHRs. 303b92f8445Sssszwic * - The requests are dispatched in the order they are recorded in FIFO. 304b92f8445Sssszwic ****************************************************************************** 305b92f8445Sssszwic */ 306b92f8445Sssszwic // When the FIFO is full, enqueue and dequeue operations do not occur at the same cycle. 307b92f8445Sssszwic // So the depth of the FIFO is set to match the number of MSHRs. 308b92f8445Sssszwic // val priorityFIFO = Module(new Queue(UInt(log2Ceil(nPrefetchMshr).W), nPrefetchMshr, hasFlush=true)) 309b92f8445Sssszwic val priorityFIFO = Module(new FIFOReg(UInt(log2Ceil(nPrefetchMshr).W), nPrefetchMshr, hasFlush = true)) 310b92f8445Sssszwic priorityFIFO.io.flush.get := io.flush || io.fencei 311b92f8445Sssszwic priorityFIFO.io.enq.valid := prefetchDemux.io.in.fire 312b92f8445Sssszwic priorityFIFO.io.enq.bits := prefetchDemux.io.chosen 313b92f8445Sssszwic priorityFIFO.io.deq.ready := prefetchArb.io.out.fire 314b92f8445Sssszwic prefetchArb.io.sel := priorityFIFO.io.deq.bits 315*cf7d6b7aSMuzi assert( 316*cf7d6b7aSMuzi !(priorityFIFO.io.enq.fire ^ prefetchDemux.io.in.fire), 317*cf7d6b7aSMuzi "priorityFIFO.io.enq and io.prefetch_req must fire at the same cycle" 318*cf7d6b7aSMuzi ) 319*cf7d6b7aSMuzi assert( 320*cf7d6b7aSMuzi !(priorityFIFO.io.deq.fire ^ prefetchArb.io.out.fire), 321*cf7d6b7aSMuzi "priorityFIFO.io.deq and prefetchArb.io.out must fire at the same cycle" 322*cf7d6b7aSMuzi ) 3237052722fSJay 324b92f8445Sssszwic /** 325b92f8445Sssszwic ****************************************************************************** 326b92f8445Sssszwic * Tilelink D channel (grant) 327b92f8445Sssszwic ****************************************************************************** 328b92f8445Sssszwic */ 329b92f8445Sssszwic // cacheline register 330b92f8445Sssszwic val readBeatCnt = RegInit(UInt(log2Up(refillCycles).W), 0.U) 331b92f8445Sssszwic val respDataReg = RegInit(VecInit(Seq.fill(refillCycles)(0.U(beatBits.W)))) 3321d8f4dcbSJay 333b92f8445Sssszwic val wait_last = readBeatCnt === (refillCycles - 1).U 334b92f8445Sssszwic when(io.mem_grant.fire && edge.hasData(io.mem_grant.bits)) { 335b92f8445Sssszwic respDataReg(readBeatCnt) := io.mem_grant.bits.data 33633a531f0Sxu_zh readBeatCnt := Mux(wait_last, 0.U, readBeatCnt + 1.U) 337b92f8445Sssszwic } 338b92f8445Sssszwic 339b92f8445Sssszwic // last transition finsh or corrupt 34033a531f0Sxu_zh val last_fire = io.mem_grant.fire && edge.hasData(io.mem_grant.bits) && wait_last 341b92f8445Sssszwic 342b92f8445Sssszwic val (_, _, refill_done, _) = edge.addr_inc(io.mem_grant) 343b92f8445Sssszwic assert(!(refill_done ^ last_fire), "refill not done!") 344b92f8445Sssszwic io.mem_grant.ready := true.B 345b92f8445Sssszwic 346b92f8445Sssszwic val last_fire_r = RegNext(last_fire) 347b92f8445Sssszwic val id_r = RegNext(io.mem_grant.bits.source) 34833a531f0Sxu_zh 34933a531f0Sxu_zh // if any beat is corrupt, the whole response (to mainPipe/metaArray/dataArray) is corrupt 35033a531f0Sxu_zh val corrupt_r = RegInit(false.B) 35133a531f0Sxu_zh when(io.mem_grant.fire && edge.hasData(io.mem_grant.bits) && io.mem_grant.bits.corrupt) { 35233a531f0Sxu_zh corrupt_r := true.B 35333a531f0Sxu_zh }.elsewhen(io.fetch_resp.fire) { 35433a531f0Sxu_zh corrupt_r := false.B 35533a531f0Sxu_zh } 356b92f8445Sssszwic 357b92f8445Sssszwic /** 358b92f8445Sssszwic ****************************************************************************** 359b92f8445Sssszwic * invalid mshr when finish transition 360b92f8445Sssszwic ****************************************************************************** 361b92f8445Sssszwic */ 362*cf7d6b7aSMuzi (0 until (nFetchMshr + nPrefetchMshr)).foreach(i => allMSHRs(i).io.invalid := last_fire_r && (id_r === i.U)) 363b92f8445Sssszwic 364b92f8445Sssszwic /** 365b92f8445Sssszwic ****************************************************************************** 366b92f8445Sssszwic * response fetch and write SRAM 367b92f8445Sssszwic ****************************************************************************** 368b92f8445Sssszwic */ 369b92f8445Sssszwic // get request information from MSHRs 370b92f8445Sssszwic val allMSHRs_resp = VecInit(allMSHRs.map(mshr => mshr.io.resp)) 371b92f8445Sssszwic val mshr_resp = allMSHRs_resp(id_r) 372b92f8445Sssszwic 373b92f8445Sssszwic // get waymask from replacer when acquire fire 3747a63335aSxu_zh io.victim.vSetIdx.valid := acquireArb.io.out.fire 375b92f8445Sssszwic io.victim.vSetIdx.bits := acquireArb.io.out.bits.vSetIdx 376b92f8445Sssszwic val waymask = UIntToOH(mshr_resp.bits.waymask) 377adf97c94Sxu_zh // NOTE: when flush/fencei, missUnit will still send response to mainPipe/prefetchPipe 378adf97c94Sxu_zh // this is intentional to fix timing (io.flush -> mainPipe/prefetchPipe s2_miss -> s2_ready -> ftq ready) 379adf97c94Sxu_zh // unnecessary response will be dropped by mainPipe/prefetchPipe/wayLookup since their sx_valid is set to false 380adf97c94Sxu_zh val fetch_resp_valid = mshr_resp.valid && last_fire_r 381adf97c94Sxu_zh // NOTE: but we should not write meta/dataArray when flush/fencei 382adf97c94Sxu_zh val write_sram_valid = fetch_resp_valid && !corrupt_r && !io.flush && !io.fencei 383b92f8445Sssszwic 384b92f8445Sssszwic // write SRAM 385*cf7d6b7aSMuzi io.meta_write.bits.generate( 386*cf7d6b7aSMuzi tag = getPhyTagFromBlk(mshr_resp.bits.blkPaddr), 387b92f8445Sssszwic idx = mshr_resp.bits.vSetIdx, 388b92f8445Sssszwic waymask = waymask, 389*cf7d6b7aSMuzi bankIdx = mshr_resp.bits.vSetIdx(0) 390*cf7d6b7aSMuzi ) 391*cf7d6b7aSMuzi io.data_write.bits.generate( 392*cf7d6b7aSMuzi data = respDataReg.asUInt, 393b92f8445Sssszwic idx = mshr_resp.bits.vSetIdx, 394b92f8445Sssszwic waymask = waymask, 395*cf7d6b7aSMuzi bankIdx = mshr_resp.bits.vSetIdx(0) 396*cf7d6b7aSMuzi ) 397b92f8445Sssszwic 398b92f8445Sssszwic io.meta_write.valid := write_sram_valid 399b92f8445Sssszwic io.data_write.valid := write_sram_valid 400b92f8445Sssszwic 401b92f8445Sssszwic // response fetch 402b92f8445Sssszwic io.fetch_resp.valid := fetch_resp_valid 403b92f8445Sssszwic io.fetch_resp.bits.blkPaddr := mshr_resp.bits.blkPaddr 404b92f8445Sssszwic io.fetch_resp.bits.vSetIdx := mshr_resp.bits.vSetIdx 405b92f8445Sssszwic io.fetch_resp.bits.waymask := waymask 406b92f8445Sssszwic io.fetch_resp.bits.data := respDataReg.asUInt 407b92f8445Sssszwic io.fetch_resp.bits.corrupt := corrupt_r 408b92f8445Sssszwic 409b92f8445Sssszwic /** 410b92f8445Sssszwic ****************************************************************************** 411b92f8445Sssszwic * performance counter 412b92f8445Sssszwic ****************************************************************************** 413b92f8445Sssszwic */ 414b92f8445Sssszwic // Duplicate requests will be excluded. 415b92f8445Sssszwic XSPerfAccumulate("enq_fetch_req", fetchDemux.io.in.fire) 416b92f8445Sssszwic XSPerfAccumulate("enq_prefetch_req", prefetchDemux.io.in.fire) 417b92f8445Sssszwic 418b92f8445Sssszwic /** 419b92f8445Sssszwic ****************************************************************************** 420b92f8445Sssszwic * ChiselDB: record ICache SRAM write log 421b92f8445Sssszwic ****************************************************************************** 422b92f8445Sssszwic */ 423b92f8445Sssszwic class ICacheSRAMDB(implicit p: Parameters) extends ICacheBundle { 424b92f8445Sssszwic val blkPaddr = UInt((PAddrBits - blockOffBits).W) 425b92f8445Sssszwic val vSetIdx = UInt(idxBits.W) 426b92f8445Sssszwic val waymask = UInt(log2Ceil(nWays).W) 427b92f8445Sssszwic } 428b92f8445Sssszwic 429*cf7d6b7aSMuzi val isWriteICacheSRAMTable = 430*cf7d6b7aSMuzi WireInit(Constantin.createRecord("isWriteICacheSRAMTable" + p(XSCoreParamsKey).HartId.toString)) 431b92f8445Sssszwic val ICacheSRAMTable = ChiselDB.createTable("ICacheSRAMTable" + p(XSCoreParamsKey).HartId.toString, new ICacheSRAMDB) 432b92f8445Sssszwic 433b92f8445Sssszwic val ICacheSRAMDBDumpData = Wire(new ICacheSRAMDB) 434b92f8445Sssszwic ICacheSRAMDBDumpData.blkPaddr := mshr_resp.bits.blkPaddr 435b92f8445Sssszwic ICacheSRAMDBDumpData.vSetIdx := mshr_resp.bits.vSetIdx 436b92f8445Sssszwic ICacheSRAMDBDumpData.waymask := OHToUInt(waymask) 437b92f8445Sssszwic ICacheSRAMTable.log( 438b92f8445Sssszwic data = ICacheSRAMDBDumpData, 439b92f8445Sssszwic en = write_sram_valid, 440b92f8445Sssszwic clock = clock, 441b92f8445Sssszwic reset = reset 442b92f8445Sssszwic ) 443b92f8445Sssszwic 444b92f8445Sssszwic /** 445b92f8445Sssszwic ****************************************************************************** 446b92f8445Sssszwic * Difftest 447b92f8445Sssszwic ****************************************************************************** 448b92f8445Sssszwic */ 449afa866b1Sguohongyu if (env.EnableDifftest) { 450a0c65233SYinan Xu val difftest = DifftestModule(new DiffRefillEvent, dontCare = true) 4517d45a146SYinan Xu difftest.coreid := io.hartId 4527d45a146SYinan Xu difftest.index := 0.U 453b92f8445Sssszwic difftest.valid := write_sram_valid 454b92f8445Sssszwic difftest.addr := Cat(mshr_resp.bits.blkPaddr, 0.U(blockOffBits.W)) 455b92f8445Sssszwic difftest.data := respDataReg.asTypeOf(difftest.data) 456935edac4STang Haojin difftest.idtfr := DontCare 45741cb8b61SJenius } 4581d8f4dcbSJay} 459