xref: /XiangShan/src/main/scala/xiangshan/backend/issue/FuBusyTableWrite.scala (revision 25bcff47f9bc19c872a1647b16fdfefdd4bae3f5)
1package xiangshan.backend.issue
2
3import chipsalliance.rocketchip.config.Parameters
4import chisel3._
5import chisel3.util._
6import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp}
7import utility.HasCircularQueuePtrHelper
8import xiangshan._
9import xiangshan.backend.fu.{FuConfig, FuType}
10import xiangshan.mem.{MemWaitUpdateReq, SqPtr}
11import xiangshan.backend.Bundles.{DynInst, IssueQueueIssueBundle, IssueQueueWakeUpBundle}
12import xiangshan.backend.datapath.DataConfig._
13import xiangshan.backend.exu.ExeUnitParams
14
15class FuBusyTableWrite(val idx: Int) (implicit  p: Parameters, iqParams: IssueBlockParams) extends XSModule {
16  val io = IO(new FuBusyTableWriteIO(idx))
17
18  val fuLatencyMap: Option[Seq[(Int, Int)]] = iqParams.exuBlockParams(idx).fuLatencyMap
19  val latencyValMax: Option[Int] = iqParams.exuBlockParams(idx).latencyValMax
20
21  val deqResp = io.in.deqResp
22  val og0Resp = io.in.og0Resp
23  val og1Resp = io.in.og1Resp
24  val fuTypeRegVec = io.in.fuTypeRegVec
25
26  val fuBusyTable = Reg(UInt(latencyValMax.get.W)) //instance of FuBusyTable insists only when latencyValMax > 0
27
28  // fuBusyTable write
29  val isLatencyNumVecDeq = Mux(deqResp(idx).valid && deqResp(idx).bits.respType === RSFeedbackType.issueSuccess,
30    Cat((0 until latencyValMax.get).map { case num =>
31      val latencyNumFuType = fuLatencyMap.get.filter(_._2 == num + 1).map(_._1) // futype with latency equal to num+1
32      val isLatencyNum = Cat(latencyNumFuType.map(futype => fuTypeRegVec(OHToUInt(deqResp(idx).bits.addrOH)) === futype.U)).asUInt.orR // The latency of the deq inst is Num
33      isLatencyNum
34    }),
35    0.U
36  ) // |  when N cycle is 2 latency, N+1 cycle could not 1 latency
37  val isLatencyNumVecOg0 = WireInit(~(0.U.asTypeOf(isLatencyNumVecDeq)))
38  isLatencyNumVecOg0 := Mux(og0Resp(idx).valid && (og0Resp(idx).bits.respType === RSFeedbackType.rfArbitFail || og0Resp(idx).bits.respType === RSFeedbackType.fuBusy),
39    ~(Cat(Cat((0 until latencyValMax.get).map { case num =>
40      val latencyNumFuType = fuLatencyMap.get.filter(_._2 == num + 1).map(_._1) // futype with latency equal to num+1
41      val isLatencyNum = Cat(latencyNumFuType.map(futype => fuTypeRegVec(OHToUInt(og0Resp(idx).bits.addrOH)) === futype.U)).asUInt.orR // The latency of the deq inst is Num
42      isLatencyNum
43    }), 0.U(1.W))),
44    ~(0.U.asTypeOf(isLatencyNumVecDeq))
45  )
46  val isLatencyNumVecOg1 = WireInit(~(0.U.asTypeOf(isLatencyNumVecDeq)))
47  isLatencyNumVecOg1 := Mux(og1Resp(idx).valid && og1Resp(idx).bits.respType === RSFeedbackType.fuBusy,
48    ~(Cat(Cat((0 until latencyValMax.get).map { case num =>
49      val latencyNumFuType = fuLatencyMap.get.filter(_._2 == num + 1).map(_._1) // futype with latency equal to num+1
50      val isLatencyNum = Cat(latencyNumFuType.map(futype => fuTypeRegVec(OHToUInt(og1Resp(idx).bits.addrOH)) === futype.U)).asUInt.orR // The latency of the deq inst is Num
51      isLatencyNum
52    }), 0.U(2.W))),
53    ~(0.U.asTypeOf(isLatencyNumVecDeq))
54  )
55
56  fuBusyTable := ((fuBusyTable << 1.U).asUInt & isLatencyNumVecOg0.asUInt & isLatencyNumVecOg1.asUInt) | isLatencyNumVecDeq
57
58  io.out.fuBusyTable := fuBusyTable
59
60}
61
62class FuBusyTableWriteIO(val idx: Int)(implicit p: Parameters, iqParams: IssueBlockParams) extends XSBundle {
63  val in = new Bundle {
64    val deqResp = Vec(iqParams.numDeq, Flipped(ValidIO(new IssueQueueDeqRespBundle)))
65    val og0Resp = Vec(iqParams.numDeq, Flipped(ValidIO(new IssueQueueDeqRespBundle)))
66    val og1Resp = Vec(iqParams.numDeq, Flipped(ValidIO(new IssueQueueDeqRespBundle)))
67    val fuTypeRegVec = Input(Vec(iqParams.numEntries, FuType()))
68  }
69  val out = new Bundle {
70    val fuBusyTable = Output(UInt(iqParams.exuBlockParams(idx).latencyValMax.get.W))
71  }
72}