dtlb.scala 15.1 KB
Newer Older
Y
Yinan Xu 已提交
1 2 3 4 5 6
package xiangshan.cache

import chisel3._
import chisel3.util._
import xiangshan._
import utils._
7 8 9 10
import chisel3.util.experimental.BoringUtils
import xiangshan.backend.decode.XSTrap
import xiangshan.mem._
import bus.simplebus._
Z
ZhangZifei 已提交
11
import xiangshan.backend.fu.HasCSRConst
Z
ZhangZifei 已提交
12
import chisel3.ExcitingUtils._
Y
Yinan Xu 已提交
13

14
trait HasTlbConst extends HasXSParameter {
Z
ZhangZifei 已提交
15 16 17
  val Level = 3

  val offLen  = 12
Z
ZhangZifei 已提交
18 19 20
  val ppnLen  = PAddrBits - offLen
  val vpnnLen = 9
  val vpnLen  = VAddrBits - offLen
Z
ZhangZifei 已提交
21 22
  val flagLen = 8
  val pteResLen = XLEN - ppnLen - 2 - flagLen
Z
ZhangZifei 已提交
23
  val asidLen = 16
Z
ZhangZifei 已提交
24 25 26 27 28

  def vaBundle = new Bundle {
    val vpn  = UInt(vpnLen.W)
    val off  = UInt(offLen.W)
  }
Z
ZhangZifei 已提交
29
  def pteBundle = new Bundle {
Z
ZhangZifei 已提交
30 31 32
    val reserved  = UInt(pteResLen.W)
    val ppn  = UInt(ppnLen.W)
    val rsw  = UInt(2.W)
Z
ZhangZifei 已提交
33
    val perm = new Bundle {
Z
ZhangZifei 已提交
34 35 36 37 38 39 40 41
      val d    = Bool()
      val a    = Bool()
      val g    = Bool()
      val u    = Bool()
      val x    = Bool()
      val w    = Bool()
      val r    = Bool()
      val v    = Bool()
Z
ZhangZifei 已提交
42 43 44 45
    }
  }
}

Z
ZhangZifei 已提交
46 47
abstract class TlbBundle extends XSBundle with HasTlbConst
abstract class TlbModule extends XSModule with HasTlbConst
Z
ZhangZifei 已提交
48 49 50 51 52 53 54 55 56 57

class PermBundle(val hasV: Boolean = true) extends TlbBundle {
  val d = Bool()
  val a = Bool()
  val g = Bool()
  val u = Bool()
  val x = Bool()
  val w = Bool()
  val r = Bool()
  if (hasV) { val v = Bool() }
Z
ZhangZifei 已提交
58 59 60 61 62

  override def toPrintable: Printable = {
    p"d:${d} a:${a} g:${g} u:${u} x:${x} w:${w} r:${r}"// + 
    //(if(hasV) (p"v:${v}") else p"")
  }
Z
ZhangZifei 已提交
63 64
}

65 66 67 68 69 70 71 72 73 74 75 76 77
class comBundle extends TlbBundle with HasRoqIdx{
  val valid = Bool()
  val bits = new PtwReq
  def isPrior(that: comBundle): Bool = {
    (this.valid && !that.valid) || (this.valid && that.valid && (that isAfter this))
  }
}
object Compare {
  def apply[T<:Data](xs: Seq[comBundle]): comBundle = {
    ParallelOperation(xs, (a: comBundle, b: comBundle) => Mux(a isPrior b, a, b))
  }
}

78
class TlbEntry extends TlbBundle {
Z
ZhangZifei 已提交
79 80 81 82 83 84 85
  val vpn = UInt(vpnLen.W) // tag is vpn
  val ppn = UInt(ppnLen.W)
  val level = UInt(log2Up(Level).W) // 0 for 4KB, 1 for 2MB, 2 for 1GB
  // val asid = UInt(asidLen.W), asid maybe expensive to support, but useless
  // val v = Bool() // v&g is special, may need sperate storage?
  val perm = new PermBundle(hasV = false)

86
  def vpnHit(vpn: UInt):Bool = {
Z
ZhangZifei 已提交
87
    val fullMask = VecInit((Seq.fill(vpnLen)(true.B))).asUInt
88
    val maskLevel = VecInit((Level-1 to 0 by -1).map{i => // NOTE: level 2 for 4KB, 1 for 2MB, 0 for 1GB
Z
ZhangZifei 已提交
89 90 91 92 93 94 95 96 97
      VecInit(Seq.fill(vpnLen-i*vpnnLen)(true.B) ++ Seq.fill(i*vpnnLen)(false.B)).asUInt})
    val mask = maskLevel(level)
    (mask&this.vpn) === (mask&vpn)
  }

