1/*************************************************************************************** 2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3* Copyright (c) 2020-2021 Peng Cheng Laboratory 4* 5* XiangShan is licensed under Mulan PSL v2. 6* You can use this software according to the terms and conditions of the Mulan PSL v2. 7* You may obtain a copy of Mulan PSL v2 at: 8* http://license.coscl.org.cn/MulanPSL2 9* 10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13* 14* See the Mulan PSL v2 for more details. 15***************************************************************************************/ 16 17package xiangshan.cache.mmu 18 19import chipsalliance.rocketchip.config.Parameters 20import chisel3._ 21import chisel3.util._ 22import xiangshan._ 23import xiangshan.cache.{HasDCacheParameters, MemoryOpConstants} 24import utils._ 25import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp} 26import freechips.rocketchip.tilelink._ 27 28/* Miss Queue dont care about duplicate req, which is done by PtwFilter 29 * PtwMissQueue is just a Queue inside Chisel with flush 30 */ 31class PtwMissQueue(implicit p: Parameters) extends XSModule with HasPtwConst { 32 val io = IO(new Bundle { 33 val in = Flipped(Decoupled(new Bundle { 34 val vpn = UInt(vpnLen.W) 35 val source = UInt(bPtwWidth.W) 36 })) 37 val sfence = Input(new SfenceBundle) 38 val out = Decoupled(new Bundle { 39 val vpn = UInt(vpnLen.W) 40 val source = UInt(bPtwWidth.W) 41 }) 42 val empty = Output(Bool()) 43 }) 44 45 val vpn = Reg(Vec(MSHRSize, UInt(vpnLen.W))) // request vpn 46 val source = Reg(Vec(MSHRSize, UInt(bPtwWidth.W))) // is itlb 47 val enqPtr = RegInit(0.U(log2Up(MSHRSize).W)) 48 val deqPtr = RegInit(0.U(log2Up(MSHRSize).W)) 49 50 val mayFull = RegInit(false.B) 51 val full = mayFull && enqPtr === deqPtr 52 val empty = !mayFull && enqPtr === deqPtr 53 54 val do_enq = io.in.fire() 55 val do_deq = io.out.fire() 56 57 when (do_enq) { 58 enqPtr := enqPtr + 1.U 59 vpn(enqPtr) := io.in.bits.vpn 60 source(enqPtr) := io.in.bits.source 61 } 62 63 when (do_deq) { 64 deqPtr := deqPtr + 1.U 65 } 66 67 when (do_enq =/= do_deq) { 68 mayFull := do_enq 69 } 70 71 when (io.sfence.valid) { 72 enqPtr := 0.U 73 deqPtr := 0.U 74 mayFull := false.B 75 } 76 77 io.in.ready := !full 78 io.out.valid := !empty 79 io.out.bits.vpn := vpn(deqPtr) 80 io.out.bits.source := source(deqPtr) 81 io.empty := empty 82 83 XSPerfAccumulate("mq_in_count", io.in.fire()) 84 XSPerfAccumulate("mq_in_block", io.in.valid && !io.in.ready) 85 val count = RegInit(0.U(log2Up(MSHRSize+1).W)) 86 when (do_enq =/= do_deq) { 87 count := Mux(do_enq, count + 1.U, count - 1.U) 88 } 89 when (io.sfence.valid) { 90 count := 0.U 91 } 92 for (i <- 0 until MSHRSize) { 93 XSPerfAccumulate(s"numExist${i}", count === i.U) 94 } 95}