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