  // def asidHit(asid: UInt) = {
  //   this.asid === asid
  // }

98
  def hit(vpn: UInt/*, asid: UInt*/):Bool = {
99
    vpnHit(vpn) // && asidHit(asid)
Z
ZhangZifei 已提交
100 101
  }

102
  def genTlbEntry(pte: UInt, level: UInt, vpn: UInt/*, asid: UInt*/) = {
103
    val e = Wire(new TlbEntry)
Z
ZhangZifei 已提交
104 105 106 107 108 109 110
    e.ppn := pte.asTypeOf(pteBundle).ppn
    e.level := level
    e.vpn := vpn
    e.perm := pte.asTypeOf(pteBundle).perm
    // e.asid := asid
    e
  }
Z
ZhangZifei 已提交
111 112 113 114

  override def toPrintable: Printable = {
    p"vpn:0x${Hexadecimal(vpn)} ppn:0x${Hexadecimal(ppn)} level:${level} perm:${perm}"
  }
Z
ZhangZifei 已提交
115 116
}

117 118 119 120 121 122
object TlbCmd {
  def read  = "b00".U
  def write = "b01".U
  def exec  = "b10".U

  def apply() = UInt(2.W)
Z
ZhangZifei 已提交
123 124 125
  def isRead(a: UInt) = a===read
  def isWrite(a: UInt) = a===write
  def isExec(a: UInt) = a===exec
126 127
}

128
class TlbReq extends TlbBundle {
Y
Yinan Xu 已提交
129
  val vaddr = UInt(VAddrBits.W)
130
  val cmd = TlbCmd()
Z
ZhangZifei 已提交
131
  val roqIdx = UInt(RoqIdxWidth.W)
132 133 134 135
  val debug = new Bundle {
    val pc = UInt(XLEN.W)
    val lsroqIdx = UInt(LsroqIdxWidth.W)
  }
Z
ZhangZifei 已提交
136 137

  override def toPrintable: Printable = {
Z
ZhangZifei 已提交
138
    p"vaddr:0x${Hexadecimal(vaddr)} cmd:${cmd} pc:0x${Hexadecimal(debug.pc)} roqIdx:${roqIdx} lsroqIdx:${debug.lsroqIdx}"
Z
ZhangZifei 已提交
139
  }
Y
Yinan Xu 已提交
140 141
}

142
class TlbResp extends TlbBundle {
Y
Yinan Xu 已提交
143 144
  val paddr = UInt(PAddrBits.W)
  val miss = Bool()
Z
ZhangZifei 已提交
145 146 147 148 149 150 151
  val excp = new Bundle {
    val pf = new Bundle {
      val ld = Bool()
      val st = Bool()
      val instr = Bool()
    }
  }
Z
ZhangZifei 已提交
152 153 154
  override def toPrintable: Printable = {
    p"paddr:0x${Hexadecimal(paddr)} miss:${miss} excp.pf: ld:${excp.pf.ld} st:${excp.pf.st} instr:${excp.pf.instr}"
  }
155 156
}

157 158 159
class TlbRequestIO() extends TlbBundle {
  val req = Valid(new TlbReq)
  val resp = Flipped(Valid(new TlbResp))
160

161
  // override def cloneType: this.type = (new TlbRequestIO(Width)).asInstanceOf[this.type]
Y
Yinan Xu 已提交
162 163
}

Z
zhanglinjuan 已提交
164 165 166 167 168
class BlockTlbRequestIO() extends TlbBundle {
  val req = DecoupledIO(new TlbReq)
  val resp = Flipped(DecoupledIO(new TlbResp))
}

Z
ZhangZifei 已提交
169
class TlbPtwIO extends TlbBundle {
Z
ZhangZifei 已提交
170 171
  val req = DecoupledIO(new PtwReq)
  val resp = Flipped(DecoupledIO(new PtwResp))
Y
Yinan Xu 已提交
172 173
}

174
class TlbIO(Width: Int) extends TlbBundle {
175
  val requestor = Vec(Width, Flipped(new TlbRequestIO))
176
  val ptw = new TlbPtwIO
177 178

  override def cloneType: this.type = (new TlbIO(Width)).asInstanceOf[this.type]
Y
Yinan Xu 已提交
179 180 181
}


