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._ 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