xref: /XiangShan/src/main/scala/xiangshan/backend/issue/FuBusyTableWrite.scala (revision fe73ba60e994e61c99093735fde726b4c3be7629)
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
10f08a822fSzhanglyGitimport xiangshan.backend.issue.EntryBundles.RespType
11de93b508SzhanglyGit
12239413e5SXuan Huclass FuBusyTableWrite(fuLatencyMap: Map[FuType.OHType, Int]) (implicit p: Parameters, iqParams: IssueBlockParams) extends XSModule {
13dd970561SzhanglyGit  private val latencyValMax: Int = fuLatencyMap.values.fold(0)(_ max _)
14bf44d649SXuan Hu  private val tableSize = latencyValMax + 1
15dd970561SzhanglyGit  val io = IO(new FuBusyTableWriteIO(latencyValMax))
16de93b508SzhanglyGit
17dd970561SzhanglyGit  val deqResp = io.in.deqResp
18dd970561SzhanglyGit  val og0Resp = io.in.og0Resp
19dd970561SzhanglyGit  val og1Resp = io.in.og1Resp
20de93b508SzhanglyGit
21bf44d649SXuan Hu  // instance of FuBusyTable insists only when latencyValMax > 0
22bf44d649SXuan Hu  private val fuBusyTable = RegInit(0.U(tableSize.W))
23de93b508SzhanglyGit
24bf44d649SXuan Hu  private val fuBusyTableNext = Wire(UInt(tableSize.W))
25de93b508SzhanglyGit
26bf44d649SXuan Hu  fuBusyTable := fuBusyTableNext
27de93b508SzhanglyGit
28bf44d649SXuan Hu  /**
29bf44d649SXuan Hu    * Map[latency, Set[fuType]]
30bf44d649SXuan Hu    */
31239413e5SXuan Hu  private val latMappedFuTypeSet: Map[Int, Set[FuType.OHType]] = MapUtils.groupByValueUnique(fuLatencyMap)
32bf44d649SXuan Hu
33ea159d42Ssinsanction  private val deqRespSuccess = deqResp.valid
34f08a822fSzhanglyGit  private val og0RespFail = og0Resp.valid
35f08a822fSzhanglyGit  private val og1RespFail = og1Resp.valid && RespType.isBlocked(og1Resp.bits.resp)
36bf44d649SXuan Hu
37bf44d649SXuan Hu  private val deqRespMatchVec = getMatchVecFromResp(deqResp)
38bf44d649SXuan Hu  private val og0RespMatchVec = getMatchVecFromResp(og0Resp)
39bf44d649SXuan Hu  private val og1RespMatchVec = getMatchVecFromResp(og1Resp)
40bf44d649SXuan Hu
41bf44d649SXuan Hu  def getMatchVecFromResp(resp: Valid[IssueQueueDeqRespBundle]) : Vec[Bool] = {
42bf44d649SXuan Hu    VecInit((0 until tableSize).map {
43bf44d649SXuan Hu      lat =>
44bf44d649SXuan Hu        Cat(
45*fe73ba60SYangyu Chen          latMappedFuTypeSet.getOrElse(lat, Set()).toSeq.sorted.map(
4666e57d91Ssinsanction            fuType => resp.bits.fuType(fuType.id)
47bf44d649SXuan Hu          ).toSeq
48bf44d649SXuan Hu        ).orR
49bf44d649SXuan Hu    })
50bf44d649SXuan Hu  }
51bf44d649SXuan Hu
52bf44d649SXuan Hu  private val fuBusyTableShift = (fuBusyTable >> 1).asUInt
536c996d9bSzhanglyGit  private val deqRespSetShift = Mux(deqRespSuccess, deqRespMatchVec.asUInt >> 1, Utils.NZeros(tableSize))
546c996d9bSzhanglyGit  private val og0RespClearShift = Mux(og0RespFail, og0RespMatchVec.asUInt >> 2, Utils.NZeros(tableSize))
556c996d9bSzhanglyGit  private val og1RespClearShift = Mux(og1RespFail, og1RespMatchVec.asUInt >> 3, Utils.NZeros(tableSize))
56bf44d649SXuan Hu
57bf44d649SXuan Hu  // Just for more readable verilog
588d081717Sszw_kaixin  if(backendParams.debugEn) {
59bf44d649SXuan Hu    dontTouch(fuBusyTableShift)
606c996d9bSzhanglyGit    dontTouch(deqRespSetShift)
616c996d9bSzhanglyGit    dontTouch(og0RespClearShift)
626c996d9bSzhanglyGit    dontTouch(og1RespClearShift)
638d081717Sszw_kaixin  }
64bf44d649SXuan Hu
656c996d9bSzhanglyGit  fuBusyTableNext := fuBusyTableShift & (~og0RespClearShift).asUInt & (~og1RespClearShift).asUInt | deqRespSetShift.asUInt
66de93b508SzhanglyGit
67de93b508SzhanglyGit  io.out.fuBusyTable := fuBusyTable
686c996d9bSzhanglyGit  io.out.deqRespSet := Mux(deqRespSuccess, deqRespMatchVec.asUInt, Utils.NZeros(tableSize)).asUInt
69de93b508SzhanglyGit}
70de93b508SzhanglyGit
71dd970561SzhanglyGitclass FuBusyTableWriteIO(latencyValMax: Int)(implicit p: Parameters, iqParams: IssueBlockParams) extends XSBundle {
72dd970561SzhanglyGit  private val tableSize = latencyValMax + 1
73de93b508SzhanglyGit  val in = new Bundle {
74dd970561SzhanglyGit    val deqResp =  Flipped(ValidIO(new IssueQueueDeqRespBundle))
75dd970561SzhanglyGit    val og0Resp = Flipped(ValidIO(new IssueQueueDeqRespBundle))
76dd970561SzhanglyGit    val og1Resp = Flipped(ValidIO(new IssueQueueDeqRespBundle))
77de93b508SzhanglyGit  }
78de93b508SzhanglyGit  val out = new Bundle {
79bf44d649SXuan Hu    val fuBusyTable = Output(UInt(tableSize.W))
80dd970561SzhanglyGit    val deqRespSet = Output(UInt(tableSize.W))
81de93b508SzhanglyGit  }
82de93b508SzhanglyGit}