Z
ZhangZifei 已提交
182
class TLB(Width: Int, isDtlb: Boolean) extends TlbModule with HasCSRConst{
183
  val io = IO(new TlbIO(Width))
Z
ZhangZifei 已提交
184

185 186
  val req    = io.requestor.map(_.req)
  val resp   = io.requestor.map(_.resp)
187
  val ptw    = io.ptw
188

189 190 191 192
  val sfence = WireInit(0.U.asTypeOf(new SfenceBundle))
  val csr    = WireInit(0.U.asTypeOf(new TlbCsrBundle))
  val satp   = csr.satp
  val priv   = csr.priv
Z
ZhangZifei 已提交
193 194
  val ifecth = if (isDtlb) false.B else true.B
  val mode   = if (isDtlb) priv.dmode else priv.imode
Z
ZhangZifei 已提交
195
  val vmEnable = satp.mode === 8.U // && (mode < ModeM) // FIXME: fix me when boot xv6/linux...
196 197 198
  BoringUtils.addSink(sfence, "SfenceBundle")
  BoringUtils.addSink(csr, "TLBCSRIO")

199
  val reqAddr = req.map(_.bits.vaddr.asTypeOf(vaBundle))
200 201
  val cmd     = req.map(_.bits.cmd)
  val valid   = req.map(_.valid)
Z
ZhangZifei 已提交
202

203 204 205
  def widthMapSeq[T <: Seq[Data]](f: Int => T) = (0 until Width).map(f)
  def widthMap[T <: Data](f: Int => T) = (0 until Width).map(f)

206
  val v = RegInit(0.U(TlbEntrySize.W))
207
  val pf = RegInit(0.U(TlbEntrySize.W)) // TODO: when ptw resp a pf(now only page not found), store here
208
  val entry = Reg(Vec(TlbEntrySize, new TlbEntry))
209
  val g = VecInit(entry.map(_.perm.g)).asUInt // TODO: need check if reverse is needed
Z
ZhangZifei 已提交
210

211 212 213 214 215 216 217
  val entryHitVec = widthMapSeq{i => VecInit(entry.map(_.hit(reqAddr(i).vpn/*, satp.asid*/))) }
  val hitVec  = widthMapSeq{ i => (v.asBools zip entryHitVec(i)).map{ case (a,b) => a&b } }
  val pfHitVec   = widthMapSeq{ i => (pf.asBools zip entryHitVec(i)).map{ case (a,b) => a&b } }
  val pfArray = widthMap{ i => ParallelOR(pfHitVec(i)).asBool && valid(i) && vmEnable }
  val hit     = widthMap{ i => ParallelOR(hitVec(i)).asBool && valid(i) && vmEnable && ~pfArray(i) }
  val miss    = widthMap{ i => !hit(i) && valid(i) && vmEnable && ~pfArray(i) }
  val hitppn  = widthMap{ i => ParallelMux(hitVec(i) zip entry.map(_.ppn)) }
218
  val hitPerm = widthMap{ i => ParallelMux(hitVec(i) zip entry.map(_.perm)) }
Z
ZhangZifei 已提交
219
  val multiHit = {
220
    val hitSum = widthMap{ i => PopCount(hitVec(i)) }
221 222
    val pfHitSum = widthMap{ i => PopCount(pfHitVec(i)) }
    ParallelOR(widthMap{ i => !(hitSum(i)===0.U || hitSum(i)===1.U) || !(pfHitSum(i)===0.U || pfHitSum(i)===1.U)})
Z
ZhangZifei 已提交
223 224
  }

Z
ZhangZifei 已提交
225
  // resp  // TODO: A/D has not being concerned
226
  for(i <- 0 until Width) {
227
    resp(i).valid := valid(i)
228
    resp(i).bits.paddr := Mux(vmEnable, Cat(hitppn(i), reqAddr(i).off), SignExt(req(i).bits.vaddr, PAddrBits))
Z
ZhangZifei 已提交
229 230 231
    resp(i).bits.miss := miss(i)

    val perm = hitPerm(i) // NOTE: given the excp, the out module choose one to use?
232
    val update = false.B && hit(i) && (!hitPerm(i).a || !hitPerm(i).d && TlbCmd.isWrite(cmd(i))) // update A/D through exception
Z
ZhangZifei 已提交
233
    val modeCheck = !(mode === ModeU && !perm.u || mode === ModeS && perm.u && (!priv.sum || ifecth))
234 235 236 237 238 239
    val ldPf = (pfArray(i) && TlbCmd.isRead(cmd(i)) && true.B /*!isAMO*/) || hit(i) && !(modeCheck && (perm.r || priv.mxr && perm.x)) && (TlbCmd.isRead(cmd(i)) && true.B/*!isAMO*/) // TODO: handle isAMO
    val stPf = (pfArray(i) && TlbCmd.isWrite(cmd(i)) || false.B /*isAMO*/ ) || hit(i) && !(modeCheck && perm.w) && (TlbCmd.isWrite(cmd(i)) || false.B/*TODO isAMO. */)
    val instrPf = (pfArray(i) && TlbCmd.isExec(cmd(i))) || hit(i) && !(modeCheck && perm.x) && TlbCmd.isExec(cmd(i))
    resp(i).bits.excp.pf.ld    := ldPf || update
    resp(i).bits.excp.pf.st    := stPf || update
    resp(i).bits.excp.pf.instr := instrPf || update
Z
ZhangZifei 已提交
240 241 242
  }

