xref: /XiangShan/src/main/scala/xiangshan/cache/dcache/Uncache.scala (revision 37225120844659e65ee2b406d16ab7853adce304)
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._
211f0e2dc7SJiawei Linimport chipsalliance.rocketchip.config.Parameters
22*37225120Ssfencevmaimport utils._
23*37225120Ssfencevmaimport xiangshan._
241f0e2dc7SJiawei Linimport freechips.rocketchip.diplomacy.{IdRange, LazyModule, LazyModuleImp, TransferSizes}
251f0e2dc7SJiawei Linimport freechips.rocketchip.tilelink.{TLArbiter, TLBundleA, TLBundleD, TLClientNode, TLEdgeOut, TLMasterParameters, TLMasterPortParameters}
26*37225120Ssfencevma
27*37225120Ssfencevmaclass UncachePtr(implicit p: Parameters) extends CircularQueuePtr[UncachePtr](
28*37225120Ssfencevma  p => p(XSCoreParamsKey).UncacheBufferSize
29*37225120Ssfencevma){
30*37225120Ssfencevma
31*37225120Ssfencevma}
32*37225120Ssfencevma
33*37225120Ssfencevmaobject UncachePtr {
34*37225120Ssfencevma  def apply(f: Bool, v: UInt)(implicit p: Parameters): UncachePtr = {
35*37225120Ssfencevma    val ptr = Wire(new UncachePtr)
36*37225120Ssfencevma    ptr.flag := f
37*37225120Ssfencevma    ptr.value := v
38*37225120Ssfencevma    ptr
39*37225120Ssfencevma  }
40*37225120Ssfencevma}
41*37225120Ssfencevma
42*37225120Ssfencevmaclass UncacheFlushBundle extends Bundle {
43*37225120Ssfencevma  val valid = Output(Bool())
44*37225120Ssfencevma  val empty = Input(Bool())
45*37225120Ssfencevma}
461f0e2dc7SJiawei Lin
471f0e2dc7SJiawei Lin// One miss entry deals with one mmio request
481f0e2dc7SJiawei Linclass MMIOEntry(edge: TLEdgeOut)(implicit p: Parameters) extends DCacheModule
491f0e2dc7SJiawei Lin{
501f0e2dc7SJiawei Lin  val io = IO(new Bundle {
511f0e2dc7SJiawei Lin    //  MSHR ID
52*37225120Ssfencevma    val hartId = Input(UInt())
53*37225120Ssfencevma    //  Control IO
54*37225120Ssfencevma    val enableOutstanding = Input(Bool())
551f0e2dc7SJiawei Lin
56*37225120Ssfencevma    //  Client requests
57*37225120Ssfencevma    val req = Flipped(DecoupledIO(new UncacheWordReq))
586786cfb7SWilliam Wang    val resp = DecoupledIO(new DCacheWordRespWithError)
591f0e2dc7SJiawei Lin
60*37225120Ssfencevma    //  TileLink
611f0e2dc7SJiawei Lin    val mem_acquire = DecoupledIO(new TLBundleA(edge.bundle))
621f0e2dc7SJiawei Lin    val mem_grant = Flipped(DecoupledIO(new TLBundleD(edge.bundle)))
63*37225120Ssfencevma
64*37225120Ssfencevma    //  This entry is selected.
65*37225120Ssfencevma    val select = Input(Bool())
66*37225120Ssfencevma    val atomic = Output(Bool())
671f0e2dc7SJiawei Lin  })
68*37225120Ssfencevma  //  ================================================
69*37225120Ssfencevma  //  FSM state description:
70*37225120Ssfencevma  //  s_invalid     : Entry is invalid.
71*37225120Ssfencevma  //  s_refill_req  : Send Acquire request.
72*37225120Ssfencevma  //  s_refill_resp : Wait for Grant response.
73*37225120Ssfencevma  //  s_send_resp   : Send Uncache response.
741f0e2dc7SJiawei Lin  val s_invalid :: s_refill_req :: s_refill_resp :: s_send_resp :: Nil = Enum(4)
751f0e2dc7SJiawei Lin  val state = RegInit(s_invalid)
761f0e2dc7SJiawei Lin
77*37225120Ssfencevma  val req = Reg(new UncacheWordReq)
781f0e2dc7SJiawei Lin  val resp_data = Reg(UInt(DataBits.W))
79*37225120Ssfencevma  def storeReq = req.cmd === MemoryOpConstants.M_XWR
801f0e2dc7SJiawei Lin
81*37225120Ssfencevma  //  Assign default values to output signals.
821f0e2dc7SJiawei Lin  io.req.ready := false.B
831f0e2dc7SJiawei Lin  io.resp.valid := false.B
841f0e2dc7SJiawei Lin  io.resp.bits := DontCare
851f0e2dc7SJiawei Lin
861f0e2dc7SJiawei Lin  io.mem_acquire.valid := false.B
871f0e2dc7SJiawei Lin  io.mem_acquire.bits := DontCare
881f0e2dc7SJiawei Lin  io.mem_grant.ready := false.B
891f0e2dc7SJiawei Lin
90*37225120Ssfencevma  io.atomic := req.atomic
91*37225120Ssfencevma  //  Receive request
921f0e2dc7SJiawei Lin  when (state === s_invalid) {
931f0e2dc7SJiawei Lin    io.req.ready := true.B
941f0e2dc7SJiawei Lin
95*37225120Ssfencevma    when (io.req.fire) {
961f0e2dc7SJiawei Lin      req := io.req.bits
971f0e2dc7SJiawei Lin      req.addr := io.req.bits.addr
981f0e2dc7SJiawei Lin      state := s_refill_req
991f0e2dc7SJiawei Lin    }
1001f0e2dc7SJiawei Lin  }
1011f0e2dc7SJiawei Lin
102*37225120Ssfencevma  //  Refill
1031f0e2dc7SJiawei Lin  //  TODO: determine 'lgSize' in memend
1041f0e2dc7SJiawei Lin  val size = PopCount(req.mask)
1051f0e2dc7SJiawei Lin  val (lgSize, legal) = PriorityMuxWithFlag(Seq(
1061f0e2dc7SJiawei Lin    1.U -> 0.U,
1071f0e2dc7SJiawei Lin    2.U -> 1.U,
1081f0e2dc7SJiawei Lin    4.U -> 2.U,
1091f0e2dc7SJiawei Lin    8.U -> 3.U
1101f0e2dc7SJiawei Lin  ).map(m => (size===m._1) -> m._2))
1111f0e2dc7SJiawei Lin  assert(!(io.mem_acquire.valid && !legal))
1121f0e2dc7SJiawei Lin
1131f0e2dc7SJiawei Lin  val load = edge.Get(
114*37225120Ssfencevma    fromSource      = io.hartId,
1151f0e2dc7SJiawei Lin    toAddress       = req.addr,
1161f0e2dc7SJiawei Lin    lgSize          = lgSize
1171f0e2dc7SJiawei Lin  )._2
1181f0e2dc7SJiawei Lin
1191f0e2dc7SJiawei Lin  val store = edge.Put(
120*37225120Ssfencevma    fromSource      = io.hartId,
1211f0e2dc7SJiawei Lin    toAddress       = req.addr,
1221f0e2dc7SJiawei Lin    lgSize          = lgSize,
1231f0e2dc7SJiawei Lin    data            = req.data,
1241f0e2dc7SJiawei Lin    mask            = req.mask
1251f0e2dc7SJiawei Lin  )._2
1261f0e2dc7SJiawei Lin
127*37225120Ssfencevma  XSDebug("entry: %d state: %d\n", io.hartId, state)
1281f0e2dc7SJiawei Lin
129*37225120Ssfencevma  when (state === s_refill_req) {
130*37225120Ssfencevma    io.mem_acquire.valid := true.B && io.select
131*37225120Ssfencevma    io.mem_acquire.bits := Mux(storeReq, store, load)
132*37225120Ssfencevma
133*37225120Ssfencevma    when (io.mem_acquire.fire) {
1341f0e2dc7SJiawei Lin      state := s_refill_resp
1351f0e2dc7SJiawei Lin    }
1361f0e2dc7SJiawei Lin  }
1371f0e2dc7SJiawei Lin
1381f0e2dc7SJiawei Lin  val (_, _, refill_done, _) = edge.addr_inc(io.mem_grant)
1391f0e2dc7SJiawei Lin  when (state === s_refill_resp) {
1401f0e2dc7SJiawei Lin    io.mem_grant.ready := true.B
1411f0e2dc7SJiawei Lin
142*37225120Ssfencevma    when (io.mem_grant.fire) {
1431f0e2dc7SJiawei Lin      resp_data := io.mem_grant.bits.data
144*37225120Ssfencevma      assert(refill_done, "Uncache response should be one beat only!")
145*37225120Ssfencevma      state := Mux(storeReq && io.enableOutstanding, s_invalid, s_send_resp)
1461f0e2dc7SJiawei Lin    }
1471f0e2dc7SJiawei Lin  }
1481f0e2dc7SJiawei Lin
149*37225120Ssfencevma  //  Response
1501f0e2dc7SJiawei Lin  when (state === s_send_resp) {
1511f0e2dc7SJiawei Lin    io.resp.valid := true.B
1521f0e2dc7SJiawei Lin    io.resp.bits.data   := resp_data
1531f0e2dc7SJiawei Lin    // meta data should go with the response
1541f0e2dc7SJiawei Lin    io.resp.bits.id     := req.id
1551f0e2dc7SJiawei Lin    io.resp.bits.miss   := false.B
1561f0e2dc7SJiawei Lin    io.resp.bits.replay := false.B
157a469aa4bSWilliam Wang    io.resp.bits.tag_error := false.B
158a469aa4bSWilliam Wang    io.resp.bits.error := false.B
1591f0e2dc7SJiawei Lin
1601f0e2dc7SJiawei Lin    when (io.resp.fire()) {
1611f0e2dc7SJiawei Lin      state := s_invalid
1621f0e2dc7SJiawei Lin    }
1631f0e2dc7SJiawei Lin  }
164*37225120Ssfencevma
165*37225120Ssfencevma  //  End
1661f0e2dc7SJiawei Lin}
1671f0e2dc7SJiawei Lin
1681f0e2dc7SJiawei Linclass UncacheIO(implicit p: Parameters) extends DCacheBundle {
169*37225120Ssfencevma  val hartId = Input(UInt())
170*37225120Ssfencevma  val enableOutstanding = Input(Bool())
171*37225120Ssfencevma  val flush = Flipped(new UncacheFlushBundle)
1726786cfb7SWilliam Wang  val lsq = Flipped(new UncacheWordIO)
1731f0e2dc7SJiawei Lin}
1741f0e2dc7SJiawei Lin
1751f0e2dc7SJiawei Lin// convert DCacheIO to TileLink
1761f0e2dc7SJiawei Lin// for Now, we only deal with TL-UL
1771f0e2dc7SJiawei Lin
178*37225120Ssfencevmaclass Uncache()(implicit p: Parameters) extends LazyModule with HasXSParameter {
179*37225120Ssfencevma  def idRange: Int = UncacheBufferSize
1801f0e2dc7SJiawei Lin
1811f0e2dc7SJiawei Lin  val clientParameters = TLMasterPortParameters.v1(
1821f0e2dc7SJiawei Lin    clients = Seq(TLMasterParameters.v1(
1831f0e2dc7SJiawei Lin      "uncache",
184*37225120Ssfencevma      sourceId = IdRange(0, idRange)
1851f0e2dc7SJiawei Lin    ))
1861f0e2dc7SJiawei Lin  )
1871f0e2dc7SJiawei Lin  val clientNode = TLClientNode(Seq(clientParameters))
1881f0e2dc7SJiawei Lin
1891f0e2dc7SJiawei Lin  lazy val module = new UncacheImp(this)
1901f0e2dc7SJiawei Lin}
1911f0e2dc7SJiawei Lin
192*37225120Ssfencevmaclass UncacheImp(outer: Uncache)extends LazyModuleImp(outer)
1931f0e2dc7SJiawei Lin  with HasTLDump
194*37225120Ssfencevma  with HasXSParameter
195*37225120Ssfencevma  with HasPerfEvents
1961f0e2dc7SJiawei Lin{
1971f0e2dc7SJiawei Lin val io = IO(new UncacheIO)
1981f0e2dc7SJiawei Lin
1991f0e2dc7SJiawei Lin  val (bus, edge) = outer.clientNode.out.head
2001f0e2dc7SJiawei Lin
2011f0e2dc7SJiawei Lin  val req  = io.lsq.req
2021f0e2dc7SJiawei Lin  val resp = io.lsq.resp
2031f0e2dc7SJiawei Lin  val mem_acquire = bus.a
2041f0e2dc7SJiawei Lin  val mem_grant   = bus.d
2051f0e2dc7SJiawei Lin
2061f0e2dc7SJiawei Lin  val req_ready = WireInit(false.B)
207*37225120Ssfencevma  val need_fence = WireInit(false.B)
2081f0e2dc7SJiawei Lin
2091f0e2dc7SJiawei Lin  // assign default values to output signals
2101f0e2dc7SJiawei Lin  bus.b.ready := false.B
2111f0e2dc7SJiawei Lin  bus.c.valid := false.B
2121f0e2dc7SJiawei Lin  bus.c.bits  := DontCare
2131f0e2dc7SJiawei Lin  bus.d.ready := false.B
2141f0e2dc7SJiawei Lin  bus.e.valid := false.B
2151f0e2dc7SJiawei Lin  bus.e.bits  := DontCare
2161f0e2dc7SJiawei Lin
217*37225120Ssfencevma  val enqPtr = RegInit(0.U.asTypeOf(new UncachePtr))
218*37225120Ssfencevma  val issPtr = RegInit(0.U.asTypeOf(new UncachePtr))
219*37225120Ssfencevma  val deqPtr = RegInit(0.U.asTypeOf(new UncachePtr))
220*37225120Ssfencevma  val fence = RegInit(Bool(), false.B)
2211f0e2dc7SJiawei Lin
222*37225120Ssfencevma  io.lsq.resp.valid := false.B
223*37225120Ssfencevma  io.lsq.resp.bits := DontCare
2241f0e2dc7SJiawei Lin
225*37225120Ssfencevma  val entries = Seq.fill(UncacheBufferSize) { Module(new MMIOEntry(edge)) }
226*37225120Ssfencevma  for ((entry, i) <- entries.zipWithIndex) {
227*37225120Ssfencevma    entry.io.hartId := io.hartId
228*37225120Ssfencevma    entry.io.enableOutstanding := io.enableOutstanding
229*37225120Ssfencevma
230*37225120Ssfencevma   //  Enqueue
231*37225120Ssfencevma    entry.io.req.valid := (i.U === enqPtr.value) && req.valid
2321f0e2dc7SJiawei Lin    entry.io.req.bits := req.bits
233*37225120Ssfencevma
234*37225120Ssfencevma    when (i.U === enqPtr.value) {
2351f0e2dc7SJiawei Lin      req_ready := entry.io.req.ready
2361f0e2dc7SJiawei Lin    }
2371f0e2dc7SJiawei Lin
238*37225120Ssfencevma    //  Acquire
239*37225120Ssfencevma    entry.io.select := (i.U === issPtr.value) && Mux(entry.io.atomic, issPtr.value === deqPtr.value, !fence)
2401f0e2dc7SJiawei Lin
241*37225120Ssfencevma    when (i.U === issPtr.value) {
242*37225120Ssfencevma      need_fence := entry.io.atomic
243*37225120Ssfencevma    }
244*37225120Ssfencevma
245*37225120Ssfencevma    //  Grant
2461f0e2dc7SJiawei Lin    entry.io.mem_grant.valid := false.B
2471f0e2dc7SJiawei Lin    entry.io.mem_grant.bits := DontCare
248*37225120Ssfencevma    when (i.U === deqPtr.value) {
2491f0e2dc7SJiawei Lin      entry.io.mem_grant <> mem_grant
2501f0e2dc7SJiawei Lin    }
251*37225120Ssfencevma
252*37225120Ssfencevma    entry.io.resp.ready := false.B
253*37225120Ssfencevma    when (i.U === deqPtr.value) {
254*37225120Ssfencevma      io.lsq.resp <> entry.io.resp
2551f0e2dc7SJiawei Lin    }
2561f0e2dc7SJiawei Lin
257*37225120Ssfencevma  }
2581f0e2dc7SJiawei Lin
259*37225120Ssfencevma  io.lsq.req.ready := req_ready
260*37225120Ssfencevma  when (io.enableOutstanding) {
261*37225120Ssfencevma    //  Uncache Buffer is a circular queue, which contains UncacheBufferSize entries.
262*37225120Ssfencevma    //  Description:
263*37225120Ssfencevma    //    enqPtr: Point to an invalid (means that the entry is free) entry.
264*37225120Ssfencevma    //    issPtr: Point to a ready entry, the entry is ready to issue.
265*37225120Ssfencevma    //    deqPtr: Point to the oldest entry, which was issued but has not accepted response (used to keep order with the program order).
266*37225120Ssfencevma    //
267*37225120Ssfencevma    //  When outstanding disabled, only one read/write request can be accepted at a time.
268*37225120Ssfencevma    //
269*37225120Ssfencevma    //  Example (Enable outstanding):
270*37225120Ssfencevma    //    1. enqPtr:
271*37225120Ssfencevma    //       1) Before enqueue
272*37225120Ssfencevma    //          enqPtr --
273*37225120Ssfencevma    //                  |
274*37225120Ssfencevma    //                  |
275*37225120Ssfencevma    //                  V
276*37225120Ssfencevma    //          +--+--+--+--+
277*37225120Ssfencevma    //          |  |  |  |  |
278*37225120Ssfencevma    //          |  |  |  |  |
279*37225120Ssfencevma    //          |  |  |  |  |
280*37225120Ssfencevma    //          +--+--+--+--+
281*37225120Ssfencevma    //
282*37225120Ssfencevma    //      2) After
283*37225120Ssfencevma    //          enqPtr+1 ---
284*37225120Ssfencevma    //                     |
285*37225120Ssfencevma    //                     |
286*37225120Ssfencevma    //                     V
287*37225120Ssfencevma    //          +--+--+--+--+
288*37225120Ssfencevma    //          |  |  |  |  |
289*37225120Ssfencevma    //          |  |  |  |  |
290*37225120Ssfencevma    //          |  |  |  |  |
291*37225120Ssfencevma    //          +--+--+--+--+
292*37225120Ssfencevma    //
293*37225120Ssfencevma    //    2. issPtr:
294*37225120Ssfencevma    //      1) Before issue
295*37225120Ssfencevma    //          issPtr --
296*37225120Ssfencevma    //                  |
297*37225120Ssfencevma    //                  |
298*37225120Ssfencevma    //                  V
299*37225120Ssfencevma    //          +--+--+--+--+
300*37225120Ssfencevma    //          |  |  |  |  |
301*37225120Ssfencevma    //          |  |  |  |  |
302*37225120Ssfencevma    //          |  |  |  |  |
303*37225120Ssfencevma    //          +--+--+--+--+
304*37225120Ssfencevma    //
305*37225120Ssfencevma    //      2) After issue
306*37225120Ssfencevma    //          issPtr+1 --
307*37225120Ssfencevma    //                    |
308*37225120Ssfencevma    //                    |
309*37225120Ssfencevma    //                    V
310*37225120Ssfencevma    //          +--+--+--+--+
311*37225120Ssfencevma    //          |  |  |  |  |
312*37225120Ssfencevma    //          |  |  |  |  |
313*37225120Ssfencevma    //          |  |  |  |  |
314*37225120Ssfencevma    //          +--+--+--+--+
315*37225120Ssfencevma    //
316*37225120Ssfencevma    //   3. deqPtr:
317*37225120Ssfencevma    //      1) Before dequeue
318*37225120Ssfencevma    //          deqPtr --
319*37225120Ssfencevma    //                  |
320*37225120Ssfencevma    //                  |
321*37225120Ssfencevma    //                  V
322*37225120Ssfencevma    //          +--+--+--+--+
323*37225120Ssfencevma    //          |  |  |  |  |
324*37225120Ssfencevma    //          |  |  |  |  |
325*37225120Ssfencevma    //          |  |  |  |  |
326*37225120Ssfencevma    //          +--+--+--+--+
327*37225120Ssfencevma    //
328*37225120Ssfencevma    //      2) After dequeue
329*37225120Ssfencevma    //          deqPtr --                    deqPtr+1 --
330*37225120Ssfencevma    //                  |                              |
331*37225120Ssfencevma    //                  |                              |
332*37225120Ssfencevma    //                  V                              V
333*37225120Ssfencevma    //          +--+--+--+--+       or      +--+--+--+--+
334*37225120Ssfencevma    //          |  |  |  |  |               |  |  |  |  |
335*37225120Ssfencevma    //          |  |  |  |  |               |  |  |  |  |
336*37225120Ssfencevma    //          |  |  |  |  |               |  |  |  |  |
337*37225120Ssfencevma    //          +--+--+--+--+               +--+--+--+--+
338*37225120Ssfencevma    //              (load)                     (store)
339*37225120Ssfencevma    //
340*37225120Ssfencevma    //      3) After response
341*37225120Ssfencevma    //          deqPtr+1 ---                   deqPtr--
342*37225120Ssfencevma    //                     |                          |
343*37225120Ssfencevma    //                     |                          |
344*37225120Ssfencevma    //                     V                          V
345*37225120Ssfencevma    //          +--+--+--+--+       or      +--+--+--+--+
346*37225120Ssfencevma    //          |  |  |  |  |               |  |  |  |  |
347*37225120Ssfencevma    //          |  |  |  |  |               |  |  |  |  |
348*37225120Ssfencevma    //          |  |  |  |  |               |  |  |  |  |
349*37225120Ssfencevma    //          +--+--+--+--+               +--+--+--+--+
350*37225120Ssfencevma    //              (load)                     (store)
351*37225120Ssfencevma    //
352*37225120Ssfencevma
353*37225120Ssfencevma    //  Enqueue
354*37225120Ssfencevma    when (req.fire) {
355*37225120Ssfencevma      enqPtr := enqPtr + 1.U
356*37225120Ssfencevma    }
357*37225120Ssfencevma
358*37225120Ssfencevma    //  Issue
359*37225120Ssfencevma    when (mem_acquire.fire) {
360*37225120Ssfencevma      issPtr := issPtr + 1.U
361*37225120Ssfencevma    }
362*37225120Ssfencevma
363*37225120Ssfencevma    when (mem_acquire.fire) {
364*37225120Ssfencevma      fence := need_fence
365*37225120Ssfencevma    }
366*37225120Ssfencevma
367*37225120Ssfencevma    //  Dequeue
368*37225120Ssfencevma    when (mem_grant.fire) {
369*37225120Ssfencevma      deqPtr := Mux(edge.hasData(mem_grant.bits), deqPtr /* Load */, deqPtr + 1.U /* Store */)
370*37225120Ssfencevma    } .elsewhen (io.lsq.resp.fire /* Load */) {
371*37225120Ssfencevma      deqPtr := deqPtr + 1.U
372*37225120Ssfencevma    }
373*37225120Ssfencevma
374*37225120Ssfencevma    when (mem_grant.fire && fence) {
375*37225120Ssfencevma      fence := false.B
376*37225120Ssfencevma    }
377*37225120Ssfencevma  } .otherwise {
378*37225120Ssfencevma    when (io.lsq.resp.fire) {
379*37225120Ssfencevma      enqPtr := enqPtr + 1.U
380*37225120Ssfencevma      issPtr := issPtr + 1.U
381*37225120Ssfencevma      deqPtr := deqPtr + 1.U
382*37225120Ssfencevma    }
383*37225120Ssfencevma  }
384*37225120Ssfencevma
3851f0e2dc7SJiawei Lin  TLArbiter.lowestFromSeq(edge, mem_acquire, entries.map(_.io.mem_acquire))
386*37225120Ssfencevma  io.flush.empty := deqPtr === enqPtr
3871f0e2dc7SJiawei Lin
388*37225120Ssfencevma  println(s"Uncahe Buffer Size: $UncacheBufferSize entries")
3891f0e2dc7SJiawei Lin
3901f0e2dc7SJiawei Lin  // print all input/output requests for debug purpose
3911f0e2dc7SJiawei Lin  // print req/resp
3921f0e2dc7SJiawei Lin  XSDebug(req.fire(), "req cmd: %x addr: %x data: %x mask: %x\n",
3931f0e2dc7SJiawei Lin    req.bits.cmd, req.bits.addr, req.bits.data, req.bits.mask)
3941f0e2dc7SJiawei Lin  XSDebug(resp.fire(), "data: %x\n", req.bits.data)
3951f0e2dc7SJiawei Lin
3961f0e2dc7SJiawei Lin  // print tilelink messages
3971f0e2dc7SJiawei Lin  when(mem_acquire.valid){
3981f0e2dc7SJiawei Lin    XSDebug("mem_acquire valid, ready=%d ", mem_acquire.ready)
3991f0e2dc7SJiawei Lin    mem_acquire.bits.dump
4001f0e2dc7SJiawei Lin  }
4011f0e2dc7SJiawei Lin  when (mem_grant.fire()) {
4021f0e2dc7SJiawei Lin    XSDebug("mem_grant fire ")
4031f0e2dc7SJiawei Lin    mem_grant.bits.dump
4041f0e2dc7SJiawei Lin  }
405*37225120Ssfencevma
406*37225120Ssfencevma  //  Performance Counters
407*37225120Ssfencevma  def isStore: Bool = io.lsq.req.bits.cmd === MemoryOpConstants.M_XWR
408*37225120Ssfencevma  XSPerfAccumulate("mmio_store", io.lsq.req.fire && isStore)
409*37225120Ssfencevma  XSPerfAccumulate("mmio_load", io.lsq.req.fire && !isStore)
410*37225120Ssfencevma  XSPerfAccumulate("mmio_outstanding", mem_acquire.fire && (deqPtr =/= issPtr))
411*37225120Ssfencevma  val perfEvents = Seq(
412*37225120Ssfencevma    ("mmio_store", io.lsq.req.fire && isStore),
413*37225120Ssfencevma    ("mmio_load", io.lsq.req.fire && !isStore),
414*37225120Ssfencevma    ("mmio_outstanding", mem_acquire.fire && (deqPtr =/= issPtr))
415*37225120Ssfencevma  )
416*37225120Ssfencevma
417*37225120Ssfencevma  generatePerfEvent()
418*37225120Ssfencevma  //  End
4191f0e2dc7SJiawei Lin}
420