xref: /XiangShan/src/main/scala/xiangshan/cache/mmu/L2TlbPrefetch.scala (revision 51e45dbbf87325e45ff2af6ca86ed6c7eed04464)
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***************************************************************************************/
16package xiangshan.cache.mmu
17
18import chisel3._
19import chisel3.util._
20import org.chipsalliance.cde.config.Parameters
21import xiangshan.{SfenceBundle, XSModule}
22import utils._
23import utility._
24
25class L2TlbPrefetchIO(implicit p: Parameters) extends MMUIOBaseBundle with HasPtwConst {
26  val in = Flipped(ValidIO(new Bundle {
27    val vpn = UInt(vpnLen.W)
28  }))
29  val out = DecoupledIO(new Bundle {
30    val vpn = UInt(vpnLen.W)
31    val source = UInt(bSourceWidth.W)
32  })
33}
34
35class L2TlbPrefetch(implicit p: Parameters) extends XSModule with HasPtwConst {
36  val io = IO(new L2TlbPrefetchIO())
37
38  val OldRecordSize = 4
39  val old_reqs = Reg(Vec(OldRecordSize, UInt(vpnLen.W)))
40  val old_v = RegInit(VecInit(Seq.fill(OldRecordSize)(false.B)))
41  val old_index = RegInit(0.U(log2Ceil(OldRecordSize).W))
42
43  def already_have(vpn: UInt): Bool = {
44    Cat(old_reqs.zip(old_v).map{ case (o,v) => dup(o,vpn) && v}).orR
45  }
46
47  val flush = io.sfence.valid || io.csr.satp.changed
48  val next_line = get_next_line(io.in.bits.vpn)
49  val next_req = RegEnable(next_line, io.in.valid)
50  val input_valid = io.in.valid && !flush && !already_have(next_line)
51  val v = ValidHold(input_valid, io.out.fire, flush)
52
53  io.out.valid := v
54  io.out.bits.vpn := next_req
55  io.out.bits.source := prefetchID.U
56
57  when (io.out.fire) {
58    old_v(old_index) := true.B
59    old_reqs(old_index) := next_req
60    old_index := Mux((old_index === (OldRecordSize-1).U), 0.U, old_index + 1.U)
61  }
62
63  when (flush) {
64    old_v.map(_ := false.B)
65  }
66
67  XSPerfAccumulate("l2tlb_prefetch_input_count", io.in.valid)
68  XSPerfAccumulate("l2tlb_prefetch_valid_count", input_valid)
69  XSPerfAccumulate("l2tlb_prefetch_output_count", io.out.fire)
70}
71