16d5ddbceSLemover/*************************************************************************************** 26d5ddbceSLemover* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3f320e0f0SYinan Xu* Copyright (c) 2020-2021 Peng Cheng Laboratory 46d5ddbceSLemover* 56d5ddbceSLemover* XiangShan is licensed under Mulan PSL v2. 66d5ddbceSLemover* You can use this software according to the terms and conditions of the Mulan PSL v2. 76d5ddbceSLemover* You may obtain a copy of Mulan PSL v2 at: 86d5ddbceSLemover* http://license.coscl.org.cn/MulanPSL2 96d5ddbceSLemover* 106d5ddbceSLemover* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 116d5ddbceSLemover* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 126d5ddbceSLemover* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 136d5ddbceSLemover* 146d5ddbceSLemover* See the Mulan PSL v2 for more details. 156d5ddbceSLemover***************************************************************************************/ 166d5ddbceSLemover 176d5ddbceSLemoverpackage xiangshan.cache.mmu 186d5ddbceSLemover 196d5ddbceSLemoverimport chipsalliance.rocketchip.config.Parameters 206d5ddbceSLemoverimport chisel3._ 21a0301c0dSLemoverimport chisel3.internal.naming.chiselName 226d5ddbceSLemoverimport chisel3.util._ 23a0301c0dSLemoverimport freechips.rocketchip.util.SRAMAnnotation 246d5ddbceSLemoverimport xiangshan._ 256d5ddbceSLemoverimport utils._ 26*b6982e83SLemoverimport xiangshan.backend.fu.{PMPChecker, PMPReqBundle} 279aca92b9SYinan Xuimport xiangshan.backend.rob.RobPtr 286d5ddbceSLemoverimport xiangshan.backend.fu.util.HasCSRConst 296d5ddbceSLemover 30a0301c0dSLemover 31a0301c0dSLemover@chiselName 32a0301c0dSLemoverclass TLB(Width: Int, q: TLBParameters)(implicit p: Parameters) extends TlbModule with HasCSRConst { 33a0301c0dSLemover val io = IO(new TlbIO(Width, q)) 34a0301c0dSLemover 35a0301c0dSLemover require(q.superAssociative == "fa") 36a0301c0dSLemover if (q.sameCycle) { 37a0301c0dSLemover require(q.normalAssociative == "fa") 38a0301c0dSLemover } 396d5ddbceSLemover 406d5ddbceSLemover val req = io.requestor.map(_.req) 416d5ddbceSLemover val resp = io.requestor.map(_.resp) 426d5ddbceSLemover val ptw = io.ptw 43*b6982e83SLemover val pmp = io.pmp 446d5ddbceSLemover 456d5ddbceSLemover val sfence = io.sfence 466d5ddbceSLemover val csr = io.csr 476d5ddbceSLemover val satp = csr.satp 486d5ddbceSLemover val priv = csr.priv 49a0301c0dSLemover val ifecth = if (q.fetchi) true.B else false.B 50a0301c0dSLemover val mode = if (q.useDmode) priv.dmode else priv.imode 516d5ddbceSLemover // val vmEnable = satp.mode === 8.U // && (mode < ModeM) // FIXME: fix me when boot xv6/linux... 526d5ddbceSLemover val vmEnable = if (EnbaleTlbDebug) (satp.mode === 8.U) 536d5ddbceSLemover else (satp.mode === 8.U && (mode < ModeM)) 546d5ddbceSLemover 55a0301c0dSLemover val reqAddr = req.map(_.bits.vaddr.asTypeOf((new VaBundle).cloneType)) 56a0301c0dSLemover val vpn = reqAddr.map(_.vpn) 576d5ddbceSLemover val cmd = req.map(_.bits.cmd) 586d5ddbceSLemover val valid = req.map(_.valid) 596d5ddbceSLemover 606d5ddbceSLemover def widthMapSeq[T <: Seq[Data]](f: Int => T) = (0 until Width).map(f) 61a0301c0dSLemover 626d5ddbceSLemover def widthMap[T <: Data](f: Int => T) = (0 until Width).map(f) 636d5ddbceSLemover 646d5ddbceSLemover // Normal page && Super page 65a0301c0dSLemover val normalPage = TlbStorage( 66a0301c0dSLemover name = "normal", 67a0301c0dSLemover associative = q.normalAssociative, 68a0301c0dSLemover sameCycle = q.sameCycle, 69a0301c0dSLemover ports = Width, 70a0301c0dSLemover nSets = q.normalNSets, 71a0301c0dSLemover nWays = q.normalNWays, 72a0301c0dSLemover sramSinglePort = sramSinglePort, 73a0301c0dSLemover normalPage = true, 74a0301c0dSLemover superPage = false 756d5ddbceSLemover ) 76a0301c0dSLemover val superPage = TlbStorage( 77a0301c0dSLemover name = "super", 78a0301c0dSLemover associative = q.superAssociative, 79a0301c0dSLemover sameCycle = q.sameCycle, 80a0301c0dSLemover ports = Width, 81a0301c0dSLemover nSets = q.superNSets, 82a0301c0dSLemover nWays = q.superNWays, 83a0301c0dSLemover sramSinglePort = sramSinglePort, 84a0301c0dSLemover normalPage = q.normalAsVictim, 85a0301c0dSLemover superPage = true, 866d5ddbceSLemover ) 876d5ddbceSLemover 88a0301c0dSLemover 896d5ddbceSLemover for (i <- 0 until Width) { 90a0301c0dSLemover normalPage.r_req_apply( 91a0301c0dSLemover valid = io.requestor(i).req.valid, 92a0301c0dSLemover vpn = vpn(i), 93a0301c0dSLemover i = i 946d5ddbceSLemover ) 95a0301c0dSLemover superPage.r_req_apply( 96a0301c0dSLemover valid = io.requestor(i).req.valid, 97a0301c0dSLemover vpn = vpn(i), 98a0301c0dSLemover i = i 99a0301c0dSLemover ) 100a0301c0dSLemover } 1016d5ddbceSLemover 1026d5ddbceSLemover 103a0301c0dSLemover normalPage.victim.in <> superPage.victim.out 104a0301c0dSLemover normalPage.victim.out <> superPage.victim.in 105a0301c0dSLemover normalPage.sfence <> io.sfence 106a0301c0dSLemover superPage.sfence <> io.sfence 107149086eaSLemover 108a0301c0dSLemover def TLBNormalRead(i: Int) = { 109a0301c0dSLemover val (normal_hit, normal_ppn, normal_perm, normal_hitVec) = normalPage.r_resp_apply(i) 110a0301c0dSLemover val (super_hit, super_ppn, super_perm, super_hitVec) = superPage.r_resp_apply(i) 111a0301c0dSLemover assert(!(normal_hit && super_hit && vmEnable && RegNext(req(i).valid, init = false.B))) 1126d5ddbceSLemover 113a0301c0dSLemover val hit = normal_hit || super_hit 114a0301c0dSLemover val ppn = Mux(normal_hit, normal_ppn, super_ppn) 115a0301c0dSLemover val perm = Mux(normal_hit, normal_perm, super_perm) 116a0301c0dSLemover 117a0301c0dSLemover val pf = perm.pf && hit 118*b6982e83SLemover val af = perm.af && hit 119a0301c0dSLemover val cmdReg = if (!q.sameCycle) RegNext(cmd(i)) else cmd(i) 120a0301c0dSLemover val validReg = if (!q.sameCycle) RegNext(valid(i)) else valid(i) 121a0301c0dSLemover val offReg = if (!q.sameCycle) RegNext(reqAddr(i).off) else reqAddr(i).off 122*b6982e83SLemover val sizeReg = if (!q.sameCycle) RegNext(req(i).bits.size) else req(i).bits.size 123a0301c0dSLemover 124a0301c0dSLemover /** *************** next cycle when two cycle is false******************* */ 125a0301c0dSLemover val miss = !hit && vmEnable 1266d5ddbceSLemover hit.suggestName(s"hit_${i}") 1276d5ddbceSLemover miss.suggestName(s"miss_${i}") 1286d5ddbceSLemover 129a0301c0dSLemover XSDebug(validReg, p"(${i.U}) hit:${hit} miss:${miss} ppn:${Hexadecimal(ppn)} perm:${perm}\n") 1306d5ddbceSLemover 131a0301c0dSLemover val paddr = Cat(ppn, offReg) 1326d5ddbceSLemover val vaddr = SignExt(req(i).bits.vaddr, PAddrBits) 1336d5ddbceSLemover 1346d5ddbceSLemover req(i).ready := resp(i).ready 1356d5ddbceSLemover resp(i).valid := validReg 136a0301c0dSLemover resp(i).bits.paddr := Mux(vmEnable, paddr, if (!q.sameCycle) RegNext(vaddr) else vaddr) 1376d5ddbceSLemover resp(i).bits.miss := miss 1386d5ddbceSLemover resp(i).bits.ptwBack := io.ptw.resp.fire() 1396d5ddbceSLemover 140*b6982e83SLemover pmp(i).valid := resp(i).valid 141*b6982e83SLemover pmp(i).bits.addr := resp(i).bits.paddr 142*b6982e83SLemover pmp(i).bits.size := sizeReg 143*b6982e83SLemover pmp(i).bits.cmd := cmdReg 144*b6982e83SLemover 145a0301c0dSLemover val update = hit && (!perm.a || !perm.d && TlbCmd.isWrite(cmdReg)) // update A/D through exception 1466d5ddbceSLemover val modeCheck = !(mode === ModeU && !perm.u || mode === ModeS && perm.u && (!priv.sum || ifecth)) 147a0301c0dSLemover val ldPf = !(modeCheck && (perm.r || priv.mxr && perm.x)) && (TlbCmd.isRead(cmdReg) && true.B /* TODO !isAMO*/) 148a0301c0dSLemover val stPf = !(modeCheck && perm.w) && (TlbCmd.isWrite(cmdReg) || false.B /*TODO isAMO. */) 149a0301c0dSLemover val instrPf = !(modeCheck && perm.x) && TlbCmd.isExec(cmdReg) 150*b6982e83SLemover resp(i).bits.excp.pf.ld := (ldPf || update || pf) && vmEnable && hit && !af 151*b6982e83SLemover resp(i).bits.excp.pf.st := (stPf || update || pf) && vmEnable && hit && !af 152*b6982e83SLemover resp(i).bits.excp.pf.instr := (instrPf || update || pf) && vmEnable && hit && !af 153*b6982e83SLemover // NOTE: pf need && with !af, page fault has higher priority than access fault 154*b6982e83SLemover // but ptw may also have access fault, then af happens, the translation is wrong. 155*b6982e83SLemover // In this case, pf has lower priority than af 1566d5ddbceSLemover 1576d5ddbceSLemover // if vmenable, use pre-calcuated pma check result 158a0301c0dSLemover resp(i).bits.mmio := Mux(TlbCmd.isExec(cmdReg), !perm.pi, !perm.pd) && vmEnable && hit 159*b6982e83SLemover resp(i).bits.excp.af.ld := (af || Mux(TlbCmd.isAtom(cmdReg), !perm.pa, !perm.pr) && TlbCmd.isRead(cmdReg)) && vmEnable && hit 160*b6982e83SLemover resp(i).bits.excp.af.st := (af || Mux(TlbCmd.isAtom(cmdReg), !perm.pa, !perm.pw) && TlbCmd.isWrite(cmdReg)) && vmEnable && hit 161*b6982e83SLemover resp(i).bits.excp.af.instr := (af || Mux(TlbCmd.isAtom(cmdReg), false.B, !perm.pe)) && vmEnable && hit 1626d5ddbceSLemover 1636d5ddbceSLemover // if !vmenable, check pma 1646d5ddbceSLemover val (pmaMode, accessWidth) = AddressSpace.memmapAddrMatch(resp(i).bits.paddr) 1656d5ddbceSLemover when(!vmEnable) { 1666d5ddbceSLemover resp(i).bits.mmio := Mux(TlbCmd.isExec(cmdReg), !PMAMode.icache(pmaMode), !PMAMode.dcache(pmaMode)) 1676d5ddbceSLemover resp(i).bits.excp.af.ld := Mux(TlbCmd.isAtom(cmdReg), !PMAMode.atomic(pmaMode), !PMAMode.read(pmaMode)) && TlbCmd.isRead(cmdReg) 1686d5ddbceSLemover resp(i).bits.excp.af.st := Mux(TlbCmd.isAtom(cmdReg), !PMAMode.atomic(pmaMode), !PMAMode.write(pmaMode)) && TlbCmd.isWrite(cmdReg) 1696d5ddbceSLemover resp(i).bits.excp.af.instr := Mux(TlbCmd.isAtom(cmdReg), false.B, !PMAMode.execute(pmaMode)) 1706d5ddbceSLemover } 1716d5ddbceSLemover 172a0301c0dSLemover (hit, miss, normal_hitVec, super_hitVec, validReg) 1736d5ddbceSLemover } 1746d5ddbceSLemover 1756d5ddbceSLemover val readResult = (0 until Width).map(TLBNormalRead(_)) 176a0301c0dSLemover val hitVec = readResult.map(_._1) 177a0301c0dSLemover val missVec = readResult.map(_._2) 178a0301c0dSLemover val normalhitVecVec = readResult.map(_._3) 179a0301c0dSLemover val superhitVecVec = readResult.map(_._4) 180a0301c0dSLemover val validRegVec = readResult.map(_._5) 1816d5ddbceSLemover 182149086eaSLemover // replacement 183a0301c0dSLemover def get_access(one_hot: UInt, valid: Bool): Valid[UInt] = { 184149086eaSLemover val res = Wire(Valid(UInt(log2Up(one_hot.getWidth).W))) 185a0301c0dSLemover res.valid := Cat(one_hot).orR && valid 186149086eaSLemover res.bits := OHToUInt(one_hot) 187149086eaSLemover res 188149086eaSLemover } 189a0301c0dSLemover 190a0301c0dSLemover val normal_refill_idx = if (q.outReplace) { 191a0301c0dSLemover io.replace.normalPage.access.sets := vpn.map(get_idx(_, q.normalNSets)) 192a0301c0dSLemover io.replace.normalPage.access.touch_ways := normalhitVecVec.zipWithIndex.map{ case (hv, i) => get_access(hv, 193a0301c0dSLemover validRegVec(i))} 194a0301c0dSLemover io.replace.normalPage.chosen_set := get_idx(io.ptw.resp.bits.entry.tag, q.normalNSets) 195a0301c0dSLemover io.replace.normalPage.refillIdx 196a0301c0dSLemover } else if (q.normalAssociative == "fa") { 197a0301c0dSLemover val re = ReplacementPolicy.fromString(q.normalReplacer, q.normalNWays) 198a0301c0dSLemover re.access(normalhitVecVec.zipWithIndex.map{ case (hv, i) => get_access(hv, validRegVec(i))}) 199a0301c0dSLemover re.way 200a0301c0dSLemover } else { // set-acco && plru 201a0301c0dSLemover val re = ReplacementPolicy.fromString(q.normalReplacer, q.normalNSets, q.normalNWays) 202a0301c0dSLemover re.access(vpn.map(get_idx(_, q.normalNSets)), normalhitVecVec.zipWithIndex.map{ case (hv, i) => get_access(hv, 203a0301c0dSLemover validRegVec(i))}) 204a0301c0dSLemover re.way(get_idx(io.ptw.resp.bits.entry.tag, q.normalNSets)) 205149086eaSLemover } 206a0301c0dSLemover 207a0301c0dSLemover val super_refill_idx = if (q.outReplace) { 208a0301c0dSLemover io.replace.superPage.access.sets := vpn.map(get_idx(_, q.normalNSets)) 209a0301c0dSLemover io.replace.superPage.access.touch_ways := superhitVecVec.zipWithIndex.map{ case (hv, i) => get_access(hv, 210a0301c0dSLemover validRegVec(i))} 211a0301c0dSLemover io.replace.superPage.chosen_set := DontCare 212a0301c0dSLemover io.replace.superPage.refillIdx 213149086eaSLemover } else { 214a0301c0dSLemover val re = ReplacementPolicy.fromString(q.superReplacer, q.superNWays) 215a0301c0dSLemover re.access(superhitVecVec.zipWithIndex.map{ case (hv, i) => get_access(hv, validRegVec(i))}) 216a0301c0dSLemover re.way 217149086eaSLemover } 218149086eaSLemover 219a0301c0dSLemover val refill = ptw.resp.fire() && !sfence.valid 220a0301c0dSLemover normalPage.w_apply( 221a0301c0dSLemover valid = { if (q.normalAsVictim) false.B 222a0301c0dSLemover else refill && ptw.resp.bits.entry.level.get === 2.U }, 223a0301c0dSLemover wayIdx = normal_refill_idx, 224a0301c0dSLemover data = ptw.resp.bits 225a0301c0dSLemover ) 226a0301c0dSLemover superPage.w_apply( 227a0301c0dSLemover valid = { if (q.normalAsVictim) refill 228a0301c0dSLemover else refill && ptw.resp.bits.entry.level.get =/= 2.U }, 229a0301c0dSLemover wayIdx = super_refill_idx, 230a0301c0dSLemover data = ptw.resp.bits 231a0301c0dSLemover ) 232a0301c0dSLemover 2336d5ddbceSLemover for (i <- 0 until Width) { 2346d5ddbceSLemover io.ptw.req(i).valid := validRegVec(i) && missVec(i) && !RegNext(refill) 2356d5ddbceSLemover io.ptw.req(i).bits.vpn := RegNext(reqAddr(i).vpn) 2366d5ddbceSLemover } 2376d5ddbceSLemover io.ptw.resp.ready := true.B 2386d5ddbceSLemover 239a0301c0dSLemover if (!q.shouldBlock) { 2406d5ddbceSLemover for (i <- 0 until Width) { 2416d5ddbceSLemover XSPerfAccumulate("first_access" + Integer.toString(i, 10), validRegVec(i) && vmEnable && RegNext(req(i).bits.debug.isFirstIssue)) 2426d5ddbceSLemover XSPerfAccumulate("access" + Integer.toString(i, 10), validRegVec(i) && vmEnable) 2436d5ddbceSLemover } 2446d5ddbceSLemover for (i <- 0 until Width) { 2456d5ddbceSLemover XSPerfAccumulate("first_miss" + Integer.toString(i, 10), validRegVec(i) && vmEnable && missVec(i) && RegNext(req(i).bits.debug.isFirstIssue)) 2466d5ddbceSLemover XSPerfAccumulate("miss" + Integer.toString(i, 10), validRegVec(i) && vmEnable && missVec(i)) 2476d5ddbceSLemover } 2486d5ddbceSLemover } else { 2496d5ddbceSLemover // NOTE: ITLB is blocked, so every resp will be valid only when hit 2506d5ddbceSLemover // every req will be ready only when hit 251a0301c0dSLemover for (i <- 0 until Width) { 252a0301c0dSLemover XSPerfAccumulate(s"access${i}", io.requestor(i).req.fire() && vmEnable) 253a0301c0dSLemover XSPerfAccumulate(s"miss${i}", ptw.req(i).fire()) 254a0301c0dSLemover } 255a0301c0dSLemover 2566d5ddbceSLemover } 2576d5ddbceSLemover //val reqCycleCnt = Reg(UInt(16.W)) 2586d5ddbceSLemover //reqCycleCnt := reqCycleCnt + BoolStopWatch(ptw.req(0).fire(), ptw.resp.fire || sfence.valid) 2596d5ddbceSLemover //XSPerfAccumulate("ptw_req_count", ptw.req.fire()) 2606d5ddbceSLemover //XSPerfAccumulate("ptw_req_cycle", Mux(ptw.resp.fire(), reqCycleCnt, 0.U)) 2616d5ddbceSLemover XSPerfAccumulate("ptw_resp_count", ptw.resp.fire()) 2626d5ddbceSLemover XSPerfAccumulate("ptw_resp_pf_count", ptw.resp.fire() && ptw.resp.bits.pf) 2636d5ddbceSLemover 2646d5ddbceSLemover // Log 2656d5ddbceSLemover for(i <- 0 until Width) { 2666d5ddbceSLemover XSDebug(req(i).valid, p"req(${i.U}): (${req(i).valid} ${req(i).ready}) ${req(i).bits}\n") 2676d5ddbceSLemover XSDebug(resp(i).valid, p"resp(${i.U}): (${resp(i).valid} ${resp(i).ready}) ${resp(i).bits}\n") 2686d5ddbceSLemover } 2696d5ddbceSLemover 2706d5ddbceSLemover XSDebug(sfence.valid, p"Sfence: ${sfence}\n") 2716d5ddbceSLemover XSDebug(ParallelOR(valid)|| ptw.resp.valid, p"CSR: ${csr}\n") 272a0301c0dSLemover XSDebug(ParallelOR(valid) || ptw.resp.valid, p"vmEnable:${vmEnable} hit:${Binary(VecInit(hitVec).asUInt)} miss:${Binary(VecInit(missVec).asUInt)}\n") 2736d5ddbceSLemover for (i <- ptw.req.indices) { 2746d5ddbceSLemover XSDebug(ptw.req(i).fire(), p"PTW req:${ptw.req(i).bits}\n") 2756d5ddbceSLemover } 2766d5ddbceSLemover XSDebug(ptw.resp.valid, p"PTW resp:${ptw.resp.bits} (v:${ptw.resp.valid}r:${ptw.resp.ready}) \n") 2776d5ddbceSLemover 278a0301c0dSLemover println(s"${q.name}: normal page: ${q.normalNWays} ${q.normalAssociative} ${q.normalReplacer.get} super page: ${q.superNWays} ${q.superAssociative} ${q.superReplacer.get}") 279a0301c0dSLemover 2806d5ddbceSLemover// // NOTE: just for simple tlb debug, comment it after tlb's debug 2816d5ddbceSLemover // assert(!io.ptw.resp.valid || io.ptw.resp.bits.entry.tag === io.ptw.resp.bits.entry.ppn, "Simple tlb debug requires vpn === ppn") 2826d5ddbceSLemover} 2836d5ddbceSLemover 284a0301c0dSLemoverclass TlbReplace(Width: Int, q: TLBParameters)(implicit p: Parameters) extends TlbModule { 285a0301c0dSLemover val io = IO(new TlbReplaceIO(Width, q)) 286a0301c0dSLemover 287a0301c0dSLemover if (q.normalAssociative == "fa") { 288a0301c0dSLemover val re = ReplacementPolicy.fromString(q.normalReplacer, q.normalNWays) 289a0301c0dSLemover re.access(io.normalPage.access.touch_ways) 290a0301c0dSLemover io.normalPage.refillIdx := re.way 291a0301c0dSLemover } else { // set-acco && plru 292a0301c0dSLemover val re = ReplacementPolicy.fromString(q.normalReplacer, q.normalNSets, q.normalNWays) 293a0301c0dSLemover re.access(io.normalPage.access.sets, io.normalPage.access.touch_ways) 294a0301c0dSLemover io.normalPage.refillIdx := { if (q.normalNWays == 1) 0.U else re.way(io.normalPage.chosen_set) } 295a0301c0dSLemover } 296a0301c0dSLemover 297a0301c0dSLemover if (q.superAssociative == "fa") { 298a0301c0dSLemover val re = ReplacementPolicy.fromString(q.superReplacer, q.superNWays) 299a0301c0dSLemover re.access(io.superPage.access.touch_ways) 300a0301c0dSLemover io.superPage.refillIdx := re.way 301a0301c0dSLemover } else { // set-acco && plru 302a0301c0dSLemover val re = ReplacementPolicy.fromString(q.superReplacer, q.superNSets, q.superNWays) 303a0301c0dSLemover re.access(io.superPage.access.sets, io.superPage.access.touch_ways) 304a0301c0dSLemover io.superPage.refillIdx := { if (q.superNWays == 1) 0.U else re.way(io.superPage.chosen_set) } 305a0301c0dSLemover } 306a0301c0dSLemover} 307a0301c0dSLemover 3086d5ddbceSLemoverobject TLB { 3096d5ddbceSLemover def apply 3106d5ddbceSLemover ( 3116d5ddbceSLemover in: Seq[BlockTlbRequestIO], 3126d5ddbceSLemover sfence: SfenceBundle, 3136d5ddbceSLemover csr: TlbCsrBundle, 3146d5ddbceSLemover width: Int, 315a0301c0dSLemover shouldBlock: Boolean, 316a0301c0dSLemover q: TLBParameters 3176d5ddbceSLemover )(implicit p: Parameters) = { 3186d5ddbceSLemover require(in.length == width) 3196d5ddbceSLemover 320a0301c0dSLemover val tlb = Module(new TLB(width, q)) 3216d5ddbceSLemover 3226d5ddbceSLemover tlb.io.sfence <> sfence 3236d5ddbceSLemover tlb.io.csr <> csr 324a0301c0dSLemover tlb.suggestName(s"tlb_${q.name}") 3256d5ddbceSLemover 3266d5ddbceSLemover if (!shouldBlock) { // dtlb 3276d5ddbceSLemover for (i <- 0 until width) { 3286d5ddbceSLemover tlb.io.requestor(i) <> in(i) 3296d5ddbceSLemover // tlb.io.requestor(i).req.valid := in(i).req.valid 3306d5ddbceSLemover // tlb.io.requestor(i).req.bits := in(i).req.bits 3316d5ddbceSLemover // in(i).req.ready := tlb.io.requestor(i).req.ready 3326d5ddbceSLemover 3336d5ddbceSLemover // in(i).resp.valid := tlb.io.requestor(i).resp.valid 3346d5ddbceSLemover // in(i).resp.bits := tlb.io.requestor(i).resp.bits 3356d5ddbceSLemover // tlb.io.requestor(i).resp.ready := in(i).resp.ready 3366d5ddbceSLemover } 3376d5ddbceSLemover } else { // itlb 338d57bda64SJinYue //require(width == 1) 339d57bda64SJinYue (0 until width).map{ i => 340d57bda64SJinYue tlb.io.requestor(i).req.valid := in(i).req.valid 341d57bda64SJinYue tlb.io.requestor(i).req.bits := in(i).req.bits 342d57bda64SJinYue in(i).req.ready := !tlb.io.requestor(i).resp.bits.miss && in(i).resp.ready && tlb.io.requestor(i).req.ready 3436d5ddbceSLemover 344d57bda64SJinYue in(i).resp.valid := tlb.io.requestor(i).resp.valid && !tlb.io.requestor(i).resp.bits.miss 345d57bda64SJinYue in(i).resp.bits := tlb.io.requestor(i).resp.bits 346d57bda64SJinYue tlb.io.requestor(i).resp.ready := in(i).resp.ready 347d57bda64SJinYue } 3486d5ddbceSLemover } 3496d5ddbceSLemover 3506d5ddbceSLemover tlb.io.ptw 3516d5ddbceSLemover } 3526d5ddbceSLemover} 353