DCacheWrapper.scala 18.1 KB
Newer Older
L
Lemover 已提交
1 2
/***************************************************************************************
* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
Y
Yinan Xu 已提交
3
* Copyright (c) 2020-2021 Peng Cheng Laboratory
L
Lemover 已提交
4 5 6 7 8 9 10 11 12 13 14 15 16
*
* XiangShan is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*          http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*
* See the Mulan PSL v2 for more details.
***************************************************************************************/

A
Allen 已提交
17 18 19 20
package xiangshan.cache

import chipsalliance.rocketchip.config.Parameters
import chisel3._
21
import chisel3.experimental.ExtModule
A
Allen 已提交
22 23 24 25
import chisel3.util._
import xiangshan._
import utils._
import freechips.rocketchip.diplomacy.{IdRange, LazyModule, LazyModuleImp, TransferSizes}
26
import freechips.rocketchip.tilelink._
27
import freechips.rocketchip.util.BundleFieldBase
28
import system.L1CacheErrorInfo
29
import device.RAMHelper
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 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 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
import huancun.{AliasField, AliasKey, PreferCacheField, PrefetchField, DirtyField}

// DCache specific parameters
case class DCacheParameters
(
  nSets: Int = 256,
  nWays: Int = 8,
  rowBits: Int = 128,
  tagECC: Option[String] = None,
  dataECC: Option[String] = None,
  replacer: Option[String] = Some("random"),
  nMissEntries: Int = 1,
  nProbeEntries: Int = 1,
  nReleaseEntries: Int = 1,
  nStoreReplayEntries: Int = 1,
  nMMIOEntries: Int = 1,
  nMMIOs: Int = 1,
  blockBytes: Int = 64
) extends L1CacheParameters {
  // if sets * blockBytes > 4KB(page size),
  // cache alias will happen,
  // we need to avoid this by recoding additional bits in L2 cache
  val setBytes = nSets * blockBytes
  val aliasBitsOpt = if(setBytes > pageSize) Some(log2Ceil(setBytes / pageSize)) else None
  val reqFields: Seq[BundleFieldBase] = Seq(
    PrefetchField(),
    PreferCacheField()
  ) ++ aliasBitsOpt.map(AliasField)
  val echoFields: Seq[BundleFieldBase] = Seq(DirtyField())

  def tagCode: Code = Code.fromString(tagECC)

  def dataCode: Code = Code.fromString(dataECC)
}

//           Physical Address
// --------------------------------------
// |   Physical Tag |  PIndex  | Offset |
// --------------------------------------
//                  |
//                  DCacheTagOffset
// 
//           Virtual Address
// --------------------------------------
// | Above index  | Set | Bank | Offset |
// --------------------------------------
//                |     |      |        |
//                |     |      |        DCacheWordOffset
//                |     |      DCacheBankOffset
//                |     DCacheSetOffset
//                DCacheAboveIndexOffset

// Default DCache size = 64 sets * 8 ways * 8 banks * 8 Byte = 32K Byte

trait HasDCacheParameters extends HasL1CacheParameters {
  val cacheParams = dcacheParameters
  val cfg = cacheParams

  def encWordBits = cacheParams.dataCode.width(wordBits)

  def encRowBits = encWordBits * rowWords // for DuplicatedDataArray only
  def eccBits = encWordBits - wordBits

  def lrscCycles = LRSCCycles // ISA requires 16-insn LRSC sequences to succeed
  def lrscBackoff = 3 // disallow LRSC reacquisition briefly
  def blockProbeAfterGrantCycles = 8 // give the processor some time to issue a request after a grant

  def nSourceType = 3
  def sourceTypeWidth = log2Up(nSourceType)
  def LOAD_SOURCE = 0
  def STORE_SOURCE = 1
  def AMO_SOURCE = 2

  // each source use a id to distinguish its multiple reqs
  def reqIdWidth = 64

  // banked dcache support
  val DCacheSets = cacheParams.nSets
  val DCacheWays = cacheParams.nWays
  val DCacheBanks = 8
  val DCacheSRAMRowBits = 64 // hardcoded

  val DCacheLineBits = DCacheSRAMRowBits * DCacheBanks * DCacheWays * DCacheSets
  val DCacheLineBytes = DCacheLineBits / 8
  val DCacheLineWords = DCacheLineBits / 64 // TODO

