xref: /XiangShan/src/main/scala/xiangshan/backend/issue/Entries.scala (revision 4b0d80d87574e82ba31737496d63ac30bed0d40a)
1package xiangshan.backend.issue
2
3import chipsalliance.rocketchip.config.Parameters
4import chisel3._
5import chisel3.util._
6import utility.HasCircularQueuePtrHelper
7import utils.{MathUtils, OptionWrapper, XSError}
8import xiangshan._
9import xiangshan.backend.Bundles._
10import xiangshan.backend.datapath.DataConfig.VAddrData
11import xiangshan.backend.datapath.DataSource
12import xiangshan.backend.fu.FuType
13import xiangshan.backend.fu.vector.Utils.NOnes
14import xiangshan.backend.rob.RobPtr
15import xiangshan.mem.{MemWaitUpdateReq, SqPtr}
16
17class StatusMemPart(implicit p:Parameters, params: IssueBlockParams) extends Bundle {
18  val waitForSqIdx = new SqPtr   // generated by store data valid check
19  val waitForRobIdx = new RobPtr // generated by store set
20  val waitForStd = Bool()
21  val strictWait = Bool()
22  val sqIdx = new SqPtr
23}
24
25class Status(implicit p:Parameters, params: IssueBlockParams) extends XSBundle {
26  val srcState = Vec(params.numRegSrc, SrcState())
27
28  val psrc = Vec(params.numRegSrc, UInt(params.rdPregIdxWidth.W))
29  val srcType = Vec(params.numRegSrc, SrcType())
30  val fuType = FuType()
31  val robIdx = new RobPtr
32  val issued = Bool()           // for predict issue
33  val firstIssue = Bool()
34  val blocked = Bool()          // for some block reason
35  // read reg or get data from bypass network
36  val dataSources = Vec(params.numRegSrc, DataSource())
37  // if waked up by iq, set when waked up by iq
38  val srcWakeUpL1ExuOH = OptionWrapper(params.hasIQWakeUp, Vec(params.numRegSrc, ExuVec()))
39  // src timer, used by cancel signal. It increases every cycle after wakeup src inst issued.
40  val srcTimer = OptionWrapper(params.hasIQWakeUp, Vec(params.numRegSrc, UInt(3.W)))
41  val issueTimer = UInt(2.W)
42  val deqPortIdx = UInt(1.W)
43  val srcLoadDependency = OptionWrapper(params.hasIQWakeUp, Vec(params.numRegSrc, Vec(LoadPipelineWidth, UInt(3.W))))
44
45
46  // mem only
47  val mem = if (params.isMemAddrIQ) Some(new StatusMemPart) else None
48
49  // need pc
50  val pc = if (params.needPc) Some(UInt(VAddrData().dataWidth.W)) else None
51
52  def srcReady: Bool = {
53    VecInit(srcState.map(SrcState.isReady)).asUInt.andR
54  }
55
56  def canIssue: Bool = {
57    srcReady && !issued && !blocked
58  }
59
60  def mergedLoadDependency = srcLoadDependency.map(_.map(_.toSeq).reduce(_ zip _ map(x => x._1 | x._2)))
61}
62
63class EntryDeqRespBundle(implicit p:Parameters, params: IssueBlockParams) extends Bundle {
64  val robIdx = new RobPtr
65  val respType = RSFeedbackType()   // update credit if needs replay
66  val dataInvalidSqIdx = new SqPtr
67  val rfWen = Bool()
68  val fuType = FuType()
69}
70
71class EntryBundle(implicit p: Parameters, params: IssueBlockParams) extends XSBundle {
72  val status = new Status()
73  val imm = UInt(XLEN.W)
74  val payload = new DynInst()
75}
76
77class DeqBundle(implicit p:Parameters, params: IssueBlockParams) extends XSBundle {
78  val isFirstIssue = Output(Bool())
79  val deqSelOH = Flipped(ValidIO(UInt(params.numEntries.W)))
80}
81
82class EntriesIO(implicit p: Parameters, params: IssueBlockParams) extends XSBundle {
83  val flush = Flipped(ValidIO(new Redirect))
84  // status
85  val valid = Output(UInt(params.numEntries.W))
86  val canIssue = Output(UInt(params.numEntries.W))
87  val clear = Output(UInt(params.numEntries.W))
88  val fuType = Output(Vec(params.numEntries, FuType()))
89  val dataSources = Output(Vec(params.numEntries, Vec(params.numRegSrc, DataSource())))
90  val srcWakeUpL1ExuOH = OptionWrapper(params.hasIQWakeUp, Output(Vec(params.numEntries, Vec(params.numRegSrc, ExuVec()))))
91  val srcTimer = OptionWrapper(params.hasIQWakeUp, Output(Vec(params.numEntries, Vec(params.numRegSrc, UInt(3.W)))))
92  //enq
93  val enq = Vec(params.numEnq, Flipped(ValidIO(new EntryBundle)))
94  // wakeup
95  val wakeUpFromWB: MixedVec[ValidIO[IssueQueueWBWakeUpBundle]] = Flipped(params.genWBWakeUpSinkValidBundle)
96  val wakeUpFromIQ: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpSinkValidBundle)
97  val og0Cancel = Input(ExuVec(backendParams.numExu))
98  val og1Cancel = Input(ExuVec(backendParams.numExu))
99  val ldCancel = Vec(backendParams.LduCnt, Flipped(new LoadCancelIO))
100  //deq
101  val deq = Vec(params.numDeq, new DeqBundle)
102  val deqResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle)))
103  val og0Resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle)))
104  val og1Resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle)))
105  val finalIssueResp = OptionWrapper(params.LduCnt > 0, Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))))
106  val transEntryDeqVec = Vec(params.numEnq, ValidIO(new EntryBundle))
107  val deqEntry = Vec(params.numDeq, ValidIO(new EntryBundle))
108  val transSelVec = Output(Vec(params.numEnq, UInt((params.numEntries-params.numEnq).W)))
109
110
111  val rsFeedback = Output(Vec(5, Bool()))
112  // mem only
113  val fromMem = if (params.isMemAddrIQ) Some(new Bundle {
114    val stIssuePtr = Input(new SqPtr)
115    val memWaitUpdateReq = Flipped(new MemWaitUpdateReq)
116    val slowResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle)))
117    val fastResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle)))
118  }) else None
119
120  // debug
121  val cancel = OptionWrapper(params.hasIQWakeUp, Output(Vec(params.numEntries, Bool())))
122
123  def wakeup = wakeUpFromWB ++ wakeUpFromIQ
124}
125
126class Entries(implicit p: Parameters, params: IssueBlockParams) extends XSModule {
127  private val EnqEntryNum = params.numEnq
128  private val OthersEntryNum = params.numEntries - params.numEnq
129  val io = IO(new EntriesIO)
130
131  val resps: Vec[Vec[ValidIO[EntryDeqRespBundle]]] = if(params.isLdAddrIQ) VecInit(io.deqResp, io.og0Resp, io.og1Resp, io.finalIssueResp.get, io.fromMem.get.fastResp, io.fromMem.get.slowResp)
132                                                     else if(params.isMemAddrIQ) VecInit(io.deqResp, io.og0Resp, io.og1Resp, io.fromMem.get.fastResp, io.fromMem.get.slowResp)
133                                                     else VecInit(io.deqResp, io.og0Resp, io.og1Resp, 0.U.asTypeOf(io.deqResp))
134
135  //Module
136  val enqEntries = Seq.fill(EnqEntryNum)(Module(EnqEntry(p, params)))
137  val othersEntries = Seq.fill(OthersEntryNum)(Module(OthersEntry(p, params)))
138  val transPolicy = Module(new EnqPolicy)
139
140  //Wire
141  val deqSelVec = Wire(Vec(params.numEntries, Bool()))
142  val transSelVec = Wire(Vec(EnqEntryNum, Vec(OthersEntryNum, Bool())))
143  val issueRespVec = Wire(Vec(params.numEntries, ValidIO(new EntryDeqRespBundle)))
144  val transEntryDeqVec = Wire(Vec(EnqEntryNum, ValidIO(new EntryBundle)))
145  val transEntryEnqVec = Wire(Vec(OthersEntryNum, ValidIO(new EntryBundle)))
146  val entries = Wire(Vec(params.numEntries, ValidIO(new EntryBundle)))
147
148  val validVec = Wire(Vec(params.numEntries, Bool()))
149  val canIssueVec = Wire(Vec(params.numEntries, Bool()))
150  val clearVec = Wire(Vec(params.numEntries, Bool()))
151  val fuTypeVec = Wire(Vec(params.numEntries, FuType()))
152  val dataSourceVec = Wire(Vec(params.numEntries, Vec(params.numRegSrc, DataSource())))
153  val srcWakeUpL1ExuOHVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Vec(params.numRegSrc, ExuVec()))))
154  val srcTimerVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Vec(params.numRegSrc, UInt(3.W)))))
155  val isFirstIssueVec = Wire(Vec(params.numEntries, Bool()))
156  val robIdxVec = Wire(Vec(params.numEntries, new RobPtr))
157  val issueTimerVec = Wire(Vec(params.numEntries, UInt(2.W)))
158  val deqPortIdxWriteVec = Wire(Vec(params.numEntries, UInt(1.W)))
159  val deqPortIdxReadVec = Wire(Vec(params.numEntries, UInt(1.W)))
160  val cancelVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Bool())))
161
162  io.transEntryDeqVec := transEntryDeqVec
163
164  //enqEntries
165  enqEntries.zipWithIndex.foreach { case (enqEntry, entryIdx) =>
166    enqEntry.io.enq := io.enq(entryIdx)
167    enqEntry.io.flush := io.flush
168    enqEntry.io.wakeUpFromWB := io.wakeUpFromWB
169    enqEntry.io.wakeUpFromIQ := io.wakeUpFromIQ
170    enqEntry.io.og0Cancel := io.og0Cancel
171    enqEntry.io.og1Cancel := io.og1Cancel
172    enqEntry.io.ldCancel := io.ldCancel
173    enqEntry.io.deqSel := deqSelVec(entryIdx)
174    enqEntry.io.deqPortIdxWrite := deqPortIdxWriteVec(entryIdx)
175    enqEntry.io.transSel := transSelVec(entryIdx).asUInt.orR
176    enqEntry.io.issueResp := issueRespVec(entryIdx)
177    validVec(entryIdx) := enqEntry.io.valid
178    canIssueVec(entryIdx) := enqEntry.io.canIssue
179    clearVec(entryIdx) := enqEntry.io.clear
180    fuTypeVec(entryIdx) := enqEntry.io.fuType
181    dataSourceVec(entryIdx) := enqEntry.io.dataSource
182    robIdxVec(entryIdx) := enqEntry.io.robIdx
183    issueTimerVec(entryIdx) := enqEntry.io.issueTimerRead
184    deqPortIdxReadVec(entryIdx) := enqEntry.io.deqPortIdxRead
185    if (params.hasIQWakeUp) {
186      srcWakeUpL1ExuOHVec.get(entryIdx) := enqEntry.io.srcWakeUpL1ExuOH.get
187      srcTimerVec.get(entryIdx) := enqEntry.io.srcTimer.get
188      cancelVec.get(entryIdx) := enqEntry.io.cancel.get
189    }
190    transEntryDeqVec(entryIdx) := enqEntry.io.transEntry
191    isFirstIssueVec(entryIdx) := enqEntry.io.isFirstIssue
192    entries(entryIdx) := enqEntry.io.entry
193    //for mem
194    if (params.isMemAddrIQ) {
195      enqEntry.io.fromMem.get.stIssuePtr := io.fromMem.get.stIssuePtr
196      enqEntry.io.fromMem.get.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
197    }
198
199  }
200  //othersEntries
201  othersEntries.zipWithIndex.foreach { case (othersEntry, entryIdx) =>
202    othersEntry.io.enq := transEntryEnqVec(entryIdx)
203    othersEntry.io.flush := io.flush
204    othersEntry.io.wakeUpFromWB := io.wakeUpFromWB
205    othersEntry.io.wakeUpFromIQ := io.wakeUpFromIQ
206    othersEntry.io.og0Cancel := io.og0Cancel
207    othersEntry.io.og1Cancel := io.og1Cancel
208    othersEntry.io.ldCancel := io.ldCancel
209    othersEntry.io.deqSel := deqSelVec(entryIdx + EnqEntryNum)
210    othersEntry.io.deqPortIdxWrite := deqPortIdxWriteVec(entryIdx + EnqEntryNum)
211    othersEntry.io.transSel := transSelVec.map(x => x(entryIdx)).reduce(_ | _)
212    othersEntry.io.issueResp := issueRespVec(entryIdx + EnqEntryNum)
213    validVec(entryIdx + EnqEntryNum) := othersEntry.io.valid
214    canIssueVec(entryIdx + EnqEntryNum) := othersEntry.io.canIssue
215    clearVec(entryIdx + EnqEntryNum) := othersEntry.io.clear
216    fuTypeVec(entryIdx + EnqEntryNum) := othersEntry.io.fuType
217    dataSourceVec(entryIdx + EnqEntryNum) := othersEntry.io.dataSource
218    robIdxVec(entryIdx + EnqEntryNum) := othersEntry.io.robIdx
219    issueTimerVec(entryIdx + EnqEntryNum) := othersEntry.io.issueTimerRead
220    deqPortIdxReadVec(entryIdx + EnqEntryNum) := othersEntry.io.deqPortIdxRead
221    if (params.hasIQWakeUp) {
222      srcWakeUpL1ExuOHVec.get(entryIdx + EnqEntryNum) := othersEntry.io.srcWakeUpL1ExuOH.get
223      srcTimerVec.get(entryIdx + EnqEntryNum) := othersEntry.io.srcTimer.get
224      cancelVec.get(entryIdx + EnqEntryNum) := othersEntry.io.cancel.get
225    }
226    isFirstIssueVec(entryIdx + EnqEntryNum) := othersEntry.io.isFirstIssue
227    entries(entryIdx + EnqEntryNum) := othersEntry.io.entry
228    //for mem
229    if (params.isMemAddrIQ) {
230      othersEntry.io.fromMem.get.stIssuePtr := io.fromMem.get.stIssuePtr
231      othersEntry.io.fromMem.get.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
232    }
233
234  }
235
236
237  deqSelVec.zip(deqPortIdxWriteVec).zipWithIndex.foreach { case ((deqSel, deqPortIdxWrite), i) =>
238    val deqVec = io.deq.map(x => x.deqSelOH.valid && x.deqSelOH.bits(i))
239    deqPortIdxWrite := OHToUInt(deqVec)
240    deqSel := deqVec.reduce(_ | _)
241  }
242
243
244  //transPolicy
245  transPolicy.io.valid := VecInit(validVec.slice(EnqEntryNum, params.numEntries)).asUInt
246  transSelVec.zip(transPolicy.io.enqSelOHVec).foreach { case (selBools, selOH) =>
247    selBools.zipWithIndex.foreach { case (selBool, i) =>
248      selBool := transPolicy.io.enqSelOHVec.map(_.valid).reduce(_ & _) && selOH.bits(i)
249    }
250  }
251
252  //transEntryEnq
253  transEntryEnqVec.zipWithIndex.foreach { case (transEntryEnq, othersIdx) =>
254    val transEnqHit = transSelVec.map(x => x(othersIdx))
255    transEntryEnq := Mux1H(transEnqHit, transEntryDeqVec)
256  }
257  dontTouch(transEntryEnqVec)
258
259  //issueRespVec
260  if(params.isMemAddrIQ){
261    issueRespVec.zip(robIdxVec).foreach { case (issueResp, robIdx) =>
262      val hitRespsVec = VecInit(resps.flatten.map(x => x.valid && (x.bits.robIdx === robIdx)))
263      issueResp.valid := hitRespsVec.reduce(_ | _)
264      issueResp.bits := Mux1H(hitRespsVec, resps.flatten.map(_.bits))
265    }
266  }
267  else {
268    issueRespVec.zip(issueTimerVec).zip(deqPortIdxReadVec).foreach { case ((issueResp, issueTimer), deqPortIdx) =>
269      val Resp = resps(issueTimer)(deqPortIdx)
270      issueResp := Resp
271    }
272  }
273
274  io.valid := validVec.asUInt
275  io.canIssue := canIssueVec.asUInt
276  io.clear := clearVec.asUInt
277  io.fuType := fuTypeVec
278  io.dataSources := dataSourceVec
279  io.srcWakeUpL1ExuOH.foreach(_ := srcWakeUpL1ExuOHVec.get)
280  io.srcTimer.foreach(_ := srcTimerVec.get)
281  io.cancel.foreach(_ := cancelVec.get)
282  io.rsFeedback := 0.U.asTypeOf(io.rsFeedback) //todo
283  io.deq.foreach{ x =>
284    x.isFirstIssue := Mux(x.deqSelOH.valid, Mux1H(x.deqSelOH.bits, isFirstIssueVec), false.B)
285  }
286  dontTouch(io.deq)
287  io.deqEntry.zip(io.deq.map(_.deqSelOH)).foreach{ case (deqEntry, deqSelOH) =>
288    deqEntry.valid := deqSelOH.valid && entries(OHToUInt(deqSelOH.bits)).valid
289    deqEntry.bits := entries(OHToUInt(deqSelOH.bits)).bits
290  }
291  io.transSelVec.zip(transSelVec).foreach { case (sink, source) =>
292    sink := source.asUInt
293  }
294}
295