xref: /XiangShan/src/main/scala/xiangshan/backend/issue/FuBusyTableWrite.scala (revision bf44d6491c7790e1355b9d5174775c10ab8496c6)
1de93b508SzhanglyGitpackage xiangshan.backend.issue
2de93b508SzhanglyGit
3de93b508SzhanglyGitimport chipsalliance.rocketchip.config.Parameters
4de93b508SzhanglyGitimport chisel3._
5de93b508SzhanglyGitimport chisel3.util._
6*bf44d649SXuan Huimport utils.MapUtils
7de93b508SzhanglyGitimport xiangshan._
8*bf44d649SXuan Huimport xiangshan.backend.fu.FuType
9*bf44d649SXuan Huimport xiangshan.backend.fu.vector.Utils
10de93b508SzhanglyGit
11de93b508SzhanglyGitclass FuBusyTableWrite(val idx: Int) (implicit p: Parameters, iqParams: IssueBlockParams) extends XSModule {
12*bf44d649SXuan Hu  private val latencyValMax: Int = iqParams.exuBlockParams(idx).latencyValMax
13*bf44d649SXuan Hu  private val tableSize = latencyValMax + 1
14*bf44d649SXuan Hu  private val fuLatencyMap: Map[Int, Int] = iqParams.exuBlockParams(idx).fuLatencyMap
15de93b508SzhanglyGit  val io = IO(new FuBusyTableWriteIO(idx))
16de93b508SzhanglyGit
17*bf44d649SXuan Hu  val deqResp = io.in.deqResp(idx)
18*bf44d649SXuan Hu  val og0Resp = io.in.og0Resp(idx)
19*bf44d649SXuan Hu  val og1Resp = io.in.og1Resp(idx)
20*bf44d649SXuan Hu  val fuTypeVec = io.in.fuTypeRegVec
21de93b508SzhanglyGit
22*bf44d649SXuan Hu  // instance of FuBusyTable insists only when latencyValMax > 0
23*bf44d649SXuan Hu  private val fuBusyTable = RegInit(0.U(tableSize.W))
24de93b508SzhanglyGit
25*bf44d649SXuan Hu  private val fuBusyTableNext = Wire(UInt(tableSize.W))
26de93b508SzhanglyGit
27*bf44d649SXuan Hu  fuBusyTable := fuBusyTableNext
28de93b508SzhanglyGit
29*bf44d649SXuan Hu  /**
30*bf44d649SXuan Hu    * Map[latency, Set[fuType]]
31*bf44d649SXuan Hu    */
32*bf44d649SXuan Hu  private val latMappedFuTypeSet: Map[Int, Set[Int]] = MapUtils.groupByValueUnique(fuLatencyMap)
33*bf44d649SXuan Hu
34*bf44d649SXuan Hu  private val deqRespSuccess = deqResp.valid && deqResp.bits.respType === RSFeedbackType.issueSuccess
35*bf44d649SXuan Hu  private val og0RespFail = og0Resp.valid && og0Resp.bits.respType === RSFeedbackType.rfArbitFail
36*bf44d649SXuan Hu  private val og1RespFail = og1Resp.valid && og1Resp.bits.respType === RSFeedbackType.fuBusy
37*bf44d649SXuan Hu
38*bf44d649SXuan Hu  private val deqRespMatchVec = getMatchVecFromResp(deqResp)
39*bf44d649SXuan Hu  private val og0RespMatchVec = getMatchVecFromResp(og0Resp)
40*bf44d649SXuan Hu  private val og1RespMatchVec = getMatchVecFromResp(og1Resp)
41*bf44d649SXuan Hu
42*bf44d649SXuan Hu  def getMatchVecFromResp(resp: Valid[IssueQueueDeqRespBundle]) : Vec[Bool] = {
43*bf44d649SXuan Hu    VecInit((0 until tableSize).map {
44*bf44d649SXuan Hu      lat =>
45*bf44d649SXuan Hu        Cat(
46*bf44d649SXuan Hu          latMappedFuTypeSet.getOrElse(lat, Set()).map(
47*bf44d649SXuan Hu            fuType => Mux1H(resp.bits.addrOH, fuTypeVec) === fuType.U
48*bf44d649SXuan Hu          ).toSeq
49*bf44d649SXuan Hu        ).orR
50*bf44d649SXuan Hu    })
51*bf44d649SXuan Hu  }
52*bf44d649SXuan Hu
53*bf44d649SXuan Hu  private val fuBusyTableShift = (fuBusyTable >> 1).asUInt
54*bf44d649SXuan Hu  private val deqRespSet = Mux(deqRespSuccess, deqRespMatchVec.asUInt >> 1, Utils.NZeros(tableSize))
55*bf44d649SXuan Hu  private val og0RespClear = Mux(og0RespFail, og0RespMatchVec.asUInt >> 2, Utils.NZeros(tableSize))
56*bf44d649SXuan Hu  private val og1RespClear = Mux(og1RespFail, og1RespMatchVec.asUInt >> 3, Utils.NZeros(tableSize))
57*bf44d649SXuan Hu
58*bf44d649SXuan Hu  // Just for more readable verilog
59*bf44d649SXuan Hu  dontTouch(fuBusyTableShift)
60*bf44d649SXuan Hu  dontTouch(deqRespSet)
61*bf44d649SXuan Hu  dontTouch(og0RespClear)
62*bf44d649SXuan Hu  dontTouch(og1RespClear)
63*bf44d649SXuan Hu
64*bf44d649SXuan Hu  fuBusyTableNext := fuBusyTableShift & (~og0RespClear).asUInt & (~og1RespClear).asUInt | deqRespSet.asUInt
65de93b508SzhanglyGit
66de93b508SzhanglyGit  io.out.fuBusyTable := fuBusyTable
67de93b508SzhanglyGit}
68de93b508SzhanglyGit
69de93b508SzhanglyGitclass FuBusyTableWriteIO(val idx: Int)(implicit p: Parameters, iqParams: IssueBlockParams) extends XSBundle {
70*bf44d649SXuan Hu  private val tableSize = iqParams.exuBlockParams(idx).latencyValMax + 1
71de93b508SzhanglyGit  val in = new Bundle {
72de93b508SzhanglyGit    val deqResp = Vec(iqParams.numDeq, Flipped(ValidIO(new IssueQueueDeqRespBundle)))
73de93b508SzhanglyGit    val og0Resp = Vec(iqParams.numDeq, Flipped(ValidIO(new IssueQueueDeqRespBundle)))
74de93b508SzhanglyGit    val og1Resp = Vec(iqParams.numDeq, Flipped(ValidIO(new IssueQueueDeqRespBundle)))
75de93b508SzhanglyGit    val fuTypeRegVec = Input(Vec(iqParams.numEntries, FuType()))
76de93b508SzhanglyGit  }
77de93b508SzhanglyGit  val out = new Bundle {
78*bf44d649SXuan Hu    val fuBusyTable = Output(UInt(tableSize.W))
79de93b508SzhanglyGit  }
80de93b508SzhanglyGit}