1package xiangshan.backend.issue 2 3import org.chipsalliance.cde.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[FuType.OHType, 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[FuType.OHType]] = MapUtils.groupByValueUnique(fuLatencyMap) 31 32 private val deqRespSuccess = deqResp.valid 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.id) 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 if(backendParams.debugEn) { 58 dontTouch(fuBusyTableShift) 59 dontTouch(deqRespSetShift) 60 dontTouch(og0RespClearShift) 61 dontTouch(og1RespClearShift) 62 } 63 64 fuBusyTableNext := fuBusyTableShift & (~og0RespClearShift).asUInt & (~og1RespClearShift).asUInt | deqRespSetShift.asUInt 65 66 io.out.fuBusyTable := fuBusyTable 67 io.out.deqRespSet := Mux(deqRespSuccess, deqRespMatchVec.asUInt, Utils.NZeros(tableSize)).asUInt 68} 69 70class FuBusyTableWriteIO(latencyValMax: Int)(implicit p: Parameters, iqParams: IssueBlockParams) extends XSBundle { 71 private val tableSize = latencyValMax + 1 72 val in = new Bundle { 73 val deqResp = Flipped(ValidIO(new IssueQueueDeqRespBundle)) 74 val og0Resp = Flipped(ValidIO(new IssueQueueDeqRespBundle)) 75 val og1Resp = Flipped(ValidIO(new IssueQueueDeqRespBundle)) 76 } 77 val out = new Bundle { 78 val fuBusyTable = Output(UInt(tableSize.W)) 79 val deqRespSet = Output(UInt(tableSize.W)) 80 } 81}