  val DCacheSameVPAddrLength = 12

  val DCacheSRAMRowBytes = DCacheSRAMRowBits / 8
  val DCacheWordOffset = 0
  val DCacheBankOffset = DCacheWordOffset + log2Up(DCacheSRAMRowBytes)
  val DCacheSetOffset = DCacheBankOffset + log2Up(DCacheBanks)
  val DCacheAboveIndexOffset = DCacheSetOffset + log2Up(DCacheSets)
  val DCacheTagOffset = DCacheAboveIndexOffset min DCacheSameVPAddrLength
  val DCacheIndexOffset = DCacheBankOffset

  def addr_to_dcache_bank(addr: UInt) = {
    require(addr.getWidth >= DCacheSetOffset)
    addr(DCacheSetOffset-1, DCacheBankOffset)
  }

  def addr_to_dcache_set(addr: UInt) = {
    require(addr.getWidth >= DCacheAboveIndexOffset)
    addr(DCacheAboveIndexOffset-1, DCacheSetOffset)
  }

  def get_data_of_bank(bank: Int, data: UInt) = {
    require(data.getWidth >= (bank+1)*DCacheSRAMRowBits)
    data(DCacheSRAMRowBits * (bank + 1) - 1, DCacheSRAMRowBits * bank)
  }

  def get_mask_of_bank(bank: Int, data: UInt) = {
    require(data.getWidth >= (bank+1)*DCacheSRAMRowBytes)
    data(DCacheSRAMRowBytes * (bank + 1) - 1, DCacheSRAMRowBytes * bank)
  }

  require(isPow2(nSets), s"nSets($nSets) must be pow2")
  require(isPow2(nWays), s"nWays($nWays) must be pow2")
  require(full_divide(rowBits, wordBits), s"rowBits($rowBits) must be multiple of wordBits($wordBits)")
  require(full_divide(beatBits, rowBits), s"beatBits($beatBits) must be multiple of rowBits($rowBits)")
}

abstract class DCacheModule(implicit p: Parameters) extends L1CacheModule
  with HasDCacheParameters

abstract class DCacheBundle(implicit p: Parameters) extends L1CacheBundle
  with HasDCacheParameters

class ReplacementAccessBundle(implicit p: Parameters) extends DCacheBundle {
  val set = UInt(log2Up(nSets).W)
  val way = UInt(log2Up(nWays).W)
}
A
Allen 已提交
162 163

// memory request in word granularity(load, mmio, lr/sc, atomics)
164
class DCacheWordReq(implicit p: Parameters)  extends DCacheBundle
A
Allen 已提交
165 166 167 168 169 170 171 172 173 174 175 176 177
{
  val cmd    = UInt(M_SZ.W)
  val addr   = UInt(PAddrBits.W)
  val data   = UInt(DataBits.W)
  val mask   = UInt((DataBits/8).W)
  val id     = UInt(reqIdWidth.W)
  def dump() = {
    XSDebug("DCacheWordReq: cmd: %x addr: %x data: %x mask: %x id: %d\n",
      cmd, addr, data, mask, id)
  }
}

// memory request in word granularity(store)
178
class DCacheLineReq(implicit p: Parameters)  extends DCacheBundle
A
Allen 已提交
179 180
{
  val cmd    = UInt(M_SZ.W)
181
  val vaddr  = UInt(VAddrBits.W)
A
Allen 已提交
182 183 184 185 186 187 188 189 190 191
  val addr   = UInt(PAddrBits.W)
  val data   = UInt((cfg.blockBytes * 8).W)
  val mask   = UInt(cfg.blockBytes.W)
  val id     = UInt(reqIdWidth.W)
  def dump() = {
    XSDebug("DCacheLineReq: cmd: %x addr: %x data: %x mask: %x id: %d\n",
      cmd, addr, data, mask, id)
  }
}

192 193 194 195
class DCacheWordReqWithVaddr(implicit p: Parameters) extends DCacheWordReq {
  val vaddr = UInt(VAddrBits.W)
}

