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

import chisel3._
import chisel3.util._
import xiangshan._
import utils._
Y
Yinan Xu 已提交
7
import xiangshan.backend.roq.RoqPtr
Z
ZhangZifei 已提交
8
import xiangshan.backend.fu.HasCSRConst
Z
ZhangZifei 已提交
9
import chisel3.ExcitingUtils._
Y
Yinan Xu 已提交
10

11
trait HasTlbConst extends HasXSParameter {
Z
ZhangZifei 已提交
12 13 14
  val Level = 3

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

  def vaBundle = new Bundle {
    val vpn  = UInt(vpnLen.W)
    val off  = UInt(offLen.W)
  }
Z
ZhangZifei 已提交
26
  def pteBundle = new Bundle {
Z
ZhangZifei 已提交
27 28 29
    val reserved  = UInt(pteResLen.W)
    val ppn  = UInt(ppnLen.W)
    val rsw  = UInt(2.W)
Z
ZhangZifei 已提交
30
    val perm = new Bundle {
Z
ZhangZifei 已提交
31 32 33 34 35 36 37 38
      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 已提交
39 40 41 42
    }
  }
}

Z
ZhangZifei 已提交
43 44
abstract class TlbBundle extends XSBundle with HasTlbConst
abstract class TlbModule extends XSModule with HasTlbConst
Z
ZhangZifei 已提交
45

46
class PtePermBundle extends TlbBundle {
Z
ZhangZifei 已提交
47 48 49 50 51 52 53
  val d = Bool()
  val a = Bool()
  val g = Bool()
  val u = Bool()
  val x = Bool()
  val w = Bool()
  val r = Bool()
Z
ZhangZifei 已提交
54 55

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

61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
class TlbPermBundle extends TlbBundle {
  val pf = Bool() // NOTE: if this is true, just raise pf
  val d = Bool()
  val a = Bool()
  val g = Bool()
  val u = Bool()
  val x = Bool()
  val w = Bool()
  val r = Bool()

  // pma perm check
  // val at = Bool() // Access Type
  // val as = Bool() // Atomic Swap
  // val al = Bool() // Atomic Logical
  // val aa = Bool() // Atomic Arithmetic
  // TODO: add pma check
}

Y
Yinan Xu 已提交
79 80
class comBundle extends TlbBundle with HasCircularQueuePtrHelper{
  val roqIdx = new RoqPtr
81 82 83
  val valid = Bool()
  val bits = new PtwReq
  def isPrior(that: comBundle): Bool = {
Y
Yinan Xu 已提交
84
    (this.valid && !that.valid) || (this.valid && that.valid && isAfter(that.roqIdx, this.roqIdx))
85 86 87 88 89 90 91 92
  }
}
object Compare {
  def apply[T<:Data](xs: Seq[comBundle]): comBundle = {
    ParallelOperation(xs, (a: comBundle, b: comBundle) => Mux(a isPrior b, a, b))
  }
}

93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
// multi-read && single-write
// input is data, output is hot-code(not one-hot)
class CAMTemplate[T <: Data](val gen: T, val set: Int, val readWidth: Int) extends TlbModule {
  val io = IO(new Bundle {
    val r = new Bundle {
      val req = Input(Vec(readWidth, gen))
      val resp = Output(Vec(readWidth, UInt(set.W)))
    }
    val w = Flipped(ValidIO(new Bundle {
      val index = UInt(log2Up(set).W)
      val data = gen
    }))
  })

  val wordType = UInt(gen.getWidth.W)
  val array = Reg(Vec(set, wordType))

  io.r.resp.zipWithIndex.map{ case (a,i) =>
    a := VecInit(array.map(io.r.req(i).asUInt === _)).asUInt
  }

  when (io.w.valid) {
    array(io.w.bits.index) := io.w.bits.data
  }
}

119
class TlbEntryData extends TlbBundle {
Z
ZhangZifei 已提交
120
  val ppn = UInt(ppnLen.W)
121
  val perm = new TlbPermBundle
122 123 124 125 126 127 128
  // TODO: change perm to every kinds of pf check

  override def toPrintable: Printable = {
    p"ppn:0x${Hexadecimal(ppn)} perm:${perm}"
  }
}

129
class TlbEntry(superpage: Boolean = false) extends TlbBundle {
130
  val tag = UInt(vpnLen.W) // tag is vpn
131
  val level = if(superpage) Some(UInt(1.W)) else None // /*2 for 4KB,*/ 1 for 2MB, 0 for 1GB
132
  val data = new TlbEntryData
Z
ZhangZifei 已提交
133

134 135

