dtlb.scala 17.9 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
8
import xiangshan.backend.fu.util.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
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
77 78 79
  override def toPrintable: Printable = {
    p"pf:${pf} d:${d} a:${a} g:${g} u:${u} x:${x} w:${w} r:${r}"
  }
80 81
}

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

96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
// 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
  }
}

122
class TlbEntryData extends TlbBundle {
Z
ZhangZifei 已提交
123
  val ppn = UInt(ppnLen.W)
124
  val perm = new TlbPermBundle
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}"
  }
}

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

137 138

  def hit(vpn: UInt): Bool = {
139
    if (superpage) {
140
      val insideLevel = level.getOrElse(0.U)
141 142
      val a = tag(vpnnLen*3-1, vpnnLen*2) === vpn(vpnnLen*3-1, vpnnLen*2)
      val b = tag(vpnnLen*2-1, vpnnLen*1) === vpn(vpnnLen*2-1, vpnnLen*1)
143
      XSDebug(Mux(insideLevel.asBool, a&b, a), p"Hit superpage: hit:${Mux(insideLevel.asBool, a&b, a)} tag:${Hexadecimal(tag)} level:${insideLevel} data:${data} a:${a} b:${b} vpn:${Hexadecimal(vpn)}\n")("TlbEntrySuperpage")
144
      Mux(insideLevel.asBool, a&b, a)
145
    } else {
146
      XSDebug(tag === vpn, p"Hit normalpage: hit:${tag === vpn} tag:${Hexadecimal(tag)} data:${data}  vpn:${Hexadecimal(vpn)}\n")("TlbEntryNormalpage")
147 148
      tag === vpn
    }
Z
ZhangZifei 已提交
149 150
  }

151 152 153 154 155 156 157 158 159 160
  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
    }
  }

161 162
  def apply(vpn: UInt, ppn: UInt, level: UInt, perm: UInt, pf: Bool) = {
    this.tag := vpn
163
    this.level.map(_ := level(0))
164
    this.data.ppn := ppn
165
    val ptePerm = perm.asTypeOf(new PtePermBundle)
166 167 168 169 170 171 172 173 174 175
    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 已提交
176
  }
Z
ZhangZifei 已提交
177 178

  override def toPrintable: Printable = {
179 180
    val insideLevel = level.getOrElse(0.U)
    p"vpn:0x${Hexadecimal(tag)} level:${insideLevel} data:${data}"
Z
ZhangZifei 已提交
181
  }
182

183
  override def cloneType: this.type = (new TlbEntry(superpage)).asInstanceOf[this.type]
Z
ZhangZifei 已提交
184 185
}

186 187 188 189 190 191
object TlbCmd {
  def read  = "b00".U
  def write = "b01".U
  def exec  = "b10".U

  def apply() = UInt(2.W)
Z
ZhangZifei 已提交
192 193 194
  def isRead(a: UInt) = a===read
  def isWrite(a: UInt) = a===write
  def isExec(a: UInt) = a===exec
195 196
}

197
class TlbReq extends TlbBundle {
Y
Yinan Xu 已提交
198
  val vaddr = UInt(VAddrBits.W)
199
  val cmd = TlbCmd()
Y
Yinan Xu 已提交
200
  val roqIdx = new RoqPtr
201 202 203
  val debug = new Bundle {
    val pc = UInt(XLEN.W)
  }
Z
ZhangZifei 已提交
204 205

  override def toPrintable: Printable = {
Y
Yinan Xu 已提交
206
    p"vaddr:0x${Hexadecimal(vaddr)} cmd:${cmd} pc:0x${Hexadecimal(debug.pc)} roqIdx:${roqIdx}"
Z
ZhangZifei 已提交
207
  }
Y
Yinan Xu 已提交
208 209
}

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

225
class TlbRequestIO() extends TlbBundle {
226 227
  val req = DecoupledIO(new TlbReq)
  val resp = Flipped(DecoupledIO(new TlbResp))
Y
Yinan Xu 已提交
228 229
}

Z
zhanglinjuan 已提交
230 231 232 233 234
class BlockTlbRequestIO() extends TlbBundle {
  val req = DecoupledIO(new TlbReq)
  val resp = Flipped(DecoupledIO(new TlbResp))
}

Z
ZhangZifei 已提交
235
class TlbPtwIO extends TlbBundle {
Z
ZhangZifei 已提交
236 237
  val req = DecoupledIO(new PtwReq)
  val resp = Flipped(DecoupledIO(new PtwResp))
Y
Yinan Xu 已提交
238 239
}

