1package xiangshan.backend.issue 2 3import org.chipsalliance.cde.config.Parameters 4import chisel3._ 5import chisel3.util._ 6import utility.HasCircularQueuePtrHelper 7import utils._ 8import utility._ 9import xiangshan._ 10import xiangshan.backend.Bundles._ 11import xiangshan.backend.datapath.DataConfig.VAddrData 12import xiangshan.backend.datapath.DataSource 13import xiangshan.backend.fu.FuType 14import xiangshan.backend.fu.vector.Utils.NOnes 15import xiangshan.backend.rob.RobPtr 16import xiangshan.mem.{LqPtr, MemWaitUpdateReq, SqPtr} 17import xiangshan.backend.issue.EntryBundles._ 18 19class Entries(implicit p: Parameters, params: IssueBlockParams) extends XSModule { 20 override def desiredName: String = params.getEntryName 21 22 require(params.numEnq <= 2, "number of enq should be no more than 2") 23 24 private val EnqEntryNum = params.numEnq 25 private val OthersEntryNum = params.numEntries - params.numEnq 26 private val SimpEntryNum = params.numSimp 27 private val CompEntryNum = params.numComp 28 val io = IO(new EntriesIO) 29 30 // only memAddrIQ use it 31 val memEtyResps: Seq[ValidIO[EntryDeqRespBundle]] = { 32 val resps = 33 if (params.isLdAddrIQ && !params.isStAddrIQ) //LDU 34 Seq(io.og0Resp, io.og1Resp, io.fromLoad.get.finalIssueResp, io.fromLoad.get.memAddrIssueResp) 35 else if (params.isLdAddrIQ && params.isStAddrIQ || params.isHyAddrIQ) //HYU 36 Seq(io.og0Resp, io.og1Resp, io.fromLoad.get.finalIssueResp, io.fromLoad.get.memAddrIssueResp, io.fromMem.get.fastResp, io.fromMem.get.slowResp) 37 else if (params.isStAddrIQ) //STU 38 Seq(io.og0Resp, io.og1Resp, io.fromMem.get.slowResp) 39 else if (params.isVecLduIQ && params.isVecStuIQ) // Vector store IQ need no vecLdIn.resp, but for now vector store share the vector load IQ 40 Seq(io.og0Resp, io.og1Resp, io.vecLdIn.get.resp, io.fromMem.get.slowResp) 41 else if (params.isVecLduIQ) 42 Seq(io.og0Resp, io.og1Resp, io.vecLdIn.get.resp) 43 else if (params.isVecStuIQ) 44 Seq(io.og0Resp, io.og1Resp, io.fromMem.get.slowResp) 45 else Seq() 46 if (params.isMemAddrIQ) { 47 println(s"[${this.desiredName}] resp: {" + 48 s"og0Resp: ${resps.contains(io.og0Resp)}, " + 49 s"og1Resp: ${resps.contains(io.og1Resp)}, " + 50 s"finalResp: ${io.fromLoad.nonEmpty && resps.contains(io.fromLoad.get.finalIssueResp)}, " + 51 s"loadBorderResp: ${io.fromLoad.nonEmpty && resps.contains(io.fromLoad.get.memAddrIssueResp)}, " + 52 s"memFastResp: ${io.fromMem.nonEmpty && resps.contains(io.fromMem.get.fastResp)}, " + 53 s"memSlowResp: ${io.fromMem.nonEmpty && resps.contains(io.fromMem.get.slowResp)}, " + 54 s"vecLoadBorderResp: ${io.vecLdIn.nonEmpty && resps.contains(io.vecLdIn.get.resp)}, " + 55 s"}" 56 ) 57 } 58 resps.flatten 59 } 60 61 val resps: Vec[Vec[ValidIO[EntryDeqRespBundle]]] = { 62 if (params.inVfSchd) 63 VecInit(io.og0Resp, io.og1Resp, io.og2Resp.get, 0.U.asTypeOf(io.og0Resp)) 64 else 65 VecInit(io.og0Resp, io.og1Resp, 0.U.asTypeOf(io.og0Resp), 0.U.asTypeOf(io.og0Resp)) 66 } 67 68 69 70 //Module 71 val enqEntries = Seq.fill(EnqEntryNum)(Module(EnqEntry(isComp = true)(p, params))) 72 val othersEntriesSimp = Seq.fill(SimpEntryNum)(Module(OthersEntry(isComp = false)(p, params))) 73 val othersEntriesComp = Seq.fill(CompEntryNum)(Module(OthersEntry(isComp = true)(p, params))) 74 val othersEntries = othersEntriesSimp ++ othersEntriesComp 75 val othersTransPolicy = OptionWrapper(params.isAllComp || params.isAllSimp, Module(new EnqPolicy)) 76 val simpTransPolicy = OptionWrapper(params.hasCompAndSimp, Module(new EnqPolicy)) 77 val compTransPolicy = OptionWrapper(params.hasCompAndSimp, Module(new EnqPolicy)) 78 79 //Wire 80 //entries status 81 val entries = Wire(Vec(params.numEntries, ValidIO(new EntryBundle))) 82 val robIdxVec = Wire(Vec(params.numEntries, new RobPtr)) 83 val validVec = Wire(Vec(params.numEntries, Bool())) 84 val canIssueVec = Wire(Vec(params.numEntries, Bool())) 85 val fuTypeVec = Wire(Vec(params.numEntries, FuType())) 86 val isFirstIssueVec = Wire(Vec(params.numEntries, Bool())) 87 val issueTimerVec = Wire(Vec(params.numEntries, UInt(2.W))) 88 val uopIdxVec = OptionWrapper(params.isVecMemIQ, Wire(Vec(params.numEntries, UopIdx()))) 89 //src status 90 val dataSourceVec = Wire(Vec(params.numEntries, Vec(params.numRegSrc, DataSource()))) 91 val loadDependencyVec = Wire(Vec(params.numEntries, Vec(LoadPipelineWidth, UInt(LoadDependencyWidth.W)))) 92 val srcWakeUpL1ExuOHVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Vec(params.numRegSrc, ExuVec())))) 93 //deq sel 94 val deqSelVec = Wire(Vec(params.numEntries, Bool())) 95 val issueRespVec = Wire(Vec(params.numEntries, ValidIO(new EntryDeqRespBundle))) 96 val deqPortIdxWriteVec = Wire(Vec(params.numEntries, UInt(1.W))) 97 val deqPortIdxReadVec = Wire(Vec(params.numEntries, UInt(1.W))) 98 //trans sel 99 val othersEntryEnqReadyVec = Wire(Vec(OthersEntryNum, Bool())) 100 val othersEntryEnqVec = Wire(Vec(OthersEntryNum, Valid(new EntryBundle))) 101 val enqEntryTransVec = Wire(Vec(EnqEntryNum, Valid(new EntryBundle))) 102 val simpEntryTransVec = OptionWrapper(params.hasCompAndSimp, Wire(Vec(SimpEntryNum, Valid(new EntryBundle)))) 103 val compEnqVec = OptionWrapper(params.hasCompAndSimp, Wire(Vec(EnqEntryNum, Valid(new EntryBundle)))) 104 105 val enqCanTrans2Simp = OptionWrapper(params.hasCompAndSimp, Wire(Bool())) 106 val enqCanTrans2Comp = OptionWrapper(params.hasCompAndSimp, Wire(Bool())) 107 val simpCanTrans2Comp = OptionWrapper(params.hasCompAndSimp, Wire(Vec(EnqEntryNum, Bool()))) 108 val simpTransSelVec = OptionWrapper(params.hasCompAndSimp, Wire(Vec(EnqEntryNum, Valid(UInt(SimpEntryNum.W))))) 109 val compTransSelVec = OptionWrapper(params.hasCompAndSimp, Wire(Vec(EnqEntryNum, Valid(UInt(CompEntryNum.W))))) 110 val finalSimpTransSelVec = OptionWrapper(params.hasCompAndSimp, Wire(Vec(EnqEntryNum, UInt(SimpEntryNum.W)))) 111 val finalCompTransSelVec = OptionWrapper(params.hasCompAndSimp, Wire(Vec(EnqEntryNum, UInt(CompEntryNum.W)))) 112 113 val enqCanTrans2Others = OptionWrapper(params.isAllComp || params.isAllSimp, Wire(Bool())) 114 val othersTransSelVec = OptionWrapper(params.isAllComp || params.isAllSimp, Wire(Vec(EnqEntryNum, Valid(UInt(OthersEntryNum.W))))) 115 val finalOthersTransSelVec = OptionWrapper(params.isAllComp || params.isAllSimp, Wire(Vec(EnqEntryNum, UInt(OthersEntryNum.W)))) 116 117 val simpEntryEnqReadyVec = othersEntryEnqReadyVec.take(SimpEntryNum) 118 val compEntryEnqReadyVec = othersEntryEnqReadyVec.takeRight(CompEntryNum) 119 val simpEntryEnqVec = othersEntryEnqVec.take(SimpEntryNum) 120 val compEntryEnqVec = othersEntryEnqVec.takeRight(CompEntryNum) 121 //debug 122 val entryInValidVec = Wire(Vec(params.numEntries, Bool())) 123 val entryOutDeqValidVec = Wire(Vec(params.numEntries, Bool())) 124 val entryOutTransValidVec = Wire(Vec(params.numEntries, Bool())) 125 val perfLdCancelVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Vec(params.numRegSrc, Bool())))) 126 val perfOg0CancelVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Vec(params.numRegSrc, Bool())))) 127 val perfWakeupByWBVec = Wire(Vec(params.numEntries, Vec(params.numRegSrc, Bool()))) 128 val perfWakeupByIQVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Vec(params.numRegSrc, Vec(params.numWakeupFromIQ, Bool()))))) 129 //cancel bypass 130 val cancelBypassVec = Wire(Vec(params.numEntries, Bool())) 131 132 133 //enqEntries 134 enqEntries.zipWithIndex.foreach { case (enqEntry, entryIdx) => 135 enqEntry.io.commonIn.enq := io.enq(entryIdx) 136 enqEntry.io.commonIn.transSel := (if (params.isAllComp || params.isAllSimp) enqCanTrans2Others.get && othersTransSelVec.get(entryIdx).valid 137 else enqCanTrans2Simp.get && simpTransSelVec.get(entryIdx).valid || enqCanTrans2Comp.get && compTransSelVec.get(entryIdx).valid) 138 EntriesConnect(enqEntry.io.commonIn, enqEntry.io.commonOut, entryIdx) 139 enqEntry.io.enqDelayIn1.wakeUpFromWB := RegEnable(io.wakeUpFromWB, io.enq(entryIdx).valid) 140 enqEntry.io.enqDelayIn1.wakeUpFromIQ := RegEnable(io.wakeUpFromIQ, io.enq(entryIdx).valid) 141 enqEntry.io.enqDelayIn1.og0Cancel := RegNext(io.og0Cancel.asUInt) 142 enqEntry.io.enqDelayIn1.ldCancel := RegNext(io.ldCancel) 143 // note: these signals with 2 cycle delay should not be enabled by io.enq.valid 144 enqEntry.io.enqDelayIn2.wakeUpFromWB := DelayN(io.wakeUpFromWB, 2) 145 enqEntry.io.enqDelayIn2.wakeUpFromIQ := DelayN(io.wakeUpFromIQ, 2) 146 enqEntry.io.enqDelayIn2.og0Cancel := DelayN(io.og0Cancel.asUInt, 2) 147 enqEntry.io.enqDelayIn2.ldCancel := DelayN(io.ldCancel, 2) 148 enqEntryTransVec(entryIdx) := enqEntry.io.commonOut.transEntry 149 } 150 //othersEntries 151 othersEntries.zipWithIndex.foreach { case (othersEntry, entryIdx) => 152 othersEntry.io.commonIn.enq := othersEntryEnqVec(entryIdx) 153 othersEntry.io.commonIn.transSel := (if (params.hasCompAndSimp && (entryIdx < SimpEntryNum)) 154 io.simpEntryDeqSelVec.get.zip(simpCanTrans2Comp.get).map(x => x._1(entryIdx) && x._2).reduce(_ | _) 155 else false.B) 156 EntriesConnect(othersEntry.io.commonIn, othersEntry.io.commonOut, entryIdx + EnqEntryNum) 157 othersEntryEnqReadyVec(entryIdx) := othersEntry.io.commonOut.enqReady 158 if (params.hasCompAndSimp && (entryIdx < SimpEntryNum)) { 159 simpEntryTransVec.get(entryIdx) := othersEntry.io.commonOut.transEntry 160 } 161 } 162 163 164 deqSelVec.zip(deqPortIdxWriteVec).zipWithIndex.foreach { case ((deqSel, deqPortIdxWrite), i) => 165 val deqVec = io.deqSelOH.zip(io.deqReady).map(x => x._1.valid && x._1.bits(i) && x._2) 166 deqPortIdxWrite := OHToUInt(deqVec) 167 deqSel := deqVec.reduce(_ | _) 168 } 169 170 171 if (params.isAllComp || params.isAllSimp) { 172 //transPolicy 173 othersTransPolicy.get.io.canEnq := othersEntryEnqReadyVec.asUInt 174 175 // we only allow all or none of the enq entries transfering to others entries. 176 enqCanTrans2Others.get := PopCount(validVec.take(EnqEntryNum)) <= PopCount(othersEntryEnqReadyVec) 177 // othersTransSelVec(i) is the target others entry for enq entry [i]. 178 // note that dispatch does not guarantee the validity of enq entries with low index. 179 // that means in some cases enq entry [0] is invalid while enq entry [1] is valid. 180 // in this case, enq entry [1] should use result [0] of TransPolicy. 181 othersTransSelVec.get(0).valid := othersTransPolicy.get.io.enqSelOHVec(0).valid && validVec(0) 182 othersTransSelVec.get(0).bits := othersTransPolicy.get.io.enqSelOHVec(0).bits 183 if (params.numEnq == 2) { 184 othersTransSelVec.get(1).valid := Mux(!validVec(0), othersTransPolicy.get.io.enqSelOHVec(0).valid, othersTransPolicy.get.io.enqSelOHVec(1).valid) 185 othersTransSelVec.get(1).bits := Mux(!validVec(0), othersTransPolicy.get.io.enqSelOHVec(0).bits, othersTransPolicy.get.io.enqSelOHVec(1).bits) 186 } 187 188 finalOthersTransSelVec.get.zip(othersTransSelVec.get).zipWithIndex.foreach { case ((finalOH, selOH), enqIdx) => 189 finalOH := Fill(OthersEntryNum, enqCanTrans2Others.get && selOH.valid) & selOH.bits 190 } 191 192 //othersEntryEnq 193 othersEntryEnqVec.zipWithIndex.foreach { case (othersEntryEnq, othersIdx) => 194 val othersEnqOH = finalOthersTransSelVec.get.map(_(othersIdx)) 195 if (othersEnqOH.size == 1) 196 othersEntryEnq := Mux(othersEnqOH.head, enqEntryTransVec.head, 0.U.asTypeOf(enqEntryTransVec.head)) 197 else 198 othersEntryEnq := Mux1H(othersEnqOH, enqEntryTransVec) 199 } 200 } 201 else { 202 //transPolicy 203 simpTransPolicy.get.io.canEnq := VecInit(simpEntryEnqReadyVec).asUInt 204 compTransPolicy.get.io.canEnq := VecInit(validVec.takeRight(CompEntryNum).map(!_)).asUInt 205 206 // we only allow all or none of the enq entries transfering to comp/simp entries. 207 // when all of simp entries are empty and comp entries are enough, transfer to comp entries. 208 // otherwise, transfer to simp entries. 209 enqCanTrans2Comp.get := PopCount(validVec.take(EnqEntryNum)) <= PopCount(validVec.takeRight(CompEntryNum).map(!_)) && !validVec.drop(EnqEntryNum).take(SimpEntryNum).reduce(_ || _) 210 enqCanTrans2Simp.get := !enqCanTrans2Comp.get && PopCount(validVec.take(EnqEntryNum)) <= PopCount(simpEntryEnqReadyVec) 211 simpCanTrans2Comp.get.zipWithIndex.foreach { case (canTrans, idx) => 212 canTrans := !enqCanTrans2Comp.get && PopCount(validVec.takeRight(CompEntryNum).map(!_)) >= (idx + 1).U 213 } 214 215 // simp/compTransSelVec(i) is the target simp/comp entry for enq entry [i]. 216 // note that dispatch does not guarantee the validity of enq entries with low index. 217 // that means in some cases enq entry [0] is invalid while enq entry [1] is valid. 218 // in this case, enq entry [1] should use result [0] of TransPolicy. 219 simpTransSelVec.get(0).valid := simpTransPolicy.get.io.enqSelOHVec(0).valid && validVec(0) 220 simpTransSelVec.get(0).bits := simpTransPolicy.get.io.enqSelOHVec(0).bits 221 compTransSelVec.get(0).valid := compTransPolicy.get.io.enqSelOHVec(0).valid && validVec(0) 222 compTransSelVec.get(0).bits := compTransPolicy.get.io.enqSelOHVec(0).bits 223 if (params.numEnq == 2) { 224 simpTransSelVec.get(1).valid := Mux(!validVec(0), simpTransPolicy.get.io.enqSelOHVec(0).valid, simpTransPolicy.get.io.enqSelOHVec(1).valid) 225 simpTransSelVec.get(1).bits := Mux(!validVec(0), simpTransPolicy.get.io.enqSelOHVec(0).bits, simpTransPolicy.get.io.enqSelOHVec(1).bits) 226 compTransSelVec.get(1).valid := Mux(!validVec(0), compTransPolicy.get.io.enqSelOHVec(0).valid, compTransPolicy.get.io.enqSelOHVec(1).valid) 227 compTransSelVec.get(1).bits := Mux(!validVec(0), compTransPolicy.get.io.enqSelOHVec(0).bits, compTransPolicy.get.io.enqSelOHVec(1).bits) 228 } 229 230 finalSimpTransSelVec.get.zip(simpTransSelVec.get).zipWithIndex.foreach { case ((finalOH, selOH), enqIdx) => 231 finalOH := Fill(SimpEntryNum, enqCanTrans2Simp.get && selOH.valid) & selOH.bits 232 } 233 finalCompTransSelVec.get.zip(compTransSelVec.get).zip(compTransPolicy.get.io.enqSelOHVec).zipWithIndex.foreach { 234 case (((finalOH, selOH), origSelOH), enqIdx) => 235 finalOH := Mux(enqCanTrans2Comp.get, Fill(CompEntryNum, selOH.valid) & selOH.bits, Fill(CompEntryNum, origSelOH.valid) & origSelOH.bits) 236 } 237 238 //othersEntryEnq 239 simpEntryEnqVec.zipWithIndex.foreach { case (simpEntryEnq, simpIdx) => 240 val simpEnqOH = finalSimpTransSelVec.get.map(_(simpIdx)) 241 // shit Mux1H directly returns in(0) if the seq has only 1 elements 242 if (simpEnqOH.size == 1) 243 simpEntryEnq := Mux(simpEnqOH.head, enqEntryTransVec.head, 0.U.asTypeOf(enqEntryTransVec.head)) 244 else 245 simpEntryEnq := Mux1H(simpEnqOH, enqEntryTransVec) 246 } 247 248 compEnqVec.get.zip(enqEntryTransVec).zip(io.simpEntryDeqSelVec.get).foreach { case ((compEnq, enqEntry), deqSel) => 249 compEnq := Mux(enqCanTrans2Comp.get, enqEntry, Mux1H(deqSel, simpEntryTransVec.get)) 250 } 251 compEntryEnqVec.zipWithIndex.foreach { case (compEntryEnq, compIdx) => 252 val compEnqOH = finalCompTransSelVec.get.map(_(compIdx)) 253 // shit Mux1H directly returns in(0) if the seq has only 1 elements 254 if (compEnqOH.size == 1) 255 compEntryEnq := Mux(compEnqOH.head, compEnqVec.get.head, 0.U.asTypeOf(compEnqVec.get.head)) 256 else 257 compEntryEnq := Mux1H(compEnqOH, compEnqVec.get) 258 } 259 260 assert(PopCount(simpEntryEnqVec.map(_.valid)) <= params.numEnq.U, "the number of simpEntryEnq is more than numEnq\n") 261 assert(PopCount(compEntryEnqVec.map(_.valid)) <= params.numEnq.U, "the number of compEntryEnq is more than numEnq\n") 262 } 263 264 if(backendParams.debugEn) { 265 dontTouch(othersEntryEnqVec) 266 } 267 268 //issueRespVec 269 if (params.isVecMemIQ) { 270 // vector memory IQ 271 issueRespVec.zip(robIdxVec).zip(uopIdxVec.get).foreach { case ((issueResp, robIdx), uopIdx) => 272 val hitRespsVec = VecInit(memEtyResps.map(x => 273 x.valid && x.bits.robIdx === robIdx && x.bits.uopIdx.get === uopIdx 274 ).toSeq) 275 issueResp.valid := hitRespsVec.reduce(_ | _) 276 issueResp.bits := Mux1H(hitRespsVec, memEtyResps.map(_.bits).toSeq) 277 } 278 } else if (params.isMemAddrIQ) { 279 // scalar memory IQ 280 issueRespVec.zip(robIdxVec).foreach { case (issueResp, robIdx) => 281 val hitRespsVec = VecInit(memEtyResps.map(x => x.valid && (x.bits.robIdx === robIdx)).toSeq) 282 issueResp.valid := hitRespsVec.reduce(_ | _) 283 issueResp.bits := Mux1H(hitRespsVec, memEtyResps.map(_.bits).toSeq) 284 } 285 } 286 else { 287 issueRespVec.zip(issueTimerVec).zip(deqPortIdxReadVec).foreach { case ((issueResp, issueTimer), deqPortIdx) => 288 val Resp = resps(issueTimer)(deqPortIdx) 289 issueResp := Resp 290 } 291 } 292 293 //deq 294 val enqEntryOldest = Wire(Vec(params.numDeq, ValidIO(new EntryBundle))) 295 val simpEntryOldest = OptionWrapper(params.hasCompAndSimp, Wire(Vec(params.numDeq, ValidIO(new EntryBundle)))) 296 val compEntryOldest = OptionWrapper(params.hasCompAndSimp, Wire(Vec(params.numDeq, ValidIO(new EntryBundle)))) 297 val othersEntryOldest = OptionWrapper(params.isAllComp || params.isAllSimp, Wire(Vec(params.numDeq, ValidIO(new EntryBundle)))) 298 val enqEntryOldestCancel = Wire(Vec(params.numDeq, Bool())) 299 val simpEntryOldestCancel = OptionWrapper(params.hasCompAndSimp, Wire(Vec(params.numDeq, Bool()))) 300 val compEntryOldestCancel = OptionWrapper(params.hasCompAndSimp, Wire(Vec(params.numDeq, Bool()))) 301 val othersEntryOldestCancel = OptionWrapper(params.isAllComp || params.isAllSimp, Wire(Vec(params.numDeq, Bool()))) 302 303 io.enqEntryOldestSel.zipWithIndex.map { case (sel, deqIdx) => 304 enqEntryOldest(deqIdx) := Mux1H(sel.bits, entries.take(EnqEntryNum)) 305 enqEntryOldestCancel(deqIdx) := Mux1H(sel.bits, cancelBypassVec.take(EnqEntryNum)) 306 } 307 308 if (params.isAllComp || params.isAllSimp) { 309 io.othersEntryOldestSel.get.zipWithIndex.map { case (sel, deqIdx) => 310 othersEntryOldest.get(deqIdx) := Mux1H(sel.bits, entries.drop(EnqEntryNum)) 311 othersEntryOldestCancel.get(deqIdx) := Mux1H(sel.bits, cancelBypassVec.drop(EnqEntryNum)) 312 } 313 } 314 else { 315 io.simpEntryOldestSel.get.zipWithIndex.map { case (sel, deqIdx) => 316 simpEntryOldest.get(deqIdx) := Mux1H(sel.bits, entries.drop(EnqEntryNum).take(SimpEntryNum)) 317 simpEntryOldestCancel.get(deqIdx) := Mux1H(sel.bits, cancelBypassVec.drop(EnqEntryNum).take(SimpEntryNum)) 318 } 319 io.compEntryOldestSel.get.zipWithIndex.map { case (sel, deqIdx) => 320 compEntryOldest.get(deqIdx) := Mux1H(sel.bits, entries.drop(EnqEntryNum).takeRight(CompEntryNum)) 321 compEntryOldestCancel.get(deqIdx) := Mux1H(sel.bits, cancelBypassVec.drop(EnqEntryNum).takeRight(CompEntryNum)) 322 } 323 } 324 325 if (params.deqFuSame) { 326 val subDeqPolicyEntryVec = Wire(Vec(params.numDeq, ValidIO(new EntryBundle))) 327 val subDeqPolicyValidVec = Wire(Vec(params.numDeq, Bool())) 328 val subDeqPolicyCancelBypassVec = Wire(Vec(params.numDeq, Bool())) 329 330 subDeqPolicyValidVec(0) := PopCount(io.subDeqRequest.get(0)) >= 1.U 331 subDeqPolicyValidVec(1) := PopCount(io.subDeqRequest.get(0)) >= 2.U 332 333 if (params.isAllComp || params.isAllSimp) { 334 subDeqPolicyEntryVec(0) := PriorityMux(io.subDeqRequest.get(0), entries) 335 subDeqPolicyEntryVec(1) := PriorityMux(Reverse(io.subDeqRequest.get(0)), entries.reverse) 336 subDeqPolicyCancelBypassVec(0) := PriorityMux(io.subDeqRequest.get(0), cancelBypassVec) 337 subDeqPolicyCancelBypassVec(1) := PriorityMux(Reverse(io.subDeqRequest.get(0)), cancelBypassVec.reverse) 338 339 io.deqEntry(0) := Mux(io.othersEntryOldestSel.get(0).valid, othersEntryOldest.get(0), subDeqPolicyEntryVec(1)) 340 io.deqEntry(1) := subDeqPolicyEntryVec(0) 341 io.cancelDeqVec(0) := Mux(io.othersEntryOldestSel.get(0).valid, othersEntryOldestCancel.get(0), subDeqPolicyCancelBypassVec(1)) 342 io.cancelDeqVec(1) := subDeqPolicyCancelBypassVec(0) 343 } 344 else { 345 subDeqPolicyEntryVec(0) := PriorityMux(Reverse(io.subDeqRequest.get(0)), entries.reverse) 346 subDeqPolicyEntryVec(1) := PriorityMux(io.subDeqRequest.get(0), entries) 347 subDeqPolicyCancelBypassVec(0) := PriorityMux(Reverse(io.subDeqRequest.get(0)), cancelBypassVec.reverse) 348 subDeqPolicyCancelBypassVec(1) := PriorityMux(io.subDeqRequest.get(0), cancelBypassVec) 349 350 io.deqEntry(0) := Mux(io.compEntryOldestSel.get(0).valid, 351 compEntryOldest.get(0), 352 Mux(io.simpEntryOldestSel.get(0).valid, simpEntryOldest.get(0), subDeqPolicyEntryVec(1))) 353 io.deqEntry(1) := subDeqPolicyEntryVec(0) 354 io.cancelDeqVec(0) := Mux(io.compEntryOldestSel.get(0).valid, 355 compEntryOldestCancel.get(0), 356 Mux(io.simpEntryOldestSel.get(0).valid, simpEntryOldestCancel.get(0), subDeqPolicyCancelBypassVec(1))) 357 io.cancelDeqVec(1) := subDeqPolicyCancelBypassVec(0) 358 } 359 360 when (subDeqPolicyValidVec(0)) { 361 assert(Mux1H(io.subDeqSelOH.get(0), entries).bits.status.robIdx === subDeqPolicyEntryVec(0).bits.status.robIdx, "subDeqSelOH(0) is not the same\n") 362 } 363 when (subDeqPolicyValidVec(1)) { 364 assert(Mux1H(io.subDeqSelOH.get(1), entries).bits.status.robIdx === subDeqPolicyEntryVec(1).bits.status.robIdx, "subDeqSelOH(1) is not the same\n") 365 } 366 } 367 else { 368 if (params.isAllComp || params.isAllSimp) { 369 io.othersEntryOldestSel.get.zipWithIndex.foreach { case (sel, i) => 370 io.deqEntry(i) := Mux(sel.valid, othersEntryOldest.get(i), enqEntryOldest(i)) 371 io.cancelDeqVec(i) := Mux(sel.valid, othersEntryOldestCancel.get(i), enqEntryOldestCancel(i)) 372 } 373 } 374 else { 375 io.compEntryOldestSel.get.zip(io.simpEntryOldestSel.get).zipWithIndex.foreach { case ((compSel, simpSel), i) => 376 io.deqEntry(i) := Mux(compSel.valid, 377 compEntryOldest.get(i), 378 Mux(simpSel.valid, simpEntryOldest.get(i), enqEntryOldest(i))) 379 io.cancelDeqVec(i) := Mux(compSel.valid, 380 compEntryOldestCancel.get(i), 381 Mux(simpSel.valid, simpEntryOldestCancel.get(i), enqEntryOldestCancel(i))) 382 } 383 } 384 } 385 386 io.valid := validVec.asUInt 387 io.canIssue := canIssueVec.asUInt 388 io.fuType := fuTypeVec 389 io.dataSources := dataSourceVec 390 io.srcWakeUpL1ExuOH.foreach(_ := srcWakeUpL1ExuOHVec.get.map(x => VecInit(x.map(_.asUInt)))) 391 io.loadDependency := loadDependencyVec 392 io.isFirstIssue.zipWithIndex.foreach{ case (isFirstIssue, deqIdx) => 393 isFirstIssue := io.deqSelOH(deqIdx).valid && Mux1H(io.deqSelOH(deqIdx).bits, isFirstIssueVec) 394 } 395 io.simpEntryEnqSelVec.foreach(_ := finalSimpTransSelVec.get.zip(enqEntryTransVec).map(x => x._1 & Fill(SimpEntryNum, x._2.valid))) 396 io.compEntryEnqSelVec.foreach(_ := finalCompTransSelVec.get.zip(compEnqVec.get).map(x => x._1 & Fill(CompEntryNum, x._2.valid))) 397 io.othersEntryEnqSelVec.foreach(_ := finalOthersTransSelVec.get.zip(enqEntryTransVec).map(x => x._1 & Fill(OthersEntryNum, x._2.valid))) 398 io.robIdx.foreach(_ := robIdxVec) 399 io.uopIdx.foreach(_ := uopIdxVec.get) 400 401 402 def EntriesConnect(in: CommonInBundle, out: CommonOutBundle, entryIdx: Int) = { 403 in.flush := io.flush 404 in.wakeUpFromWB := io.wakeUpFromWB 405 in.wakeUpFromIQ := io.wakeUpFromIQ 406 in.vlIsZero := io.vlIsZero 407 in.vlIsVlmax := io.vlIsVlmax 408 in.og0Cancel := io.og0Cancel 409 in.og1Cancel := io.og1Cancel 410 in.ldCancel := io.ldCancel 411 in.deqSel := deqSelVec(entryIdx) 412 in.deqPortIdxWrite := deqPortIdxWriteVec(entryIdx) 413 in.issueResp := issueRespVec(entryIdx) 414 if (params.isVecMemIQ) { 415 in.fromLsq.get.sqDeqPtr := io.vecMemIn.get.sqDeqPtr 416 in.fromLsq.get.lqDeqPtr := io.vecMemIn.get.lqDeqPtr 417 } 418 validVec(entryIdx) := out.valid 419 canIssueVec(entryIdx) := out.canIssue 420 fuTypeVec(entryIdx) := out.fuType 421 robIdxVec(entryIdx) := out.robIdx 422 dataSourceVec(entryIdx) := out.dataSource 423 isFirstIssueVec(entryIdx) := out.isFirstIssue 424 entries(entryIdx) := out.entry 425 deqPortIdxReadVec(entryIdx) := out.deqPortIdxRead 426 issueTimerVec(entryIdx) := out.issueTimerRead 427 loadDependencyVec(entryIdx) := out.entry.bits.status.mergedLoadDependency 428 cancelBypassVec(entryIdx) := out.cancelBypass 429 if (params.hasIQWakeUp) { 430 srcWakeUpL1ExuOHVec.get(entryIdx) := out.srcWakeUpL1ExuOH.get 431 } 432 if (params.isVecMemIQ) { 433 uopIdxVec.get(entryIdx) := out.uopIdx.get 434 } 435 entryInValidVec(entryIdx) := out.entryInValid 436 entryOutDeqValidVec(entryIdx) := out.entryOutDeqValid 437 entryOutTransValidVec(entryIdx) := out.entryOutTransValid 438 perfWakeupByWBVec(entryIdx) := out.perfWakeupByWB 439 if (params.hasIQWakeUp) { 440 perfLdCancelVec.get(entryIdx) := out.perfLdCancel.get 441 perfOg0CancelVec.get(entryIdx) := out.perfOg0Cancel.get 442 perfWakeupByIQVec.get(entryIdx) := out.perfWakeupByIQ.get 443 } 444 } 445 446 io.vecLdIn.foreach(dontTouch(_)) 447 448 // entries perf counter 449 // enq 450 for (i <- 0 until params.numEnq) { 451 XSPerfAccumulate(s"enqEntry_${i}_in_cnt", entryInValidVec(i)) 452 XSPerfAccumulate(s"enqEntry_${i}_out_deq_cnt", entryOutDeqValidVec(i)) 453 XSPerfAccumulate(s"enqEntry_${i}_out_trans_cnt", entryOutTransValidVec(i)) 454 } 455 // simple 456 for (i <- 0 until params.numSimp) { 457 XSPerfAccumulate(s"simpEntry_${i}_in_cnt", entryInValidVec(i + params.numEnq)) 458 XSPerfAccumulate(s"simpEntry_${i}_out_deq_cnt", entryOutDeqValidVec(i + params.numEnq)) 459 XSPerfAccumulate(s"simpEntry_${i}_out_trans_cnt", entryOutTransValidVec(i + params.numEnq)) 460 } 461 // complex 462 for (i <- 0 until params.numComp) { 463 XSPerfAccumulate(s"compEntry_${i}_in_cnt", entryInValidVec(i + params.numEnq + params.numSimp)) 464 XSPerfAccumulate(s"compEntry_${i}_out_deq_cnt", entryOutDeqValidVec(i + params.numEnq + params.numSimp)) 465 XSPerfAccumulate(s"compEntry_${i}_out_trans_cnt", entryOutTransValidVec(i + params.numEnq + params.numSimp)) 466 } 467 // total 468 XSPerfAccumulate(s"enqEntry_all_in_cnt", PopCount(entryInValidVec.take(params.numEnq))) 469 XSPerfAccumulate(s"enqEntry_all_out_deq_cnt", PopCount(entryOutDeqValidVec.take(params.numEnq))) 470 XSPerfAccumulate(s"enqEntry_all_out_trans_cnt", PopCount(entryOutTransValidVec.take(params.numEnq))) 471 for (srcIdx <- 0 until params.numRegSrc) { 472 XSPerfAccumulate(s"enqEntry_all_wakeup_wb_src${srcIdx}_cnt", PopCount(perfWakeupByWBVec.take(params.numEnq).map(_(srcIdx)))) 473 if (params.hasIQWakeUp) { 474 XSPerfAccumulate(s"enqEntry_all_ldCancel_src${srcIdx}_cnt", PopCount(perfLdCancelVec.get.take(params.numEnq).map(_(srcIdx)))) 475 XSPerfAccumulate(s"enqEntry_all_og0Cancel_src${srcIdx}_cnt", PopCount(perfOg0CancelVec.get.take(params.numEnq).map(_(srcIdx)))) 476 for (iqIdx <- 0 until params.numWakeupFromIQ) { 477 XSPerfAccumulate(s"enqEntry_all_wakeup_iq_from_exu${params.wakeUpSourceExuIdx(iqIdx)}_src${srcIdx}_cnt", PopCount(perfWakeupByIQVec.get.take(params.numEnq).map(_(srcIdx)(iqIdx)))) 478 } 479 } 480 } 481 482 XSPerfAccumulate(s"othersEntry_all_in_cnt", PopCount(entryInValidVec.drop(params.numEnq))) 483 XSPerfAccumulate(s"othersEntry_all_out_deq_cnt", PopCount(entryOutDeqValidVec.drop(params.numEnq))) 484 XSPerfAccumulate(s"othersEntry_all_out_trans_cnt", PopCount(entryOutTransValidVec.drop(params.numEnq))) 485 486 for (srcIdx <- 0 until params.numRegSrc) { 487 XSPerfAccumulate(s"othersEntry_all_wakeup_wb_src${srcIdx}_cnt", PopCount(perfWakeupByWBVec.drop(params.numEnq).map(_(srcIdx)))) 488 if (params.hasIQWakeUp) { 489 XSPerfAccumulate(s"othersEntry_all_ldCancel_src${srcIdx}_cnt", PopCount(perfLdCancelVec.get.drop(params.numEnq).map(_(srcIdx)))) 490 XSPerfAccumulate(s"othersEntry_all_og0Cancel_src${srcIdx}_cnt", PopCount(perfOg0CancelVec.get.drop(params.numEnq).map(_(srcIdx)))) 491 for (iqIdx <- 0 until params.numWakeupFromIQ) { 492 XSPerfAccumulate(s"othersEntry_all_wakeup_iq_from_exu${params.wakeUpSourceExuIdx(iqIdx)}_src${srcIdx}_cnt", PopCount(perfWakeupByIQVec.get.drop(params.numEnq).map(_(srcIdx)(iqIdx)))) 493 } 494 } 495 } 496 497 for (t <- FuType.functionNameMap.keys) { 498 val fuName = FuType.functionNameMap(t) 499 if (params.getFuCfgs.map(_.fuType == t).reduce(_ | _) && params.getFuCfgs.size > 1) { 500 for (srcIdx <- 0 until params.numRegSrc) { 501 XSPerfAccumulate(s"allEntry_futype_${fuName}_wakeup_wb_src${srcIdx}_cnt", PopCount(perfWakeupByWBVec.zip(fuTypeVec).map{ case(x, fu) => x(srcIdx) && fu(t.id) })) 502 if (params.hasIQWakeUp) { 503 XSPerfAccumulate(s"allEntry_futype_${fuName}_ldCancel_src${srcIdx}_cnt", PopCount(perfLdCancelVec.get.zip(fuTypeVec).map{ case(x, fu) => x(srcIdx) && fu(t.id) })) 504 XSPerfAccumulate(s"allEntry_futype_${fuName}_og0Cancel_src${srcIdx}_cnt", PopCount(perfOg0CancelVec.get.zip(fuTypeVec).map{ case(x, fu) => x(srcIdx) && fu(t.id) })) 505 for (iqIdx <- 0 until params.numWakeupFromIQ) { 506 XSPerfAccumulate(s"allEntry_futype_${fuName}_wakeup_iq_from_exu${params.wakeUpSourceExuIdx(iqIdx)}_src${srcIdx}_cnt", PopCount(perfWakeupByIQVec.get.zip(fuTypeVec).map{ case(x, fu) => x(srcIdx)(iqIdx) && fu(t.id) })) 507 } 508 } 509 } 510 } 511 } 512} 513 514class EntriesIO(implicit p: Parameters, params: IssueBlockParams) extends XSBundle { 515 val flush = Flipped(ValidIO(new Redirect)) 516 //enq 517 val enq = Vec(params.numEnq, Flipped(ValidIO(new EntryBundle))) 518 val og0Resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 519 val og1Resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 520 val og2Resp = OptionWrapper(params.inVfSchd, Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle)))) 521 //deq sel 522 val deqReady = Vec(params.numDeq, Input(Bool())) 523 val deqSelOH = Vec(params.numDeq, Flipped(ValidIO(UInt(params.numEntries.W)))) 524 val enqEntryOldestSel = Vec(params.numDeq, Flipped(ValidIO(UInt(params.numEnq.W)))) 525 val simpEntryOldestSel = OptionWrapper(params.hasCompAndSimp, Vec(params.numDeq, Flipped(ValidIO(UInt(params.numSimp.W))))) 526 val compEntryOldestSel = OptionWrapper(params.hasCompAndSimp, Vec(params.numDeq, Flipped(ValidIO(UInt(params.numComp.W))))) 527 val othersEntryOldestSel= OptionWrapper(params.isAllComp || params.isAllSimp, Vec(params.numDeq, Flipped(ValidIO(UInt((params.numEntries - params.numEnq).W))))) 528 val subDeqRequest = OptionWrapper(params.deqFuSame, Vec(params.numDeq, Input(UInt(params.numEntries.W)))) 529 val subDeqSelOH = OptionWrapper(params.deqFuSame, Vec(params.numDeq, Input(UInt(params.numEntries.W)))) 530 // wakeup 531 val wakeUpFromWB: MixedVec[ValidIO[IssueQueueWBWakeUpBundle]] = Flipped(params.genWBWakeUpSinkValidBundle) 532 val wakeUpFromIQ: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpSinkValidBundle) 533 val vlIsZero = Input(Bool()) 534 val vlIsVlmax = Input(Bool()) 535 val og0Cancel = Input(ExuOH(backendParams.numExu)) 536 val og1Cancel = Input(ExuOH(backendParams.numExu)) 537 val ldCancel = Vec(backendParams.LdExuCnt, Flipped(new LoadCancelIO)) 538 //entries status 539 val valid = Output(UInt(params.numEntries.W)) 540 val canIssue = Output(UInt(params.numEntries.W)) 541 val fuType = Vec(params.numEntries, Output(FuType())) 542 val dataSources = Vec(params.numEntries, Vec(params.numRegSrc, Output(DataSource()))) 543 val loadDependency = Vec(params.numEntries, Vec(LoadPipelineWidth, UInt(LoadDependencyWidth.W))) 544 val srcWakeUpL1ExuOH = OptionWrapper(params.hasIQWakeUp, Vec(params.numEntries, Vec(params.numRegSrc, Output(ExuOH())))) 545 //deq status 546 val isFirstIssue = Vec(params.numDeq, Output(Bool())) 547 val deqEntry = Vec(params.numDeq, ValidIO(new EntryBundle)) 548 val cancelDeqVec = Vec(params.numDeq, Output(Bool())) 549 550 // load/hybird only 551 val fromLoad = OptionWrapper(params.isLdAddrIQ || params.isHyAddrIQ, new Bundle { 552 val finalIssueResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 553 val memAddrIssueResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 554 }) 555 // mem only 556 val fromMem = OptionWrapper(params.isMemAddrIQ, new Bundle { 557 val slowResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 558 val fastResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 559 }) 560 // vec mem only 561 val vecMemIn = OptionWrapper(params.isVecMemIQ, new Bundle { 562 val sqDeqPtr = Input(new SqPtr) 563 val lqDeqPtr = Input(new LqPtr) 564 }) 565 val vecLdIn = OptionWrapper(params.isVecLduIQ, new Bundle { 566 val resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 567 }) 568 val robIdx = OptionWrapper(params.isVecMemIQ, Output(Vec(params.numEntries, new RobPtr))) 569 val uopIdx = OptionWrapper(params.isVecMemIQ, Output(Vec(params.numEntries, UopIdx()))) 570 571 // trans 572 val simpEntryDeqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Input(UInt(params.numSimp.W)))) 573 val simpEntryEnqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Output(UInt(params.numSimp.W)))) 574 val compEntryEnqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Output(UInt(params.numComp.W)))) 575 val othersEntryEnqSelVec = OptionWrapper(params.isAllComp || params.isAllSimp, Vec(params.numEnq, Output(UInt((params.numEntries - params.numEnq).W)))) 576 577 def wakeup = wakeUpFromWB ++ wakeUpFromIQ 578} 579