dtlb.scala 16.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._
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 47 48 49 50 51 52 53 54

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 已提交
55 56

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

62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
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 已提交
80 81
class comBundle extends TlbBundle with HasCircularQueuePtrHelper{
  val roqIdx = new RoqPtr
82 83 84
  val valid = Bool()
  val bits = new PtwReq
  def isPrior(that: comBundle): Bool = {
Y
Yinan Xu 已提交
85
    (this.valid && !that.valid) || (this.valid && that.valid && isAfter(that.roqIdx, this.roqIdx))
86 87 88 89 90 91 92 93
  }
}
object Compare {
  def apply[T<:Data](xs: Seq[comBundle]): comBundle = {
    ParallelOperation(xs, (a: comBundle, b: comBundle) => Mux(a isPrior b, a, b))
  }
}

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 119
// 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
  }
}

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

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

class TlbEntry(superpage: Boolean = false, superpageOnly: Boolean = false) extends TlbBundle {
  val tag = UInt(vpnLen.W) // tag is vpn
132
  val level = UInt(log2Up(Level).W) // 2 for 4KB, 1 for 2MB, 0 for 1GB
133
  val data = new TlbEntryData
Z
ZhangZifei 已提交
134

135
  def hit(vpn: UInt):Bool = {
136 137 138 139 140 141 142 143 144
    if (superpage) {
      val fullMask = VecInit((Seq.fill(vpnLen)(true.B))).asUInt
      val maskLevel = VecInit((Level-1 to 0 by -1).map{i => // NOTE: level 2 for 4KB, 1 for 2MB, 0 for 1GB
        Reverse(VecInit(Seq.fill(vpnLen-i*vpnnLen)(true.B) ++ Seq.fill(i*vpnnLen)(false.B)).asUInt)})
      val mask = maskLevel(level)
      (mask&this.tag) === (mask&vpn)
    } else {
      tag === vpn
    }
Z
ZhangZifei 已提交
145 146
  }

147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
  def apply(vpn: UInt, ppn: UInt, level: UInt, perm: UInt, pf: Bool) = {
    this.tag := vpn
    this.level := level
    this.data.ppn := ppn
    val ptePerm = perm.asTypeOf(new PermBundle)
    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

    XSDebug(p"refill: vpn:${Hexadecimal(vpn)} level:${level} ppn:${Hexadecimal(ppn)} pf:${pf} d:${ptePerm.d} a:${ptePerm.a} g:${ptePerm.g} u:${ptePerm.u} x:${ptePerm.x} w:${ptePerm.w} r:${ptePerm.r}\n")("Tlbrefill")

    this
Z
ZhangZifei 已提交
164
  }
Z
ZhangZifei 已提交
165 166

  override def toPrintable: Printable = {
167
    p"vpn:0x${Hexadecimal(tag)} level:${level} data:${data}"
Z
ZhangZifei 已提交
168
  }
169 170

  override def cloneType: this.type = (new TlbEntry(superpage, superpageOnly)).asInstanceOf[this.type]
Z
ZhangZifei 已提交
171 172
}

173 174 175 176 177 178
object TlbCmd {
  def read  = "b00".U
  def write = "b01".U
  def exec  = "b10".U

  def apply() = UInt(2.W)
Z
ZhangZifei 已提交
179 180 181
  def isRead(a: UInt) = a===read
  def isWrite(a: UInt) = a===write
  def isExec(a: UInt) = a===exec
182 183
}

184
class TlbReq extends TlbBundle {
Y
Yinan Xu 已提交
185
  val vaddr = UInt(VAddrBits.W)
186
  val cmd = TlbCmd()
Y
Yinan Xu 已提交
187
  val roqIdx = new RoqPtr
188 189 190
  val debug = new Bundle {
    val pc = UInt(XLEN.W)
  }
Z
ZhangZifei 已提交
191 192

  override def toPrintable: Printable = {
Y
Yinan Xu 已提交
193
    p"vaddr:0x${Hexadecimal(vaddr)} cmd:${cmd} pc:0x${Hexadecimal(debug.pc)} roqIdx:${roqIdx}"
Z
ZhangZifei 已提交
194
  }
Y
Yinan Xu 已提交
195 196
}