  def hit(vpn: UInt): Bool = {
136
    if (superpage) {
137 138 139 140
      val insideLevel = level.getOrElse(0.U)
      val a = tag(vpnnLen*3-1, vpnnLen*2) === data.ppn(vpnnLen*3-1, vpnnLen*2)
      val b = tag(vpnnLen*2-1, vpnnLen*1) === data.ppn(vpnnLen*2-1, vpnnLen*1)
      Mux(insideLevel.asBool, a&b, a)
141 142 143
    } else {
      tag === vpn
    }
Z
ZhangZifei 已提交
144 145
  }

146 147 148 149 150 151 152 153 154 155
  def ppn(vpn: UInt): UInt = {
    if (superpage) {
      val insideLevel = level.getOrElse(0.U)
      Mux(insideLevel.asBool, Cat(data.ppn(data.ppn.getWidth-1, vpnnLen*1), vpn(vpnnLen*1-1, 0)),
                              Cat(data.ppn(data.ppn.getWidth-1, vpnnLen*2), vpn(vpnnLen*2-1, 0)))
    } else {
      data.ppn
    }
  }

156 157
  def apply(vpn: UInt, ppn: UInt, level: UInt, perm: UInt, pf: Bool) = {
    this.tag := vpn
158
    this.level.map(_ := level(0))
159
    this.data.ppn := ppn
160
    val ptePerm = perm.asTypeOf(new PtePermBundle)
161 162 163 164 165 166 167 168 169 170
    this.data.perm.pf:= pf
    this.data.perm.d := ptePerm.d
    this.data.perm.a := ptePerm.a
    this.data.perm.g := ptePerm.g
    this.data.perm.u := ptePerm.u
    this.data.perm.x := ptePerm.x
    this.data.perm.w := ptePerm.w
    this.data.perm.r := ptePerm.r

    this
Z
ZhangZifei 已提交
171
  }
Z
ZhangZifei 已提交
172 173

  override def toPrintable: Printable = {
174 175
    val insideLevel = level.getOrElse(0.U)
    p"vpn:0x${Hexadecimal(tag)} level:${insideLevel} data:${data}"
Z
ZhangZifei 已提交
176
  }
177

178
  override def cloneType: this.type = (new TlbEntry(superpage)).asInstanceOf[this.type]
Z
ZhangZifei 已提交
179 180
}

181 182 183 184 185 186
object TlbCmd {
  def read  = "b00".U
  def write = "b01".U
  def exec  = "b10".U

  def apply() = UInt(2.W)
Z
ZhangZifei 已提交
187 188 189
  def isRead(a: UInt) = a===read
  def isWrite(a: UInt) = a===write
  def isExec(a: UInt) = a===exec
190 191
}

192
class TlbReq extends TlbBundle {
Y
Yinan Xu 已提交
193
  val vaddr = UInt(VAddrBits.W)
194
  val cmd = TlbCmd()
Y
Yinan Xu 已提交
195
  val roqIdx = new RoqPtr
196 197 198
  val debug = new Bundle {
    val pc = UInt(XLEN.W)
  }
Z
ZhangZifei 已提交
199 200

  override def toPrintable: Printable = {
Y
Yinan Xu 已提交
201
    p"vaddr:0x${Hexadecimal(vaddr)} cmd:${cmd} pc:0x${Hexadecimal(debug.pc)} roqIdx:${roqIdx}"
Z
ZhangZifei 已提交
202
  }
Y
Yinan Xu 已提交
203 204
}

205
class TlbResp extends TlbBundle {
Y
Yinan Xu 已提交
206 207
  val paddr = UInt(PAddrBits.W)
  val miss = Bool()
Z
ZhangZifei 已提交
208 209 210 211 212 213 214
  val excp = new Bundle {
    val pf = new Bundle {
      val ld = Bool()
      val st = Bool()
      val instr = Bool()
    }
  }
Z
ZhangZifei 已提交
215 216 217
  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}"
  }
218 219
}

220
class TlbRequestIO() extends TlbBundle {
221 222
  val req = DecoupledIO(new TlbReq)
  val resp = Flipped(DecoupledIO(new TlbResp))
Y
Yinan Xu 已提交
223 224
}

