xref: /XiangShan/src/main/scala/xiangshan/mem/lsqueue/LoadExceptionBuffer.scala (revision 9e12e8edb26ee7dce62315a8f279ea9f61aa239d)
114a67055Ssfencevma/***************************************************************************************
214a67055Ssfencevma* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
314a67055Ssfencevma* Copyright (c) 2020-2021 Peng Cheng Laboratory
414a67055Ssfencevma*
514a67055Ssfencevma* XiangShan is licensed under Mulan PSL v2.
614a67055Ssfencevma* You can use this software according to the terms and conditions of the Mulan PSL v2.
714a67055Ssfencevma* You may obtain a copy of Mulan PSL v2 at:
814a67055Ssfencevma*          http://license.coscl.org.cn/MulanPSL2
914a67055Ssfencevma*
1014a67055Ssfencevma* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
1114a67055Ssfencevma* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
1214a67055Ssfencevma* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
1314a67055Ssfencevma*
1414a67055Ssfencevma* See the Mulan PSL v2 for more details.
1514a67055Ssfencevma***************************************************************************************/
1614a67055Ssfencevma
1714a67055Ssfencevmapackage xiangshan.mem
1814a67055Ssfencevma
198891a219SYinan Xuimport org.chipsalliance.cde.config.Parameters
2014a67055Ssfencevmaimport chisel3._
2114a67055Ssfencevmaimport chisel3.util._
2214a67055Ssfencevmaimport utils._
2314a67055Ssfencevmaimport utility._
2414a67055Ssfencevmaimport xiangshan._
25*9e12e8edScz4eimport xiangshan.ExceptionNO._
26*9e12e8edScz4eimport xiangshan.frontend.FtqPtr
27870f462dSXuan Huimport xiangshan.backend.fu.FuConfig._
2814a67055Ssfencevmaimport xiangshan.backend.fu.fpu.FPU
2914a67055Ssfencevmaimport xiangshan.backend.rob.RobLsqIO
3014a67055Ssfencevmaimport xiangshan.backend.rob.RobPtr
31*9e12e8edScz4eimport xiangshan.mem.Bundles._
32*9e12e8edScz4eimport xiangshan.cache._
33*9e12e8edScz4eimport xiangshan.cache.wpu.ReplayCarry
3414a67055Ssfencevma
3514a67055Ssfencevmaclass LqExceptionBuffer(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelper {
36e9e6cd09SYanqin Li  val enqPortNum = LoadPipelineWidth + VecLoadPipelineWidth + 1 // 1 for mmio bus non-data error
3758cb1b0bSzhanglinjuan
3814a67055Ssfencevma  val io = IO(new Bundle() {
3914a67055Ssfencevma    val redirect      = Flipped(Valid(new Redirect))
4058cb1b0bSzhanglinjuan    val req           = Vec(enqPortNum, Flipped(Valid(new LqWriteBundle)))
4114a67055Ssfencevma    val exceptionAddr = new ExceptionAddrIO
4214a67055Ssfencevma  })
4314a67055Ssfencevma
4414a67055Ssfencevma  val req_valid = RegInit(false.B)
4514a67055Ssfencevma  val req = Reg(new LqWriteBundle)
4614a67055Ssfencevma
4714a67055Ssfencevma  // enqueue
4814a67055Ssfencevma  // s1:
4914a67055Ssfencevma  val s1_req = VecInit(io.req.map(_.bits))
5014a67055Ssfencevma  val s1_valid = VecInit(io.req.map(x => x.valid))
5114a67055Ssfencevma
5214a67055Ssfencevma  // s2: delay 1 cycle
535003e6f8SHuijin Li  val s2_req = (0 until enqPortNum).map(i => {
545003e6f8SHuijin Li    RegEnable(s1_req(i), s1_valid(i))})
5558cb1b0bSzhanglinjuan  val s2_valid = (0 until enqPortNum).map(i =>
5614a67055Ssfencevma    RegNext(s1_valid(i)) &&
5714a67055Ssfencevma    !s2_req(i).uop.robIdx.needFlush(RegNext(io.redirect)) &&
5814a67055Ssfencevma    !s2_req(i).uop.robIdx.needFlush(io.redirect)
5914a67055Ssfencevma  )
60870f462dSXuan Hu  val s2_has_exception = s2_req.map(x => ExceptionNO.selectByFu(x.uop.exceptionVec, LduCfg).asUInt.orR)
6114a67055Ssfencevma
6258cb1b0bSzhanglinjuan  val s2_enqueue = Wire(Vec(enqPortNum, Bool()))
6358cb1b0bSzhanglinjuan  for (w <- 0 until enqPortNum) {
6414a67055Ssfencevma    s2_enqueue(w) := s2_valid(w) && s2_has_exception(w)
6514a67055Ssfencevma  }
6614a67055Ssfencevma
678a956654Ssfencevma  when (req_valid && req.uop.robIdx.needFlush(io.redirect)) {
688a956654Ssfencevma    req_valid := s2_enqueue.asUInt.orR
6914a67055Ssfencevma  } .elsewhen (s2_enqueue.asUInt.orR) {
70b240e1c0SAnzooooo    req_valid := true.B
7114a67055Ssfencevma  }
7214a67055Ssfencevma
7314a67055Ssfencevma  def selectOldest[T <: LqWriteBundle](valid: Seq[Bool], bits: Seq[T]): (Seq[Bool], Seq[T]) = {
7414a67055Ssfencevma    assert(valid.length == bits.length)
7514a67055Ssfencevma    if (valid.length == 0 || valid.length == 1) {
7614a67055Ssfencevma      (valid, bits)
7714a67055Ssfencevma    } else if (valid.length == 2) {
7814a67055Ssfencevma      val res = Seq.fill(2)(Wire(ValidIO(chiselTypeOf(bits(0)))))
7914a67055Ssfencevma      for (i <- res.indices) {
8014a67055Ssfencevma        res(i).valid := valid(i)
8114a67055Ssfencevma        res(i).bits := bits(i)
8214a67055Ssfencevma      }
8326af847eSgood-circle      val oldest = Mux(valid(0) && valid(1),
8426af847eSgood-circle        Mux(isAfter(bits(0).uop.robIdx, bits(1).uop.robIdx) ||
852159ac24SAnzooooo          (bits(0).uop.robIdx === bits(1).uop.robIdx && bits(0).uop.uopIdx > bits(1).uop.uopIdx), res(1), res(0)),
8626af847eSgood-circle        Mux(valid(0) && !valid(1), res(0), res(1)))
8714a67055Ssfencevma      (Seq(oldest.valid), Seq(oldest.bits))
8814a67055Ssfencevma    } else {
8914a67055Ssfencevma      val left = selectOldest(valid.take(valid.length / 2), bits.take(bits.length / 2))
9014a67055Ssfencevma      val right = selectOldest(valid.takeRight(valid.length - (valid.length / 2)), bits.takeRight(bits.length - (bits.length / 2)))
9114a67055Ssfencevma      selectOldest(left._1 ++ right._1, left._2 ++ right._2)
9214a67055Ssfencevma    }
9314a67055Ssfencevma  }
9414a67055Ssfencevma
9514a67055Ssfencevma  val reqSel = selectOldest(s2_enqueue, s2_req)
9614a67055Ssfencevma
9714a67055Ssfencevma  when (req_valid) {
98d60bad71SAnzooooo    req := Mux(
992159ac24SAnzooooo      reqSel._1(0) && (isAfter(req.uop.robIdx, reqSel._2(0).uop.robIdx) || (req.uop.robIdx === reqSel._2(0).uop.robIdx && req.uop.uopIdx > reqSel._2(0).uop.uopIdx)),
100d60bad71SAnzooooo      reqSel._2(0),
101d60bad71SAnzooooo      req)
10214a67055Ssfencevma  } .elsewhen (s2_enqueue.asUInt.orR) {
10314a67055Ssfencevma    req := reqSel._2(0)
10414a67055Ssfencevma  }
10514a67055Ssfencevma
106db6cfb5aSHaoyuan Feng  io.exceptionAddr.vaddr  := req.fullva
10746e9ee74SHaoyuan Feng  io.exceptionAddr.vaNeedExt := req.vaNeedExt
10846e9ee74SHaoyuan Feng  io.exceptionAddr.isHyper := req.isHyper
10955178b77Sweiding liu  io.exceptionAddr.vstart := req.uop.vpu.vstart
11055178b77Sweiding liu  io.exceptionAddr.vl     := req.uop.vpu.vl
111c3d5cfb3Speixiaokun  io.exceptionAddr.gpaddr := req.gpaddr
112ad415ae0SXiaokun-Pei  io.exceptionAddr.isForVSnonLeafPTE := req.isForVSnonLeafPTE
11341d8d239Shappy-lx
11414a67055Ssfencevma  XSPerfAccumulate("exception", !RegNext(req_valid) && req_valid)
11514a67055Ssfencevma
11614a67055Ssfencevma  // end
11714a67055Ssfencevma}
118