196
class DCacheWordResp(implicit p: Parameters) extends DCacheBundle
A
Allen 已提交
197 198 199 200 201 202 203 204 205 206 207 208 209
{
  val data         = UInt(DataBits.W)
  // cache req missed, send it to miss queue
  val miss   = Bool()
  // cache req nacked, replay it later
  val replay = Bool()
  val id     = UInt(reqIdWidth.W)
  def dump() = {
    XSDebug("DCacheWordResp: data: %x id: %d miss: %b replay: %b\n",
      data, id, miss, replay)
  }
}

210
class DCacheLineResp(implicit p: Parameters) extends DCacheBundle
A
Allen 已提交
211 212 213 214 215 216 217 218 219 220 221 222 223
{
  val data   = UInt((cfg.blockBytes * 8).W)
  // cache req missed, send it to miss queue
  val miss   = Bool()
  // cache req nacked, replay it later
  val replay = Bool()
  val id     = UInt(reqIdWidth.W)
  def dump() = {
    XSDebug("DCacheLineResp: data: %x id: %d miss: %b replay: %b\n",
      data, id, miss, replay)
  }
}

224
class Refill(implicit p: Parameters) extends DCacheBundle
A
Allen 已提交
225 226
{
  val addr   = UInt(PAddrBits.W)
227
  val data   = UInt(l1BusDataWidth.W)
228 229 230 231
  // for debug usage
  val data_raw = UInt((cfg.blockBytes * 8).W)
  val hasdata = Bool()
  val refill_done = Bool()
A
Allen 已提交
232 233 234 235 236
  def dump() = {
    XSDebug("Refill: addr: %x data: %x\n", addr, data)
  }
}

237
class DCacheWordIO(implicit p: Parameters) extends DCacheBundle
A
Allen 已提交
238 239 240 241 242
{
  val req  = DecoupledIO(new DCacheWordReq)
  val resp = Flipped(DecoupledIO(new DCacheWordResp))
}

243 244 245 246 247 248
class DCacheWordIOWithVaddr(implicit p: Parameters) extends DCacheBundle
{
  val req  = DecoupledIO(new DCacheWordReqWithVaddr)
  val resp = Flipped(DecoupledIO(new DCacheWordResp))
}

A
Allen 已提交
249
// used by load unit
250
class DCacheLoadIO(implicit p: Parameters) extends DCacheWordIO
251 252 253 254 255 256
{
  // kill previous cycle's req
  val s1_kill  = Output(Bool())
  // cycle 0: virtual address: req.addr
  // cycle 1: physical address: s1_paddr
  val s1_paddr = Output(UInt(PAddrBits.W))
257
  val s1_hit_way = Input(UInt(nWays.W))
258
  val s1_disable_fast_wakeup = Input(Bool())
259 260
}

261
class DCacheLineIO(implicit p: Parameters) extends DCacheBundle
A
Allen 已提交
262
{
263
  val req  = DecoupledIO(new DCacheLineReq)
A
Allen 已提交
264 265 266
  val resp = Flipped(DecoupledIO(new DCacheLineResp))
}

267
class DCacheToLsuIO(implicit p: Parameters) extends DCacheBundle {
A
Allen 已提交
268 269 270
  val load  = Vec(LoadPipelineWidth, Flipped(new DCacheLoadIO)) // for speculative load
  val lsq = ValidIO(new Refill)  // refill to load queue, wake up load misses
  val store = Flipped(new DCacheLineIO) // for sbuffer
271
  val atomics  = Flipped(new DCacheWordIOWithVaddr)  // atomics reqs
A
Allen 已提交
272 273
}

274
class DCacheIO(implicit p: Parameters) extends DCacheBundle {
A
Allen 已提交
275
  val lsu = new DCacheToLsuIO
276
  val error = new L1CacheErrorInfo
277
  val mshrFull = Output(Bool())
A
Allen 已提交
278 279 280 281 282 283 284 285 286 287
}


class DCache()(implicit p: Parameters) extends LazyModule with HasDCacheParameters {

  val clientParameters = TLMasterPortParameters.v1(
    Seq(TLMasterParameters.v1(
      name = "dcache",
      sourceId = IdRange(0, cfg.nMissEntries+1),
      supportsProbe = TransferSizes(cfg.blockBytes)
288 289 290
    )),
    requestFields = cacheParams.reqFields,
    echoFields = cacheParams.echoFields
A
Allen 已提交
291 292 293 294 295 296 297 298
  )