Z
zhanglinjuan 已提交
225 226 227 228 229
class BlockTlbRequestIO() extends TlbBundle {
  val req = DecoupledIO(new TlbReq)
  val resp = Flipped(DecoupledIO(new TlbResp))
}

Z
ZhangZifei 已提交
230
class TlbPtwIO extends TlbBundle {
Z
ZhangZifei 已提交
231 232
  val req = DecoupledIO(new PtwReq)
  val resp = Flipped(DecoupledIO(new PtwResp))
Y
Yinan Xu 已提交
233 234
}

235
class TlbIO(Width: Int) extends TlbBundle {
236
  val requestor = Vec(Width, Flipped(new TlbRequestIO))
237
  val ptw = new TlbPtwIO
L
LinJiawei 已提交
238
  val sfence = Input(new SfenceBundle)
L
LinJiawei 已提交
239
  val csr = Input(new TlbCsrBundle)
240 241

  override def cloneType: this.type = (new TlbIO(Width)).asInstanceOf[this.type]
Y
Yinan Xu 已提交
242 243 244
}


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

248 249
  val req    = io.requestor.map(_.req)
  val resp   = io.requestor.map(_.resp)
250
  val ptw    = io.ptw
251

L
LinJiawei 已提交
252
  val sfence = io.sfence
L
LinJiawei 已提交
253
  val csr    = io.csr
254 255
  val satp   = csr.satp
  val priv   = csr.priv
Z
ZhangZifei 已提交
256 257
  val ifecth = if (isDtlb) false.B else true.B
  val mode   = if (isDtlb) priv.dmode else priv.imode
258 259
  val vmEnable = satp.mode === 8.U // && (mode < ModeM) // FIXME: fix me when boot xv6/linux...
  // val vmEnable = satp.mode === 8.U && (mode < ModeM)
260

261
  val reqAddr = req.map(_.bits.vaddr.asTypeOf(vaBundle))
262 263
  val cmd     = req.map(_.bits.cmd)
  val valid   = req.map(_.valid)
Z
ZhangZifei 已提交
264

265 266 267
  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)

268 269 270 271 272 273 274 275 276
  // Normal page && Super page
  val nv = RegInit(VecInit(Seq.fill(TlbEntrySize)(false.B)))
  val nentry = Reg(Vec(TlbEntrySize, new TlbEntry(false)))
  val sv = RegInit(VecInit(Seq.fill(TlbSPEntrySize)(false.B)))
  val sentry = Reg(Vec(TlbSPEntrySize, new TlbEntry(true)))
  val v = nv ++ sv
  val entry = nentry ++ sentry
  val g = VecInit(entry.map(_.data.perm.g))
  val pf = VecInit(entry.zip(v).map{ case(e, vi) => e.data.perm.pf & vi })
Z
ZhangZifei 已提交
277

278 279 280 281
  /**
    * PTW refill
    */
  val refill = ptw.resp.fire()
282 283 284 285 286 287 288 289
  def randReplace(v: UInt) = {
    val width = v.getWidth
    val randIdx = LFSR64()(log2Up(width)-1, 0)
    val priorIdx = PriorityEncoder(~(v))
    val full = Cat(v).andR
    Mux(full, randIdx, priorIdx)
  }

290
  when (refill) {
291
    val resp = ptw.resp.bits
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
    when (resp.entry.level === 2.U) {
      val refillIdx = randReplace(nv.asUInt)
      nv(refillIdx) := true.B
      nentry(refillIdx).apply(
        vpn   = resp.entry.tag,
        ppn   = resp.entry.ppn,
        level = resp.entry.level,
        perm  = VecInit(resp.entry.perm).asUInt,
        pf    = resp.pf
      )
      XSDebug(p"Refill normal: idx:${refillIdx} entry:${resp.entry} pf:${resp.pf}\n")
    }.otherwise {
      val refillIdx = randReplace(sv.asUInt)
      sv(refillIdx) := true.B
      sentry(refillIdx).apply(
        vpn   = resp.entry.tag,
        ppn   = resp.entry.ppn,
        level = resp.entry.level,
        perm  = VecInit(resp.entry.perm).asUInt,
        pf    = resp.pf
      )
      XSDebug(p"Refill superpage: idx:${refillIdx} entry:${resp.entry} pf:${resp.pf}\n")
    }
315 316 317 318 319
  }

  /**
    * L1 TLB read
    */
