xref: /XiangShan/src/main/scala/xiangshan/backend/issue/FuBusyTableWrite.scala (revision 83ba63b34cf09b33c0a9e1b3203138e51af4491b)
1de93b508SzhanglyGitpackage xiangshan.backend.issue
2de93b508SzhanglyGit
3*83ba63b3SXuan 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(
45dd970561SzhanglyGit            fuType => resp.bits.fuType === fuType.U
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
57bf44d649SXuan Hu  dontTouch(fuBusyTableShift)
586c996d9bSzhanglyGit  dontTouch(deqRespSetShift)
596c996d9bSzhanglyGit  dontTouch(og0RespClearShift)
606c996d9bSzhanglyGit  dontTouch(og1RespClearShift)
61bf44d649SXuan Hu
626c996d9bSzhanglyGit  fuBusyTableNext := fuBusyTableShift & (~og0RespClearShift).asUInt & (~og1RespClearShift).asUInt | deqRespSetShift.asUInt
63de93b508SzhanglyGit
64de93b508SzhanglyGit  io.out.fuBusyTable := fuBusyTable
656c996d9bSzhanglyGit  io.out.deqRespSet := Mux(deqRespSuccess, deqRespMatchVec.asUInt, Utils.NZeros(tableSize)).asUInt
66de93b508SzhanglyGit}
67de93b508SzhanglyGit
68dd970561SzhanglyGitclass FuBusyTableWriteIO(latencyValMax: Int)(implicit p: Parameters, iqParams: IssueBlockParams) extends XSBundle {
69dd970561SzhanglyGit  private val tableSize = latencyValMax + 1
70de93b508SzhanglyGit  val in = new Bundle {
71dd970561SzhanglyGit    val deqResp =  Flipped(ValidIO(new IssueQueueDeqRespBundle))
72dd970561SzhanglyGit    val og0Resp = Flipped(ValidIO(new IssueQueueDeqRespBundle))
73dd970561SzhanglyGit    val og1Resp = Flipped(ValidIO(new IssueQueueDeqRespBundle))
74de93b508SzhanglyGit  }
75de93b508SzhanglyGit  val out = new Bundle {
76bf44d649SXuan Hu    val fuBusyTable = Output(UInt(tableSize.W))
77dd970561SzhanglyGit    val deqRespSet = Output(UInt(tableSize.W))
78de93b508SzhanglyGit  }
79de93b508SzhanglyGit}