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