320
  val tlb_read_mask = Mux(refill, (1<<(TlbEntrySize+TlbSPEntrySize)-1).U, 0.U((TlbEntrySize+TlbSPEntrySize).W))
321
  def TLBNormalRead(i: Int) = {
322 323 324 325 326 327
    val entryHitVec = (
      if (isDtlb)
        VecInit((tlb_read_mask.asBools zip entry).map{ case (r, e) => !r && e.hit(reqAddr(i).vpn/*, satp.asid*/)})
      else
        VecInit(entry.map(_.hit(reqAddr(i).vpn/*, satp.asid*/)))
    )
Y
Yinan Xu 已提交
328 329 330 331 332 333

    val reqAddrReg = if (isDtlb) RegNext(reqAddr(i)) else reqAddr(i)
    val cmdReg = if (isDtlb) RegNext(cmd(i)) else cmd(i)
    val validReg = if (isDtlb) RegNext(valid(i)) else valid(i)
    val entryHitVecReg = if (isDtlb) RegNext(entryHitVec) else entryHitVec

334 335
    val hitVec  = (v zip entryHitVecReg).map{ case (a,b) => a&b }
    val pfHitVec   = (pf zip entryHitVecReg).map{ case (a,b) => a&b }
Y
Yinan Xu 已提交
336 337 338
    val pfArray = ParallelOR(pfHitVec).asBool && validReg && vmEnable
    val hit     = ParallelOR(hitVec).asBool && validReg && vmEnable && ~pfArray
    val miss    = !hit && validReg && vmEnable && ~pfArray
339
    val hitppn  = ParallelMux(hitVec zip entry.map(_.ppn(reqAddrReg.vpn)))
340
    val hitPerm = ParallelMux(hitVec zip entry.map(_.data.perm))
341

Y
Yinan Xu 已提交
342 343
    val multiHit = {
      val hitSum = PopCount(hitVec)
344
      !(hitSum===0.U || hitSum===1.U)
Y
Yinan Xu 已提交
345
    }
Z
ZhangZifei 已提交
346

Y
Yinan Xu 已提交
347
    // resp  // TODO: A/D has not being concerned
348
    val paddr = Cat(hitppn, reqAddrReg.off)
349
    val vaddr = SignExt(req(i).bits.vaddr, PAddrBits)
350

351
    req(i).ready := resp(i).ready
Y
Yinan Xu 已提交
352
    resp(i).valid := validReg
353
    resp(i).bits.paddr := Mux(vmEnable, paddr, if (isDtlb) RegNext(vaddr) else vaddr)
Y
Yinan Xu 已提交
354
    resp(i).bits.miss := miss
Z
ZhangZifei 已提交
355

Y
Yinan Xu 已提交
356
    val perm = hitPerm // NOTE: given the excp, the out module choose one to use?
Y
Yinan Xu 已提交
357
    val update = false.B && hit && (!hitPerm.a || !hitPerm.d && TlbCmd.isWrite(cmdReg)) // update A/D through exception
Z
ZhangZifei 已提交
358
    val modeCheck = !(mode === ModeU && !perm.u || mode === ModeS && perm.u && (!priv.sum || ifecth))
Y
Yinan Xu 已提交
359 360 361
    val ldPf = (pfArray && TlbCmd.isRead(cmdReg) && true.B /*!isAMO*/) || hit && !(modeCheck && (perm.r || priv.mxr && perm.x)) && (TlbCmd.isRead(cmdReg) && true.B/*!isAMO*/) // TODO: handle isAMO
    val stPf = (pfArray && TlbCmd.isWrite(cmdReg) || false.B /*isAMO*/ ) || hit && !(modeCheck && perm.w) && (TlbCmd.isWrite(cmdReg) || false.B/*TODO isAMO. */)
    val instrPf = (pfArray && TlbCmd.isExec(cmdReg)) || hit && !(modeCheck && perm.x) && TlbCmd.isExec(cmdReg)
362 363 364
    resp(i).bits.excp.pf.ld    := ldPf || update
    resp(i).bits.excp.pf.st    := stPf || update
    resp(i).bits.excp.pf.instr := instrPf || update
Y
Yinan Xu 已提交
365 366

    (hit, miss, pfHitVec, multiHit)
Z
ZhangZifei 已提交
367 368
  }

369
  val readResult = (0 until Width).map(TLBNormalRead(_))
