xref: /XiangShan/src/main/scala/xiangshan/cache/dcache/Uncache.scala (revision 58cb1b0b6bd1a77315b3851d1cb42a07c4d215ef)
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
6506999a30Ssfencevma    // This entry is valid.
6606999a30Ssfencevma    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))
82*58cb1b0bSzhanglinjuan  val resp_nderr = Reg(Bool())
8337225120Ssfencevma  def storeReq = req.cmd === MemoryOpConstants.M_XWR
841f0e2dc7SJiawei Lin
8506999a30Ssfencevma  io.invalid := state === s_invalid
8637225120Ssfencevma  //  Assign default values to output signals.
871f0e2dc7SJiawei Lin  io.req.ready := false.B
881f0e2dc7SJiawei Lin  io.resp.valid := false.B
891f0e2dc7SJiawei Lin  io.resp.bits := DontCare
901f0e2dc7SJiawei Lin
911f0e2dc7SJiawei Lin  io.mem_acquire.valid := false.B
921f0e2dc7SJiawei Lin  io.mem_acquire.bits := DontCare
931f0e2dc7SJiawei Lin  io.mem_grant.ready := false.B
941f0e2dc7SJiawei Lin
9537225120Ssfencevma  io.atomic := req.atomic
9637225120Ssfencevma  //  Receive request
971f0e2dc7SJiawei Lin  when (state === s_invalid) {
981f0e2dc7SJiawei Lin    io.req.ready := true.B
991f0e2dc7SJiawei Lin
10037225120Ssfencevma    when (io.req.fire) {
1011f0e2dc7SJiawei Lin      req := io.req.bits
1021f0e2dc7SJiawei Lin      req.addr := io.req.bits.addr
103*58cb1b0bSzhanglinjuan      resp_nderr := false.B
1041f0e2dc7SJiawei Lin      state := s_refill_req
1051f0e2dc7SJiawei Lin    }
1061f0e2dc7SJiawei Lin  }
1071f0e2dc7SJiawei Lin
10837225120Ssfencevma  //  Refill
1091f0e2dc7SJiawei Lin  //  TODO: determine 'lgSize' in memend
1101f0e2dc7SJiawei Lin  val size = PopCount(req.mask)
1111f0e2dc7SJiawei Lin  val (lgSize, legal) = PriorityMuxWithFlag(Seq(
1121f0e2dc7SJiawei Lin    1.U -> 0.U,
1131f0e2dc7SJiawei Lin    2.U -> 1.U,
1141f0e2dc7SJiawei Lin    4.U -> 2.U,
1151f0e2dc7SJiawei Lin    8.U -> 3.U
1161f0e2dc7SJiawei Lin  ).map(m => (size===m._1) -> m._2))
1171f0e2dc7SJiawei Lin  assert(!(io.mem_acquire.valid && !legal))
1181f0e2dc7SJiawei Lin
1191f0e2dc7SJiawei Lin  val load = edge.Get(
12037225120Ssfencevma    fromSource      = io.hartId,
1211f0e2dc7SJiawei Lin    toAddress       = req.addr,
1221f0e2dc7SJiawei Lin    lgSize          = lgSize
1231f0e2dc7SJiawei Lin  )._2
1241f0e2dc7SJiawei Lin
1251f0e2dc7SJiawei Lin  val store = edge.Put(
12637225120Ssfencevma    fromSource      = io.hartId,
1271f0e2dc7SJiawei Lin    toAddress       = req.addr,
1281f0e2dc7SJiawei Lin    lgSize          = lgSize,
1291f0e2dc7SJiawei Lin    data            = req.data,
1301f0e2dc7SJiawei Lin    mask            = req.mask
1311f0e2dc7SJiawei Lin  )._2
1321f0e2dc7SJiawei Lin
13337225120Ssfencevma  XSDebug("entry: %d state: %d\n", io.hartId, state)
1341f0e2dc7SJiawei Lin
13537225120Ssfencevma  when (state === s_refill_req) {
13637225120Ssfencevma    io.mem_acquire.valid := true.B && io.select
13737225120Ssfencevma    io.mem_acquire.bits := Mux(storeReq, store, load)
13837225120Ssfencevma
13937225120Ssfencevma    when (io.mem_acquire.fire) {
1401f0e2dc7SJiawei Lin      state := s_refill_resp
1411f0e2dc7SJiawei Lin    }
1421f0e2dc7SJiawei Lin  }
1431f0e2dc7SJiawei Lin
1441f0e2dc7SJiawei Lin  val (_, _, refill_done, _) = edge.addr_inc(io.mem_grant)
1451f0e2dc7SJiawei Lin  when (state === s_refill_resp) {
1461f0e2dc7SJiawei Lin    io.mem_grant.ready := true.B
1471f0e2dc7SJiawei Lin
14837225120Ssfencevma    when (io.mem_grant.fire) {
1491f0e2dc7SJiawei Lin      resp_data := io.mem_grant.bits.data
150*58cb1b0bSzhanglinjuan      resp_nderr := io.mem_grant.bits.denied
151*58cb1b0bSzhanglinjuan      // TODO: consider corrupt
15237225120Ssfencevma      assert(refill_done, "Uncache response should be one beat only!")
15337225120Ssfencevma      state := Mux(storeReq && io.enableOutstanding, s_invalid, s_send_resp)
1541f0e2dc7SJiawei Lin    }
1551f0e2dc7SJiawei Lin  }
1561f0e2dc7SJiawei Lin
15737225120Ssfencevma  //  Response
1581f0e2dc7SJiawei Lin  when (state === s_send_resp) {
1591f0e2dc7SJiawei Lin    io.resp.valid := true.B
1601f0e2dc7SJiawei Lin    io.resp.bits.data   := resp_data
1611f0e2dc7SJiawei Lin    // meta data should go with the response
1621f0e2dc7SJiawei Lin    io.resp.bits.id     := req.id
1631f0e2dc7SJiawei Lin    io.resp.bits.miss   := false.B
1641f0e2dc7SJiawei Lin    io.resp.bits.replay := false.B
165a469aa4bSWilliam Wang    io.resp.bits.tag_error := false.B
166a469aa4bSWilliam Wang    io.resp.bits.error := false.B
167*58cb1b0bSzhanglinjuan    io.resp.bits.nderr := resp_nderr
1681f0e2dc7SJiawei Lin
169935edac4STang Haojin    when (io.resp.fire) {
1701f0e2dc7SJiawei Lin      state := s_invalid
1711f0e2dc7SJiawei Lin    }
1721f0e2dc7SJiawei Lin  }
17337225120Ssfencevma
17437225120Ssfencevma  //  End
1751f0e2dc7SJiawei Lin}
1761f0e2dc7SJiawei Lin
1771f0e2dc7SJiawei Linclass UncacheIO(implicit p: Parameters) extends DCacheBundle {
17837225120Ssfencevma  val hartId = Input(UInt())
17937225120Ssfencevma  val enableOutstanding = Input(Bool())
18037225120Ssfencevma  val flush = Flipped(new UncacheFlushBundle)
1816786cfb7SWilliam Wang  val lsq = Flipped(new UncacheWordIO)
1821f0e2dc7SJiawei Lin}
1831f0e2dc7SJiawei Lin
1841f0e2dc7SJiawei Lin// convert DCacheIO to TileLink
1851f0e2dc7SJiawei Lin// for Now, we only deal with TL-UL
1861f0e2dc7SJiawei Lin
18737225120Ssfencevmaclass Uncache()(implicit p: Parameters) extends LazyModule with HasXSParameter {
18895e60e55STang Haojin  override def shouldBeInlined: Boolean = false
18937225120Ssfencevma  def idRange: Int = UncacheBufferSize
1901f0e2dc7SJiawei Lin
1911f0e2dc7SJiawei Lin  val clientParameters = TLMasterPortParameters.v1(
1921f0e2dc7SJiawei Lin    clients = Seq(TLMasterParameters.v1(
1931f0e2dc7SJiawei Lin      "uncache",
19437225120Ssfencevma      sourceId = IdRange(0, idRange)
1951f0e2dc7SJiawei Lin    ))
1961f0e2dc7SJiawei Lin  )
1971f0e2dc7SJiawei Lin  val clientNode = TLClientNode(Seq(clientParameters))
1981f0e2dc7SJiawei Lin
1991f0e2dc7SJiawei Lin  lazy val module = new UncacheImp(this)
2001f0e2dc7SJiawei Lin}
2011f0e2dc7SJiawei Lin
20237225120Ssfencevmaclass UncacheImp(outer: Uncache)extends LazyModuleImp(outer)
2031f0e2dc7SJiawei Lin  with HasTLDump
20437225120Ssfencevma  with HasXSParameter
20537225120Ssfencevma  with HasPerfEvents
2061f0e2dc7SJiawei Lin{
2071f0e2dc7SJiawei Lin val io = IO(new UncacheIO)
2081f0e2dc7SJiawei Lin
2091f0e2dc7SJiawei Lin  val (bus, edge) = outer.clientNode.out.head
2101f0e2dc7SJiawei Lin
2111f0e2dc7SJiawei Lin  val req  = io.lsq.req
2121f0e2dc7SJiawei Lin  val resp = io.lsq.resp
2131f0e2dc7SJiawei Lin  val mem_acquire = bus.a
2141f0e2dc7SJiawei Lin  val mem_grant   = bus.d
2151f0e2dc7SJiawei Lin
2161f0e2dc7SJiawei Lin  val req_ready = WireInit(false.B)
21737225120Ssfencevma  val need_fence = WireInit(false.B)
2181f0e2dc7SJiawei Lin
2191f0e2dc7SJiawei Lin  // assign default values to output signals
2201f0e2dc7SJiawei Lin  bus.b.ready := false.B
2211f0e2dc7SJiawei Lin  bus.c.valid := false.B
2221f0e2dc7SJiawei Lin  bus.c.bits  := DontCare
2231f0e2dc7SJiawei Lin  bus.d.ready := false.B
2241f0e2dc7SJiawei Lin  bus.e.valid := false.B
2251f0e2dc7SJiawei Lin  bus.e.bits  := DontCare
2261f0e2dc7SJiawei Lin
22737225120Ssfencevma  val enqPtr = RegInit(0.U.asTypeOf(new UncachePtr))
22837225120Ssfencevma  val issPtr = RegInit(0.U.asTypeOf(new UncachePtr))
22937225120Ssfencevma  val deqPtr = RegInit(0.U.asTypeOf(new UncachePtr))
23037225120Ssfencevma  val fence = RegInit(Bool(), false.B)
2311f0e2dc7SJiawei Lin
23237225120Ssfencevma  io.lsq.resp.valid := false.B
23337225120Ssfencevma  io.lsq.resp.bits := DontCare
2341f0e2dc7SJiawei Lin
23537225120Ssfencevma  val entries = Seq.fill(UncacheBufferSize) { Module(new MMIOEntry(edge)) }
23637225120Ssfencevma  for ((entry, i) <- entries.zipWithIndex) {
23737225120Ssfencevma    entry.io.hartId := io.hartId
23837225120Ssfencevma    entry.io.enableOutstanding := io.enableOutstanding
23937225120Ssfencevma
24037225120Ssfencevma   //  Enqueue
24137225120Ssfencevma    entry.io.req.valid := (i.U === enqPtr.value) && req.valid
2421f0e2dc7SJiawei Lin    entry.io.req.bits := req.bits
24337225120Ssfencevma
24437225120Ssfencevma    when (i.U === enqPtr.value) {
2451f0e2dc7SJiawei Lin      req_ready := entry.io.req.ready
2461f0e2dc7SJiawei Lin    }
2471f0e2dc7SJiawei Lin
24837225120Ssfencevma    //  Acquire
24937225120Ssfencevma    entry.io.select := (i.U === issPtr.value) && Mux(entry.io.atomic, issPtr.value === deqPtr.value, !fence)
2501f0e2dc7SJiawei Lin
25137225120Ssfencevma    when (i.U === issPtr.value) {
25237225120Ssfencevma      need_fence := entry.io.atomic
25337225120Ssfencevma    }
25437225120Ssfencevma
25537225120Ssfencevma    //  Grant
2561f0e2dc7SJiawei Lin    entry.io.mem_grant.valid := false.B
2571f0e2dc7SJiawei Lin    entry.io.mem_grant.bits := DontCare
25837225120Ssfencevma    when (i.U === deqPtr.value) {
2591f0e2dc7SJiawei Lin      entry.io.mem_grant <> mem_grant
2601f0e2dc7SJiawei Lin    }
26137225120Ssfencevma
26237225120Ssfencevma    entry.io.resp.ready := false.B
26337225120Ssfencevma    when (i.U === deqPtr.value) {
26437225120Ssfencevma      io.lsq.resp <> entry.io.resp
2651f0e2dc7SJiawei Lin    }
2661f0e2dc7SJiawei Lin
26737225120Ssfencevma  }
2681f0e2dc7SJiawei Lin
26937225120Ssfencevma  io.lsq.req.ready := req_ready
27037225120Ssfencevma  when (io.enableOutstanding) {
27137225120Ssfencevma    //  Uncache Buffer is a circular queue, which contains UncacheBufferSize entries.
27237225120Ssfencevma    //  Description:
27337225120Ssfencevma    //    enqPtr: Point to an invalid (means that the entry is free) entry.
27437225120Ssfencevma    //    issPtr: Point to a ready entry, the entry is ready to issue.
27537225120Ssfencevma    //    deqPtr: Point to the oldest entry, which was issued but has not accepted response (used to keep order with the program order).
27637225120Ssfencevma    //
27737225120Ssfencevma    //  When outstanding disabled, only one read/write request can be accepted at a time.
27837225120Ssfencevma    //
27937225120Ssfencevma    //  Example (Enable outstanding):
28037225120Ssfencevma    //    1. enqPtr:
28137225120Ssfencevma    //       1) Before enqueue
28237225120Ssfencevma    //          enqPtr --
28337225120Ssfencevma    //                  |
28437225120Ssfencevma    //                  |
28537225120Ssfencevma    //                  V
28637225120Ssfencevma    //          +--+--+--+--+
28737225120Ssfencevma    //          |  |  |  |  |
28837225120Ssfencevma    //          |  |  |  |  |
28937225120Ssfencevma    //          |  |  |  |  |
29037225120Ssfencevma    //          +--+--+--+--+
29137225120Ssfencevma    //
29237225120Ssfencevma    //      2) After
29337225120Ssfencevma    //          enqPtr+1 ---
29437225120Ssfencevma    //                     |
29537225120Ssfencevma    //                     |
29637225120Ssfencevma    //                     V
29737225120Ssfencevma    //          +--+--+--+--+
29837225120Ssfencevma    //          |  |  |  |  |
29937225120Ssfencevma    //          |  |  |  |  |
30037225120Ssfencevma    //          |  |  |  |  |
30137225120Ssfencevma    //          +--+--+--+--+
30237225120Ssfencevma    //
30337225120Ssfencevma    //    2. issPtr:
30437225120Ssfencevma    //      1) Before issue
30537225120Ssfencevma    //          issPtr --
30637225120Ssfencevma    //                  |
30737225120Ssfencevma    //                  |
30837225120Ssfencevma    //                  V
30937225120Ssfencevma    //          +--+--+--+--+
31037225120Ssfencevma    //          |  |  |  |  |
31137225120Ssfencevma    //          |  |  |  |  |
31237225120Ssfencevma    //          |  |  |  |  |
31337225120Ssfencevma    //          +--+--+--+--+
31437225120Ssfencevma    //
31537225120Ssfencevma    //      2) After issue
31637225120Ssfencevma    //          issPtr+1 --
31737225120Ssfencevma    //                    |
31837225120Ssfencevma    //                    |
31937225120Ssfencevma    //                    V
32037225120Ssfencevma    //          +--+--+--+--+
32137225120Ssfencevma    //          |  |  |  |  |
32237225120Ssfencevma    //          |  |  |  |  |
32337225120Ssfencevma    //          |  |  |  |  |
32437225120Ssfencevma    //          +--+--+--+--+
32537225120Ssfencevma    //
32637225120Ssfencevma    //   3. deqPtr:
32737225120Ssfencevma    //      1) Before dequeue
32837225120Ssfencevma    //          deqPtr --
32937225120Ssfencevma    //                  |
33037225120Ssfencevma    //                  |
33137225120Ssfencevma    //                  V
33237225120Ssfencevma    //          +--+--+--+--+
33337225120Ssfencevma    //          |  |  |  |  |
33437225120Ssfencevma    //          |  |  |  |  |
33537225120Ssfencevma    //          |  |  |  |  |
33637225120Ssfencevma    //          +--+--+--+--+
33737225120Ssfencevma    //
33837225120Ssfencevma    //      2) After dequeue
33937225120Ssfencevma    //          deqPtr --                    deqPtr+1 --
34037225120Ssfencevma    //                  |                              |
34137225120Ssfencevma    //                  |                              |
34237225120Ssfencevma    //                  V                              V
34337225120Ssfencevma    //          +--+--+--+--+       or      +--+--+--+--+
34437225120Ssfencevma    //          |  |  |  |  |               |  |  |  |  |
34537225120Ssfencevma    //          |  |  |  |  |               |  |  |  |  |
34637225120Ssfencevma    //          |  |  |  |  |               |  |  |  |  |
34737225120Ssfencevma    //          +--+--+--+--+               +--+--+--+--+
34837225120Ssfencevma    //              (load)                     (store)
34937225120Ssfencevma    //
35037225120Ssfencevma    //      3) After response
35137225120Ssfencevma    //          deqPtr+1 ---                   deqPtr--
35237225120Ssfencevma    //                     |                          |
35337225120Ssfencevma    //                     |                          |
35437225120Ssfencevma    //                     V                          V
35537225120Ssfencevma    //          +--+--+--+--+       or      +--+--+--+--+
35637225120Ssfencevma    //          |  |  |  |  |               |  |  |  |  |
35737225120Ssfencevma    //          |  |  |  |  |               |  |  |  |  |
35837225120Ssfencevma    //          |  |  |  |  |               |  |  |  |  |
35937225120Ssfencevma    //          +--+--+--+--+               +--+--+--+--+
36037225120Ssfencevma    //              (load)                     (store)
36137225120Ssfencevma    //
36237225120Ssfencevma
36337225120Ssfencevma    //  Enqueue
36437225120Ssfencevma    when (req.fire) {
36537225120Ssfencevma      enqPtr := enqPtr + 1.U
36637225120Ssfencevma    }
36737225120Ssfencevma
36837225120Ssfencevma    //  Issue
36937225120Ssfencevma    when (mem_acquire.fire) {
37037225120Ssfencevma      issPtr := issPtr + 1.U
37137225120Ssfencevma    }
37237225120Ssfencevma
37337225120Ssfencevma    when (mem_acquire.fire) {
37437225120Ssfencevma      fence := need_fence
37537225120Ssfencevma    }
37637225120Ssfencevma
37737225120Ssfencevma    //  Dequeue
37837225120Ssfencevma    when (mem_grant.fire) {
37937225120Ssfencevma      deqPtr := Mux(edge.hasData(mem_grant.bits), deqPtr /* Load */, deqPtr + 1.U /* Store */)
38037225120Ssfencevma    } .elsewhen (io.lsq.resp.fire /* Load */) {
38137225120Ssfencevma      deqPtr := deqPtr + 1.U
38237225120Ssfencevma    }
38337225120Ssfencevma
38437225120Ssfencevma    when (mem_grant.fire && fence) {
38537225120Ssfencevma      fence := false.B
38637225120Ssfencevma    }
38737225120Ssfencevma  } .otherwise {
38837225120Ssfencevma    when (io.lsq.resp.fire) {
38937225120Ssfencevma      enqPtr := enqPtr + 1.U
39037225120Ssfencevma      issPtr := issPtr + 1.U
39137225120Ssfencevma      deqPtr := deqPtr + 1.U
39237225120Ssfencevma    }
39337225120Ssfencevma  }
39437225120Ssfencevma
3951f0e2dc7SJiawei Lin  TLArbiter.lowestFromSeq(edge, mem_acquire, entries.map(_.io.mem_acquire))
39606999a30Ssfencevma  val invalid_entries = PopCount(entries.map(_.io.invalid))
39706999a30Ssfencevma  io.flush.empty := invalid_entries === UncacheBufferSize.U
3981f0e2dc7SJiawei Lin
39937225120Ssfencevma  println(s"Uncahe Buffer Size: $UncacheBufferSize entries")
4001f0e2dc7SJiawei Lin
4011f0e2dc7SJiawei Lin  // print all input/output requests for debug purpose
4021f0e2dc7SJiawei Lin  // print req/resp
403935edac4STang Haojin  XSDebug(req.fire, "req cmd: %x addr: %x data: %x mask: %x\n",
4041f0e2dc7SJiawei Lin    req.bits.cmd, req.bits.addr, req.bits.data, req.bits.mask)
405935edac4STang Haojin  XSDebug(resp.fire, "data: %x\n", req.bits.data)
4061f0e2dc7SJiawei Lin
4071f0e2dc7SJiawei Lin  // print tilelink messages
4081f0e2dc7SJiawei Lin  when(mem_acquire.valid){
4091f0e2dc7SJiawei Lin    XSDebug("mem_acquire valid, ready=%d ", mem_acquire.ready)
4101f0e2dc7SJiawei Lin    mem_acquire.bits.dump
4111f0e2dc7SJiawei Lin  }
412935edac4STang Haojin  when (mem_grant.fire) {
4131f0e2dc7SJiawei Lin    XSDebug("mem_grant fire ")
4141f0e2dc7SJiawei Lin    mem_grant.bits.dump
4151f0e2dc7SJiawei Lin  }
41637225120Ssfencevma
41737225120Ssfencevma  //  Performance Counters
41837225120Ssfencevma  def isStore: Bool = io.lsq.req.bits.cmd === MemoryOpConstants.M_XWR
41937225120Ssfencevma  XSPerfAccumulate("mmio_store", io.lsq.req.fire && isStore)
42037225120Ssfencevma  XSPerfAccumulate("mmio_load", io.lsq.req.fire && !isStore)
42137225120Ssfencevma  XSPerfAccumulate("mmio_outstanding", mem_acquire.fire && (deqPtr =/= issPtr))
42237225120Ssfencevma  val perfEvents = Seq(
42337225120Ssfencevma    ("mmio_store", io.lsq.req.fire && isStore),
42437225120Ssfencevma    ("mmio_load", io.lsq.req.fire && !isStore),
42537225120Ssfencevma    ("mmio_outstanding", mem_acquire.fire && (deqPtr =/= issPtr))
42637225120Ssfencevma  )
42737225120Ssfencevma
42837225120Ssfencevma  generatePerfEvent()
42937225120Ssfencevma  //  End
4301f0e2dc7SJiawei Lin}
431