197
class TlbResp extends TlbBundle {
Y
Yinan Xu 已提交
198 199
  val paddr = UInt(PAddrBits.W)
  val miss = Bool()
Z
ZhangZifei 已提交
200 201 202 203 204 205 206
  val excp = new Bundle {
    val pf = new Bundle {
      val ld = Bool()
      val st = Bool()
      val instr = Bool()
    }
  }
Z
ZhangZifei 已提交
207 208 209
  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}"
  }
210 211
}

212
class TlbRequestIO() extends TlbBundle {
213 214
  val req = DecoupledIO(new TlbReq)
  val resp = Flipped(DecoupledIO(new TlbResp))
Y
Yinan Xu 已提交
215 216
}

Z
zhanglinjuan 已提交
217 218 219 220 221
class BlockTlbRequestIO() extends TlbBundle {
  val req = DecoupledIO(new TlbReq)
  val resp = Flipped(DecoupledIO(new TlbResp))
}

Z
ZhangZifei 已提交
222
class TlbPtwIO extends TlbBundle {
Z
ZhangZifei 已提交
223 224
  val req = DecoupledIO(new PtwReq)
  val resp = Flipped(DecoupledIO(new PtwResp))
Y
Yinan Xu 已提交
225 226
}

227
class TlbIO(Width: Int) extends TlbBundle {
228
  val requestor = Vec(Width, Flipped(new TlbRequestIO))
229
  val ptw = new TlbPtwIO
L
LinJiawei 已提交
230
  val sfence = Input(new SfenceBundle)
L
LinJiawei 已提交
231
  val csr = Input(new TlbCsrBundle)
232 233

  override def cloneType: this.type = (new TlbIO(Width)).asInstanceOf[this.type]
Y
Yinan Xu 已提交
234 235 236
}


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

240 241
  val req    = io.requestor.map(_.req)
  val resp   = io.requestor.map(_.resp)
242
  val ptw    = io.ptw
243

L
LinJiawei 已提交
244
  val sfence = io.sfence
L
LinJiawei 已提交
245
  val csr    = io.csr
246 247
  val satp   = csr.satp
  val priv   = csr.priv
Z
ZhangZifei 已提交
248 249
  val ifecth = if (isDtlb) false.B else true.B
  val mode   = if (isDtlb) priv.dmode else priv.imode
250 251
  val vmEnable = satp.mode === 8.U // && (mode < ModeM) // FIXME: fix me when boot xv6/linux...
  // val vmEnable = satp.mode === 8.U && (mode < ModeM)
252

253
  val reqAddr = req.map(_.bits.vaddr.asTypeOf(vaBundle))
254 255
  val cmd     = req.map(_.bits.cmd)
  val valid   = req.map(_.valid)
Z
ZhangZifei 已提交
256

257 258 259
  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)

260
  // normal page: 4k
261
  val v = RegInit(0.U(TlbEntrySize.W))
262
  // val pf = RegInit(0.U(TlbEntrySize.W))
263
  val entry = Reg(Vec(TlbEntrySize, new TlbEntry))
264
  val pf = VecInit(entry.map(_.data.perm.pf)).asUInt & v
265
  val g = VecInit(entry.map(_.data.perm.g)).asUInt
Z
ZhangZifei 已提交
266

267 268 269 270 271
  /**
    * PTW refill
    */
  val refill = ptw.resp.fire()
  val randIdx = LFSR64()(log2Up(TlbEntrySize)-1,0)
272 273
  val priorIdx = PriorityEncoder(~(v))
  val tlbfull = ParallelAND((v).asBools)
274 275 276
  val refillIdx = Mux(tlbfull, randIdx, priorIdx)
  val refillIdxOH = UIntToOH(refillIdx)
  when (refill) {
277 278 279 280 281 282 283 284 285 286
    val resp = ptw.resp.bits
    v := v | refillIdxOH
    entry(refillIdx).apply(
      vpn   = resp.entry.tag,
      ppn   = resp.entry.ppn,
      level = resp.entry.level,
      perm  = Cat(VecInit(resp.entry.perm).asUInt, 0.U(1.W)).asUInt,
      pf    = resp.pf
    )
    XSDebug(p"Refill: idx:${refillIdx} entry:${resp.entry} pf:${resp.pf}\n")
287 288 289 290 291 292
  }

  /**
    * L1 TLB read
    */
  val tlb_read_mask = Mux(refill, refillIdxOH, 0.U(TlbEntrySize.W))