Y
Yinan Xu 已提交
370 371 372 373 374 375
  val hitVec = readResult.map(res => res._1)
  val missVec = readResult.map(res => res._2)
  val pfHitVecVec = readResult.map(res => res._3)
  val multiHitVec = readResult.map(res => res._4)
  val hasMissReq = Cat(missVec).orR

Z
ZhangZifei 已提交
376
  // ptw
377 378 379 380 381 382 383 384 385
  val waiting = RegInit(false.B)
  when (ptw.req.fire()) {
    waiting := true.B
  }.elsewhen (sfence.valid && ptw.resp.valid) {
    waiting := false.B
  }
  // ptw <> DontCare // TODO: need check it
  ptw.req.valid := hasMissReq && !sfence.valid && !waiting
  ptw.resp.ready := waiting
386

387 388 389
  // val ptwReqSeq = Wire(Seq.fill(Width)(new comBundle()))
  val ptwReqSeq = Seq.fill(Width)(Wire(new comBundle()))
  for (i <- 0 until Width) {
Y
Yinan Xu 已提交
390 391 392
    ptwReqSeq(i).valid := ((if (isDtlb) RegNext(valid(i)) else valid(i)) && missVec(i))
    ptwReqSeq(i).roqIdx := (if (isDtlb) RegNext(req(i).bits.roqIdx) else req(i).bits.roqIdx)
    ptwReqSeq(i).bits.vpn := (if (isDtlb) RegNext(reqAddr(i).vpn) else reqAddr(i).vpn)
393 394 395
  }
  ptw.req.bits := Compare(ptwReqSeq).bits

396 397 398 399
  val tooManyPf = PopCount(pf) > 5.U
  when (tooManyPf) { // when too much pf, just clear
    XSDebug(p"Too many pf just flush all the pf v:${Hexadecimal(VecInit(v).asUInt)} pf:${Hexadecimal(pf.asUInt)}\n")
    v.zipWithIndex.map{ case (a, i) => a := a & !pf(i) }
400 401 402 403
  }

  // sfence (flush)
  when (sfence.valid) {
404
    ptw.req.valid := false.B
405 406
    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)
407
        // all addr and all asid
408
        v.map(_ := false.B)
409 410
      }.otherwise {
        // all addr but specific asid
411
        v.zipWithIndex.map{ case (a,i) => a := a & g(i) }
412
      }
413
    }.otherwise {
414
      val sfenceVpn = sfence.bits.addr.asTypeOf(vaBundle).vpn
415 416
      when (sfence.bits.rs2) {
        // specific addr but all asid
417
        v.zipWithIndex.map{ case (a,i) => a := a & !entry(i).hit(sfenceVpn) }
418 419
      }.otherwise {
        // specific addr and specific asid
420
        v.zipWithIndex.map{ case (a,i) => a := a & !(entry(i).hit(sfenceVpn) && !g(i))}
421 422 423 424
      }
    }
  }

Z
zhanglinjuan 已提交
425
  if (!env.FPGAPlatform && isDtlb) {
426 427 428 429 430 431 432 433
    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 && missVec(0), "perfCntDtlbMissCnt0", Perf)
    ExcitingUtils.addSource(valid(1) && vmEnable && missVec(1), "perfCntDtlbMissCnt1", Perf)
    ExcitingUtils.addSource(valid(2) && vmEnable && missVec(2), "perfCntDtlbMissCnt2", Perf)
    ExcitingUtils.addSource(valid(3) && vmEnable && missVec(3), "perfCntDtlbMissCnt3", Perf)
Z
ZhangZifei 已提交
434 435
  }

Z
zhanglinjuan 已提交
436
  if (!env.FPGAPlatform && !isDtlb) {
437 438
    ExcitingUtils.addSource(valid(0) && vmEnable, "perfCntItlbReqCnt0", Perf)
    ExcitingUtils.addSource(valid(0) && vmEnable && missVec(0), "perfCntItlbMissCnt0", Perf)
Z
zhanglinjuan 已提交
439 440
  }

441
  // Log
Z
ZhangZifei 已提交
442
  for(i <- 0 until Width) {
443 444
    XSDebug(req(i).valid, p"req(${i.U}): (${req(i).valid} ${req(i).ready}) ${req(i).bits}\n")
    XSDebug(resp(i).valid, p"resp(${i.U}): (${resp(i).valid} ${resp(i).ready}) ${resp(i).bits}\n")
Z
ZhangZifei 已提交
445 446 447
  }

  XSDebug(sfence.valid, p"Sfence: ${sfence}\n")
