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