xref: /XiangShan/src/main/scala/xiangshan/cache/mmu/L2TLBMissQueue.scala (revision 6d5ddbce72c9c67dcf0ec08cc682a9545ceb5f6c)
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}