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(fuLatencyMap: Map[Int, Int]) (implicit p: Parameters, iqParams: IssueBlockParams) extends XSModule { 12 private val latencyValMax: Int = fuLatencyMap.values.fold(0)(_ max _) 13 private val tableSize = latencyValMax + 1 14 val io = IO(new FuBusyTableWriteIO(latencyValMax)) 15 16 val deqResp = io.in.deqResp 17 val og0Resp = io.in.og0Resp 18 val og1Resp = io.in.og1Resp 19 20 // instance of FuBusyTable insists only when latencyValMax > 0 21 private val fuBusyTable = RegInit(0.U(tableSize.W)) 22 23 private val fuBusyTableNext = Wire(UInt(tableSize.W)) 24 25 fuBusyTable := fuBusyTableNext 26 27 /** 28 * Map[latency, Set[fuType]] 29 */ 30 private val latMappedFuTypeSet: Map[Int, Set[Int]] = MapUtils.groupByValueUnique(fuLatencyMap) 31 32 private val deqRespSuccess = deqResp.valid && deqResp.bits.respType === RSFeedbackType.issueSuccess 33 private val og0RespFail = og0Resp.valid && og0Resp.bits.respType === RSFeedbackType.rfArbitFail 34 private val og1RespFail = og1Resp.valid && og1Resp.bits.respType === RSFeedbackType.fuBusy 35 36 private val deqRespMatchVec = getMatchVecFromResp(deqResp) 37 private val og0RespMatchVec = getMatchVecFromResp(og0Resp) 38 private val og1RespMatchVec = getMatchVecFromResp(og1Resp) 39 40 def getMatchVecFromResp(resp: Valid[IssueQueueDeqRespBundle]) : Vec[Bool] = { 41 VecInit((0 until tableSize).map { 42 lat => 43 Cat( 44 latMappedFuTypeSet.getOrElse(lat, Set()).map( 45 fuType => resp.bits.fuType === fuType.U 46 ).toSeq 47 ).orR 48 }) 49 } 50 51 private val fuBusyTableShift = (fuBusyTable >> 1).asUInt 52 private val deqRespSetShift = Mux(deqRespSuccess, deqRespMatchVec.asUInt >> 1, Utils.NZeros(tableSize)) 53 private val og0RespClearShift = Mux(og0RespFail, og0RespMatchVec.asUInt >> 2, Utils.NZeros(tableSize)) 54 private val og1RespClearShift = Mux(og1RespFail, og1RespMatchVec.asUInt >> 3, Utils.NZeros(tableSize)) 55 56 // Just for more readable verilog 57 dontTouch(fuBusyTableShift) 58 dontTouch(deqRespSetShift) 59 dontTouch(og0RespClearShift) 60 dontTouch(og1RespClearShift) 61 62 fuBusyTableNext := fuBusyTableShift & (~og0RespClearShift).asUInt & (~og1RespClearShift).asUInt | deqRespSetShift.asUInt 63 64 io.out.fuBusyTable := fuBusyTable 65 io.out.deqRespSet := Mux(deqRespSuccess, deqRespMatchVec.asUInt, Utils.NZeros(tableSize)).asUInt 66} 67 68class FuBusyTableWriteIO(latencyValMax: Int)(implicit p: Parameters, iqParams: IssueBlockParams) extends XSBundle { 69 private val tableSize = latencyValMax + 1 70 val in = new Bundle { 71 val deqResp = Flipped(ValidIO(new IssueQueueDeqRespBundle)) 72 val og0Resp = Flipped(ValidIO(new IssueQueueDeqRespBundle)) 73 val og1Resp = Flipped(ValidIO(new IssueQueueDeqRespBundle)) 74 } 75 val out = new Bundle { 76 val fuBusyTable = Output(UInt(tableSize.W)) 77 val deqRespSet = Output(UInt(tableSize.W)) 78 } 79}