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