240
class TlbIO(Width: Int) extends TlbBundle {
241
  val requestor = Vec(Width, Flipped(new TlbRequestIO))
242
  val ptw = new TlbPtwIO
L
LinJiawei 已提交
243
  val sfence = Input(new SfenceBundle)
L
LinJiawei 已提交
244
  val csr = Input(new TlbCsrBundle)
245 246

  override def cloneType: this.type = (new TlbIO(Width)).asInstanceOf[this.type]
Y
Yinan Xu 已提交
247 248 249
}


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

253 254
  val req    = io.requestor.map(_.req)
  val resp   = io.requestor.map(_.resp)
255
  val ptw    = io.ptw
256

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

266
  val reqAddr = req.map(_.bits.vaddr.asTypeOf(vaBundle))
267 268
  val cmd     = req.map(_.bits.cmd)
  val valid   = req.map(_.valid)
Z
ZhangZifei 已提交
269

270 271 272
  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)

273 274 275 276 277 278 279 280 281
  // 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 已提交
282

283 284 285 286
  /**
    * PTW refill
    */
  val refill = ptw.resp.fire()
287 288 289 290 291 292 293 294
  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)
  }

295
  when (refill) {
296
    val resp = ptw.resp.bits
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
    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")
    }
320 321 322 323 324
  }

  /**
    * L1 TLB read
    */
325
  val tlb_read_mask = Mux(refill, (1<<(TlbEntrySize+TlbSPEntrySize)-1).U, 0.U((TlbEntrySize+TlbSPEntrySize).W))
326
  def TLBNormalRead(i: Int) = {
327 328 329 330 331 332
    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 已提交
333 334 335 336 337 338

    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

339 340
    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 已提交
341 342 343
    val pfArray = ParallelOR(pfHitVec).asBool && validReg && vmEnable
    val hit     = ParallelOR(hitVec).asBool && validReg && vmEnable && ~pfArray
    val miss    = !hit && validReg && vmEnable && ~pfArray
344
    val hitppn  = ParallelMux(hitVec zip entry.map(_.ppn(reqAddrReg.vpn)))
345
    val hitPerm = ParallelMux(hitVec zip entry.map(_.data.perm))
346

347 348
    XSDebug(valid(i), p"(${i.U}) entryHit:${Hexadecimal(entryHitVec.asUInt)}\n")
    XSDebug(validReg, p"(${i.U}) entryHitReg:${Hexadecimal(entryHitVecReg.asUInt)} hitVec:${Hexadecimal(VecInit(hitVec).asUInt)} pfHitVec:${Hexadecimal(VecInit(pfHitVec).asUInt)} pfArray:${Hexadecimal(pfArray.asUInt)} hit:${hit} miss:${miss} hitppn:${Hexadecimal(hitppn)} hitPerm:${hitPerm}\n")
349

Y
Yinan Xu 已提交
350 351
    val multiHit = {
      val hitSum = PopCount(hitVec)
352
      !(hitSum===0.U || hitSum===1.U)
Y
Yinan Xu 已提交
353
    }
Z
ZhangZifei 已提交
354

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

359
    req(i).ready := resp(i).ready
Y
Yinan Xu 已提交
360
    resp(i).valid := validReg
361
    resp(i).bits.paddr := Mux(vmEnable, paddr, if (isDtlb) RegNext(vaddr) else vaddr)
Y
Yinan Xu 已提交
362
    resp(i).bits.miss := miss
Z
ZhangZifei 已提交
363

Y
Yinan Xu 已提交
364
    val perm = hitPerm // NOTE: given the excp, the out module choose one to use?
Y
Yinan Xu 已提交
365
    val update = false.B && hit && (!hitPerm.a || !hitPerm.d && TlbCmd.isWrite(cmdReg)) // update A/D through exception
Z
ZhangZifei 已提交
366
    val modeCheck = !(mode === ModeU && !perm.u || mode === ModeS && perm.u && (!priv.sum || ifecth))
Y
Yinan Xu 已提交
367 368 369
    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)
370 371 372
    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 已提交
373 374

    (hit, miss, pfHitVec, multiHit)
Z
ZhangZifei 已提交
375 376
  }

377
  val readResult = (0 until Width).map(TLBNormalRead(_))
Y
Yinan Xu 已提交
378 379 380 381 382 383
  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 已提交