448
  XSDebug(ParallelOR(valid)|| ptw.resp.valid, p"CSR: ${csr}\n")
449
  XSDebug(ParallelOR(valid) || ptw.resp.valid, p"vmEnable:${vmEnable} hit:${Binary(VecInit(hitVec).asUInt)} miss:${Binary(VecInit(missVec).asUInt)} v:${Hexadecimal(VecInit(v).asUInt)} pf:${Hexadecimal(pf.asUInt)}\n")
Z
ZhangZifei 已提交
450
  XSDebug(ptw.req.fire(), p"PTW req:${ptw.req.bits}\n")
451
  XSDebug(ptw.resp.valid, p"PTW resp:${ptw.resp.bits} (v:${ptw.resp.valid}r:${ptw.resp.ready}) \n")
452 453 454 455 456 457 458

  // NOTE: just for simple tlb debug, comment it after tlb's debug
  for (i <- 0 until Width) {
    if(isDtlb) {
      XSDebug(!(!vmEnable || RegNext(req(i).bits.vaddr)===resp(i).bits.paddr || !resp(i).valid || resp(i).bits.miss), p"Dtlb: vaddr:${Hexadecimal(RegNext(req(i).bits.vaddr))} paddr:${Hexadecimal(resp(i).bits.paddr)} should be equal\n")
      assert(!vmEnable || RegNext(req(i).bits.vaddr)===resp(i).bits.paddr || !resp(i).valid || resp(i).bits.miss)
    } else {
459
      XSDebug(!(!vmEnable || req(i).bits.vaddr===resp(i).bits.paddr || !resp(i).valid || resp(i).bits.miss), p"Itlb: vaddr:${Hexadecimal(RegNext(req(i).bits.vaddr))} paddr:${Hexadecimal(resp(i).bits.paddr)} should be equal\n")
460 461 462
      assert(!vmEnable || req(i).bits.vaddr===resp(i).bits.paddr || !resp(i).valid || resp(i).bits.miss)
    }
  }
Y
Yinan Xu 已提交
463
}
Z
zhanglinjuan 已提交
464 465

object TLB {
L
LinJiawei 已提交
466 467 468 469
  def apply
  (
    in: Seq[BlockTlbRequestIO],
    sfence: SfenceBundle,
L
LinJiawei 已提交
470
    csr: TlbCsrBundle,
L
LinJiawei 已提交
471 472 473 474
    width: Int,
    isDtlb: Boolean,
    shouldBlock: Boolean
  ) = {
Z
zhanglinjuan 已提交
475
    require(in.length == width)
476

Z
zhanglinjuan 已提交
477
    val tlb = Module(new TLB(width, isDtlb))
L
LinJiawei 已提交
478 479

    tlb.io.sfence <> sfence
L
LinJiawei 已提交
480
    tlb.io.csr <> csr
481

Z
zhanglinjuan 已提交
482 483
    if (!shouldBlock) { // dtlb
      for (i <- 0 until width) {
484 485 486 487 488 489 490 491
        tlb.io.requestor(i) <> in(i)
        // tlb.io.requestor(i).req.valid := in(i).req.valid
        // tlb.io.requestor(i).req.bits := in(i).req.bits
        // in(i).req.ready := tlb.io.requestor(i).req.ready

        // in(i).resp.valid := tlb.io.requestor(i).resp.valid
        // in(i).resp.bits := tlb.io.requestor(i).resp.bits
        // tlb.io.requestor(i).resp.ready := in(i).resp.ready
Z
zhanglinjuan 已提交
492 493 494 495
      }
    } else { // itlb
      require(width == 1)
      tlb.io.requestor(0).req.valid := in(0).req.valid
Z
zhanglinjuan 已提交
496
      tlb.io.requestor(0).req.bits := in(0).req.bits
497
      in(0).req.ready := !tlb.io.requestor(0).resp.bits.miss && in(0).resp.ready && tlb.io.requestor(0).req.ready
Z
zhanglinjuan 已提交
498 499 500

      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
501
      tlb.io.requestor(0).resp.ready := in(0).resp.ready
Z
zhanglinjuan 已提交
502 503 504 505
    }

    tlb.io.ptw
  }
Z
ZhangZifei 已提交
506
}