293
  def TLBNormalRead(i: Int) = {
294 295 296 297 298 299
    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 已提交
300 301 302 303 304 305 306 307 308 309 310

    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

    val hitVec  = (v.asBools zip entryHitVecReg).map{ case (a,b) => a&b }
    val pfHitVec   = (pf.asBools zip entryHitVecReg).map{ case (a,b) => a&b }
    val pfArray = ParallelOR(pfHitVec).asBool && validReg && vmEnable
    val hit     = ParallelOR(hitVec).asBool && validReg && vmEnable && ~pfArray
    val miss    = !hit && validReg && vmEnable && ~pfArray
311 312
    val hitppn  = ParallelMux(hitVec zip entry.map(_.data.ppn))
    val hitPerm = ParallelMux(hitVec zip entry.map(_.data.perm))
Y
Yinan Xu 已提交
313 314 315
    val hitLevel= ParallelMux(hitVec zip entry.map(_.level))
    val multiHit = {
      val hitSum = PopCount(hitVec)
316
      !(hitSum===0.U || hitSum===1.U)
Y
Yinan Xu 已提交
317
    }
Z
ZhangZifei 已提交
318

Y
Yinan Xu 已提交
319
    // resp  // TODO: A/D has not being concerned
Y
Yinan Xu 已提交
320 321 322 323
    val paddr = LookupTreeDefault(hitLevel, Cat(hitppn, reqAddrReg.off), List(
      0.U -> Cat(hitppn(ppnLen - 1, 2*vpnnLen), reqAddrReg.vpn(2*vpnnLen - 1, 0), reqAddrReg.off),
      1.U -> Cat(hitppn(ppnLen - 1, vpnnLen), reqAddrReg.vpn(vpnnLen - 1, 0), reqAddrReg.off),
      2.U -> Cat(hitppn, reqAddrReg.off)
324
    ))
325
    val vaddr = SignExt(req(i).bits.vaddr, PAddrBits)
326

327
    req(i).ready := resp(i).ready
Y
Yinan Xu 已提交
328
    resp(i).valid := validReg
329
    resp(i).bits.paddr := Mux(vmEnable, paddr, if (isDtlb) RegNext(vaddr) else vaddr)
Y
Yinan Xu 已提交
330
    resp(i).bits.miss := miss
Z
ZhangZifei 已提交
331

Y
Yinan Xu 已提交
332
    val perm = hitPerm // NOTE: given the excp, the out module choose one to use?
Y
Yinan Xu 已提交
333
    val update = false.B && hit && (!hitPerm.a || !hitPerm.d && TlbCmd.isWrite(cmdReg)) // update A/D through exception
Z
ZhangZifei 已提交
334
    val modeCheck = !(mode === ModeU && !perm.u || mode === ModeS && perm.u && (!priv.sum || ifecth))
Y
Yinan Xu 已提交
335 336 337
    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)
338 339 340
    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 已提交
341 342

    (hit, miss, pfHitVec, multiHit)
Z
ZhangZifei 已提交
343 344
  }

345
  val readResult = (0 until Width).map(TLBNormalRead(_))
Y
Yinan Xu 已提交
346 347 348 349 350 351
  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 已提交
352
  // ptw
353
  ptw <> DontCare // TODO: need check it
Z
ZhangZifei 已提交
354 355
  ptw.req.valid := hasMissReq && !sfence.valid
  ptw.resp.ready := true.B
356

357 358 359
  // val ptwReqSeq = Wire(Seq.fill(Width)(new comBundle()))
  val ptwReqSeq = Seq.fill(Width)(Wire(new comBundle()))
  for (i <- 0 until Width) {
Y
Yinan Xu 已提交
360 361 362
    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)
363 364 365
  }
  ptw.req.bits := Compare(ptwReqSeq).bits

Z
ZhangZifei 已提交
366
  when (PopCount(pf) > 10.U) { // when too much pf, just clear
367 368
    // pf := Mux(refill && ptw.resp.bits.pf, refillIdxOH, 0.U)
    v := v & ~pf
369 370 371 372
  }

  // sfence (flush)
  when (sfence.valid) {
373
    ptw.req.valid := false.B
374 375
    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)