384
  // ptw
385 386 387
  val waiting = RegInit(false.B)
  when (ptw.req.fire()) {
    waiting := true.B
388
  }.elsewhen (sfence.valid || ptw.resp.valid) {
389 390 391 392 393
    waiting := false.B
  }
  // ptw <> DontCare // TODO: need check it
  ptw.req.valid := hasMissReq && !sfence.valid && !waiting
  ptw.resp.ready := waiting
394

395 396 397
  // val ptwReqSeq = Wire(Seq.fill(Width)(new comBundle()))
  val ptwReqSeq = Seq.fill(Width)(Wire(new comBundle()))
  for (i <- 0 until Width) {
Y
Yinan Xu 已提交
398 399 400
    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)
401 402 403
  }
  ptw.req.bits := Compare(ptwReqSeq).bits

404 405 406 407
  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) }
408 409 410 411
  }

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

Z
zhanglinjuan 已提交
433
  if (!env.FPGAPlatform && isDtlb) {
434 435 436 437 438 439 440 441
    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 已提交
442 443
  }

Z
zhanglinjuan 已提交
444
  if (!env.FPGAPlatform && !isDtlb) {
445 446
    ExcitingUtils.addSource(valid(0) && vmEnable, "perfCntItlbReqCnt0", Perf)
    ExcitingUtils.addSource(valid(0) && vmEnable && missVec(0), "perfCntItlbMissCnt0", Perf)
Z
zhanglinjuan 已提交
447 448
  }

449
  // Log
Z
ZhangZifei 已提交
450
  for(i <- 0 until Width) {
451 452
    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 已提交
453 454 455
  }

  XSDebug(sfence.valid, p"Sfence: ${sfence}\n")
456
  XSDebug(ParallelOR(valid)|| ptw.resp.valid, p"CSR: ${csr}\n")
457
  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 已提交
458
  XSDebug(ptw.req.fire(), p"PTW req:${ptw.req.bits}\n")
459
  XSDebug(ptw.resp.valid, p"PTW resp:${ptw.resp.bits} (v:${ptw.resp.valid}r:${ptw.resp.ready}) \n")
460

Z
ZhangZifei 已提交
461 462 463 464 465 466 467 468 469 470
//   // 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 || Cat(VecInit(resp(i).bits.excp.pf).asUInt).orR), 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 || Cat(VecInit(resp(i).bits.excp.pf).asUInt).orR)
//     } else {
//       XSDebug(!(!vmEnable || req(i).bits.vaddr===resp(i).bits.paddr || !resp(i).valid || resp(i).bits.miss || Cat(VecInit(resp(i).bits.excp.pf).asUInt).orR), 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 || Cat(VecInit(resp(i).bits.excp.pf).asUInt).orR)
//     }
//   }
Y
Yinan Xu 已提交
471
}
Z
zhanglinjuan 已提交
472 473

object TLB {
L
LinJiawei 已提交
474 475 476 477
  def apply
  (
    in: Seq[BlockTlbRequestIO],
    sfence: SfenceBundle,
L
LinJiawei 已提交
478
    csr: TlbCsrBundle,
L
LinJiawei 已提交
479 480 481 482
    width: Int,
    isDtlb: Boolean,
    shouldBlock: Boolean
  ) = {
Z
zhanglinjuan 已提交
483
    require(in.length == width)
484

Z
zhanglinjuan 已提交
485
    val tlb = Module(new TLB(width, isDtlb))
L
LinJiawei 已提交
486 487

    tlb.io.sfence <> sfence
L
LinJiawei 已提交
488
    tlb.io.csr <> csr
489

Z
zhanglinjuan 已提交
490 491
    if (!shouldBlock) { // dtlb
      for (i <- 0 until width) {
492 493 494 495 496 497 498 499
        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 已提交
500 501 502 503
      }
    } else { // itlb
      require(width == 1)
      tlb.io.requestor(0).req.valid := in(0).req.valid
Z
zhanglinjuan 已提交
504
      tlb.io.requestor(0).req.bits := in(0).req.bits
505
      in(0).req.ready := !tlb.io.requestor(0).resp.bits.miss && in(0).resp.ready && tlb.io.requestor(0).req.ready
Z
zhanglinjuan 已提交
506 507 508

      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
509
      tlb.io.requestor(0).resp.ready := in(0).resp.ready
Z
zhanglinjuan 已提交
510 511 512 513
    }

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