  // ptw
Z
ZhangZifei 已提交
243 244
  val state_idle :: state_wait :: Nil = Enum(2)
  val state = RegInit(state_idle)
Z
ZhangZifei 已提交
245

246
  ptw <> DontCare // TODO: need check it
247
  ptw.req.valid := ParallelOR(miss).asBool && state===state_idle
248
  ptw.resp.ready := state===state_wait
249

250 251 252 253
  // val ptwReqSeq = Wire(Seq.fill(Width)(new comBundle()))
  val ptwReqSeq = Seq.fill(Width)(Wire(new comBundle()))
  for (i <- 0 until Width) {
    ptwReqSeq(i).valid := valid(i) && miss(i)
Z
ZhangZifei 已提交
254
    ptwReqSeq(i).roqIdx := req(i).bits.roqIdx
255 256 257 258
    ptwReqSeq(i).bits.vpn := reqAddr(i).vpn
  }
  ptw.req.bits := Compare(ptwReqSeq).bits

Z
ZhangZifei 已提交
259
  switch (state) {
Z
ZhangZifei 已提交
260
    is (state_idle) {
Z
ZhangZifei 已提交
261
      when (ParallelOR(miss).asBool && ptw.req.fire()) {
262
        state := state_wait
Z
ZhangZifei 已提交
263
      }
264
      assert(!ptw.resp.valid)
Z
ZhangZifei 已提交
265
    }
266

Z
ZhangZifei 已提交
267
    is (state_wait) {
268
      when (ptw.resp.fire()) {
Z
ZhangZifei 已提交
269
        state := state_idle
Z
ZhangZifei 已提交
270
      }
A
Allen 已提交
271
    }
Z
ZhangZifei 已提交
272 273
  }

274
  // reset pf when pf hit
Z
ZhangZifei 已提交
275 276
  val pfHitReset = ParallelOR(widthMap{i => Mux(valid(i), VecInit(pfHitVec(i)).asUInt, 0.U) })
  val pfHitRefill = ParallelOR(pfHitReset.asBools)
277

Z
ZhangZifei 已提交
278
  // refill
279
  val refill = ptw.resp.fire()
280
  val randIdx = LFSR64()(log2Up(TlbEntrySize)-1,0)
Z
ZhangZifei 已提交
281
  val priorIdx = PriorityEncoder(~(v|pf))
Z
ZhangZifei 已提交
282 283 284
  val tlbfull = ParallelAND((v|pf).asBools)
  val refillIdx = Mux(tlbfull, randIdx, priorIdx)
  val re2OH = UIntToOH(refillIdx)
Z
ZhangZifei 已提交
285
  when (refill) {
Z
ZhangZifei 已提交
286
    v := Mux(ptw.resp.bits.pf, v & ~re2OH, v | re2OH)
Z
ZhangZifei 已提交
287
    entry(refillIdx) := ptw.resp.bits.entry
288
    XSDebug(p"Refill: idx:${refillIdx} entry:${ptw.resp.bits.entry}\n")
Z
ZhangZifei 已提交
289
  }
Z
ZhangZifei 已提交
290

291
  // pf update
Z
ZhangZifei 已提交
292 293 294 295 296 297 298 299 300 301 302 303 304
  when (refill) {
    when (pfHitRefill) {
      pf := Mux(ptw.resp.bits.pf, pf | re2OH, pf & ~re2OH) & ~pfHitReset
    } .otherwise {
      pf := Mux(ptw.resp.bits.pf, pf | re2OH, pf & ~re2OH)
    }
  } .otherwise {
    when (pfHitRefill) {
      pf := pf & ~pfHitReset
    }
  }
  when (PopCount(pf) > 10.U) { // when too much pf, just clear
    pf := Mux(refill && ptw.resp.bits.pf, re2OH, 0.U)
305 306 307 308 309 310
  }