376 377 378 379 380
        // all addr and all asid
        v := 0.U
      }.otherwise {
        // all addr but specific asid
        v := v & g // TODO: need check if reverse is needed
381
      }
382
    }.otherwise {
383
      val sfenceVpn = sfence.bits.addr.asTypeOf(vaBundle).vpn
384 385
      when (sfence.bits.rs2) {
        // specific addr but all asid
386
        v := v & ~VecInit(entry.map(_.hit(sfenceVpn))).asUInt
387 388
      }.otherwise {
        // specific addr and specific asid
389
        v := v & ~VecInit(entry.map(e => e.hit(sfenceVpn) && !e.data.perm.g)).asUInt
390 391 392 393
      }
    }
  }

Z
zhanglinjuan 已提交
394
  if (!env.FPGAPlatform && isDtlb) {
395 396 397 398 399 400 401 402
    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 已提交
403 404
  }

Z
zhanglinjuan 已提交
405
  if (!env.FPGAPlatform && !isDtlb) {
406 407
    ExcitingUtils.addSource(valid(0) && vmEnable, "perfCntItlbReqCnt0", Perf)
    ExcitingUtils.addSource(valid(0) && vmEnable && missVec(0), "perfCntItlbMissCnt0", Perf)
Z
zhanglinjuan 已提交
408 409
  }

410
  // Log
Z
ZhangZifei 已提交
411
  for(i <- 0 until Width) {
412 413
    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 已提交
414 415 416
  }

  XSDebug(sfence.valid, p"Sfence: ${sfence}\n")
417
  XSDebug(ParallelOR(valid)|| ptw.resp.valid, p"CSR: ${csr}\n")
Z
ZhangZifei 已提交
418
  XSDebug(ParallelOR(valid) || ptw.resp.valid, p"vmEnable:${vmEnable} hit:${Binary(VecInit(hitVec).asUInt)} miss:${Binary(VecInit(missVec).asUInt)} v:${Hexadecimal(v)} pf:${Hexadecimal(pf)}\n")
Z
ZhangZifei 已提交
419
  XSDebug(ptw.req.fire(), p"PTW req:${ptw.req.bits}\n")
420
  XSDebug(ptw.resp.valid, p"PTW resp:${ptw.resp.bits} (v:${ptw.resp.valid}r:${ptw.resp.ready}) \n")
421 422 423 424 425 426 427 428 429 430 431

  // 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 {
      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")
      assert(!vmEnable || req(i).bits.vaddr===resp(i).bits.paddr || !resp(i).valid || resp(i).bits.miss)
    }
  }
Y
Yinan Xu 已提交
432
}
Z
zhanglinjuan 已提交
433 434

object TLB {
L
LinJiawei 已提交
435 436 437 438
  def apply
  (
    in: Seq[BlockTlbRequestIO],
    sfence: SfenceBundle,
L
LinJiawei 已提交
439
    csr: TlbCsrBundle,
L
LinJiawei 已提交
440 441 442 443
    width: Int,
    isDtlb: Boolean,
    shouldBlock: Boolean
  ) = {
Z
zhanglinjuan 已提交
444
    require(in.length == width)
445

Z
zhanglinjuan 已提交
446
    val tlb = Module(new TLB(width, isDtlb))
L
LinJiawei 已提交
447 448

    tlb.io.sfence <> sfence
L
LinJiawei 已提交
449
    tlb.io.csr <> csr
450

Z
zhanglinjuan 已提交
451 452
    if (!shouldBlock) { // dtlb
      for (i <- 0 until width) {
453 454 455 456 457 458 459 460
        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 已提交
461 462 463 464
      }
    } else { // itlb
      require(width == 1)
      tlb.io.requestor(0).req.valid := in(0).req.valid
Z
zhanglinjuan 已提交
465
      tlb.io.requestor(0).req.bits := in(0).req.bits
466
      in(0).req.ready := !tlb.io.requestor(0).resp.bits.miss && in(0).resp.ready && tlb.io.requestor(0).req.ready
Z
zhanglinjuan 已提交
467 468 469

      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
470
      tlb.io.requestor(0).resp.ready := in(0).resp.ready
Z
zhanglinjuan 已提交
471 472 473 474
    }

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