xref: /XiangShan/src/main/scala/xiangshan/backend/issue/FuBusyTableWrite.scala (revision 8d081717cfe3863e6c0d38305abd6327c65a653a)
1de93b508SzhanglyGitpackage xiangshan.backend.issue
2de93b508SzhanglyGit
383ba63b3SXuan Huimport org.chipsalliance.cde.config.Parameters
4de93b508SzhanglyGitimport chisel3._
5de93b508SzhanglyGitimport chisel3.util._
6bf44d649SXuan Huimport utils.MapUtils
7de93b508SzhanglyGitimport xiangshan._
8bf44d649SXuan Huimport xiangshan.backend.fu.FuType
9bf44d649SXuan Huimport xiangshan.backend.fu.vector.Utils
10de93b508SzhanglyGit
11239413e5SXuan Huclass FuBusyTableWrite(fuLatencyMap: Map[FuType.OHType, Int]) (implicit p: Parameters, iqParams: IssueBlockParams) extends XSModule {
12dd970561SzhanglyGit  private val latencyValMax: Int = fuLatencyMap.values.fold(0)(_ max _)
13bf44d649SXuan Hu  private val tableSize = latencyValMax + 1
14dd970561SzhanglyGit  val io = IO(new FuBusyTableWriteIO(latencyValMax))
15de93b508SzhanglyGit
16dd970561SzhanglyGit  val deqResp = io.in.deqResp
17dd970561SzhanglyGit  val og0Resp = io.in.og0Resp
18dd970561SzhanglyGit  val og1Resp = io.in.og1Resp
19de93b508SzhanglyGit
20bf44d649SXuan Hu  // instance of FuBusyTable insists only when latencyValMax > 0
21bf44d649SXuan Hu  private val fuBusyTable = RegInit(0.U(tableSize.W))
22de93b508SzhanglyGit
23bf44d649SXuan Hu  private val fuBusyTableNext = Wire(UInt(tableSize.W))
24de93b508SzhanglyGit
25bf44d649SXuan Hu  fuBusyTable := fuBusyTableNext
26de93b508SzhanglyGit
27bf44d649SXuan Hu  /**
28bf44d649SXuan Hu    * Map[latency, Set[fuType]]
29bf44d649SXuan Hu    */
30239413e5SXuan Hu  private val latMappedFuTypeSet: Map[Int, Set[FuType.OHType]] = MapUtils.groupByValueUnique(fuLatencyMap)
31bf44d649SXuan Hu
32bf44d649SXuan Hu  private val deqRespSuccess = deqResp.valid && deqResp.bits.respType === RSFeedbackType.issueSuccess
33bf44d649SXuan Hu  private val og0RespFail = og0Resp.valid && og0Resp.bits.respType === RSFeedbackType.rfArbitFail
34bf44d649SXuan Hu  private val og1RespFail = og1Resp.valid && og1Resp.bits.respType === RSFeedbackType.fuBusy
35bf44d649SXuan Hu
36bf44d649SXuan Hu  private val deqRespMatchVec = getMatchVecFromResp(deqResp)
37bf44d649SXuan Hu  private val og0RespMatchVec = getMatchVecFromResp(og0Resp)
38bf44d649SXuan Hu  private val og1RespMatchVec = getMatchVecFromResp(og1Resp)
39bf44d649SXuan Hu
40bf44d649SXuan Hu  def getMatchVecFromResp(resp: Valid[IssueQueueDeqRespBundle]) : Vec[Bool] = {
41bf44d649SXuan Hu    VecInit((0 until tableSize).map {
42bf44d649SXuan Hu      lat =>
43bf44d649SXuan Hu        Cat(
44bf44d649SXuan Hu          latMappedFuTypeSet.getOrElse(lat, Set()).map(
4566e57d91Ssinsanction            fuType => resp.bits.fuType(fuType.id)
46bf44d649SXuan Hu          ).toSeq
47bf44d649SXuan Hu        ).orR
48bf44d649SXuan Hu    })
49bf44d649SXuan Hu  }
50bf44d649SXuan Hu
51bf44d649SXuan Hu  private val fuBusyTableShift = (fuBusyTable >> 1).asUInt
526c996d9bSzhanglyGit  private val deqRespSetShift = Mux(deqRespSuccess, deqRespMatchVec.asUInt >> 1, Utils.NZeros(tableSize))
536c996d9bSzhanglyGit  private val og0RespClearShift = Mux(og0RespFail, og0RespMatchVec.asUInt >> 2, Utils.NZeros(tableSize))
546c996d9bSzhanglyGit  private val og1RespClearShift = Mux(og1RespFail, og1RespMatchVec.asUInt >> 3, Utils.NZeros(tableSize))
55bf44d649SXuan Hu
56bf44d649SXuan Hu  // Just for more readable verilog
57*8d081717Sszw_kaixin  if(backendParams.debugEn) {
58bf44d649SXuan Hu    dontTouch(fuBusyTableShift)
596c996d9bSzhanglyGit    dontTouch(deqRespSetShift)
606c996d9bSzhanglyGit    dontTouch(og0RespClearShift)
616c996d9bSzhanglyGit    dontTouch(og1RespClearShift)
62*8d081717Sszw_kaixin  }
63bf44d649SXuan Hu
646c996d9bSzhanglyGit  fuBusyTableNext := fuBusyTableShift & (~og0RespClearShift).asUInt & (~og1RespClearShift).asUInt | deqRespSetShift.asUInt
65de93b508SzhanglyGit
66de93b508SzhanglyGit  io.out.fuBusyTable := fuBusyTable
676c996d9bSzhanglyGit  io.out.deqRespSet := Mux(deqRespSuccess, deqRespMatchVec.asUInt, Utils.NZeros(tableSize)).asUInt
68de93b508SzhanglyGit}
69de93b508SzhanglyGit
70dd970561SzhanglyGitclass FuBusyTableWriteIO(latencyValMax: Int)(implicit p: Parameters, iqParams: IssueBlockParams) extends XSBundle {
71dd970561SzhanglyGit  private val tableSize = latencyValMax + 1
72de93b508SzhanglyGit  val in = new Bundle {
73dd970561SzhanglyGit    val deqResp =  Flipped(ValidIO(new IssueQueueDeqRespBundle))
74dd970561SzhanglyGit    val og0Resp = Flipped(ValidIO(new IssueQueueDeqRespBundle))
75dd970561SzhanglyGit    val og1Resp = Flipped(ValidIO(new IssueQueueDeqRespBundle))
76de93b508SzhanglyGit  }
77de93b508SzhanglyGit  val out = new Bundle {
78bf44d649SXuan Hu    val fuBusyTable = Output(UInt(tableSize.W))
79dd970561SzhanglyGit    val deqRespSet = Output(UInt(tableSize.W))
80de93b508SzhanglyGit  }
81de93b508SzhanglyGit}