  val clientNode = TLClientNode(Seq(clientParameters))

  lazy val module = new DCacheImp(this)
}


L
ljw 已提交
299
class DCacheImp(outer: DCache) extends LazyModuleImp(outer) with HasDCacheParameters {
A
Allen 已提交
300 301 302 303 304 305

  val io = IO(new DCacheIO)

  val (bus, edge) = outer.clientNode.out.head
  require(bus.d.bits.data.getWidth == l1BusDataWidth, "DCache: tilelink width does not match")

306 307 308 309 310 311 312 313 314 315 316
  println("DCache:") 
  println("  DCacheSets: " + DCacheSets) 
  println("  DCacheWays: " + DCacheWays) 
  println("  DCacheBanks: " + DCacheBanks) 
  println("  DCacheSRAMRowBits: " + DCacheSRAMRowBits) 
  println("  DCacheWordOffset: " + DCacheWordOffset) 
  println("  DCacheBankOffset: " + DCacheBankOffset) 
  println("  DCacheSetOffset: " + DCacheSetOffset) 
  println("  DCacheTagOffset: " + DCacheTagOffset) 
  println("  DCacheAboveIndexOffset: " + DCacheAboveIndexOffset) 

A
Allen 已提交
317 318
  //----------------------------------------
  // core data structures
319 320 321 322 323
  val bankedDataArray = Module(new BankedDataArray)
  val metaArray = Module(new DuplicatedMetaArray(numReadPorts = 3))
  bankedDataArray.dump()

  val errors = bankedDataArray.io.errors ++ metaArray.io.errors
324
  io.error <> RegNext(Mux1H(errors.map(e => e.ecc_error.valid -> e)))
325
  // assert(!io.error.ecc_error.valid)
A
Allen 已提交
326 327 328

  //----------------------------------------
  // core modules
329
  val ldu = Seq.tabulate(LoadPipelineWidth)({ i => Module(new LoadPipe(i))})
A
Allen 已提交
330 331 332
  val storeReplayUnit = Module(new StoreReplayQueue)
  val atomicsReplayUnit = Module(new AtomicsReplayEntry)

333
  val mainPipe   = Module(new MainPipe)
A
Allen 已提交
334 335
  val missQueue  = Module(new MissQueue(edge))
  val probeQueue = Module(new ProbeQueue(edge))
336
  val wb         = Module(new WritebackQueue(edge))
A
Allen 已提交
337 338 339 340 341 342 343 344 345


  //----------------------------------------
  // meta array
  val MetaWritePortCount = 1
  val MainPipeMetaWritePort = 0
  metaArray.io.write <> mainPipe.io.meta_write

  // MainPipe contend MetaRead with Load 0
346
  // give priority to MainPipe
A
Allen 已提交
347
  val MetaReadPortCount = 2
348 349
  val MainPipeMetaReadPort = 0
  val LoadPipeMetaReadPort = 1
A
Allen 已提交
350

351 352
  metaArray.io.read(LoadPipelineWidth) <> mainPipe.io.meta_read
  mainPipe.io.meta_resp <> metaArray.io.resp(LoadPipelineWidth)
A
Allen 已提交
353

354
  for (w <- 0 until LoadPipelineWidth) {
A
Allen 已提交
355 356 357 358 359 360 361
    metaArray.io.read(w) <> ldu(w).io.meta_read
    ldu(w).io.meta_resp <> metaArray.io.resp(w)
  }

  //----------------------------------------
  // data array

362 363 364 365
  bankedDataArray.io.write <> mainPipe.io.banked_data_write
  bankedDataArray.io.read(0) <> ldu(0).io.banked_data_read
  bankedDataArray.io.read(1) <> ldu(1).io.banked_data_read
  bankedDataArray.io.readline <> mainPipe.io.banked_data_read
A
Allen 已提交
366

367 368 369
  ldu(0).io.banked_data_resp := bankedDataArray.io.resp
  ldu(1).io.banked_data_resp := bankedDataArray.io.resp
  mainPipe.io.banked_data_resp := bankedDataArray.io.resp
A
Allen 已提交
370

371 372 373 374
  ldu(0).io.bank_conflict_fast := bankedDataArray.io.bank_conflict_fast(0)
  ldu(1).io.bank_conflict_fast := bankedDataArray.io.bank_conflict_fast(1)
  ldu(0).io.bank_conflict_slow := bankedDataArray.io.bank_conflict_slow(0)
  ldu(1).io.bank_conflict_slow := bankedDataArray.io.bank_conflict_slow(1)
A
Allen 已提交
375 376 377 378 379 380

