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