  // sfence (flush)
  when (sfence.valid) {
    when (sfence.bits.rs1) { // virtual address *.rs1 <- (rs1===0.U)
      when (sfence.bits.rs2) { // asid, but i do not want to support asid, *.rs2 <- (rs2===0.U)
311 312
        // all addr and all asid
        v := 0.U
313
        pf := 0.U
314 315 316 317
      }.otherwise {
        // all addr but specific asid
        v := v & g // TODO: need check if reverse is needed
        pf := pf & g
318
      }
319 320 321 322 323 324 325 326 327
    }.otherwise {
      when (sfence.bits.rs2) {
        // specific addr but all asid
        v := v & ~VecInit(entry.map(_.hit(sfence.bits.addr.asTypeOf(vaBundle).vpn))).asUInt
        pf := pf & ~VecInit(entry.map(_.hit(sfence.bits.addr.asTypeOf(vaBundle).vpn))).asUInt
      }.otherwise {
        // specific addr and specific asid
        v := v & ~VecInit(entry.map(e => e.hit(sfence.bits.addr.asTypeOf(vaBundle).vpn) && (/*e.asid === sfence.bits.asid && */!e.perm.g))).asUInt
        pf := pf & ~VecInit(entry.map(e => e.hit(sfence.bits.addr.asTypeOf(vaBundle).vpn) && (/*e.asid === sfence.bits.asid && */!e.perm.g))).asUInt
328 329 330 331
      }
    }
  }

Z
zhanglinjuan 已提交
332
  if (!env.FPGAPlatform && isDtlb) {
Z
ZhangZifei 已提交
333 334 335 336 337 338 339 340 341 342
    ExcitingUtils.addSource(valid(0)/* && vmEnable*/, "perfCntDtlbReqCnt0", Perf)
    ExcitingUtils.addSource(valid(1)/* && vmEnable*/, "perfCntDtlbReqCnt1", Perf)
    ExcitingUtils.addSource(valid(2)/* && vmEnable*/, "perfCntDtlbReqCnt2", Perf)
    ExcitingUtils.addSource(valid(3)/* && vmEnable*/, "perfCntDtlbReqCnt3", Perf)
    ExcitingUtils.addSource(valid(0)/* && vmEnable*/ && miss(0), "perfCntDtlbMissCnt0", Perf)
    ExcitingUtils.addSource(valid(1)/* && vmEnable*/ && miss(1), "perfCntDtlbMissCnt1", Perf)
    ExcitingUtils.addSource(valid(2)/* && vmEnable*/ && miss(2), "perfCntDtlbMissCnt2", Perf)
    ExcitingUtils.addSource(valid(3)/* && vmEnable*/ && miss(3), "perfCntDtlbMissCnt3", Perf)
  }

Z
zhanglinjuan 已提交
343 344 345 346 347
  if (!env.FPGAPlatform && !isDtlb) {
    ExcitingUtils.addSource(valid(0)/* && vmEnable*/, "perfCntItlbReqCnt0", Perf)
    ExcitingUtils.addSource(valid(0)/* && vmEnable*/ && miss(0), "perfCntItlbMissCnt0", Perf)
  }

348
  // Log
Z
ZhangZifei 已提交
349 350
  for(i <- 0 until Width) {
    XSDebug(req(i).valid, p"req(${i.U}): ${req(i).bits}\n")
351
    XSDebug(resp(i).valid, p"resp(${i.U}): ${resp(i).bits}\n")
Z
ZhangZifei 已提交
352 353 354
  }

  XSDebug(sfence.valid, p"Sfence: ${sfence}\n")
355
  XSDebug(ParallelOR(valid)|| ptw.resp.valid, p"CSR: ${csr}\n")
356
  XSDebug(ParallelOR(valid) || ptw.resp.valid, p"vmEnable:${vmEnable} hit:${Binary(VecInit(hit).asUInt)} miss:${Binary(VecInit(miss).asUInt)} v:${Hexadecimal(v)} pf:${Hexadecimal(pf)} state:${state}\n")
Z
ZhangZifei 已提交
357
  XSDebug(ptw.req.fire(), p"PTW req:${ptw.req.bits}\n")
358 359 360 361 362 363 364 365 366 367 368 369 370
  XSDebug(ptw.resp.valid, p"PTW resp:${ptw.resp.bits} (v:${ptw.resp.valid}r:${ptw.resp.ready}) \n")