  //----------------------------------------
  // load pipe
  // the s1 kill signal
  // only lsu uses this, replay never kills
  for (w <- 0 until LoadPipelineWidth) {
381
    ldu(w).io.lsu <> io.lsu.load(w)
A
Allen 已提交
382 383 384 385

    // replay and nack not needed anymore
    // TODO: remove replay and nack
    ldu(w).io.nack := false.B
386

387 388 389
    ldu(w).io.disable_ld_fast_wakeup := 
      mainPipe.io.disable_ld_fast_wakeup(w) || 
      bankedDataArray.io.bank_conflict_fast(w) // load pipe fast wake up should be disabled when bank conflict
A
Allen 已提交
390 391 392 393 394 395 396 397 398
  }

  //----------------------------------------
  // store pipe and store miss queue
  storeReplayUnit.io.lsu    <> io.lsu.store

  //----------------------------------------
  // atomics
  // atomics not finished yet
A
Allen 已提交
399
  io.lsu.atomics <> atomicsReplayUnit.io.lsu
A
Allen 已提交
400 401 402 403 404 405 406

  //----------------------------------------
  // miss queue
  val MissReqPortCount = LoadPipelineWidth + 1
  val MainPipeMissReqPort = 0

  // Request
407
  val missReqArb = Module(new RRArbiter(new MissReq, MissReqPortCount))
A
Allen 已提交
408 409 410 411

  missReqArb.io.in(MainPipeMissReqPort) <> mainPipe.io.miss_req
  for (w <- 0 until LoadPipelineWidth) { missReqArb.io.in(w + 1) <> ldu(w).io.miss_req }

412 413 414 415
  wb.io.miss_req.valid := missReqArb.io.out.valid
  wb.io.miss_req.bits  := missReqArb.io.out.bits.addr

  block_decoupled(missReqArb.io.out, missQueue.io.req, wb.io.block_miss_req)
A
Allen 已提交
416 417 418 419 420 421 422

  // refill to load queue
  io.lsu.lsq <> missQueue.io.refill

  // tilelink stuff
  bus.a <> missQueue.io.mem_acquire
  bus.e <> missQueue.io.mem_finish
423
  missQueue.io.probe_req := bus.b.bits.address
A
Allen 已提交
424 425 426

  //----------------------------------------
  // probe
427 428
  // probeQueue.io.mem_probe <> bus.b
  block_decoupled(bus.b, probeQueue.io.mem_probe, missQueue.io.probe_block)
A
Allen 已提交
429 430 431 432 433 434 435 436 437

  //----------------------------------------
  // mainPipe
  val MainPipeReqPortCount = 4
  val MissMainPipeReqPort = 0
  val StoreMainPipeReqPort = 1
  val AtomicsMainPipeReqPort = 2
  val ProbeMainPipeReqPort = 3

438
  val mainPipeReqArb = Module(new RRArbiter(new MainPipeReq, MainPipeReqPortCount))
A
Allen 已提交
439 440 441 442 443
  mainPipeReqArb.io.in(MissMainPipeReqPort)    <> missQueue.io.pipe_req
  mainPipeReqArb.io.in(StoreMainPipeReqPort)   <> storeReplayUnit.io.pipe_req
  mainPipeReqArb.io.in(AtomicsMainPipeReqPort) <> atomicsReplayUnit.io.pipe_req
  mainPipeReqArb.io.in(ProbeMainPipeReqPort)   <> probeQueue.io.pipe_req

444 445 446 447 448
  // add a stage to break the Arbiter bits.addr to ready path
  val mainPipeReq_valid = RegInit(false.B)
  val mainPipeReq_fire  = mainPipeReq_valid && mainPipe.io.req.ready
  val mainPipeReq_req   = RegEnable(mainPipeReqArb.io.out.bits, mainPipeReqArb.io.out.fire())

449
  mainPipeReqArb.io.out.ready := mainPipeReq_fire || !mainPipeReq_valid
450 451 452 453 454
  mainPipe.io.req.valid := mainPipeReq_valid
  mainPipe.io.req.bits  := mainPipeReq_req

