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