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