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._ 21*a0301c0dSLemoverimport chisel3.internal.naming.chiselName 226d5ddbceSLemoverimport chisel3.util._ 23*a0301c0dSLemoverimport freechips.rocketchip.util.SRAMAnnotation 246d5ddbceSLemoverimport xiangshan._ 256d5ddbceSLemoverimport utils._ 266d5ddbceSLemoverimport xiangshan.backend.roq.RoqPtr 276d5ddbceSLemoverimport xiangshan.backend.fu.util.HasCSRConst 286d5ddbceSLemover 29*a0301c0dSLemover 30*a0301c0dSLemover@chiselName 31*a0301c0dSLemoverclass TLB(Width: Int, q: TLBParameters)(implicit p: Parameters) extends TlbModule with HasCSRConst { 32*a0301c0dSLemover val io = IO(new TlbIO(Width, q)) 33*a0301c0dSLemover 34*a0301c0dSLemover require(q.superAssociative == "fa") 35*a0301c0dSLemover if (q.sameCycle) { 36*a0301c0dSLemover require(q.normalAssociative == "fa") 37*a0301c0dSLemover } 386d5ddbceSLemover 396d5ddbceSLemover val req = io.requestor.map(_.req) 406d5ddbceSLemover val resp = io.requestor.map(_.resp) 416d5ddbceSLemover val ptw = io.ptw 426d5ddbceSLemover 436d5ddbceSLemover val sfence = io.sfence 446d5ddbceSLemover val csr = io.csr 456d5ddbceSLemover val satp = csr.satp 466d5ddbceSLemover val priv = csr.priv 47*a0301c0dSLemover val ifecth = if (q.fetchi) true.B else false.B 48*a0301c0dSLemover val mode = if (q.useDmode) priv.dmode else priv.imode 496d5ddbceSLemover // val vmEnable = satp.mode === 8.U // && (mode < ModeM) // FIXME: fix me when boot xv6/linux... 506d5ddbceSLemover val vmEnable = if (EnbaleTlbDebug) (satp.mode === 8.U) 516d5ddbceSLemover else (satp.mode === 8.U && (mode < ModeM)) 526d5ddbceSLemover 53*a0301c0dSLemover val reqAddr = req.map(_.bits.vaddr.asTypeOf((new VaBundle).cloneType)) 54*a0301c0dSLemover val vpn = reqAddr.map(_.vpn) 556d5ddbceSLemover val cmd = req.map(_.bits.cmd) 566d5ddbceSLemover val valid = req.map(_.valid) 576d5ddbceSLemover 586d5ddbceSLemover def widthMapSeq[T <: Seq[Data]](f: Int => T) = (0 until Width).map(f) 59*a0301c0dSLemover 606d5ddbceSLemover def widthMap[T <: Data](f: Int => T) = (0 until Width).map(f) 616d5ddbceSLemover 626d5ddbceSLemover // Normal page && Super page 63*a0301c0dSLemover val normalPage = TlbStorage( 64*a0301c0dSLemover name = "normal", 65*a0301c0dSLemover associative = q.normalAssociative, 66*a0301c0dSLemover sameCycle = q.sameCycle, 67*a0301c0dSLemover ports = Width, 68*a0301c0dSLemover nSets = q.normalNSets, 69*a0301c0dSLemover nWays = q.normalNWays, 70*a0301c0dSLemover sramSinglePort = sramSinglePort, 71*a0301c0dSLemover normalPage = true, 72*a0301c0dSLemover superPage = false 736d5ddbceSLemover ) 74*a0301c0dSLemover val superPage = TlbStorage( 75*a0301c0dSLemover name = "super", 76*a0301c0dSLemover associative = q.superAssociative, 77*a0301c0dSLemover sameCycle = q.sameCycle, 78*a0301c0dSLemover ports = Width, 79*a0301c0dSLemover nSets = q.superNSets, 80*a0301c0dSLemover nWays = q.superNWays, 81*a0301c0dSLemover sramSinglePort = sramSinglePort, 82*a0301c0dSLemover normalPage = q.normalAsVictim, 83*a0301c0dSLemover superPage = true, 846d5ddbceSLemover ) 856d5ddbceSLemover 86*a0301c0dSLemover 876d5ddbceSLemover for (i <- 0 until Width) { 88*a0301c0dSLemover normalPage.r_req_apply( 89*a0301c0dSLemover valid = io.requestor(i).req.valid, 90*a0301c0dSLemover vpn = vpn(i), 91*a0301c0dSLemover i = i 926d5ddbceSLemover ) 93*a0301c0dSLemover superPage.r_req_apply( 94*a0301c0dSLemover valid = io.requestor(i).req.valid, 95*a0301c0dSLemover vpn = vpn(i), 96*a0301c0dSLemover i = i 97*a0301c0dSLemover ) 98*a0301c0dSLemover } 996d5ddbceSLemover 1006d5ddbceSLemover 101*a0301c0dSLemover normalPage.victim.in <> superPage.victim.out 102*a0301c0dSLemover normalPage.victim.out <> superPage.victim.in 103*a0301c0dSLemover normalPage.sfence <> io.sfence 104*a0301c0dSLemover superPage.sfence <> io.sfence 105149086eaSLemover 106*a0301c0dSLemover def TLBNormalRead(i: Int) = { 107*a0301c0dSLemover val (normal_hit, normal_ppn, normal_perm, normal_hitVec) = normalPage.r_resp_apply(i) 108*a0301c0dSLemover val (super_hit, super_ppn, super_perm, super_hitVec) = superPage.r_resp_apply(i) 109*a0301c0dSLemover assert(!(normal_hit && super_hit && vmEnable && RegNext(req(i).valid, init = false.B))) 1106d5ddbceSLemover 111*a0301c0dSLemover val hit = normal_hit || super_hit 112*a0301c0dSLemover val ppn = Mux(normal_hit, normal_ppn, super_ppn) 113*a0301c0dSLemover val perm = Mux(normal_hit, normal_perm, super_perm) 114*a0301c0dSLemover 115*a0301c0dSLemover val pf = perm.pf && hit 116*a0301c0dSLemover val cmdReg = if (!q.sameCycle) RegNext(cmd(i)) else cmd(i) 117*a0301c0dSLemover val validReg = if (!q.sameCycle) RegNext(valid(i)) else valid(i) 118*a0301c0dSLemover val offReg = if (!q.sameCycle) RegNext(reqAddr(i).off) else reqAddr(i).off 119*a0301c0dSLemover 120*a0301c0dSLemover /** *************** next cycle when two cycle is false******************* */ 121*a0301c0dSLemover val miss = !hit && vmEnable 1226d5ddbceSLemover hit.suggestName(s"hit_${i}") 1236d5ddbceSLemover miss.suggestName(s"miss_${i}") 1246d5ddbceSLemover 125*a0301c0dSLemover XSDebug(validReg, p"(${i.U}) hit:${hit} miss:${miss} ppn:${Hexadecimal(ppn)} perm:${perm}\n") 1266d5ddbceSLemover 127*a0301c0dSLemover val paddr = Cat(ppn, offReg) 1286d5ddbceSLemover val vaddr = SignExt(req(i).bits.vaddr, PAddrBits) 1296d5ddbceSLemover 1306d5ddbceSLemover req(i).ready := resp(i).ready 1316d5ddbceSLemover resp(i).valid := validReg 132*a0301c0dSLemover resp(i).bits.paddr := Mux(vmEnable, paddr, if (!q.sameCycle) RegNext(vaddr) else vaddr) 1336d5ddbceSLemover resp(i).bits.miss := miss 1346d5ddbceSLemover resp(i).bits.ptwBack := io.ptw.resp.fire() 1356d5ddbceSLemover 136*a0301c0dSLemover val update = hit && (!perm.a || !perm.d && TlbCmd.isWrite(cmdReg)) // update A/D through exception 1376d5ddbceSLemover val modeCheck = !(mode === ModeU && !perm.u || mode === ModeS && perm.u && (!priv.sum || ifecth)) 138*a0301c0dSLemover val ldPf = !(modeCheck && (perm.r || priv.mxr && perm.x)) && (TlbCmd.isRead(cmdReg) && true.B /* TODO !isAMO*/) 139*a0301c0dSLemover val stPf = !(modeCheck && perm.w) && (TlbCmd.isWrite(cmdReg) || false.B /*TODO isAMO. */) 140*a0301c0dSLemover val instrPf = !(modeCheck && perm.x) && TlbCmd.isExec(cmdReg) 141*a0301c0dSLemover resp(i).bits.excp.pf.ld := (ldPf || update || pf) && vmEnable && hit 142*a0301c0dSLemover resp(i).bits.excp.pf.st := (stPf || update || pf) && vmEnable && hit 143*a0301c0dSLemover resp(i).bits.excp.pf.instr := (instrPf || update || pf) && vmEnable && hit 1446d5ddbceSLemover 1456d5ddbceSLemover // if vmenable, use pre-calcuated pma check result 146*a0301c0dSLemover resp(i).bits.mmio := Mux(TlbCmd.isExec(cmdReg), !perm.pi, !perm.pd) && vmEnable && hit 147*a0301c0dSLemover resp(i).bits.excp.af.ld := Mux(TlbCmd.isAtom(cmdReg), !perm.pa, !perm.pr) && TlbCmd.isRead(cmdReg) && vmEnable && hit 148*a0301c0dSLemover resp(i).bits.excp.af.st := Mux(TlbCmd.isAtom(cmdReg), !perm.pa, !perm.pw) && TlbCmd.isWrite(cmdReg) && vmEnable && hit 149*a0301c0dSLemover resp(i).bits.excp.af.instr := Mux(TlbCmd.isAtom(cmdReg), false.B, !perm.pe) && vmEnable && hit 1506d5ddbceSLemover 1516d5ddbceSLemover // if !vmenable, check pma 1526d5ddbceSLemover val (pmaMode, accessWidth) = AddressSpace.memmapAddrMatch(resp(i).bits.paddr) 1536d5ddbceSLemover when(!vmEnable) { 1546d5ddbceSLemover resp(i).bits.mmio := Mux(TlbCmd.isExec(cmdReg), !PMAMode.icache(pmaMode), !PMAMode.dcache(pmaMode)) 1556d5ddbceSLemover resp(i).bits.excp.af.ld := Mux(TlbCmd.isAtom(cmdReg), !PMAMode.atomic(pmaMode), !PMAMode.read(pmaMode)) && TlbCmd.isRead(cmdReg) 1566d5ddbceSLemover resp(i).bits.excp.af.st := Mux(TlbCmd.isAtom(cmdReg), !PMAMode.atomic(pmaMode), !PMAMode.write(pmaMode)) && TlbCmd.isWrite(cmdReg) 1576d5ddbceSLemover resp(i).bits.excp.af.instr := Mux(TlbCmd.isAtom(cmdReg), false.B, !PMAMode.execute(pmaMode)) 1586d5ddbceSLemover } 1596d5ddbceSLemover 160*a0301c0dSLemover (hit, miss, normal_hitVec, super_hitVec, validReg) 1616d5ddbceSLemover } 1626d5ddbceSLemover 1636d5ddbceSLemover val readResult = (0 until Width).map(TLBNormalRead(_)) 164*a0301c0dSLemover val hitVec = readResult.map(_._1) 165*a0301c0dSLemover val missVec = readResult.map(_._2) 166*a0301c0dSLemover val normalhitVecVec = readResult.map(_._3) 167*a0301c0dSLemover val superhitVecVec = readResult.map(_._4) 168*a0301c0dSLemover val validRegVec = readResult.map(_._5) 1696d5ddbceSLemover 170149086eaSLemover // replacement 171*a0301c0dSLemover def get_access(one_hot: UInt, valid: Bool): Valid[UInt] = { 172149086eaSLemover val res = Wire(Valid(UInt(log2Up(one_hot.getWidth).W))) 173*a0301c0dSLemover res.valid := Cat(one_hot).orR && valid 174149086eaSLemover res.bits := OHToUInt(one_hot) 175149086eaSLemover res 176149086eaSLemover } 177*a0301c0dSLemover 178*a0301c0dSLemover val normal_refill_idx = if (q.outReplace) { 179*a0301c0dSLemover io.replace.normalPage.access.sets := vpn.map(get_idx(_, q.normalNSets)) 180*a0301c0dSLemover io.replace.normalPage.access.touch_ways := normalhitVecVec.zipWithIndex.map{ case (hv, i) => get_access(hv, 181*a0301c0dSLemover validRegVec(i))} 182*a0301c0dSLemover io.replace.normalPage.chosen_set := get_idx(io.ptw.resp.bits.entry.tag, q.normalNSets) 183*a0301c0dSLemover io.replace.normalPage.refillIdx 184*a0301c0dSLemover } else if (q.normalAssociative == "fa") { 185*a0301c0dSLemover val re = ReplacementPolicy.fromString(q.normalReplacer, q.normalNWays) 186*a0301c0dSLemover re.access(normalhitVecVec.zipWithIndex.map{ case (hv, i) => get_access(hv, validRegVec(i))}) 187*a0301c0dSLemover re.way 188*a0301c0dSLemover } else { // set-acco && plru 189*a0301c0dSLemover val re = ReplacementPolicy.fromString(q.normalReplacer, q.normalNSets, q.normalNWays) 190*a0301c0dSLemover re.access(vpn.map(get_idx(_, q.normalNSets)), normalhitVecVec.zipWithIndex.map{ case (hv, i) => get_access(hv, 191*a0301c0dSLemover validRegVec(i))}) 192*a0301c0dSLemover re.way(get_idx(io.ptw.resp.bits.entry.tag, q.normalNSets)) 193149086eaSLemover } 194*a0301c0dSLemover 195*a0301c0dSLemover val super_refill_idx = if (q.outReplace) { 196*a0301c0dSLemover io.replace.superPage.access.sets := vpn.map(get_idx(_, q.normalNSets)) 197*a0301c0dSLemover io.replace.superPage.access.touch_ways := superhitVecVec.zipWithIndex.map{ case (hv, i) => get_access(hv, 198*a0301c0dSLemover validRegVec(i))} 199*a0301c0dSLemover io.replace.superPage.chosen_set := DontCare 200*a0301c0dSLemover io.replace.superPage.refillIdx 201149086eaSLemover } else { 202*a0301c0dSLemover val re = ReplacementPolicy.fromString(q.superReplacer, q.superNWays) 203*a0301c0dSLemover re.access(superhitVecVec.zipWithIndex.map{ case (hv, i) => get_access(hv, validRegVec(i))}) 204*a0301c0dSLemover re.way 205149086eaSLemover } 206149086eaSLemover 207*a0301c0dSLemover val refill = ptw.resp.fire() && !sfence.valid 208*a0301c0dSLemover normalPage.w_apply( 209*a0301c0dSLemover valid = { if (q.normalAsVictim) false.B 210*a0301c0dSLemover else refill && ptw.resp.bits.entry.level.get === 2.U }, 211*a0301c0dSLemover wayIdx = normal_refill_idx, 212*a0301c0dSLemover data = ptw.resp.bits 213*a0301c0dSLemover ) 214*a0301c0dSLemover superPage.w_apply( 215*a0301c0dSLemover valid = { if (q.normalAsVictim) refill 216*a0301c0dSLemover else refill && ptw.resp.bits.entry.level.get =/= 2.U }, 217*a0301c0dSLemover wayIdx = super_refill_idx, 218*a0301c0dSLemover data = ptw.resp.bits 219*a0301c0dSLemover ) 220*a0301c0dSLemover 2216d5ddbceSLemover for (i <- 0 until Width) { 2226d5ddbceSLemover io.ptw.req(i).valid := validRegVec(i) && missVec(i) && !RegNext(refill) 2236d5ddbceSLemover io.ptw.req(i).bits.vpn := RegNext(reqAddr(i).vpn) 2246d5ddbceSLemover } 2256d5ddbceSLemover io.ptw.resp.ready := true.B 2266d5ddbceSLemover 227*a0301c0dSLemover if (!q.shouldBlock) { 2286d5ddbceSLemover for (i <- 0 until Width) { 2296d5ddbceSLemover XSPerfAccumulate("first_access" + Integer.toString(i, 10), validRegVec(i) && vmEnable && RegNext(req(i).bits.debug.isFirstIssue)) 2306d5ddbceSLemover XSPerfAccumulate("access" + Integer.toString(i, 10), validRegVec(i) && vmEnable) 2316d5ddbceSLemover } 2326d5ddbceSLemover for (i <- 0 until Width) { 2336d5ddbceSLemover XSPerfAccumulate("first_miss" + Integer.toString(i, 10), validRegVec(i) && vmEnable && missVec(i) && RegNext(req(i).bits.debug.isFirstIssue)) 2346d5ddbceSLemover XSPerfAccumulate("miss" + Integer.toString(i, 10), validRegVec(i) && vmEnable && missVec(i)) 2356d5ddbceSLemover } 2366d5ddbceSLemover } else { 2376d5ddbceSLemover // NOTE: ITLB is blocked, so every resp will be valid only when hit 2386d5ddbceSLemover // every req will be ready only when hit 239*a0301c0dSLemover for (i <- 0 until Width) { 240*a0301c0dSLemover XSPerfAccumulate(s"access${i}", io.requestor(i).req.fire() && vmEnable) 241*a0301c0dSLemover XSPerfAccumulate(s"miss${i}", ptw.req(i).fire()) 242*a0301c0dSLemover } 243*a0301c0dSLemover 2446d5ddbceSLemover } 2456d5ddbceSLemover //val reqCycleCnt = Reg(UInt(16.W)) 2466d5ddbceSLemover //reqCycleCnt := reqCycleCnt + BoolStopWatch(ptw.req(0).fire(), ptw.resp.fire || sfence.valid) 2476d5ddbceSLemover //XSPerfAccumulate("ptw_req_count", ptw.req.fire()) 2486d5ddbceSLemover //XSPerfAccumulate("ptw_req_cycle", Mux(ptw.resp.fire(), reqCycleCnt, 0.U)) 2496d5ddbceSLemover XSPerfAccumulate("ptw_resp_count", ptw.resp.fire()) 2506d5ddbceSLemover XSPerfAccumulate("ptw_resp_pf_count", ptw.resp.fire() && ptw.resp.bits.pf) 2516d5ddbceSLemover 2526d5ddbceSLemover // Log 2536d5ddbceSLemover for(i <- 0 until Width) { 2546d5ddbceSLemover XSDebug(req(i).valid, p"req(${i.U}): (${req(i).valid} ${req(i).ready}) ${req(i).bits}\n") 2556d5ddbceSLemover XSDebug(resp(i).valid, p"resp(${i.U}): (${resp(i).valid} ${resp(i).ready}) ${resp(i).bits}\n") 2566d5ddbceSLemover } 2576d5ddbceSLemover 2586d5ddbceSLemover XSDebug(sfence.valid, p"Sfence: ${sfence}\n") 2596d5ddbceSLemover XSDebug(ParallelOR(valid)|| ptw.resp.valid, p"CSR: ${csr}\n") 260*a0301c0dSLemover XSDebug(ParallelOR(valid) || ptw.resp.valid, p"vmEnable:${vmEnable} hit:${Binary(VecInit(hitVec).asUInt)} miss:${Binary(VecInit(missVec).asUInt)}\n") 2616d5ddbceSLemover for (i <- ptw.req.indices) { 2626d5ddbceSLemover XSDebug(ptw.req(i).fire(), p"PTW req:${ptw.req(i).bits}\n") 2636d5ddbceSLemover } 2646d5ddbceSLemover XSDebug(ptw.resp.valid, p"PTW resp:${ptw.resp.bits} (v:${ptw.resp.valid}r:${ptw.resp.ready}) \n") 2656d5ddbceSLemover 266*a0301c0dSLemover println(s"${q.name}: normal page: ${q.normalNWays} ${q.normalAssociative} ${q.normalReplacer.get} super page: ${q.superNWays} ${q.superAssociative} ${q.superReplacer.get}") 267*a0301c0dSLemover 2686d5ddbceSLemover// // NOTE: just for simple tlb debug, comment it after tlb's debug 2696d5ddbceSLemover // assert(!io.ptw.resp.valid || io.ptw.resp.bits.entry.tag === io.ptw.resp.bits.entry.ppn, "Simple tlb debug requires vpn === ppn") 2706d5ddbceSLemover} 2716d5ddbceSLemover 272*a0301c0dSLemoverclass TlbReplace(Width: Int, q: TLBParameters)(implicit p: Parameters) extends TlbModule { 273*a0301c0dSLemover val io = IO(new TlbReplaceIO(Width, q)) 274*a0301c0dSLemover 275*a0301c0dSLemover if (q.normalAssociative == "fa") { 276*a0301c0dSLemover val re = ReplacementPolicy.fromString(q.normalReplacer, q.normalNWays) 277*a0301c0dSLemover re.access(io.normalPage.access.touch_ways) 278*a0301c0dSLemover io.normalPage.refillIdx := re.way 279*a0301c0dSLemover } else { // set-acco && plru 280*a0301c0dSLemover val re = ReplacementPolicy.fromString(q.normalReplacer, q.normalNSets, q.normalNWays) 281*a0301c0dSLemover re.access(io.normalPage.access.sets, io.normalPage.access.touch_ways) 282*a0301c0dSLemover io.normalPage.refillIdx := { if (q.normalNWays == 1) 0.U else re.way(io.normalPage.chosen_set) } 283*a0301c0dSLemover } 284*a0301c0dSLemover 285*a0301c0dSLemover if (q.superAssociative == "fa") { 286*a0301c0dSLemover val re = ReplacementPolicy.fromString(q.superReplacer, q.superNWays) 287*a0301c0dSLemover re.access(io.superPage.access.touch_ways) 288*a0301c0dSLemover io.superPage.refillIdx := re.way 289*a0301c0dSLemover } else { // set-acco && plru 290*a0301c0dSLemover val re = ReplacementPolicy.fromString(q.superReplacer, q.superNSets, q.superNWays) 291*a0301c0dSLemover re.access(io.superPage.access.sets, io.superPage.access.touch_ways) 292*a0301c0dSLemover io.superPage.refillIdx := { if (q.superNWays == 1) 0.U else re.way(io.superPage.chosen_set) } 293*a0301c0dSLemover } 294*a0301c0dSLemover} 295*a0301c0dSLemover 2966d5ddbceSLemoverobject TLB { 2976d5ddbceSLemover def apply 2986d5ddbceSLemover ( 2996d5ddbceSLemover in: Seq[BlockTlbRequestIO], 3006d5ddbceSLemover sfence: SfenceBundle, 3016d5ddbceSLemover csr: TlbCsrBundle, 3026d5ddbceSLemover width: Int, 303*a0301c0dSLemover shouldBlock: Boolean, 304*a0301c0dSLemover q: TLBParameters 3056d5ddbceSLemover )(implicit p: Parameters) = { 3066d5ddbceSLemover require(in.length == width) 3076d5ddbceSLemover 308*a0301c0dSLemover val tlb = Module(new TLB(width, q)) 3096d5ddbceSLemover 3106d5ddbceSLemover tlb.io.sfence <> sfence 3116d5ddbceSLemover tlb.io.csr <> csr 312*a0301c0dSLemover tlb.suggestName(s"tlb_${q.name}") 3136d5ddbceSLemover 3146d5ddbceSLemover if (!shouldBlock) { // dtlb 3156d5ddbceSLemover for (i <- 0 until width) { 3166d5ddbceSLemover tlb.io.requestor(i) <> in(i) 3176d5ddbceSLemover // tlb.io.requestor(i).req.valid := in(i).req.valid 3186d5ddbceSLemover // tlb.io.requestor(i).req.bits := in(i).req.bits 3196d5ddbceSLemover // in(i).req.ready := tlb.io.requestor(i).req.ready 3206d5ddbceSLemover 3216d5ddbceSLemover // in(i).resp.valid := tlb.io.requestor(i).resp.valid 3226d5ddbceSLemover // in(i).resp.bits := tlb.io.requestor(i).resp.bits 3236d5ddbceSLemover // tlb.io.requestor(i).resp.ready := in(i).resp.ready 3246d5ddbceSLemover } 3256d5ddbceSLemover } else { // itlb 326d57bda64SJinYue //require(width == 1) 327d57bda64SJinYue (0 until width).map{ i => 328d57bda64SJinYue tlb.io.requestor(i).req.valid := in(i).req.valid 329d57bda64SJinYue tlb.io.requestor(i).req.bits := in(i).req.bits 330d57bda64SJinYue in(i).req.ready := !tlb.io.requestor(i).resp.bits.miss && in(i).resp.ready && tlb.io.requestor(i).req.ready 3316d5ddbceSLemover 332d57bda64SJinYue in(i).resp.valid := tlb.io.requestor(i).resp.valid && !tlb.io.requestor(i).resp.bits.miss 333d57bda64SJinYue in(i).resp.bits := tlb.io.requestor(i).resp.bits 334d57bda64SJinYue tlb.io.requestor(i).resp.ready := in(i).resp.ready 335d57bda64SJinYue } 3366d5ddbceSLemover } 3376d5ddbceSLemover 3386d5ddbceSLemover tlb.io.ptw 3396d5ddbceSLemover } 3406d5ddbceSLemover} 341