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 L2TlbWithHptwIdBundle) 30} 31 32class L2TlbPrefetch(implicit p: Parameters) extends XSModule with HasPtwConst { 33 val io = IO(new L2TlbPrefetchIO()) 34 35 val OldRecordSize = 4 36 val old_reqs = Reg(Vec(OldRecordSize, UInt(vpnLen.W))) 37 val old_v = RegInit(VecInit(Seq.fill(OldRecordSize)(false.B))) 38 val old_index = RegInit(0.U(log2Ceil(OldRecordSize).W)) 39 40 def already_have(vpn: UInt): Bool = { 41 Cat(old_reqs.zip(old_v).map{ case (o,v) => dup(o,vpn) && v}).orR 42 } 43 44 val flush = io.sfence.valid || io.csr.satp.changed || io.csr.vsatp.changed || io.csr.hgatp.changed 45 val next_line = get_next_line(io.in.bits.vpn) 46 val next_req = RegEnable(next_line, io.in.valid) 47 val input_valid = io.in.valid && !flush && !already_have(next_line) 48 val v = ValidHold(input_valid, io.out.fire, flush) 49 val s2xlate = Wire(UInt(2.W)) 50 s2xlate := MuxCase(noS2xlate, Seq( 51 (io.csr.priv.virt && io.csr.vsatp.mode =/= 0.U && io.csr.hgatp.mode =/= 0.U) -> allStage, 52 (io.csr.priv.virt && io.csr.vsatp.mode =/= 0.U) -> onlyStage1, 53 (io.csr.priv.virt && io.csr.hgatp.mode =/= 0.U) -> onlyStage2 54 )) 55 io.out.valid := v 56 io.out.bits.req_info.vpn := next_req 57 io.out.bits.req_info.s2xlate := s2xlate 58 io.out.bits.req_info.source := prefetchID.U 59 io.out.bits.isHptwReq := false.B 60 io.out.bits.isLLptw := false.B 61 io.out.bits.hptwId := DontCare 62 63 when (io.out.fire) { 64 old_v(old_index) := true.B 65 old_reqs(old_index) := next_req 66 old_index := Mux((old_index === (OldRecordSize-1).U), 0.U, old_index + 1.U) 67 } 68 69 when (flush) { 70 old_v.map(_ := false.B) 71 } 72 73 XSPerfAccumulate("l2tlb_prefetch_input_count", io.in.valid) 74 XSPerfAccumulate("l2tlb_prefetch_valid_count", input_valid) 75 XSPerfAccumulate("l2tlb_prefetch_output_count", io.out.fire) 76} 77