  when (mainPipeReqArb.io.out.fire()) { mainPipeReq_valid := true.B }
  when (!mainPipeReqArb.io.out.fire() && mainPipeReq_fire) { mainPipeReq_valid := false.B }
A
Allen 已提交
455 456 457 458 459 460 461

  missQueue.io.pipe_resp         <> mainPipe.io.miss_resp
  storeReplayUnit.io.pipe_resp   <> mainPipe.io.store_resp
  atomicsReplayUnit.io.pipe_resp <> mainPipe.io.amo_resp

  probeQueue.io.lrsc_locked_block <> mainPipe.io.lrsc_locked_block

462 463 464 465
  for(i <- 0 until LoadPipelineWidth) {
    mainPipe.io.replace_access(i) <> ldu(i).io.replace_access
  }

A
Allen 已提交
466 467 468
  //----------------------------------------
  // wb
  // add a queue between MainPipe and WritebackUnit to reduce MainPipe stalls due to WritebackUnit busy
469
  wb.io.req <> mainPipe.io.wb_req
A
Allen 已提交
470 471
  bus.c     <> wb.io.mem_release

472
  // connect bus d
A
Allen 已提交
473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488
  missQueue.io.mem_grant.valid := false.B
  missQueue.io.mem_grant.bits  := DontCare

  wb.io.mem_grant.valid := false.B
  wb.io.mem_grant.bits  := DontCare

  // in L1DCache, we ony expect Grant[Data] and ReleaseAck
  bus.d.ready := false.B
  when (bus.d.bits.opcode === TLMessages.Grant || bus.d.bits.opcode === TLMessages.GrantData) {
    missQueue.io.mem_grant <> bus.d
  } .elsewhen (bus.d.bits.opcode === TLMessages.ReleaseAck) {
    wb.io.mem_grant <> bus.d
  } .otherwise {
    assert (!bus.d.fire())
  }

489 490
  //----------------------------------------
  // assertions
A
Allen 已提交
491 492 493 494 495 496 497 498 499 500 501
  // dcache should only deal with DRAM addresses
  when (bus.a.fire()) {
    assert(bus.a.bits.address >= 0x80000000L.U)
  }
  when (bus.b.fire()) {
    assert(bus.b.bits.address >= 0x80000000L.U)
  }
  when (bus.c.fire()) {
    assert(bus.c.bits.address >= 0x80000000L.U)
  }

502 503
  //----------------------------------------
  // utility functions
504 505 506 507 508
  def block_decoupled[T <: Data](source: DecoupledIO[T], sink: DecoupledIO[T], block_signal: Bool) = {
    sink.valid   := source.valid && !block_signal
    source.ready := sink.ready   && !block_signal
    sink.bits    := source.bits
  }
509 510 511 512

  //----------------------------------------
  // performance counters
  val num_loads = PopCount(ldu.map(e => e.io.lsu.req.fire()))
513
  XSPerfAccumulate("num_loads", num_loads)
514 515

  io.mshrFull := missQueue.io.full
A
Allen 已提交
516
}
517

518 519 520 521 522 523 524 525 526 527
class AMOHelper() extends ExtModule {
//  val io = IO(new Bundle {
    val clock  = IO(Input(Clock()))
    val enable = IO(Input(Bool()))
    val cmd    = IO(Input(UInt(5.W)))
    val addr   = IO(Input(UInt(64.W)))
    val wdata  = IO(Input(UInt(64.W)))
    val mask   = IO(Input(UInt(8.W)))
    val rdata  = IO(Output(UInt(64.W)))
//  })
528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549
}


class DCacheWrapper()(implicit p: Parameters) extends LazyModule with HasDCacheParameters {

  val clientNode = if (!useFakeDCache) TLIdentityNode() else null
  val dcache = if (!useFakeDCache) LazyModule(new DCache()) else null
  if (!useFakeDCache) {
    clientNode := dcache.clientNode
  }

  lazy val module = new LazyModuleImp(this) {
    val io = IO(new DCacheIO)
    if (useFakeDCache) {
      val fake_dcache = Module(new FakeDCache())
      io <> fake_dcache.io
    }
    else {
      io <> dcache.module.io
    }
  }
}