1package xiangshan.backend.issue 2 3import chipsalliance.rocketchip.config.Parameters 4import chisel3._ 5import chisel3.util._ 6import utils.MapUtils 7import xiangshan._ 8import xiangshan.backend.fu.FuType 9import xiangshan.backend.fu.vector.Utils 10 11class FuBusyTableWrite(val idx: Int) (implicit p: Parameters, iqParams: IssueBlockParams) extends XSModule { 12 private val latencyValMax: Int = iqParams.exuBlockParams(idx).latencyValMax 13 private val tableSize = latencyValMax + 1 14 private val fuLatencyMap: Map[Int, Int] = iqParams.exuBlockParams(idx).fuLatencyMap 15 val io = IO(new FuBusyTableWriteIO(idx)) 16 17 val deqResp = io.in.deqResp(idx) 18 val og0Resp = io.in.og0Resp(idx) 19 val og1Resp = io.in.og1Resp(idx) 20 val fuTypeVec = io.in.fuTypeRegVec 21 22 // instance of FuBusyTable insists only when latencyValMax > 0 23 private val fuBusyTable = RegInit(0.U(tableSize.W)) 24 25 private val fuBusyTableNext = Wire(UInt(tableSize.W)) 26 27 fuBusyTable := fuBusyTableNext 28 29 /** 30 * Map[latency, Set[fuType]] 31 */ 32 private val latMappedFuTypeSet: Map[Int, Set[Int]] = MapUtils.groupByValueUnique(fuLatencyMap) 33 34 private val deqRespSuccess = deqResp.valid && deqResp.bits.respType === RSFeedbackType.issueSuccess 35 private val og0RespFail = og0Resp.valid && og0Resp.bits.respType === RSFeedbackType.rfArbitFail 36 private val og1RespFail = og1Resp.valid && og1Resp.bits.respType === RSFeedbackType.fuBusy 37 38 private val deqRespMatchVec = getMatchVecFromResp(deqResp) 39 private val og0RespMatchVec = getMatchVecFromResp(og0Resp) 40 private val og1RespMatchVec = getMatchVecFromResp(og1Resp) 41 42 def getMatchVecFromResp(resp: Valid[IssueQueueDeqRespBundle]) : Vec[Bool] = { 43 VecInit((0 until tableSize).map { 44 lat => 45 Cat( 46 latMappedFuTypeSet.getOrElse(lat, Set()).map( 47 fuType => Mux1H(resp.bits.addrOH, fuTypeVec) === fuType.U 48 ).toSeq 49 ).orR 50 }) 51 } 52 53 private val fuBusyTableShift = (fuBusyTable >> 1).asUInt 54 private val deqRespSet = Mux(deqRespSuccess, deqRespMatchVec.asUInt >> 1, Utils.NZeros(tableSize)) 55 private val og0RespClear = Mux(og0RespFail, og0RespMatchVec.asUInt >> 2, Utils.NZeros(tableSize)) 56 private val og1RespClear = Mux(og1RespFail, og1RespMatchVec.asUInt >> 3, Utils.NZeros(tableSize)) 57 58 // Just for more readable verilog 59 dontTouch(fuBusyTableShift) 60 dontTouch(deqRespSet) 61 dontTouch(og0RespClear) 62 dontTouch(og1RespClear) 63 64 fuBusyTableNext := fuBusyTableShift & (~og0RespClear).asUInt & (~og1RespClear).asUInt | deqRespSet.asUInt 65 66 io.out.fuBusyTable := fuBusyTable 67} 68 69class FuBusyTableWriteIO(val idx: Int)(implicit p: Parameters, iqParams: IssueBlockParams) extends XSBundle { 70 private val tableSize = iqParams.exuBlockParams(idx).latencyValMax + 1 71 val in = new Bundle { 72 val deqResp = Vec(iqParams.numDeq, Flipped(ValidIO(new IssueQueueDeqRespBundle))) 73 val og0Resp = Vec(iqParams.numDeq, Flipped(ValidIO(new IssueQueueDeqRespBundle))) 74 val og1Resp = Vec(iqParams.numDeq, Flipped(ValidIO(new IssueQueueDeqRespBundle))) 75 val fuTypeRegVec = Input(Vec(iqParams.numEntries, FuType())) 76 } 77 val out = new Bundle { 78 val fuBusyTable = Output(UInt(tableSize.W)) 79 } 80}