  // assert check, can be remove when tlb can work
  for(i <- 0 until Width) {
    assert((hit(i)&pfArray(i))===false.B, "hit(%d):%d pfArray(%d):%d v:0x%x pf:0x%x", i.U, hit(i), i.U, pfArray(i), v, pf)
  }
  for(i <- 0 until Width) {
    XSDebug(multiHit, p"vpn:0x${Hexadecimal(reqAddr(i).vpn)} hitVec:0x${Hexadecimal(VecInit(hitVec(i)).asUInt)} pfHitVec:0x${Hexadecimal(VecInit(pfHitVec(i)).asUInt)}\n")
  }
  for(i <- 0 until TlbEntrySize) {
    XSDebug(multiHit, p"entry(${i.U}): v:${v(i)} ${entry(i)}\n")
  }
  assert(!multiHit) // add multiHit here, later it should be removed (maybe), turn to miss and flush
371 372

  for (i <- 0 until Width) {
Z
ZhangZifei 已提交
373 374
    XSDebug(resp(i).valid && hit(i) && !(req(i).bits.vaddr===resp(i).bits.paddr), p"vaddr:0x${Hexadecimal(req(i).bits.vaddr)} paddr:0x${Hexadecimal(resp(i).bits.paddr)} hitVec:0x${Hexadecimal(VecInit(hitVec(i)).asUInt)}}\n")
    when (resp(i).valid && hit(i) && !(req(i).bits.vaddr===resp(i).bits.paddr)) {
375 376 377
      for (j <- 0 until TlbEntrySize) {
        XSDebug(true.B, p"TLBEntry(${j.U}): v:${v(j)} ${entry(j)}\n")
      }
378
    } // FIXME: remove me when tlb may be ok
Z
ZhangZifei 已提交
379
    when(resp(i).valid && hit(i)) {
380 381
      assert(req(i).bits.vaddr===resp(i).bits.paddr, "vaddr:0x%x paddr:0x%x hitVec:%x ", req(i).bits.vaddr, resp(i).bits.paddr, VecInit(hitVec(i)).asUInt)
    } // FIXME: remove me when tlb may be ok
382
  }
383 384
  
  assert((v&pf)===0.U, "v and pf can't be true at same time: v:0x%x pf:0x%x", v, pf)
Y
Yinan Xu 已提交
385
}
Z
zhanglinjuan 已提交
386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404

object TLB {
  def apply(in: Seq[BlockTlbRequestIO], width: Int, isDtlb: Boolean, shouldBlock: Boolean) = {
    require(in.length == width)
    
    val tlb = Module(new TLB(width, isDtlb))
    
    if (!shouldBlock) { // dtlb
      for (i <- 0 until width) {
        tlb.io.requestor(i).req.valid := in(i).req.valid
        tlb.io.requestor(i).req.bits := in(i).req.bits
        in(i).req.ready := DontCare

        in(i).resp.valid := tlb.io.requestor(i).resp.valid
        in(i).resp.bits := tlb.io.requestor(i).resp.bits
      }
    } else { // itlb
      require(width == 1)
      tlb.io.requestor(0).req.valid := in(0).req.valid
Z
zhanglinjuan 已提交
405
      tlb.io.requestor(0).req.bits := in(0).req.bits
Z
zhanglinjuan 已提交
406 407 408 409 410 411 412 413 414 415 416 417 418 419 420
      in(0).req.ready := !tlb.io.requestor(0).resp.bits.miss && in(0).resp.ready

      // val pf = LookupTree(tlb.io.requestor(0).req.bits.cmd, List(
      //   TlbCmd.read -> tlb.io.requestor(0).resp.bits.excp.pf.ld,
      //   TlbCmd.write -> tlb.io.requestor(0).resp.bits.excp.pf.st,
      //   TlbCmd.exec -> tlb.io.requestor(0).resp.bits.excp.pf.instr
      // ))

      in(0).resp.valid := tlb.io.requestor(0).resp.valid && !tlb.io.requestor(0).resp.bits.miss
      in(0).resp.bits := tlb.io.requestor(0).resp.bits
    }

    tlb.io.ptw
  }
}