xref: /XiangShan/src/main/scala/xiangshan/cache/dcache/Uncache.scala (revision 06999a3092bc2cd125a5bbefdbb5bb77252e935f)
11f0e2dc7SJiawei Lin/***************************************************************************************
21f0e2dc7SJiawei Lin* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
31f0e2dc7SJiawei Lin* Copyright (c) 2020-2021 Peng Cheng Laboratory
41f0e2dc7SJiawei Lin*
51f0e2dc7SJiawei Lin* XiangShan is licensed under Mulan PSL v2.
61f0e2dc7SJiawei Lin* You can use this software according to the terms and conditions of the Mulan PSL v2.
71f0e2dc7SJiawei Lin* You may obtain a copy of Mulan PSL v2 at:
81f0e2dc7SJiawei Lin*          http://license.coscl.org.cn/MulanPSL2
91f0e2dc7SJiawei Lin*
101f0e2dc7SJiawei Lin* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
111f0e2dc7SJiawei Lin* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
121f0e2dc7SJiawei Lin* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
131f0e2dc7SJiawei Lin*
141f0e2dc7SJiawei Lin* See the Mulan PSL v2 for more details.
151f0e2dc7SJiawei Lin***************************************************************************************/
161f0e2dc7SJiawei Lin
171f0e2dc7SJiawei Linpackage xiangshan.cache
181f0e2dc7SJiawei Lin
191f0e2dc7SJiawei Linimport chisel3._
201f0e2dc7SJiawei Linimport chisel3.util._
218891a219SYinan Xuimport org.chipsalliance.cde.config.Parameters
2237225120Ssfencevmaimport utils._
233c02ee8fSwakafaimport utility._
2437225120Ssfencevmaimport xiangshan._
251f0e2dc7SJiawei Linimport freechips.rocketchip.diplomacy.{IdRange, LazyModule, LazyModuleImp, TransferSizes}
261f0e2dc7SJiawei Linimport freechips.rocketchip.tilelink.{TLArbiter, TLBundleA, TLBundleD, TLClientNode, TLEdgeOut, TLMasterParameters, TLMasterPortParameters}
2737225120Ssfencevma
2837225120Ssfencevmaclass UncachePtr(implicit p: Parameters) extends CircularQueuePtr[UncachePtr](
2937225120Ssfencevma  p => p(XSCoreParamsKey).UncacheBufferSize
3037225120Ssfencevma){
3137225120Ssfencevma
3237225120Ssfencevma}
3337225120Ssfencevma
3437225120Ssfencevmaobject UncachePtr {
3537225120Ssfencevma  def apply(f: Bool, v: UInt)(implicit p: Parameters): UncachePtr = {
3637225120Ssfencevma    val ptr = Wire(new UncachePtr)
3737225120Ssfencevma    ptr.flag := f
3837225120Ssfencevma    ptr.value := v
3937225120Ssfencevma    ptr
4037225120Ssfencevma  }
4137225120Ssfencevma}
4237225120Ssfencevma
4337225120Ssfencevmaclass UncacheFlushBundle extends Bundle {
4437225120Ssfencevma  val valid = Output(Bool())
4537225120Ssfencevma  val empty = Input(Bool())
4637225120Ssfencevma}
471f0e2dc7SJiawei Lin
481f0e2dc7SJiawei Lin// One miss entry deals with one mmio request
491f0e2dc7SJiawei Linclass MMIOEntry(edge: TLEdgeOut)(implicit p: Parameters) extends DCacheModule
501f0e2dc7SJiawei Lin{
511f0e2dc7SJiawei Lin  val io = IO(new Bundle {
521f0e2dc7SJiawei Lin    //  MSHR ID
5337225120Ssfencevma    val hartId = Input(UInt())
5437225120Ssfencevma    //  Control IO
5537225120Ssfencevma    val enableOutstanding = Input(Bool())
561f0e2dc7SJiawei Lin
5737225120Ssfencevma    //  Client requests
5837225120Ssfencevma    val req = Flipped(DecoupledIO(new UncacheWordReq))
596786cfb7SWilliam Wang    val resp = DecoupledIO(new DCacheWordRespWithError)
601f0e2dc7SJiawei Lin
6137225120Ssfencevma    //  TileLink
621f0e2dc7SJiawei Lin    val mem_acquire = DecoupledIO(new TLBundleA(edge.bundle))
631f0e2dc7SJiawei Lin    val mem_grant = Flipped(DecoupledIO(new TLBundleD(edge.bundle)))
6437225120Ssfencevma
65*06999a30Ssfencevma    // This entry is valid.
66*06999a30Ssfencevma    val invalid = Output(Bool())
6737225120Ssfencevma    //  This entry is selected.
6837225120Ssfencevma    val select = Input(Bool())
6937225120Ssfencevma    val atomic = Output(Bool())
701f0e2dc7SJiawei Lin  })
7137225120Ssfencevma  //  ================================================
7237225120Ssfencevma  //  FSM state description:
7337225120Ssfencevma  //  s_invalid     : Entry is invalid.
7437225120Ssfencevma  //  s_refill_req  : Send Acquire request.
7537225120Ssfencevma  //  s_refill_resp : Wait for Grant response.
7637225120Ssfencevma  //  s_send_resp   : Send Uncache response.
771f0e2dc7SJiawei Lin  val s_invalid :: s_refill_req :: s_refill_resp :: s_send_resp :: Nil = Enum(4)
781f0e2dc7SJiawei Lin  val state = RegInit(s_invalid)
791f0e2dc7SJiawei Lin
8037225120Ssfencevma  val req = Reg(new UncacheWordReq)
811f0e2dc7SJiawei Lin  val resp_data = Reg(UInt(DataBits.W))
8237225120Ssfencevma  def storeReq = req.cmd === MemoryOpConstants.M_XWR
831f0e2dc7SJiawei Lin
84*06999a30Ssfencevma  io.invalid := state === s_invalid
8537225120Ssfencevma  //  Assign default values to output signals.
861f0e2dc7SJiawei Lin  io.req.ready := false.B
871f0e2dc7SJiawei Lin  io.resp.valid := false.B
881f0e2dc7SJiawei Lin  io.resp.bits := DontCare
891f0e2dc7SJiawei Lin
901f0e2dc7SJiawei Lin  io.mem_acquire.valid := false.B
911f0e2dc7SJiawei Lin  io.mem_acquire.bits := DontCare
921f0e2dc7SJiawei Lin  io.mem_grant.ready := false.B
931f0e2dc7SJiawei Lin
9437225120Ssfencevma  io.atomic := req.atomic
9537225120Ssfencevma  //  Receive request
961f0e2dc7SJiawei Lin  when (state === s_invalid) {
971f0e2dc7SJiawei Lin    io.req.ready := true.B
981f0e2dc7SJiawei Lin
9937225120Ssfencevma    when (io.req.fire) {
1001f0e2dc7SJiawei Lin      req := io.req.bits
1011f0e2dc7SJiawei Lin      req.addr := io.req.bits.addr
1021f0e2dc7SJiawei Lin      state := s_refill_req
1031f0e2dc7SJiawei Lin    }
1041f0e2dc7SJiawei Lin  }
1051f0e2dc7SJiawei Lin
10637225120Ssfencevma  //  Refill
1071f0e2dc7SJiawei Lin  //  TODO: determine 'lgSize' in memend
1081f0e2dc7SJiawei Lin  val size = PopCount(req.mask)
1091f0e2dc7SJiawei Lin  val (lgSize, legal) = PriorityMuxWithFlag(Seq(
1101f0e2dc7SJiawei Lin    1.U -> 0.U,
1111f0e2dc7SJiawei Lin    2.U -> 1.U,
1121f0e2dc7SJiawei Lin    4.U -> 2.U,
1131f0e2dc7SJiawei Lin    8.U -> 3.U
1141f0e2dc7SJiawei Lin  ).map(m => (size===m._1) -> m._2))
1151f0e2dc7SJiawei Lin  assert(!(io.mem_acquire.valid && !legal))
1161f0e2dc7SJiawei Lin
1171f0e2dc7SJiawei Lin  val load = edge.Get(
11837225120Ssfencevma    fromSource      = io.hartId,
1191f0e2dc7SJiawei Lin    toAddress       = req.addr,
1201f0e2dc7SJiawei Lin    lgSize          = lgSize
1211f0e2dc7SJiawei Lin  )._2
1221f0e2dc7SJiawei Lin
1231f0e2dc7SJiawei Lin  val store = edge.Put(
12437225120Ssfencevma    fromSource      = io.hartId,
1251f0e2dc7SJiawei Lin    toAddress       = req.addr,
1261f0e2dc7SJiawei Lin    lgSize          = lgSize,
1271f0e2dc7SJiawei Lin    data            = req.data,
1281f0e2dc7SJiawei Lin    mask            = req.mask
1291f0e2dc7SJiawei Lin  )._2
1301f0e2dc7SJiawei Lin
13137225120Ssfencevma  XSDebug("entry: %d state: %d\n", io.hartId, state)
1321f0e2dc7SJiawei Lin
13337225120Ssfencevma  when (state === s_refill_req) {
13437225120Ssfencevma    io.mem_acquire.valid := true.B && io.select
13537225120Ssfencevma    io.mem_acquire.bits := Mux(storeReq, store, load)
13637225120Ssfencevma
13737225120Ssfencevma    when (io.mem_acquire.fire) {
1381f0e2dc7SJiawei Lin      state := s_refill_resp
1391f0e2dc7SJiawei Lin    }
1401f0e2dc7SJiawei Lin  }
1411f0e2dc7SJiawei Lin
1421f0e2dc7SJiawei Lin  val (_, _, refill_done, _) = edge.addr_inc(io.mem_grant)
1431f0e2dc7SJiawei Lin  when (state === s_refill_resp) {
1441f0e2dc7SJiawei Lin    io.mem_grant.ready := true.B
1451f0e2dc7SJiawei Lin
14637225120Ssfencevma    when (io.mem_grant.fire) {
1471f0e2dc7SJiawei Lin      resp_data := io.mem_grant.bits.data
14837225120Ssfencevma      assert(refill_done, "Uncache response should be one beat only!")
14937225120Ssfencevma      state := Mux(storeReq && io.enableOutstanding, s_invalid, s_send_resp)
1501f0e2dc7SJiawei Lin    }
1511f0e2dc7SJiawei Lin  }
1521f0e2dc7SJiawei Lin
15337225120Ssfencevma  //  Response
1541f0e2dc7SJiawei Lin  when (state === s_send_resp) {
1551f0e2dc7SJiawei Lin    io.resp.valid := true.B
1561f0e2dc7SJiawei Lin    io.resp.bits.data   := resp_data
1571f0e2dc7SJiawei Lin    // meta data should go with the response
1581f0e2dc7SJiawei Lin    io.resp.bits.id     := req.id
1591f0e2dc7SJiawei Lin    io.resp.bits.miss   := false.B
1601f0e2dc7SJiawei Lin    io.resp.bits.replay := false.B
161a469aa4bSWilliam Wang    io.resp.bits.tag_error := false.B
162a469aa4bSWilliam Wang    io.resp.bits.error := false.B
1631f0e2dc7SJiawei Lin
164935edac4STang Haojin    when (io.resp.fire) {
1651f0e2dc7SJiawei Lin      state := s_invalid
1661f0e2dc7SJiawei Lin    }
1671f0e2dc7SJiawei Lin  }
16837225120Ssfencevma
16937225120Ssfencevma  //  End
1701f0e2dc7SJiawei Lin}
1711f0e2dc7SJiawei Lin
1721f0e2dc7SJiawei Linclass UncacheIO(implicit p: Parameters) extends DCacheBundle {
17337225120Ssfencevma  val hartId = Input(UInt())
17437225120Ssfencevma  val enableOutstanding = Input(Bool())
17537225120Ssfencevma  val flush = Flipped(new UncacheFlushBundle)
1766786cfb7SWilliam Wang  val lsq = Flipped(new UncacheWordIO)
1771f0e2dc7SJiawei Lin}
1781f0e2dc7SJiawei Lin
1791f0e2dc7SJiawei Lin// convert DCacheIO to TileLink
1801f0e2dc7SJiawei Lin// for Now, we only deal with TL-UL
1811f0e2dc7SJiawei Lin
18237225120Ssfencevmaclass Uncache()(implicit p: Parameters) extends LazyModule with HasXSParameter {
18395e60e55STang Haojin  override def shouldBeInlined: Boolean = false
18437225120Ssfencevma  def idRange: Int = UncacheBufferSize
1851f0e2dc7SJiawei Lin
1861f0e2dc7SJiawei Lin  val clientParameters = TLMasterPortParameters.v1(
1871f0e2dc7SJiawei Lin    clients = Seq(TLMasterParameters.v1(
1881f0e2dc7SJiawei Lin      "uncache",
18937225120Ssfencevma      sourceId = IdRange(0, idRange)
1901f0e2dc7SJiawei Lin    ))
1911f0e2dc7SJiawei Lin  )
1921f0e2dc7SJiawei Lin  val clientNode = TLClientNode(Seq(clientParameters))
1931f0e2dc7SJiawei Lin
1941f0e2dc7SJiawei Lin  lazy val module = new UncacheImp(this)
1951f0e2dc7SJiawei Lin}
1961f0e2dc7SJiawei Lin
19737225120Ssfencevmaclass UncacheImp(outer: Uncache)extends LazyModuleImp(outer)
1981f0e2dc7SJiawei Lin  with HasTLDump
19937225120Ssfencevma  with HasXSParameter
20037225120Ssfencevma  with HasPerfEvents
2011f0e2dc7SJiawei Lin{
2021f0e2dc7SJiawei Lin val io = IO(new UncacheIO)
2031f0e2dc7SJiawei Lin
2041f0e2dc7SJiawei Lin  val (bus, edge) = outer.clientNode.out.head
2051f0e2dc7SJiawei Lin
2061f0e2dc7SJiawei Lin  val req  = io.lsq.req
2071f0e2dc7SJiawei Lin  val resp = io.lsq.resp
2081f0e2dc7SJiawei Lin  val mem_acquire = bus.a
2091f0e2dc7SJiawei Lin  val mem_grant   = bus.d
2101f0e2dc7SJiawei Lin
2111f0e2dc7SJiawei Lin  val req_ready = WireInit(false.B)
21237225120Ssfencevma  val need_fence = WireInit(false.B)
2131f0e2dc7SJiawei Lin
2141f0e2dc7SJiawei Lin  // assign default values to output signals
2151f0e2dc7SJiawei Lin  bus.b.ready := false.B
2161f0e2dc7SJiawei Lin  bus.c.valid := false.B
2171f0e2dc7SJiawei Lin  bus.c.bits  := DontCare
2181f0e2dc7SJiawei Lin  bus.d.ready := false.B
2191f0e2dc7SJiawei Lin  bus.e.valid := false.B
2201f0e2dc7SJiawei Lin  bus.e.bits  := DontCare
2211f0e2dc7SJiawei Lin
22237225120Ssfencevma  val enqPtr = RegInit(0.U.asTypeOf(new UncachePtr))
22337225120Ssfencevma  val issPtr = RegInit(0.U.asTypeOf(new UncachePtr))
22437225120Ssfencevma  val deqPtr = RegInit(0.U.asTypeOf(new UncachePtr))
22537225120Ssfencevma  val fence = RegInit(Bool(), false.B)
2261f0e2dc7SJiawei Lin
22737225120Ssfencevma  io.lsq.resp.valid := false.B
22837225120Ssfencevma  io.lsq.resp.bits := DontCare
2291f0e2dc7SJiawei Lin
23037225120Ssfencevma  val entries = Seq.fill(UncacheBufferSize) { Module(new MMIOEntry(edge)) }
23137225120Ssfencevma  for ((entry, i) <- entries.zipWithIndex) {
23237225120Ssfencevma    entry.io.hartId := io.hartId
23337225120Ssfencevma    entry.io.enableOutstanding := io.enableOutstanding
23437225120Ssfencevma
23537225120Ssfencevma   //  Enqueue
23637225120Ssfencevma    entry.io.req.valid := (i.U === enqPtr.value) && req.valid
2371f0e2dc7SJiawei Lin    entry.io.req.bits := req.bits
23837225120Ssfencevma
23937225120Ssfencevma    when (i.U === enqPtr.value) {
2401f0e2dc7SJiawei Lin      req_ready := entry.io.req.ready
2411f0e2dc7SJiawei Lin    }
2421f0e2dc7SJiawei Lin
24337225120Ssfencevma    //  Acquire
24437225120Ssfencevma    entry.io.select := (i.U === issPtr.value) && Mux(entry.io.atomic, issPtr.value === deqPtr.value, !fence)
2451f0e2dc7SJiawei Lin
24637225120Ssfencevma    when (i.U === issPtr.value) {
24737225120Ssfencevma      need_fence := entry.io.atomic
24837225120Ssfencevma    }
24937225120Ssfencevma
25037225120Ssfencevma    //  Grant
2511f0e2dc7SJiawei Lin    entry.io.mem_grant.valid := false.B
2521f0e2dc7SJiawei Lin    entry.io.mem_grant.bits := DontCare
25337225120Ssfencevma    when (i.U === deqPtr.value) {
2541f0e2dc7SJiawei Lin      entry.io.mem_grant <> mem_grant
2551f0e2dc7SJiawei Lin    }
25637225120Ssfencevma
25737225120Ssfencevma    entry.io.resp.ready := false.B
25837225120Ssfencevma    when (i.U === deqPtr.value) {
25937225120Ssfencevma      io.lsq.resp <> entry.io.resp
2601f0e2dc7SJiawei Lin    }
2611f0e2dc7SJiawei Lin
26237225120Ssfencevma  }
2631f0e2dc7SJiawei Lin
26437225120Ssfencevma  io.lsq.req.ready := req_ready
26537225120Ssfencevma  when (io.enableOutstanding) {
26637225120Ssfencevma    //  Uncache Buffer is a circular queue, which contains UncacheBufferSize entries.
26737225120Ssfencevma    //  Description:
26837225120Ssfencevma    //    enqPtr: Point to an invalid (means that the entry is free) entry.
26937225120Ssfencevma    //    issPtr: Point to a ready entry, the entry is ready to issue.
27037225120Ssfencevma    //    deqPtr: Point to the oldest entry, which was issued but has not accepted response (used to keep order with the program order).
27137225120Ssfencevma    //
27237225120Ssfencevma    //  When outstanding disabled, only one read/write request can be accepted at a time.
27337225120Ssfencevma    //
27437225120Ssfencevma    //  Example (Enable outstanding):
27537225120Ssfencevma    //    1. enqPtr:
27637225120Ssfencevma    //       1) Before enqueue
27737225120Ssfencevma    //          enqPtr --
27837225120Ssfencevma    //                  |
27937225120Ssfencevma    //                  |
28037225120Ssfencevma    //                  V
28137225120Ssfencevma    //          +--+--+--+--+
28237225120Ssfencevma    //          |  |  |  |  |
28337225120Ssfencevma    //          |  |  |  |  |
28437225120Ssfencevma    //          |  |  |  |  |
28537225120Ssfencevma    //          +--+--+--+--+
28637225120Ssfencevma    //
28737225120Ssfencevma    //      2) After
28837225120Ssfencevma    //          enqPtr+1 ---
28937225120Ssfencevma    //                     |
29037225120Ssfencevma    //                     |
29137225120Ssfencevma    //                     V
29237225120Ssfencevma    //          +--+--+--+--+
29337225120Ssfencevma    //          |  |  |  |  |
29437225120Ssfencevma    //          |  |  |  |  |
29537225120Ssfencevma    //          |  |  |  |  |
29637225120Ssfencevma    //          +--+--+--+--+
29737225120Ssfencevma    //
29837225120Ssfencevma    //    2. issPtr:
29937225120Ssfencevma    //      1) Before issue
30037225120Ssfencevma    //          issPtr --
30137225120Ssfencevma    //                  |
30237225120Ssfencevma    //                  |
30337225120Ssfencevma    //                  V
30437225120Ssfencevma    //          +--+--+--+--+
30537225120Ssfencevma    //          |  |  |  |  |
30637225120Ssfencevma    //          |  |  |  |  |
30737225120Ssfencevma    //          |  |  |  |  |
30837225120Ssfencevma    //          +--+--+--+--+
30937225120Ssfencevma    //
31037225120Ssfencevma    //      2) After issue
31137225120Ssfencevma    //          issPtr+1 --
31237225120Ssfencevma    //                    |
31337225120Ssfencevma    //                    |
31437225120Ssfencevma    //                    V
31537225120Ssfencevma    //          +--+--+--+--+
31637225120Ssfencevma    //          |  |  |  |  |
31737225120Ssfencevma    //          |  |  |  |  |
31837225120Ssfencevma    //          |  |  |  |  |
31937225120Ssfencevma    //          +--+--+--+--+
32037225120Ssfencevma    //
32137225120Ssfencevma    //   3. deqPtr:
32237225120Ssfencevma    //      1) Before dequeue
32337225120Ssfencevma    //          deqPtr --
32437225120Ssfencevma    //                  |
32537225120Ssfencevma    //                  |
32637225120Ssfencevma    //                  V
32737225120Ssfencevma    //          +--+--+--+--+
32837225120Ssfencevma    //          |  |  |  |  |
32937225120Ssfencevma    //          |  |  |  |  |
33037225120Ssfencevma    //          |  |  |  |  |
33137225120Ssfencevma    //          +--+--+--+--+
33237225120Ssfencevma    //
33337225120Ssfencevma    //      2) After dequeue
33437225120Ssfencevma    //          deqPtr --                    deqPtr+1 --
33537225120Ssfencevma    //                  |                              |
33637225120Ssfencevma    //                  |                              |
33737225120Ssfencevma    //                  V                              V
33837225120Ssfencevma    //          +--+--+--+--+       or      +--+--+--+--+
33937225120Ssfencevma    //          |  |  |  |  |               |  |  |  |  |
34037225120Ssfencevma    //          |  |  |  |  |               |  |  |  |  |
34137225120Ssfencevma    //          |  |  |  |  |               |  |  |  |  |
34237225120Ssfencevma    //          +--+--+--+--+               +--+--+--+--+
34337225120Ssfencevma    //              (load)                     (store)
34437225120Ssfencevma    //
34537225120Ssfencevma    //      3) After response
34637225120Ssfencevma    //          deqPtr+1 ---                   deqPtr--
34737225120Ssfencevma    //                     |                          |
34837225120Ssfencevma    //                     |                          |
34937225120Ssfencevma    //                     V                          V
35037225120Ssfencevma    //          +--+--+--+--+       or      +--+--+--+--+
35137225120Ssfencevma    //          |  |  |  |  |               |  |  |  |  |
35237225120Ssfencevma    //          |  |  |  |  |               |  |  |  |  |
35337225120Ssfencevma    //          |  |  |  |  |               |  |  |  |  |
35437225120Ssfencevma    //          +--+--+--+--+               +--+--+--+--+
35537225120Ssfencevma    //              (load)                     (store)
35637225120Ssfencevma    //
35737225120Ssfencevma
35837225120Ssfencevma    //  Enqueue
35937225120Ssfencevma    when (req.fire) {
36037225120Ssfencevma      enqPtr := enqPtr + 1.U
36137225120Ssfencevma    }
36237225120Ssfencevma
36337225120Ssfencevma    //  Issue
36437225120Ssfencevma    when (mem_acquire.fire) {
36537225120Ssfencevma      issPtr := issPtr + 1.U
36637225120Ssfencevma    }
36737225120Ssfencevma
36837225120Ssfencevma    when (mem_acquire.fire) {
36937225120Ssfencevma      fence := need_fence
37037225120Ssfencevma    }
37137225120Ssfencevma
37237225120Ssfencevma    //  Dequeue
37337225120Ssfencevma    when (mem_grant.fire) {
37437225120Ssfencevma      deqPtr := Mux(edge.hasData(mem_grant.bits), deqPtr /* Load */, deqPtr + 1.U /* Store */)
37537225120Ssfencevma    } .elsewhen (io.lsq.resp.fire /* Load */) {
37637225120Ssfencevma      deqPtr := deqPtr + 1.U
37737225120Ssfencevma    }
37837225120Ssfencevma
37937225120Ssfencevma    when (mem_grant.fire && fence) {
38037225120Ssfencevma      fence := false.B
38137225120Ssfencevma    }
38237225120Ssfencevma  } .otherwise {
38337225120Ssfencevma    when (io.lsq.resp.fire) {
38437225120Ssfencevma      enqPtr := enqPtr + 1.U
38537225120Ssfencevma      issPtr := issPtr + 1.U
38637225120Ssfencevma      deqPtr := deqPtr + 1.U
38737225120Ssfencevma    }
38837225120Ssfencevma  }
38937225120Ssfencevma
3901f0e2dc7SJiawei Lin  TLArbiter.lowestFromSeq(edge, mem_acquire, entries.map(_.io.mem_acquire))
391*06999a30Ssfencevma  val invalid_entries = PopCount(entries.map(_.io.invalid))
392*06999a30Ssfencevma  io.flush.empty := invalid_entries === UncacheBufferSize.U
3931f0e2dc7SJiawei Lin
39437225120Ssfencevma  println(s"Uncahe Buffer Size: $UncacheBufferSize entries")
3951f0e2dc7SJiawei Lin
3961f0e2dc7SJiawei Lin  // print all input/output requests for debug purpose
3971f0e2dc7SJiawei Lin  // print req/resp
398935edac4STang Haojin  XSDebug(req.fire, "req cmd: %x addr: %x data: %x mask: %x\n",
3991f0e2dc7SJiawei Lin    req.bits.cmd, req.bits.addr, req.bits.data, req.bits.mask)
400935edac4STang Haojin  XSDebug(resp.fire, "data: %x\n", req.bits.data)
4011f0e2dc7SJiawei Lin
4021f0e2dc7SJiawei Lin  // print tilelink messages
4031f0e2dc7SJiawei Lin  when(mem_acquire.valid){
4041f0e2dc7SJiawei Lin    XSDebug("mem_acquire valid, ready=%d ", mem_acquire.ready)
4051f0e2dc7SJiawei Lin    mem_acquire.bits.dump
4061f0e2dc7SJiawei Lin  }
407935edac4STang Haojin  when (mem_grant.fire) {
4081f0e2dc7SJiawei Lin    XSDebug("mem_grant fire ")
4091f0e2dc7SJiawei Lin    mem_grant.bits.dump
4101f0e2dc7SJiawei Lin  }
41137225120Ssfencevma
41237225120Ssfencevma  //  Performance Counters
41337225120Ssfencevma  def isStore: Bool = io.lsq.req.bits.cmd === MemoryOpConstants.M_XWR
41437225120Ssfencevma  XSPerfAccumulate("mmio_store", io.lsq.req.fire && isStore)
41537225120Ssfencevma  XSPerfAccumulate("mmio_load", io.lsq.req.fire && !isStore)
41637225120Ssfencevma  XSPerfAccumulate("mmio_outstanding", mem_acquire.fire && (deqPtr =/= issPtr))
41737225120Ssfencevma  val perfEvents = Seq(
41837225120Ssfencevma    ("mmio_store", io.lsq.req.fire && isStore),
41937225120Ssfencevma    ("mmio_load", io.lsq.req.fire && !isStore),
42037225120Ssfencevma    ("mmio_outstanding", mem_acquire.fire && (deqPtr =/= issPtr))
42137225120Ssfencevma  )
42237225120Ssfencevma
42337225120Ssfencevma  generatePerfEvent()
42437225120Ssfencevma  //  End
4251f0e2dc7SJiawei Lin}
426