1780712aaSxiaofeibao-xjtu/*************************************************************************************** 2780712aaSxiaofeibao-xjtu * Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3780712aaSxiaofeibao-xjtu * Copyright (c) 2020-2021 Peng Cheng Laboratory 4780712aaSxiaofeibao-xjtu * 5780712aaSxiaofeibao-xjtu * XiangShan is licensed under Mulan PSL v2. 6780712aaSxiaofeibao-xjtu * You can use this software according to the terms and conditions of the Mulan PSL v2. 7780712aaSxiaofeibao-xjtu * You may obtain a copy of Mulan PSL v2 at: 8780712aaSxiaofeibao-xjtu * http://license.coscl.org.cn/MulanPSL2 9780712aaSxiaofeibao-xjtu * 10780712aaSxiaofeibao-xjtu * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11780712aaSxiaofeibao-xjtu * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12780712aaSxiaofeibao-xjtu * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13780712aaSxiaofeibao-xjtu * 14780712aaSxiaofeibao-xjtu * See the Mulan PSL v2 for more details. 15780712aaSxiaofeibao-xjtu ***************************************************************************************/ 16780712aaSxiaofeibao-xjtu 17780712aaSxiaofeibao-xjtupackage xiangshan.backend.rob 18780712aaSxiaofeibao-xjtu 19780712aaSxiaofeibao-xjtuimport org.chipsalliance.cde.config.Parameters 20780712aaSxiaofeibao-xjtuimport chisel3._ 21780712aaSxiaofeibao-xjtuimport chisel3.util._ 22780712aaSxiaofeibao-xjtuimport difftest._ 23780712aaSxiaofeibao-xjtuimport freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp} 24780712aaSxiaofeibao-xjtuimport utility._ 25780712aaSxiaofeibao-xjtuimport utils._ 26780712aaSxiaofeibao-xjtuimport xiangshan._ 27780712aaSxiaofeibao-xjtuimport xiangshan.backend.BackendParams 28780712aaSxiaofeibao-xjtuimport xiangshan.backend.Bundles.{DynInst, ExceptionInfo, ExuOutput} 29780712aaSxiaofeibao-xjtuimport xiangshan.backend.fu.{FuConfig, FuType} 30780712aaSxiaofeibao-xjtuimport xiangshan.frontend.FtqPtr 31780712aaSxiaofeibao-xjtuimport xiangshan.mem.{LqPtr, LsqEnqIO, SqPtr} 32780712aaSxiaofeibao-xjtuimport xiangshan.backend.Bundles.{DynInst, ExceptionInfo, ExuOutput} 33780712aaSxiaofeibao-xjtuimport xiangshan.backend.ctrlblock.{DebugLSIO, DebugLsInfo, LsTopdownInfo} 34780712aaSxiaofeibao-xjtuimport xiangshan.backend.fu.vector.Bundles.VType 35780712aaSxiaofeibao-xjtuimport xiangshan.backend.rename.SnapshotGenerator 36780712aaSxiaofeibao-xjtu 37780712aaSxiaofeibao-xjtuclass ExceptionGen(params: BackendParams)(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelper { 38780712aaSxiaofeibao-xjtu val io = IO(new Bundle { 39780712aaSxiaofeibao-xjtu val redirect = Input(Valid(new Redirect)) 40780712aaSxiaofeibao-xjtu val flush = Input(Bool()) 41780712aaSxiaofeibao-xjtu val enq = Vec(RenameWidth, Flipped(ValidIO(new RobExceptionInfo))) 42780712aaSxiaofeibao-xjtu // csr + load + store + varith + vload + vstore 43780712aaSxiaofeibao-xjtu val wb = Vec(params.numException, Flipped(ValidIO(new RobExceptionInfo))) 44780712aaSxiaofeibao-xjtu val out = ValidIO(new RobExceptionInfo) 45780712aaSxiaofeibao-xjtu val state = ValidIO(new RobExceptionInfo) 46780712aaSxiaofeibao-xjtu }) 47780712aaSxiaofeibao-xjtu 48780712aaSxiaofeibao-xjtu val wbExuParams = params.allExuParams.filter(_.exceptionOut.nonEmpty) 49780712aaSxiaofeibao-xjtu 50780712aaSxiaofeibao-xjtu def getOldest(valid: Seq[Bool], bits: Seq[RobExceptionInfo]): RobExceptionInfo = { 51780712aaSxiaofeibao-xjtu def getOldest_recursion(valid: Seq[Bool], bits: Seq[RobExceptionInfo]): (Seq[Bool], Seq[RobExceptionInfo]) = { 52780712aaSxiaofeibao-xjtu assert(valid.length == bits.length) 53780712aaSxiaofeibao-xjtu if (valid.length == 1) { 54780712aaSxiaofeibao-xjtu (valid, bits) 55780712aaSxiaofeibao-xjtu } else if (valid.length == 2) { 56780712aaSxiaofeibao-xjtu val res = Seq.fill(2)(Wire(ValidIO(chiselTypeOf(bits(0))))) 57780712aaSxiaofeibao-xjtu for (i <- res.indices) { 58780712aaSxiaofeibao-xjtu res(i).valid := valid(i) 59780712aaSxiaofeibao-xjtu res(i).bits := bits(i) 60780712aaSxiaofeibao-xjtu } 61780712aaSxiaofeibao-xjtu val oldest = Mux(!valid(1) || valid(0) && isAfter(bits(1).robIdx, bits(0).robIdx), res(0), res(1)) 62780712aaSxiaofeibao-xjtu (Seq(oldest.valid), Seq(oldest.bits)) 63780712aaSxiaofeibao-xjtu } else { 64780712aaSxiaofeibao-xjtu val left = getOldest_recursion(valid.take(valid.length / 2), bits.take(valid.length / 2)) 65780712aaSxiaofeibao-xjtu val right = getOldest_recursion(valid.drop(valid.length / 2), bits.drop(valid.length / 2)) 66780712aaSxiaofeibao-xjtu getOldest_recursion(left._1 ++ right._1, left._2 ++ right._2) 67780712aaSxiaofeibao-xjtu } 68780712aaSxiaofeibao-xjtu } 69780712aaSxiaofeibao-xjtu getOldest_recursion(valid, bits)._2.head 70780712aaSxiaofeibao-xjtu } 71780712aaSxiaofeibao-xjtu 72780712aaSxiaofeibao-xjtu 73780712aaSxiaofeibao-xjtu val currentValid = RegInit(false.B) 74780712aaSxiaofeibao-xjtu val current = Reg(new RobExceptionInfo) 75780712aaSxiaofeibao-xjtu 76780712aaSxiaofeibao-xjtu // orR the exceptionVec 77780712aaSxiaofeibao-xjtu val lastCycleFlush = RegNext(io.flush) 78*3e8a0170SXuan Hu val enq_s0_valid = VecInit(io.enq.map(e => e.valid && e.bits.has_exception && !lastCycleFlush)) 79*3e8a0170SXuan Hu val enq_s0_bits = WireInit(VecInit(io.enq.map(_.bits))) 80*3e8a0170SXuan Hu enq_s0_bits zip io.enq foreach { case (sink, source) => 81*3e8a0170SXuan Hu sink.flushPipe := source.bits.flushPipe && !source.bits.hasException 82*3e8a0170SXuan Hu } 83780712aaSxiaofeibao-xjtu 84780712aaSxiaofeibao-xjtu // s0: compare wb in 6 groups 85780712aaSxiaofeibao-xjtu val csr_wb = io.wb.zip(wbExuParams).filter(_._2.fuConfigs.filter(t => t.isCsr).nonEmpty).map(_._1) 86780712aaSxiaofeibao-xjtu val load_wb = io.wb.zip(wbExuParams).filter(_._2.fuConfigs.filter(_.fuType == FuType.ldu).nonEmpty).map(_._1) 87780712aaSxiaofeibao-xjtu val store_wb = io.wb.zip(wbExuParams).filter(_._2.fuConfigs.filter(t => t.isSta || t.fuType == FuType.mou).nonEmpty).map(_._1) 88780712aaSxiaofeibao-xjtu val varith_wb = io.wb.zip(wbExuParams).filter(_._2.fuConfigs.filter(_.isVecArith).nonEmpty).map(_._1) 89985804e6SXuan Hu val vls_wb = io.wb.zip(wbExuParams).filter(_._2.fuConfigs.exists(x => FuType.FuTypeOrR(x.fuType, FuType.vecMem))).map(_._1) 90780712aaSxiaofeibao-xjtu 91985804e6SXuan Hu val writebacks = Seq(csr_wb, load_wb, store_wb, varith_wb, vls_wb) 92780712aaSxiaofeibao-xjtu val in_wb_valids = writebacks.map(_.map(w => w.valid && w.bits.has_exception && !lastCycleFlush)) 93780712aaSxiaofeibao-xjtu val wb_valid = in_wb_valids.zip(writebacks).map { case (valid, wb) => 94780712aaSxiaofeibao-xjtu valid.zip(wb.map(_.bits)).map { case (v, bits) => v && !(bits.robIdx.needFlush(io.redirect) || io.flush) }.reduce(_ || _) 95780712aaSxiaofeibao-xjtu } 96780712aaSxiaofeibao-xjtu val wb_bits = in_wb_valids.zip(writebacks).map { case (valid, wb) => getOldest(valid, wb.map(_.bits))} 97780712aaSxiaofeibao-xjtu 98780712aaSxiaofeibao-xjtu val s0_out_valid = wb_valid.map(x => RegNext(x)) 99780712aaSxiaofeibao-xjtu val s0_out_bits = wb_bits.zip(wb_valid).map{ case(b, v) => RegEnable(b, v)} 100780712aaSxiaofeibao-xjtu 101780712aaSxiaofeibao-xjtu // s1: compare last six and current flush 102780712aaSxiaofeibao-xjtu val s1_valid = VecInit(s0_out_valid.zip(s0_out_bits).map{ case (v, b) => v && !(b.robIdx.needFlush(io.redirect) || io.flush) }) 103780712aaSxiaofeibao-xjtu val s1_out_bits = RegEnable(getOldest(s0_out_valid, s0_out_bits), s1_valid.asUInt.orR) 104780712aaSxiaofeibao-xjtu val s1_out_valid = RegNext(s1_valid.asUInt.orR) 105780712aaSxiaofeibao-xjtu 106*3e8a0170SXuan Hu val enq_s1_valid = RegNext(enq_s0_valid.asUInt.orR && !io.redirect.valid && !io.flush) 107*3e8a0170SXuan Hu val enq_s1_bits: RobExceptionInfo = RegEnable(ParallelPriorityMux(enq_s0_valid, enq_s0_bits), enq_s0_valid.asUInt.orR && !io.redirect.valid && !io.flush) 108780712aaSxiaofeibao-xjtu 109780712aaSxiaofeibao-xjtu // s2: compare the input exception with the current one 110780712aaSxiaofeibao-xjtu // priorities: 111780712aaSxiaofeibao-xjtu // (1) system reset 112780712aaSxiaofeibao-xjtu // (2) current is valid: flush, remain, merge, update 113780712aaSxiaofeibao-xjtu // (3) current is not valid: s1 or enq 114780712aaSxiaofeibao-xjtu val current_flush = current.robIdx.needFlush(io.redirect) || io.flush 115780712aaSxiaofeibao-xjtu val s1_flush = s1_out_bits.robIdx.needFlush(io.redirect) || io.flush 116780712aaSxiaofeibao-xjtu when (currentValid) { 117780712aaSxiaofeibao-xjtu when (current_flush) { 118780712aaSxiaofeibao-xjtu currentValid := Mux(s1_flush, false.B, s1_out_valid) 119780712aaSxiaofeibao-xjtu } 120780712aaSxiaofeibao-xjtu when (s1_out_valid && !s1_flush) { 121780712aaSxiaofeibao-xjtu when (isAfter(current.robIdx, s1_out_bits.robIdx)) { 122780712aaSxiaofeibao-xjtu current := s1_out_bits 123780712aaSxiaofeibao-xjtu }.elsewhen (current.robIdx === s1_out_bits.robIdx) { 124780712aaSxiaofeibao-xjtu current.exceptionVec := (s1_out_bits.exceptionVec.asUInt | current.exceptionVec.asUInt).asTypeOf(ExceptionVec()) 125780712aaSxiaofeibao-xjtu current.flushPipe := s1_out_bits.flushPipe || current.flushPipe 126780712aaSxiaofeibao-xjtu current.replayInst := s1_out_bits.replayInst || current.replayInst 127780712aaSxiaofeibao-xjtu current.singleStep := s1_out_bits.singleStep || current.singleStep 128780712aaSxiaofeibao-xjtu current.trigger := (s1_out_bits.trigger.asUInt | current.trigger.asUInt).asTypeOf(new TriggerCf) 129780712aaSxiaofeibao-xjtu } 130780712aaSxiaofeibao-xjtu } 131780712aaSxiaofeibao-xjtu }.elsewhen (s1_out_valid && !s1_flush) { 132780712aaSxiaofeibao-xjtu currentValid := true.B 133780712aaSxiaofeibao-xjtu current := s1_out_bits 134*3e8a0170SXuan Hu }.elsewhen (enq_s1_valid && !(io.redirect.valid || io.flush)) { 135780712aaSxiaofeibao-xjtu currentValid := true.B 136*3e8a0170SXuan Hu current := enq_s1_bits 137780712aaSxiaofeibao-xjtu } 138780712aaSxiaofeibao-xjtu 139*3e8a0170SXuan Hu io.out.valid := s1_out_valid || enq_s1_valid && enq_s1_bits.can_writeback 140*3e8a0170SXuan Hu io.out.bits := Mux(s1_out_valid, s1_out_bits, enq_s1_bits) 141780712aaSxiaofeibao-xjtu io.state.valid := currentValid 142780712aaSxiaofeibao-xjtu io.state.bits := current 143780712aaSxiaofeibao-xjtu 144780712aaSxiaofeibao-xjtu}