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