xref: /XiangShan/src/main/scala/xiangshan/mem/lsqueue/StoreMisalignBuffer.scala (revision 4a02bbda53e20fbaf49032cf1deb7376a2aeefe5)
141d8d239Shappy-lx/***************************************************************************************
241d8d239Shappy-lx* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
341d8d239Shappy-lx* Copyright (c) 2020-2021 Peng Cheng Laboratory
441d8d239Shappy-lx*
541d8d239Shappy-lx* XiangShan is licensed under Mulan PSL v2.
641d8d239Shappy-lx* You can use this software according to the terms and conditions of the Mulan PSL v2.
741d8d239Shappy-lx* You may obtain a copy of Mulan PSL v2 at:
841d8d239Shappy-lx*          http://license.coscl.org.cn/MulanPSL2
941d8d239Shappy-lx*
1041d8d239Shappy-lx* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
1141d8d239Shappy-lx* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
1241d8d239Shappy-lx* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
1341d8d239Shappy-lx*
1441d8d239Shappy-lx* See the Mulan PSL v2 for more details.
1541d8d239Shappy-lx***************************************************************************************/
1641d8d239Shappy-lx
1741d8d239Shappy-lxpackage xiangshan.mem
1841d8d239Shappy-lx
1941d8d239Shappy-lximport org.chipsalliance.cde.config.Parameters
2041d8d239Shappy-lximport chisel3._
2141d8d239Shappy-lximport chisel3.util._
2241d8d239Shappy-lximport utils._
2341d8d239Shappy-lximport utility._
2441d8d239Shappy-lximport xiangshan._
259e12e8edScz4eimport xiangshan.ExceptionNO._
269e12e8edScz4eimport xiangshan.frontend.FtqPtr
2741d8d239Shappy-lximport xiangshan.backend.fu.FuConfig._
2841d8d239Shappy-lximport xiangshan.backend.fu.fpu.FPU
2941d8d239Shappy-lximport xiangshan.backend.rob.RobLsqIO
3041d8d239Shappy-lximport xiangshan.backend.rob.RobPtr
31b240e1c0SAnzoooooimport xiangshan.backend.Bundles._
32282dd18cSsfencevmaimport xiangshan.backend.fu.FuConfig.StaCfg
33b240e1c0SAnzoooooimport xiangshan.backend.fu.FuType.isVStore
349e12e8edScz4eimport xiangshan.mem.Bundles._
359e12e8edScz4eimport xiangshan.cache._
369e12e8edScz4eimport xiangshan.cache.wpu.ReplayCarry
3741d8d239Shappy-lx
3841d8d239Shappy-lxclass StoreMisalignBuffer(implicit p: Parameters) extends XSModule
3941d8d239Shappy-lx  with HasCircularQueuePtrHelper
4041d8d239Shappy-lx{
4141d8d239Shappy-lx  private val enqPortNum = StorePipelineWidth
4241d8d239Shappy-lx  private val maxSplitNum = 2
4341d8d239Shappy-lx
4441d8d239Shappy-lx  require(maxSplitNum == 2)
4541d8d239Shappy-lx
4641d8d239Shappy-lx  private val SB = "b00".U(2.W)
4741d8d239Shappy-lx  private val SH = "b01".U(2.W)
4841d8d239Shappy-lx  private val SW = "b10".U(2.W)
4941d8d239Shappy-lx  private val SD = "b11".U(2.W)
5041d8d239Shappy-lx
5141d8d239Shappy-lx  // encode of how many bytes to shift or truncate
5241d8d239Shappy-lx  private val BYTE0 = "b000".U(3.W)
5341d8d239Shappy-lx  private val BYTE1 = "b001".U(3.W)
5441d8d239Shappy-lx  private val BYTE2 = "b010".U(3.W)
5541d8d239Shappy-lx  private val BYTE3 = "b011".U(3.W)
5641d8d239Shappy-lx  private val BYTE4 = "b100".U(3.W)
5741d8d239Shappy-lx  private val BYTE5 = "b101".U(3.W)
5841d8d239Shappy-lx  private val BYTE6 = "b110".U(3.W)
5941d8d239Shappy-lx  private val BYTE7 = "b111".U(3.W)
6041d8d239Shappy-lx
6141d8d239Shappy-lx  def getMask(sizeEncode: UInt) = LookupTree(sizeEncode, List(
6241d8d239Shappy-lx    SB -> 0x1.U,
6341d8d239Shappy-lx    SH -> 0x3.U,
6441d8d239Shappy-lx    SW -> 0xf.U,
6541d8d239Shappy-lx    SD -> 0xff.U
6641d8d239Shappy-lx  ))
6741d8d239Shappy-lx
68b240e1c0SAnzooooo  def selectOldest[T <: LsPipelineBundle](valid: Seq[Bool], bits: Seq[T], index: Seq[UInt]): (Seq[Bool], Seq[T], Seq[UInt]) = {
6941d8d239Shappy-lx    assert(valid.length == bits.length)
7041d8d239Shappy-lx    if (valid.length == 0 || valid.length == 1) {
71b240e1c0SAnzooooo      (valid, bits, index)
7241d8d239Shappy-lx    } else if (valid.length == 2) {
7341d8d239Shappy-lx      val res = Seq.fill(2)(Wire(ValidIO(chiselTypeOf(bits(0)))))
74b240e1c0SAnzooooo      val resIndex = Seq.fill(2)(Wire(chiselTypeOf(index(0))))
7541d8d239Shappy-lx      for (i <- res.indices) {
7641d8d239Shappy-lx        res(i).valid := valid(i)
7741d8d239Shappy-lx        res(i).bits := bits(i)
78b240e1c0SAnzooooo        resIndex(i) := index(i)
7941d8d239Shappy-lx      }
8041d8d239Shappy-lx      val oldest = Mux(valid(0) && valid(1),
8141d8d239Shappy-lx        Mux(isAfter(bits(0).uop.robIdx, bits(1).uop.robIdx) ||
8241d8d239Shappy-lx          (isNotBefore(bits(0).uop.robIdx, bits(1).uop.robIdx) && bits(0).uop.uopIdx > bits(1).uop.uopIdx), res(1), res(0)),
8341d8d239Shappy-lx        Mux(valid(0) && !valid(1), res(0), res(1)))
84b240e1c0SAnzooooo
85b240e1c0SAnzooooo      val oldestIndex = Mux(valid(0) && valid(1),
86b240e1c0SAnzooooo        Mux(isAfter(bits(0).uop.robIdx, bits(1).uop.robIdx) ||
87b240e1c0SAnzooooo          (bits(0).uop.robIdx === bits(1).uop.robIdx && bits(0).uop.uopIdx > bits(1).uop.uopIdx), resIndex(1), resIndex(0)),
88b240e1c0SAnzooooo        Mux(valid(0) && !valid(1), resIndex(0), resIndex(1)))
89b240e1c0SAnzooooo      (Seq(oldest.valid), Seq(oldest.bits), Seq(oldestIndex))
9041d8d239Shappy-lx    } else {
91b240e1c0SAnzooooo      val left = selectOldest(valid.take(valid.length / 2), bits.take(bits.length / 2), index.take(index.length / 2))
92b240e1c0SAnzooooo      val right = selectOldest(valid.takeRight(valid.length - (valid.length / 2)), bits.takeRight(bits.length - (bits.length / 2)), index.takeRight(index.length - (index.length / 2)))
93b240e1c0SAnzooooo      selectOldest(left._1 ++ right._1, left._2 ++ right._2, left._3 ++ right._3)
9441d8d239Shappy-lx    }
9541d8d239Shappy-lx  }
9641d8d239Shappy-lx
9741d8d239Shappy-lx  val io = IO(new Bundle() {
9841d8d239Shappy-lx    val redirect        = Flipped(Valid(new Redirect))
994ec1f462Scz4e    val enq             = Vec(enqPortNum, Flipped(new MisalignBufferEnqIO))
10041d8d239Shappy-lx    val rob             = Flipped(new RobLsqIO)
10141d8d239Shappy-lx    val splitStoreReq   = Decoupled(new LsPipelineBundle)
10241d8d239Shappy-lx    val splitStoreResp  = Flipped(Valid(new SqWriteBundle))
10341d8d239Shappy-lx    val writeBack       = Decoupled(new MemExuOutput)
104b240e1c0SAnzooooo    val vecWriteBack    = Vec(VecStorePipelineWidth, Decoupled(new VecPipelineFeedbackIO(isVStore = true)))
105b240e1c0SAnzooooo    val storeOutValid    = Input(Bool())
106b240e1c0SAnzooooo    val storeVecOutValid = Input(Bool())
10741d8d239Shappy-lx    val overwriteExpBuf = Output(new XSBundle {
10841d8d239Shappy-lx      val valid = Bool()
10946e9ee74SHaoyuan Feng      val vaddr = UInt(XLEN.W)
11046e9ee74SHaoyuan Feng      val isHyper = Bool()
11146e9ee74SHaoyuan Feng      val gpaddr = UInt(XLEN.W)
112ad415ae0SXiaokun-Pei      val isForVSnonLeafPTE = Bool()
11341d8d239Shappy-lx    })
11441d8d239Shappy-lx    val sqControl       = new StoreMaBufToSqControlIO
115b240e1c0SAnzooooo
116b240e1c0SAnzooooo    val toVecStoreMergeBuffer = Vec(VecStorePipelineWidth, new StoreMaBufToVecStoreMergeBufferIO)
117b240e1c0SAnzooooo    val full = Bool()
11841d8d239Shappy-lx  })
11941d8d239Shappy-lx
12041d8d239Shappy-lx  io.rob.mmio := 0.U.asTypeOf(Vec(LoadPipelineWidth, Bool()))
12141d8d239Shappy-lx  io.rob.uop  := 0.U.asTypeOf(Vec(LoadPipelineWidth, new DynInst))
12241d8d239Shappy-lx
123b240e1c0SAnzooooo  class StoreMisalignBufferEntry(implicit p: Parameters) extends LsPipelineBundle {
124b240e1c0SAnzooooo    val portIndex = UInt(log2Up(enqPortNum).W)
125b240e1c0SAnzooooo  }
12641d8d239Shappy-lx  val req_valid = RegInit(false.B)
127b240e1c0SAnzooooo  val req = Reg(new StoreMisalignBufferEntry)
128b240e1c0SAnzooooo
129b240e1c0SAnzooooo  val cross4KBPageBoundary = Wire(Bool())
130b240e1c0SAnzooooo  val needFlushPipe = RegInit(false.B)
13141d8d239Shappy-lx
132acc50f3bSAnzo  // buffer control:
133acc50f3bSAnzo  //  - s_idle:  Idle
134acc50f3bSAnzo  //  - s_split: Split miss-aligned store into aligned stores
135acc50f3bSAnzo  //  - s_req:   Send split store to sta and get result from sta
136acc50f3bSAnzo  //  - s_resp:  Responds to a split store access request
137acc50f3bSAnzo  //  - s_wb:    writeback yo rob/vecMergeBuffer
138acc50f3bSAnzo  //  - s_block: Wait for this instr to reach the head of Rob.
139acc50f3bSAnzo  val s_idle :: s_split :: s_req :: s_resp :: s_wb :: s_block :: Nil = Enum(6)
140acc50f3bSAnzo  val bufferState    = RegInit(s_idle)
141acc50f3bSAnzo
14241d8d239Shappy-lx  // enqueue
14341d8d239Shappy-lx  // s1:
1444ec1f462Scz4e  val s1_req = VecInit(io.enq.map(_.req.bits))
1454ec1f462Scz4e  val s1_valid = VecInit(io.enq.map(x => x.req.valid))
14641d8d239Shappy-lx
1474ec1f462Scz4e  val s1_index = (0 until io.enq.length).map(_.asUInt)
148b240e1c0SAnzooooo  val reqSel = selectOldest(s1_valid, s1_req, s1_index)
14941d8d239Shappy-lx
150b240e1c0SAnzooooo  val reqSelValid = reqSel._1(0)
151b240e1c0SAnzooooo  val reqSelBits  = reqSel._2(0)
152b240e1c0SAnzooooo  val reqSelPort  = reqSel._3(0)
153b240e1c0SAnzooooo
154b240e1c0SAnzooooo  val reqRedirect = reqSelBits.uop.robIdx.needFlush(io.redirect)
155b240e1c0SAnzooooo
156b240e1c0SAnzooooo  val canEnq = !req_valid && !reqRedirect && reqSelValid
157acc50f3bSAnzo  val robMatch = req_valid && io.rob.pendingst && (io.rob.pendingPtr === req.uop.robIdx)
158acc50f3bSAnzo
1594ec1f462Scz4e  val s2_canEnq = GatedRegNext(canEnq)
1604ec1f462Scz4e  val s2_reqSelPort = GatedRegNext(reqSelPort)
1614ec1f462Scz4e  val misalign_can_split = Wire(Bool())
1624ec1f462Scz4e  misalign_can_split := Mux(s2_canEnq, (0 until enqPortNum).map {
1634ec1f462Scz4e    case i => !io.enq(i).revoke && s2_reqSelPort === i.U
1644ec1f462Scz4e  }.reduce(_|_), GatedRegNext(misalign_can_split))
1654ec1f462Scz4e
166b240e1c0SAnzooooo  when(canEnq) {
167b240e1c0SAnzooooo    connectSamePort(req, reqSelBits)
168b240e1c0SAnzooooo    req.portIndex := reqSelPort
1694ec1f462Scz4e    req_valid := true.B
170b240e1c0SAnzooooo  }
171b240e1c0SAnzooooo  val cross4KBPageEnq = WireInit(false.B)
172b240e1c0SAnzooooo  when (cross4KBPageBoundary && !reqRedirect) {
173acc50f3bSAnzo    when(
1744ec1f462Scz4e      reqSelValid &&
175acc50f3bSAnzo      (isAfter(req.uop.robIdx, reqSelBits.uop.robIdx) || (isNotBefore(req.uop.robIdx, reqSelBits.uop.robIdx) && req.uop.uopIdx > reqSelBits.uop.uopIdx)) &&
176acc50f3bSAnzo      bufferState === s_idle
177acc50f3bSAnzo    ) {
178b240e1c0SAnzooooo      connectSamePort(req, reqSelBits)
179b240e1c0SAnzooooo      req.portIndex := reqSelPort
180b240e1c0SAnzooooo      cross4KBPageEnq := true.B
181b240e1c0SAnzooooo      needFlushPipe   := true.B
182b240e1c0SAnzooooo    } .otherwise {
183b240e1c0SAnzooooo      req := req
184b240e1c0SAnzooooo      cross4KBPageEnq := false.B
185b240e1c0SAnzooooo    }
18641d8d239Shappy-lx  }
18741d8d239Shappy-lx
188b240e1c0SAnzooooo  val reqSelCanEnq = UIntToOH(reqSelPort)
189b240e1c0SAnzooooo
1904ec1f462Scz4e  io.enq.zipWithIndex.map{
1914ec1f462Scz4e    case (reqPort, index) => reqPort.req.ready := reqSelCanEnq(index) && (!req_valid || cross4KBPageBoundary && cross4KBPageEnq)
19241d8d239Shappy-lx  }
19341d8d239Shappy-lx
194b240e1c0SAnzooooo  io.toVecStoreMergeBuffer.zipWithIndex.map{
195b240e1c0SAnzooooo    case (toStMB, index) => {
196b240e1c0SAnzooooo      toStMB.flush   := req_valid && cross4KBPageBoundary && cross4KBPageEnq && UIntToOH(req.portIndex)(index)
197b240e1c0SAnzooooo      toStMB.mbIndex := req.mbIndex
19841d8d239Shappy-lx    }
199b240e1c0SAnzooooo  }
200b240e1c0SAnzooooo  io.full := req_valid
20141d8d239Shappy-lx
202acc50f3bSAnzo  //logic
20341d8d239Shappy-lx  val splitStoreReqs = RegInit(VecInit(List.fill(maxSplitNum)(0.U.asTypeOf(new LsPipelineBundle))))
20441d8d239Shappy-lx  val splitStoreResp = RegInit(VecInit(List.fill(maxSplitNum)(0.U.asTypeOf(new SqWriteBundle))))
205b240e1c0SAnzooooo  val isCrossPage    = RegInit(false.B)
206282dd18cSsfencevma  val exceptionVec   = RegInit(0.U.asTypeOf(ExceptionVec()))
20741d8d239Shappy-lx  val unSentStores   = RegInit(0.U(maxSplitNum.W))
20841d8d239Shappy-lx  val unWriteStores  = RegInit(0.U(maxSplitNum.W))
20941d8d239Shappy-lx  val curPtr = RegInit(0.U(log2Ceil(maxSplitNum).W))
21041d8d239Shappy-lx
21141d8d239Shappy-lx  // if there is exception or mmio in split store
21241d8d239Shappy-lx  val globalException = RegInit(false.B)
21335bb7796SAnzo  val globalUncache = RegInit(false.B)
21435bb7796SAnzo
21535bb7796SAnzo  // debug info
21641d8d239Shappy-lx  val globalMMIO = RegInit(false.B)
21735bb7796SAnzo  val globalNC   = RegInit(false.B)
21841d8d239Shappy-lx
219da51a7acSAnzo  val hasException = io.splitStoreResp.bits.vecActive && !io.splitStoreResp.bits.need_rep &&
220da51a7acSAnzo    ExceptionNO.selectByFu(io.splitStoreResp.bits.uop.exceptionVec, StaCfg).asUInt.orR || TriggerAction.isDmode(io.splitStoreResp.bits.uop.trigger)
22135bb7796SAnzo  val isUncache = (io.splitStoreResp.bits.mmio || io.splitStoreResp.bits.nc) && !io.splitStoreResp.bits.need_rep
22241d8d239Shappy-lx
223b240e1c0SAnzooooo  io.sqControl.toStoreQueue.crossPageWithHit := io.sqControl.toStoreMisalignBuffer.sqPtr === req.uop.sqIdx && isCrossPage
224b240e1c0SAnzooooo  io.sqControl.toStoreQueue.crossPageCanDeq := !isCrossPage || bufferState === s_block
225b240e1c0SAnzooooo  io.sqControl.toStoreQueue.paddr := Cat(splitStoreResp(1).paddr(splitStoreResp(1).paddr.getWidth - 1, 3), 0.U(3.W))
226b240e1c0SAnzooooo
227b240e1c0SAnzooooo  io.sqControl.toStoreQueue.withSameUop := io.sqControl.toStoreMisalignBuffer.uop.robIdx === req.uop.robIdx && io.sqControl.toStoreMisalignBuffer.uop.uopIdx === req.uop.uopIdx && req.isvec && robMatch && isCrossPage
228b240e1c0SAnzooooo
229acc50f3bSAnzo  //state transition
23041d8d239Shappy-lx  switch(bufferState) {
23141d8d239Shappy-lx    is (s_idle) {
2324ec1f462Scz4e      when(cross4KBPageBoundary && misalign_can_split) {
23341d8d239Shappy-lx        when(robMatch) {
23441d8d239Shappy-lx          bufferState := s_split
235b240e1c0SAnzooooo          isCrossPage := true.B
23641d8d239Shappy-lx        }
237b240e1c0SAnzooooo      } .otherwise {
2384ec1f462Scz4e        when (req_valid && misalign_can_split) {
239b240e1c0SAnzooooo          bufferState := s_split
240b240e1c0SAnzooooo          isCrossPage := false.B
241b240e1c0SAnzooooo        }
242b240e1c0SAnzooooo      }
24341d8d239Shappy-lx    }
24441d8d239Shappy-lx
24541d8d239Shappy-lx    is (s_split) {
24641d8d239Shappy-lx      bufferState := s_req
24741d8d239Shappy-lx    }
24841d8d239Shappy-lx
24941d8d239Shappy-lx    is (s_req) {
25041d8d239Shappy-lx      when (io.splitStoreReq.fire) {
25141d8d239Shappy-lx        bufferState := s_resp
25241d8d239Shappy-lx      }
25341d8d239Shappy-lx    }
25441d8d239Shappy-lx
25541d8d239Shappy-lx    is (s_resp) {
256*4a02bbdaSAnzo      val needDelay = WireInit(false.B)
257*4a02bbdaSAnzo
25841d8d239Shappy-lx      when (io.splitStoreResp.valid) {
25941d8d239Shappy-lx        val clearOh = UIntToOH(curPtr)
26035bb7796SAnzo        when (hasException || isUncache) {
26141d8d239Shappy-lx          // commit directly when exception ocurs
26241d8d239Shappy-lx          // if any split store reaches mmio space, delegate to software storeAddrMisaligned exception
26341d8d239Shappy-lx          bufferState := s_wb
26441d8d239Shappy-lx          globalException := hasException
26535bb7796SAnzo          globalUncache := isUncache
26635bb7796SAnzo          globalMMIO := io.splitStoreResp.bits.mmio
26735bb7796SAnzo          globalNC   := io.splitStoreResp.bits.nc
268b240e1c0SAnzooooo        } .elsewhen(io.splitStoreResp.bits.need_rep || (unSentStores & (~clearOh).asUInt).orR) {
26941d8d239Shappy-lx          // need replay or still has unsent requests
27041d8d239Shappy-lx          bufferState := s_req
27141d8d239Shappy-lx        } .otherwise {
272*4a02bbdaSAnzo          // got result, goto calculate data and control sq.
273*4a02bbdaSAnzo          // Wait a beat to get  misalign writeback aligned raw rollback.
274*4a02bbdaSAnzo          needDelay := true.B
275*4a02bbdaSAnzo          bufferState := s_resp
27641d8d239Shappy-lx        }
27741d8d239Shappy-lx      }
278*4a02bbdaSAnzo
279*4a02bbdaSAnzo      when (RegNextN(needDelay, RAWTotalDelayCycles)) {
280*4a02bbdaSAnzo        bufferState := s_wb
281*4a02bbdaSAnzo      }
28241d8d239Shappy-lx    }
28341d8d239Shappy-lx
28441d8d239Shappy-lx    is (s_wb) {
285b240e1c0SAnzooooo      when (req.isvec) {
286b240e1c0SAnzooooo        when (io.vecWriteBack.map(x => x.fire).reduce( _ || _)) {
28741d8d239Shappy-lx          bufferState := s_idle
28841d8d239Shappy-lx          req_valid := false.B
28941d8d239Shappy-lx          curPtr := 0.U
29041d8d239Shappy-lx          unSentStores := 0.U
29141d8d239Shappy-lx          unWriteStores := 0.U
29241d8d239Shappy-lx          globalException := false.B
29335bb7796SAnzo          globalUncache := false.B
294b240e1c0SAnzooooo          isCrossPage := false.B
295b240e1c0SAnzooooo          needFlushPipe := false.B
29635bb7796SAnzo
29735bb7796SAnzo          globalMMIO := false.B
29835bb7796SAnzo          globalNC   := false.B
299b240e1c0SAnzooooo        }
30075efee3dSAnzo
30175efee3dSAnzo      }.otherwise {
30235bb7796SAnzo        when (io.writeBack.fire && (!isCrossPage || globalUncache || globalException)) {
303b240e1c0SAnzooooo          bufferState := s_idle
304b240e1c0SAnzooooo          req_valid := false.B
305b240e1c0SAnzooooo          curPtr := 0.U
306b240e1c0SAnzooooo          unSentStores := 0.U
307b240e1c0SAnzooooo          unWriteStores := 0.U
308b240e1c0SAnzooooo          globalException := false.B
30935bb7796SAnzo          globalUncache := false.B
310b240e1c0SAnzooooo          isCrossPage := false.B
311b240e1c0SAnzooooo          needFlushPipe := false.B
31235bb7796SAnzo
31335bb7796SAnzo          globalMMIO := false.B
31435bb7796SAnzo          globalNC   := false.B
315b240e1c0SAnzooooo        } .elsewhen(io.writeBack.fire && isCrossPage) {
316b240e1c0SAnzooooo          bufferState := s_block
317b240e1c0SAnzooooo        } .otherwise {
318b240e1c0SAnzooooo          bufferState := s_wb
319b240e1c0SAnzooooo        }
32075efee3dSAnzo
32175efee3dSAnzo      }
322b240e1c0SAnzooooo    }
323b240e1c0SAnzooooo
324b240e1c0SAnzooooo    is (s_block) {
325b240e1c0SAnzooooo      when (io.sqControl.toStoreMisalignBuffer.doDeq) {
326b240e1c0SAnzooooo        bufferState := s_idle
327b240e1c0SAnzooooo        req_valid := false.B
328b240e1c0SAnzooooo        curPtr := 0.U
329b240e1c0SAnzooooo        unSentStores := 0.U
330b240e1c0SAnzooooo        unWriteStores := 0.U
331b240e1c0SAnzooooo        globalException := false.B
33235bb7796SAnzo        globalUncache := false.B
333b240e1c0SAnzooooo        isCrossPage := false.B
33435bb7796SAnzo        needFlushPipe := false.B
33535bb7796SAnzo
33635bb7796SAnzo        globalMMIO := false.B
33735bb7796SAnzo        globalNC   := false.B
33841d8d239Shappy-lx      }
33941d8d239Shappy-lx    }
34041d8d239Shappy-lx  }
34141d8d239Shappy-lx
342b240e1c0SAnzooooo  val alignedType = Mux(req.isvec, req.alignedType(1,0), req.uop.fuOpType(1, 0))
343b240e1c0SAnzooooo
344b240e1c0SAnzooooo  val highAddress = LookupTree(alignedType, List(
34541d8d239Shappy-lx    SB -> 0.U,
34641d8d239Shappy-lx    SH -> 1.U,
34741d8d239Shappy-lx    SW -> 3.U,
34841d8d239Shappy-lx    SD -> 7.U
34941d8d239Shappy-lx  )) + req.vaddr(4, 0)
350b240e1c0SAnzooooo
351b240e1c0SAnzooooo  val highPageAddress = LookupTree(alignedType, List(
352b240e1c0SAnzooooo    SB -> 0.U,
353b240e1c0SAnzooooo    SH -> 1.U,
354b240e1c0SAnzooooo    SW -> 3.U,
355b240e1c0SAnzooooo    SD -> 7.U
356b240e1c0SAnzooooo  )) + req.vaddr(12, 0)
35741d8d239Shappy-lx  // to see if (vaddr + opSize - 1) and vaddr are in the same 16 bytes region
35841d8d239Shappy-lx  val cross16BytesBoundary = req_valid && (highAddress(4) =/= req.vaddr(4))
359b240e1c0SAnzooooo  cross4KBPageBoundary := req_valid && (highPageAddress(12) =/= req.vaddr(12))
36041d8d239Shappy-lx  val aligned16BytesAddr   = (req.vaddr >> 4) << 4// req.vaddr & ~("b1111".U)
36141d8d239Shappy-lx  val aligned16BytesSel    = req.vaddr(3, 0)
36241d8d239Shappy-lx
36341d8d239Shappy-lx  // meta of 128 bit store
36441d8d239Shappy-lx  val new128Store = WireInit(0.U.asTypeOf(new LsPipelineBundle))
36541d8d239Shappy-lx  // meta of split loads
36641d8d239Shappy-lx  val lowAddrStore  = WireInit(0.U.asTypeOf(new LsPipelineBundle))
36741d8d239Shappy-lx  val highAddrStore = WireInit(0.U.asTypeOf(new LsPipelineBundle))
36841d8d239Shappy-lx  // final lowResult = Cat(`lowResultWidth` of store data, 0.U(make it to fill total length of Vlen))
36941d8d239Shappy-lx  val lowResultWidth = RegInit(0.U(3.W)) // how many bytes should we take from the store data
37041d8d239Shappy-lx  // final highResult = Zero extend to Vlen(`highResultWidth` of (store data >> lowResultWidth))
37141d8d239Shappy-lx  val highResultWidth = RegInit(0.U(3.W)) // how many bytes should we take from the store data
37241d8d239Shappy-lx
37341d8d239Shappy-lx  when (bufferState === s_split) {
37441d8d239Shappy-lx    when (!cross16BytesBoundary) {
375b240e1c0SAnzooooo      assert(false.B, s"There should be no non-aligned access that does not cross 16Byte boundaries.")
37641d8d239Shappy-lx    } .otherwise {
37741d8d239Shappy-lx      // split this unaligned store into `maxSplitNum` aligned stores
37841d8d239Shappy-lx      unWriteStores := Fill(maxSplitNum, 1.U(1.W))
37941d8d239Shappy-lx      unSentStores := Fill(maxSplitNum, 1.U(1.W))
38041d8d239Shappy-lx      curPtr := 0.U
38141d8d239Shappy-lx      lowAddrStore.uop := req.uop
38241d8d239Shappy-lx      lowAddrStore.uop.exceptionVec(storeAddrMisaligned) := false.B
38341d8d239Shappy-lx      highAddrStore.uop := req.uop
38441d8d239Shappy-lx      highAddrStore.uop.exceptionVec(storeAddrMisaligned) := false.B
38541d8d239Shappy-lx
386b240e1c0SAnzooooo      switch (alignedType(1, 0)) {
38741d8d239Shappy-lx        is (SB) {
38841d8d239Shappy-lx          assert(false.B, "lb should not trigger miss align")
38941d8d239Shappy-lx        }
39041d8d239Shappy-lx
39141d8d239Shappy-lx        is (SH) {
39241d8d239Shappy-lx          lowAddrStore.uop.fuOpType := SB
39341d8d239Shappy-lx          lowAddrStore.vaddr := req.vaddr
39441d8d239Shappy-lx          lowAddrStore.mask  := 0x1.U << lowAddrStore.vaddr(3, 0)
39541d8d239Shappy-lx          lowResultWidth    := BYTE1
39641d8d239Shappy-lx
39741d8d239Shappy-lx          highAddrStore.uop.fuOpType := SB
39841d8d239Shappy-lx          highAddrStore.vaddr := req.vaddr + 1.U
39941d8d239Shappy-lx          highAddrStore.mask  := 0x1.U << highAddrStore.vaddr(3, 0)
40041d8d239Shappy-lx          highResultWidth    := BYTE1
40141d8d239Shappy-lx        }
40241d8d239Shappy-lx
40341d8d239Shappy-lx        is (SW) {
40441d8d239Shappy-lx          switch (req.vaddr(1, 0)) {
40541d8d239Shappy-lx            is ("b00".U) {
40641d8d239Shappy-lx              assert(false.B, "should not trigger miss align")
40741d8d239Shappy-lx            }
40841d8d239Shappy-lx
40941d8d239Shappy-lx            is ("b01".U) {
41041d8d239Shappy-lx              lowAddrStore.uop.fuOpType := SW
41141d8d239Shappy-lx              lowAddrStore.vaddr := req.vaddr - 1.U
41241d8d239Shappy-lx              lowAddrStore.mask  := 0xf.U << lowAddrStore.vaddr(3, 0)
41341d8d239Shappy-lx              lowResultWidth    := BYTE3
41441d8d239Shappy-lx
41541d8d239Shappy-lx              highAddrStore.uop.fuOpType := SB
41641d8d239Shappy-lx              highAddrStore.vaddr := req.vaddr + 3.U
41741d8d239Shappy-lx              highAddrStore.mask  := 0x1.U << highAddrStore.vaddr(3, 0)
41841d8d239Shappy-lx              highResultWidth    := BYTE1
41941d8d239Shappy-lx            }
42041d8d239Shappy-lx
42141d8d239Shappy-lx            is ("b10".U) {
42241d8d239Shappy-lx              lowAddrStore.uop.fuOpType := SH
42341d8d239Shappy-lx              lowAddrStore.vaddr := req.vaddr
42441d8d239Shappy-lx              lowAddrStore.mask  := 0x3.U << lowAddrStore.vaddr(3, 0)
42541d8d239Shappy-lx              lowResultWidth    := BYTE2
42641d8d239Shappy-lx
42741d8d239Shappy-lx              highAddrStore.uop.fuOpType := SH
42841d8d239Shappy-lx              highAddrStore.vaddr := req.vaddr + 2.U
42941d8d239Shappy-lx              highAddrStore.mask  := 0x3.U << highAddrStore.vaddr(3, 0)
43041d8d239Shappy-lx              highResultWidth    := BYTE2
43141d8d239Shappy-lx            }
43241d8d239Shappy-lx
43341d8d239Shappy-lx            is ("b11".U) {
43441d8d239Shappy-lx              lowAddrStore.uop.fuOpType := SB
43541d8d239Shappy-lx              lowAddrStore.vaddr := req.vaddr
43641d8d239Shappy-lx              lowAddrStore.mask  := 0x1.U << lowAddrStore.vaddr(3, 0)
43741d8d239Shappy-lx              lowResultWidth    := BYTE1
43841d8d239Shappy-lx
43941d8d239Shappy-lx              highAddrStore.uop.fuOpType := SW
44041d8d239Shappy-lx              highAddrStore.vaddr := req.vaddr + 1.U
44141d8d239Shappy-lx              highAddrStore.mask  := 0xf.U << highAddrStore.vaddr(3, 0)
44241d8d239Shappy-lx              highResultWidth    := BYTE3
44341d8d239Shappy-lx            }
44441d8d239Shappy-lx          }
44541d8d239Shappy-lx        }
44641d8d239Shappy-lx
44741d8d239Shappy-lx        is (SD) {
44841d8d239Shappy-lx          switch (req.vaddr(2, 0)) {
44941d8d239Shappy-lx            is ("b000".U) {
45041d8d239Shappy-lx              assert(false.B, "should not trigger miss align")
45141d8d239Shappy-lx            }
45241d8d239Shappy-lx
45341d8d239Shappy-lx            is ("b001".U) {
45441d8d239Shappy-lx              lowAddrStore.uop.fuOpType := SD
45541d8d239Shappy-lx              lowAddrStore.vaddr := req.vaddr - 1.U
45641d8d239Shappy-lx              lowAddrStore.mask  := 0xff.U << lowAddrStore.vaddr(3, 0)
45741d8d239Shappy-lx              lowResultWidth    := BYTE7
45841d8d239Shappy-lx
45941d8d239Shappy-lx              highAddrStore.uop.fuOpType := SB
46041d8d239Shappy-lx              highAddrStore.vaddr := req.vaddr + 7.U
46141d8d239Shappy-lx              highAddrStore.mask  := 0x1.U << highAddrStore.vaddr(3, 0)
46241d8d239Shappy-lx              highResultWidth    := BYTE1
46341d8d239Shappy-lx            }
46441d8d239Shappy-lx
46541d8d239Shappy-lx            is ("b010".U) {
46641d8d239Shappy-lx              lowAddrStore.uop.fuOpType := SD
46741d8d239Shappy-lx              lowAddrStore.vaddr := req.vaddr - 2.U
46841d8d239Shappy-lx              lowAddrStore.mask  := 0xff.U << lowAddrStore.vaddr(3, 0)
46941d8d239Shappy-lx              lowResultWidth    := BYTE6
47041d8d239Shappy-lx
47141d8d239Shappy-lx              highAddrStore.uop.fuOpType := SH
47241d8d239Shappy-lx              highAddrStore.vaddr := req.vaddr + 6.U
47341d8d239Shappy-lx              highAddrStore.mask  := 0x3.U << highAddrStore.vaddr(3, 0)
47441d8d239Shappy-lx              highResultWidth    := BYTE2
47541d8d239Shappy-lx            }
47641d8d239Shappy-lx
47741d8d239Shappy-lx            is ("b011".U) {
47841d8d239Shappy-lx              lowAddrStore.uop.fuOpType := SD
47941d8d239Shappy-lx              lowAddrStore.vaddr := req.vaddr - 3.U
48041d8d239Shappy-lx              lowAddrStore.mask  := 0xff.U << lowAddrStore.vaddr(3, 0)
48141d8d239Shappy-lx              lowResultWidth    := BYTE5
48241d8d239Shappy-lx
48341d8d239Shappy-lx              highAddrStore.uop.fuOpType := SW
48441d8d239Shappy-lx              highAddrStore.vaddr := req.vaddr + 5.U
48541d8d239Shappy-lx              highAddrStore.mask  := 0xf.U << highAddrStore.vaddr(3, 0)
48641d8d239Shappy-lx              highResultWidth    := BYTE3
48741d8d239Shappy-lx            }
48841d8d239Shappy-lx
48941d8d239Shappy-lx            is ("b100".U) {
49041d8d239Shappy-lx              lowAddrStore.uop.fuOpType := SW
49141d8d239Shappy-lx              lowAddrStore.vaddr := req.vaddr
49241d8d239Shappy-lx              lowAddrStore.mask  := 0xf.U << lowAddrStore.vaddr(3, 0)
49341d8d239Shappy-lx              lowResultWidth    := BYTE4
49441d8d239Shappy-lx
49541d8d239Shappy-lx              highAddrStore.uop.fuOpType := SW
49641d8d239Shappy-lx              highAddrStore.vaddr := req.vaddr + 4.U
49741d8d239Shappy-lx              highAddrStore.mask  := 0xf.U << highAddrStore.vaddr(3, 0)
49841d8d239Shappy-lx              highResultWidth    := BYTE4
49941d8d239Shappy-lx            }
50041d8d239Shappy-lx
50141d8d239Shappy-lx            is ("b101".U) {
50241d8d239Shappy-lx              lowAddrStore.uop.fuOpType := SD
50341d8d239Shappy-lx              lowAddrStore.vaddr := req.vaddr - 5.U
50441d8d239Shappy-lx              lowAddrStore.mask  := 0xff.U << lowAddrStore.vaddr(3, 0)
50541d8d239Shappy-lx              lowResultWidth    := BYTE3
50641d8d239Shappy-lx
50741d8d239Shappy-lx              highAddrStore.uop.fuOpType := SD
50841d8d239Shappy-lx              highAddrStore.vaddr := req.vaddr + 3.U
50941d8d239Shappy-lx              highAddrStore.mask  := 0xff.U << highAddrStore.vaddr(3, 0)
51041d8d239Shappy-lx              highResultWidth    := BYTE5
51141d8d239Shappy-lx            }
51241d8d239Shappy-lx
51341d8d239Shappy-lx            is ("b110".U) {
51441d8d239Shappy-lx              lowAddrStore.uop.fuOpType := SD
51541d8d239Shappy-lx              lowAddrStore.vaddr := req.vaddr - 6.U
51641d8d239Shappy-lx              lowAddrStore.mask  := 0xff.U << lowAddrStore.vaddr(3, 0)
51741d8d239Shappy-lx              lowResultWidth    := BYTE2
51841d8d239Shappy-lx
51941d8d239Shappy-lx              highAddrStore.uop.fuOpType := SD
52041d8d239Shappy-lx              highAddrStore.vaddr := req.vaddr + 2.U
52141d8d239Shappy-lx              highAddrStore.mask  := 0xff.U << highAddrStore.vaddr(3, 0)
52241d8d239Shappy-lx              highResultWidth    := BYTE6
52341d8d239Shappy-lx            }
52441d8d239Shappy-lx
52541d8d239Shappy-lx            is ("b111".U) {
52641d8d239Shappy-lx              lowAddrStore.uop.fuOpType := SD
52741d8d239Shappy-lx              lowAddrStore.vaddr := req.vaddr - 7.U
52841d8d239Shappy-lx              lowAddrStore.mask  := 0xff.U << lowAddrStore.vaddr(3, 0)
52941d8d239Shappy-lx              lowResultWidth    := BYTE1
53041d8d239Shappy-lx
53141d8d239Shappy-lx              highAddrStore.uop.fuOpType := SD
53241d8d239Shappy-lx              highAddrStore.vaddr := req.vaddr + 1.U
53341d8d239Shappy-lx              highAddrStore.mask  := 0xff.U << highAddrStore.vaddr(3, 0)
53441d8d239Shappy-lx              highResultWidth    := BYTE7
53541d8d239Shappy-lx            }
53641d8d239Shappy-lx          }
53741d8d239Shappy-lx        }
53841d8d239Shappy-lx      }
53941d8d239Shappy-lx
54041d8d239Shappy-lx      splitStoreReqs(0) := lowAddrStore
54141d8d239Shappy-lx      splitStoreReqs(1) := highAddrStore
54241d8d239Shappy-lx    }
54341d8d239Shappy-lx  }
54441d8d239Shappy-lx
54541d8d239Shappy-lx  io.splitStoreReq.valid := req_valid && (bufferState === s_req)
54641d8d239Shappy-lx  io.splitStoreReq.bits  := splitStoreReqs(curPtr)
547562eaa0cSAnzooooo  io.splitStoreReq.bits.isvec  := req.isvec
5484c5e04f2Shappy-lx  // Restore the information of H extension store
5494c5e04f2Shappy-lx  // bit encoding: | hsv 1 | store 00 | size(2bit) |
5504c5e04f2Shappy-lx  val reqIsHsv  = LSUOpType.isHsv(req.uop.fuOpType)
551b240e1c0SAnzooooo  io.splitStoreReq.bits.uop.fuOpType := Mux(req.isvec, req.uop.fuOpType, Cat(reqIsHsv, 0.U(2.W), splitStoreReqs(curPtr).uop.fuOpType(1, 0)))
552b240e1c0SAnzooooo  io.splitStoreReq.bits.alignedType  := Mux(req.isvec, splitStoreReqs(curPtr).uop.fuOpType(1, 0), req.alignedType)
553b240e1c0SAnzooooo  io.splitStoreReq.bits.isFinalSplit := curPtr(0)
55441d8d239Shappy-lx
55541d8d239Shappy-lx  when (io.splitStoreResp.valid) {
556282dd18cSsfencevma    val resp = io.splitStoreResp.bits
55741d8d239Shappy-lx    splitStoreResp(curPtr) := io.splitStoreResp.bits
55835bb7796SAnzo    when (isUncache) {
55941d8d239Shappy-lx      unWriteStores := 0.U
56041d8d239Shappy-lx      unSentStores := 0.U
561e7ab4635SHuijin Li      exceptionVec := ExceptionNO.selectByFu(0.U.asTypeOf(exceptionVec.cloneType), StaCfg)
56241d8d239Shappy-lx      // delegate to software
563282dd18cSsfencevma      exceptionVec(storeAddrMisaligned) := true.B
56441d8d239Shappy-lx    } .elsewhen (hasException) {
56541d8d239Shappy-lx      unWriteStores := 0.U
56641d8d239Shappy-lx      unSentStores := 0.U
567282dd18cSsfencevma      StaCfg.exceptionOut.map(no => exceptionVec(no) := exceptionVec(no) || resp.uop.exceptionVec(no))
56841d8d239Shappy-lx    } .elsewhen (!io.splitStoreResp.bits.need_rep) {
569b240e1c0SAnzooooo      unSentStores := unSentStores & (~UIntToOH(curPtr)).asUInt
57041d8d239Shappy-lx      curPtr := curPtr + 1.U
571282dd18cSsfencevma      exceptionVec := 0.U.asTypeOf(ExceptionVec())
57241d8d239Shappy-lx    }
57341d8d239Shappy-lx  }
57441d8d239Shappy-lx
57541d8d239Shappy-lx  val splitStoreData = RegInit(VecInit(List.fill(maxSplitNum)(0.U.asTypeOf(new XSBundle {
57641d8d239Shappy-lx    val wdata = UInt(VLEN.W)
57741d8d239Shappy-lx    val wmask = UInt((VLEN / 8).W)
57841d8d239Shappy-lx  }))))
57941d8d239Shappy-lx
58041d8d239Shappy-lx  val wmaskLow  = Wire(Vec(VLEN / 8, Bool()))
58141d8d239Shappy-lx  val wmaskHigh = Wire(Vec(VLEN / 8, Bool()))
58241d8d239Shappy-lx  (0 until (VLEN / 8)).map {
58341d8d239Shappy-lx    case i  => {
58441d8d239Shappy-lx      when (i.U < highResultWidth) {
58541d8d239Shappy-lx        wmaskHigh(i) := true.B
58641d8d239Shappy-lx      } .otherwise {
58741d8d239Shappy-lx        wmaskHigh(i) := false.B
58841d8d239Shappy-lx      }
58941d8d239Shappy-lx      when (i.U < lowResultWidth) {
59041d8d239Shappy-lx        wmaskLow(i) := true.B
59141d8d239Shappy-lx      } .otherwise {
59241d8d239Shappy-lx        wmaskLow(i) := false.B
59341d8d239Shappy-lx      }
59441d8d239Shappy-lx    }
59541d8d239Shappy-lx  }
59641d8d239Shappy-lx
597b240e1c0SAnzooooo  io.writeBack.valid := req_valid && (bufferState === s_wb) && !io.storeOutValid && !req.isvec
59841d8d239Shappy-lx  io.writeBack.bits.uop := req.uop
599282dd18cSsfencevma  io.writeBack.bits.uop.exceptionVec := DontCare
60035bb7796SAnzo  StaCfg.exceptionOut.map(no => io.writeBack.bits.uop.exceptionVec(no) := (globalUncache || globalException) && exceptionVec(no))
601b240e1c0SAnzooooo  io.writeBack.bits.uop.flushPipe := needFlushPipe
60241d8d239Shappy-lx  io.writeBack.bits.uop.replayInst := false.B
603b240e1c0SAnzooooo  io.writeBack.bits.data := DontCare
604bd3e32c1Ssinsanction  io.writeBack.bits.isFromLoadUnit := DontCare
60541d8d239Shappy-lx  io.writeBack.bits.debug.isMMIO := globalMMIO
60635bb7796SAnzo  io.writeBack.bits.debug.isNC := globalNC
60741d8d239Shappy-lx  io.writeBack.bits.debug.isPerfCnt := false.B
60841d8d239Shappy-lx  io.writeBack.bits.debug.paddr := req.paddr
60941d8d239Shappy-lx  io.writeBack.bits.debug.vaddr := req.vaddr
61041d8d239Shappy-lx
611b240e1c0SAnzooooo  io.vecWriteBack.zipWithIndex.map{
612b240e1c0SAnzooooo    case (wb, index) => {
613b240e1c0SAnzooooo      wb.valid := req_valid && (bufferState === s_wb) && req.isvec && !io.storeVecOutValid && UIntToOH(req.portIndex)(index)
614b240e1c0SAnzooooo
615b240e1c0SAnzooooo      wb.bits.mBIndex           := req.mbIndex
616b240e1c0SAnzooooo      wb.bits.hit               := true.B
617b240e1c0SAnzooooo      wb.bits.isvec             := true.B
618b240e1c0SAnzooooo      wb.bits.sourceType        := RSFeedbackType.tlbMiss
619b240e1c0SAnzooooo      wb.bits.flushState        := DontCare
620b240e1c0SAnzooooo      wb.bits.trigger           := TriggerAction.None
621b240e1c0SAnzooooo      wb.bits.mmio              := globalMMIO
622b240e1c0SAnzooooo      wb.bits.exceptionVec      := ExceptionNO.selectByFu(exceptionVec, VstuCfg)
623da51a7acSAnzo      wb.bits.hasException      := globalException
624b240e1c0SAnzooooo      wb.bits.usSecondInv       := req.usSecondInv
625b240e1c0SAnzooooo      wb.bits.vecFeedback       := true.B
626b240e1c0SAnzooooo      wb.bits.elemIdx           := req.elemIdx
627b240e1c0SAnzooooo      wb.bits.alignedType       := req.alignedType
628b240e1c0SAnzooooo      wb.bits.mask              := req.mask
629b240e1c0SAnzooooo      wb.bits.vaddr             := req.vaddr
630b240e1c0SAnzooooo      wb.bits.vaNeedExt         := req.vaNeedExt
631b240e1c0SAnzooooo      wb.bits.gpaddr            := req.gpaddr
632b240e1c0SAnzooooo      wb.bits.isForVSnonLeafPTE := req.isForVSnonLeafPTE
633b240e1c0SAnzooooo      wb.bits.vstart            := req.uop.vpu.vstart
634b240e1c0SAnzooooo      wb.bits.vecTriggerMask    := 0.U
63535bb7796SAnzo      wb.bits.nc                := globalNC
636b240e1c0SAnzooooo    }
637b240e1c0SAnzooooo  }
63841d8d239Shappy-lx
63941d8d239Shappy-lx  val flush = req_valid && req.uop.robIdx.needFlush(io.redirect)
64041d8d239Shappy-lx
641b240e1c0SAnzooooo  when (flush) {
64241d8d239Shappy-lx    bufferState := s_idle
643b240e1c0SAnzooooo    req_valid := Mux(cross4KBPageEnq && cross4KBPageBoundary && !reqRedirect, req_valid, false.B)
64441d8d239Shappy-lx    curPtr := 0.U
64541d8d239Shappy-lx    unSentStores := 0.U
64641d8d239Shappy-lx    unWriteStores := 0.U
64741d8d239Shappy-lx    globalException := false.B
64835bb7796SAnzo    globalUncache := false.B
649b240e1c0SAnzooooo    isCrossPage := false.B
650b240e1c0SAnzooooo    needFlushPipe := false.B
65135bb7796SAnzo
65235bb7796SAnzo    globalMMIO := false.B
65335bb7796SAnzo    globalNC   := false.B
65441d8d239Shappy-lx  }
65541d8d239Shappy-lx
65641d8d239Shappy-lx  // NOTE: spectial case (unaligned store cross page, page fault happens in next page)
65741d8d239Shappy-lx  // if exception happens in the higher page address part, overwrite the storeExceptionBuffer vaddr
6586444fe09Sgood-circle  val shouldOverwrite = req_valid && cross16BytesBoundary && globalException && (curPtr === 1.U)
6596444fe09Sgood-circle  val overwriteExpBuf = GatedValidRegNext(shouldOverwrite)
6606444fe09Sgood-circle  val overwriteVaddr = RegEnable(splitStoreResp(curPtr).vaddr, shouldOverwrite)
6616444fe09Sgood-circle  val overwriteIsHyper = RegEnable(splitStoreResp(curPtr).isHyper, shouldOverwrite)
6626444fe09Sgood-circle  val overwriteGpaddr = RegEnable(splitStoreResp(curPtr).gpaddr, shouldOverwrite)
6636444fe09Sgood-circle  val overwriteIsForVSnonLeafPTE = RegEnable(splitStoreResp(curPtr).isForVSnonLeafPTE, shouldOverwrite)
66441d8d239Shappy-lx
665b240e1c0SAnzooooo  //TODO In theory, there is no need to overwrite, but for now, the signal is retained in the code in this way.
666b240e1c0SAnzooooo  // and the signal will be removed after sufficient verification.
667b240e1c0SAnzooooo  io.overwriteExpBuf.valid := false.B
66846e9ee74SHaoyuan Feng  io.overwriteExpBuf.vaddr := overwriteVaddr
66946e9ee74SHaoyuan Feng  io.overwriteExpBuf.isHyper := overwriteIsHyper
670a53daa0fSHaoyuan Feng  io.overwriteExpBuf.gpaddr := overwriteGpaddr
671ad415ae0SXiaokun-Pei  io.overwriteExpBuf.isForVSnonLeafPTE := overwriteIsForVSnonLeafPTE
67241d8d239Shappy-lx
67341d8d239Shappy-lx  XSPerfAccumulate("alloc",                  RegNext(!req_valid) && req_valid)
67441d8d239Shappy-lx  XSPerfAccumulate("flush",                  flush)
67541d8d239Shappy-lx  XSPerfAccumulate("flush_idle",             flush && (bufferState === s_idle))
67641d8d239Shappy-lx  XSPerfAccumulate("flush_non_idle",         flush && (bufferState =/= s_idle))
67741d8d239Shappy-lx}
678