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