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
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,
47 48
  blockBytes: Int = 64,
  alwaysReleaseData: Boolean = true
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 162
) 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 已提交
163 164

// memory request in word granularity(load, mmio, lr/sc, atomics)
165
class DCacheWordReq(implicit p: Parameters)  extends DCacheBundle
A
Allen 已提交
166 167 168 169 170 171 172 173 174 175 176 177 178
{
  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)
179
class DCacheLineReq(implicit p: Parameters)  extends DCacheBundle
A
Allen 已提交
180 181
{
  val cmd    = UInt(M_SZ.W)
182
  val vaddr  = UInt(VAddrBits.W)
A
Allen 已提交
183 184 185 186 187 188 189 190 191 192
  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)
  }
}

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

197
class DCacheWordResp(implicit p: Parameters) extends DCacheBundle
A
Allen 已提交
198 199 200 201 202 203 204 205 206 207 208 209 210
{
  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)
  }
}

211
class DCacheLineResp(implicit p: Parameters) extends DCacheBundle
A
Allen 已提交
212 213 214 215 216 217 218 219 220 221 222 223 224
{
  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)
  }
}

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

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

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

A
Allen 已提交
250
// used by load unit
251
class DCacheLoadIO(implicit p: Parameters) extends DCacheWordIO
252 253 254 255 256 257
{
  // 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))
258
  val s1_hit_way = Input(UInt(nWays.W))
259
  val s1_disable_fast_wakeup = Input(Bool())
260 261
}

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

268
class DCacheToLsuIO(implicit p: Parameters) extends DCacheBundle {
A
Allen 已提交
269 270 271
  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
272
  val atomics  = Flipped(new DCacheWordIOWithVaddr)  // atomics reqs
A
Allen 已提交
273 274
}

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


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)
289 290 291
    )),
    requestFields = cacheParams.reqFields,
    echoFields = cacheParams.echoFields
A
Allen 已提交
292 293 294 295 296 297 298 299
  )

  val clientNode = TLClientNode(Seq(clientParameters))

  lazy val module = new DCacheImp(this)
}


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

  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")

307 308 309 310 311 312 313 314 315 316 317
  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 已提交
318 319
  //----------------------------------------
  // core data structures
320 321 322 323 324
  val bankedDataArray = Module(new BankedDataArray)
  val metaArray = Module(new DuplicatedMetaArray(numReadPorts = 3))
  bankedDataArray.dump()

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

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

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


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

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

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

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

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

363 364 365 366
  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 已提交
367

368 369 370
  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 已提交
371

372 373 374 375
  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 已提交
376 377 378 379 380 381

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

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

388 389 390
    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 已提交
391 392 393 394 395 396 397 398 399
  }

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

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

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

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

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

413 414 415 416
  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 已提交
417 418 419 420 421 422 423

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

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

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

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

439
  val mainPipeReqArb = Module(new RRArbiter(new MainPipeReq, MainPipeReqPortCount))
A
Allen 已提交
440 441 442 443 444
  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

445 446 447 448 449
  // 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())

450
  mainPipeReqArb.io.out.ready := mainPipeReq_fire || !mainPipeReq_valid
451 452 453 454 455
  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 已提交
456 457 458 459 460 461 462

  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

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

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

473
  // connect bus d
A
Allen 已提交
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489
  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())
  }

490 491
  //----------------------------------------
  // assertions
A
Allen 已提交
492 493 494 495 496 497 498 499 500 501 502
  // 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)
  }

503 504
  //----------------------------------------
  // utility functions
505 506 507 508 509
  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
  }
510 511 512 513

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

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

519 520 521 522 523 524 525 526 527 528
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)))
//  })
529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550
}


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