1package xiangshan.backend.issue 2 3import org.chipsalliance.cde.config.Parameters 4import chisel3._ 5import chisel3.util._ 6import utility.HasCircularQueuePtrHelper 7import utils.{MathUtils, OptionWrapper, XSError} 8import xiangshan._ 9import xiangshan.backend.Bundles._ 10import xiangshan.backend.datapath.DataConfig.VAddrData 11import xiangshan.backend.datapath.DataSource 12import xiangshan.backend.fu.FuType 13import xiangshan.backend.fu.vector.Utils.NOnes 14import xiangshan.backend.rob.RobPtr 15import xiangshan.mem.{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) 32 MixedVecInit(io.og0Resp ++ io.og1Resp ++ io.finalIssueResp.get) 33 else if (params.isLdAddrIQ && params.isStAddrIQ || params.isHyAddrIQ) 34 MixedVecInit(io.og0Resp ++ io.og1Resp ++ io.finalIssueResp.get ++ io.fromMem.get.fastResp ++ io.fromMem.get.slowResp) 35 else if (params.isMemAddrIQ) 36 MixedVecInit(io.og0Resp ++ io.og1Resp ++ io.fromMem.get.fastResp ++ io.fromMem.get.slowResp) 37 else MixedVecInit(Seq()) 38 } 39 40 val resps: Vec[Vec[ValidIO[EntryDeqRespBundle]]] = VecInit(io.og0Resp, io.og1Resp, 0.U.asTypeOf(io.og0Resp), 0.U.asTypeOf(io.og0Resp)) 41 42 //Module 43 val enqEntries = Seq.fill(EnqEntryNum)(Module(EnqEntry(isComp = true)(p, params))) 44 val othersEntriesSimp = Seq.fill(SimpEntryNum)(Module(OthersEntry(isComp = false)(p, params))) 45 val othersEntriesComp = Seq.fill(CompEntryNum)(Module(OthersEntry(isComp = true)(p, params))) 46 val othersEntries = othersEntriesSimp ++ othersEntriesComp 47 val othersTransPolicy = OptionWrapper(params.isAllComp || params.isAllSimp, Module(new EnqPolicy)) 48 val simpTransPolicy = OptionWrapper(params.hasCompAndSimp, Module(new EnqPolicy)) 49 val compTransPolicy = OptionWrapper(params.hasCompAndSimp, Module(new EnqPolicy)) 50 51 //Wire 52 //entries status 53 val entries = Wire(Vec(params.numEntries, ValidIO(new EntryBundle))) 54 val robIdxVec = Wire(Vec(params.numEntries, new RobPtr)) 55 val validVec = Wire(Vec(params.numEntries, Bool())) 56 val canIssueVec = Wire(Vec(params.numEntries, Bool())) 57 val fuTypeVec = Wire(Vec(params.numEntries, FuType())) 58 val isFirstIssueVec = Wire(Vec(params.numEntries, Bool())) 59 val issueTimerVec = Wire(Vec(params.numEntries, UInt(2.W))) 60 //src status 61 val dataSourceVec = Wire(Vec(params.numEntries, Vec(params.numRegSrc, DataSource()))) 62 val loadDependencyVec = Wire(Vec(params.numEntries, Vec(LoadPipelineWidth, UInt(3.W)))) 63 val srcLoadDependencyVec= Wire(Vec(params.numEntries, Vec(params.numRegSrc, Vec(LoadPipelineWidth, UInt(3.W))))) 64 val srcTimerVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Vec(params.numRegSrc, UInt(3.W))))) 65 val srcWakeUpL1ExuOHVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Vec(params.numRegSrc, ExuVec())))) 66 //deq sel 67 val deqSelVec = Wire(Vec(params.numEntries, Bool())) 68 val issueRespVec = Wire(Vec(params.numEntries, ValidIO(new EntryDeqRespBundle))) 69 val deqPortIdxWriteVec = Wire(Vec(params.numEntries, UInt(1.W))) 70 val deqPortIdxReadVec = Wire(Vec(params.numEntries, UInt(1.W))) 71 //trans sel 72 val othersEntryEnqReadyVec = Wire(Vec(OthersEntryNum, Bool())) 73 val othersEntryEnqVec = Wire(Vec(OthersEntryNum, Valid(new EntryBundle))) 74 val enqEntryTransVec = Wire(Vec(EnqEntryNum, Valid(new EntryBundle))) 75 val simpEntryTransVec = OptionWrapper(params.hasCompAndSimp, Wire(Vec(SimpEntryNum, Valid(new EntryBundle)))) 76 val compEnqVec = OptionWrapper(params.hasCompAndSimp, Wire(Vec(EnqEntryNum, Valid(new EntryBundle)))) 77 78 val enqCanTrans2Simp = OptionWrapper(params.hasCompAndSimp, Wire(Bool())) 79 val enqCanTrans2Comp = OptionWrapper(params.hasCompAndSimp, Wire(Bool())) 80 val simpCanTrans2Comp = OptionWrapper(params.hasCompAndSimp, Wire(Vec(EnqEntryNum, Bool()))) 81 val simpTransSelVec = OptionWrapper(params.hasCompAndSimp, Wire(Vec(EnqEntryNum, Valid(UInt(SimpEntryNum.W))))) 82 val compTransSelVec = OptionWrapper(params.hasCompAndSimp, Wire(Vec(EnqEntryNum, Valid(UInt(CompEntryNum.W))))) 83 val finalSimpTransSelVec = OptionWrapper(params.hasCompAndSimp, Wire(Vec(EnqEntryNum, UInt(SimpEntryNum.W)))) 84 val finalCompTransSelVec = OptionWrapper(params.hasCompAndSimp, Wire(Vec(EnqEntryNum, UInt(CompEntryNum.W)))) 85 86 val enqCanTrans2Others = OptionWrapper(params.isAllComp || params.isAllSimp, Wire(Bool())) 87 val othersTransSelVec = OptionWrapper(params.isAllComp || params.isAllSimp, Wire(Vec(EnqEntryNum, Valid(UInt(OthersEntryNum.W))))) 88 val finalOthersTransSelVec = OptionWrapper(params.isAllComp || params.isAllSimp, Wire(Vec(EnqEntryNum, UInt(OthersEntryNum.W)))) 89 90 val simpEntryEnqReadyVec = othersEntryEnqReadyVec.take(SimpEntryNum) 91 val compEntryEnqReadyVec = othersEntryEnqReadyVec.takeRight(CompEntryNum) 92 val simpEntryEnqVec = othersEntryEnqVec.take(SimpEntryNum) 93 val compEntryEnqVec = othersEntryEnqVec.takeRight(CompEntryNum) 94 //debug 95 val cancelVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Bool()))) 96 //cancel bypass 97 val cancelBypassVec = Wire(Vec(params.numEntries, Bool())) 98 val uopIdxVec = OptionWrapper(params.isVecMemIQ, Wire(Vec(params.numEntries, UopIdx()))) 99 100 101 //enqEntries 102 enqEntries.zipWithIndex.foreach { case (enqEntry, entryIdx) => 103 enqEntry.io.commonIn.enq := io.enq(entryIdx) 104 enqEntry.io.commonIn.transSel := (if (params.isAllComp || params.isAllSimp) enqCanTrans2Others.get && othersTransSelVec.get(entryIdx).valid 105 else enqCanTrans2Simp.get && simpTransSelVec.get(entryIdx).valid || enqCanTrans2Comp.get && compTransSelVec.get(entryIdx).valid) 106 EntriesConnect(enqEntry.io.commonIn, enqEntry.io.commonOut, entryIdx) 107 enqEntry.io.enqDelayWakeUpFromWB := RegNext(io.wakeUpFromWB) 108 enqEntry.io.enqDelayWakeUpFromIQ := RegNext(io.wakeUpFromIQ) 109 enqEntry.io.enqDelayOg0Cancel := RegNext(io.og0Cancel.asUInt) 110 enqEntry.io.enqDelayLdCancel := RegNext(io.ldCancel) 111 enqEntryTransVec(entryIdx) := enqEntry.io.commonOut.transEntry 112 // TODO: move it into EntriesConnect 113 if (params.isVecMemIQ) { 114 enqEntry.io.commonIn.fromLsq.get.sqDeqPtr := io.vecMemIn.get.sqDeqPtr 115 enqEntry.io.commonIn.fromLsq.get.lqDeqPtr := io.vecMemIn.get.lqDeqPtr 116 } 117 } 118 //othersEntries 119 othersEntries.zipWithIndex.foreach { case (othersEntry, entryIdx) => 120 othersEntry.io.commonIn.enq := othersEntryEnqVec(entryIdx) 121 othersEntry.io.commonIn.transSel := (if (params.hasCompAndSimp && (entryIdx < SimpEntryNum)) 122 io.simpEntryDeqSelVec.get.zip(simpCanTrans2Comp.get).map(x => x._1(entryIdx) && x._2).reduce(_ | _) 123 else false.B) 124 EntriesConnect(othersEntry.io.commonIn, othersEntry.io.commonOut, entryIdx + EnqEntryNum) 125 othersEntryEnqReadyVec(entryIdx) := othersEntry.io.commonOut.enqReady 126 if (params.hasCompAndSimp && (entryIdx < SimpEntryNum)) { 127 simpEntryTransVec.get(entryIdx) := othersEntry.io.commonOut.transEntry 128 } 129 if (params.isVecMemIQ) { 130 othersEntry.io.commonIn.fromLsq.get.sqDeqPtr := io.vecMemIn.get.sqDeqPtr 131 othersEntry.io.commonIn.fromLsq.get.lqDeqPtr := io.vecMemIn.get.lqDeqPtr 132 } 133 } 134 135 136 deqSelVec.zip(deqPortIdxWriteVec).zipWithIndex.foreach { case ((deqSel, deqPortIdxWrite), i) => 137 val deqVec = io.deqSelOH.zip(io.deqReady).map(x => x._1.valid && x._1.bits(i) && x._2) 138 deqPortIdxWrite := OHToUInt(deqVec) 139 deqSel := deqVec.reduce(_ | _) 140 } 141 142 143 if (params.isAllComp || params.isAllSimp) { 144 //transPolicy 145 othersTransPolicy.get.io.canEnq := othersEntryEnqReadyVec.asUInt 146 enqCanTrans2Others.get := PopCount(validVec.take(EnqEntryNum)) <= PopCount(othersEntryEnqReadyVec) 147 othersTransSelVec.get(0).valid := othersTransPolicy.get.io.enqSelOHVec(0).valid && validVec(0) 148 othersTransSelVec.get(0).bits := othersTransPolicy.get.io.enqSelOHVec(0).bits 149 // Todo: comments why enqTransSelVec(1).valid relies on validVec(0) 150 if (params.numEnq == 2) { 151 othersTransSelVec.get(1).valid := Mux(!validVec(0), othersTransPolicy.get.io.enqSelOHVec(0).valid, othersTransPolicy.get.io.enqSelOHVec(1).valid) 152 othersTransSelVec.get(1).bits := Mux(!validVec(0), othersTransPolicy.get.io.enqSelOHVec(0).bits, othersTransPolicy.get.io.enqSelOHVec(1).bits) 153 } 154 155 finalOthersTransSelVec.get.zip(othersTransSelVec.get).zipWithIndex.foreach { case ((finalOH, selOH), enqIdx) => 156 finalOH := Fill(OthersEntryNum, enqCanTrans2Others.get && selOH.valid) & selOH.bits 157 } 158 159 //othersEntryEnq 160 othersEntryEnqVec.zipWithIndex.foreach { case (othersEntryEnq, othersIdx) => 161 val othersEnqOH = finalOthersTransSelVec.get.map(_(othersIdx)) 162 if (othersEnqOH.size == 1) 163 othersEntryEnq := Mux(othersEnqOH.head, enqEntryTransVec.head, 0.U.asTypeOf(enqEntryTransVec.head)) 164 else 165 othersEntryEnq := Mux1H(othersEnqOH, enqEntryTransVec) 166 } 167 } 168 else { 169 //transPolicy 170 simpTransPolicy.get.io.canEnq := VecInit(simpEntryEnqReadyVec).asUInt 171 compTransPolicy.get.io.canEnq := VecInit(validVec.takeRight(CompEntryNum).map(!_)).asUInt 172 173 enqCanTrans2Comp.get := PopCount(validVec.take(EnqEntryNum)) <= PopCount(validVec.takeRight(CompEntryNum).map(!_)) && !validVec.drop(EnqEntryNum).take(SimpEntryNum).reduce(_ || _) 174 enqCanTrans2Simp.get := !enqCanTrans2Comp.get && PopCount(validVec.take(EnqEntryNum)) <= PopCount(simpEntryEnqReadyVec) 175 simpCanTrans2Comp.get.zipWithIndex.foreach { case (canTrans, idx) => 176 canTrans := !enqCanTrans2Comp.get && PopCount(validVec.takeRight(CompEntryNum).map(!_)) >= (idx + 1).U 177 } 178 179 simpTransSelVec.get(0).valid := simpTransPolicy.get.io.enqSelOHVec(0).valid && validVec(0) 180 simpTransSelVec.get(0).bits := simpTransPolicy.get.io.enqSelOHVec(0).bits 181 compTransSelVec.get(0).valid := compTransPolicy.get.io.enqSelOHVec(0).valid && validVec(0) 182 compTransSelVec.get(0).bits := compTransPolicy.get.io.enqSelOHVec(0).bits 183 if (params.numEnq == 2) { 184 simpTransSelVec.get(1).valid := Mux(!validVec(0), simpTransPolicy.get.io.enqSelOHVec(0).valid, simpTransPolicy.get.io.enqSelOHVec(1).valid) 185 simpTransSelVec.get(1).bits := Mux(!validVec(0), simpTransPolicy.get.io.enqSelOHVec(0).bits, simpTransPolicy.get.io.enqSelOHVec(1).bits) 186 compTransSelVec.get(1).valid := Mux(!validVec(0), compTransPolicy.get.io.enqSelOHVec(0).valid, compTransPolicy.get.io.enqSelOHVec(1).valid) 187 compTransSelVec.get(1).bits := Mux(!validVec(0), compTransPolicy.get.io.enqSelOHVec(0).bits, compTransPolicy.get.io.enqSelOHVec(1).bits) 188 } 189 190 finalSimpTransSelVec.get.zip(simpTransSelVec.get).zipWithIndex.foreach { case ((finalOH, selOH), enqIdx) => 191 finalOH := Fill(SimpEntryNum, enqCanTrans2Simp.get && selOH.valid) & selOH.bits 192 } 193 finalCompTransSelVec.get.zip(compTransSelVec.get).zip(compTransPolicy.get.io.enqSelOHVec).zipWithIndex.foreach { 194 case (((finalOH, selOH), origSelOH), enqIdx) => 195 finalOH := Mux(enqCanTrans2Comp.get, Fill(CompEntryNum, selOH.valid) & selOH.bits, Fill(CompEntryNum, origSelOH.valid) & origSelOH.bits) 196 } 197 198 //othersEntryEnq 199 simpEntryEnqVec.zipWithIndex.foreach { case (simpEntryEnq, simpIdx) => 200 val simpEnqOH = finalSimpTransSelVec.get.map(_(simpIdx)) 201 // shit Mux1H directly returns in(0) if the seq has only 1 elements 202 if (simpEnqOH.size == 1) 203 simpEntryEnq := Mux(simpEnqOH.head, enqEntryTransVec.head, 0.U.asTypeOf(enqEntryTransVec.head)) 204 else 205 simpEntryEnq := Mux1H(simpEnqOH, enqEntryTransVec) 206 } 207 208 compEnqVec.get.zip(enqEntryTransVec).zip(io.simpEntryDeqSelVec.get).foreach { case ((compEnq, enqEntry), deqSel) => 209 compEnq := Mux(enqCanTrans2Comp.get, enqEntry, Mux1H(deqSel, simpEntryTransVec.get)) 210 } 211 compEntryEnqVec.zipWithIndex.foreach { case (compEntryEnq, compIdx) => 212 val compEnqOH = finalCompTransSelVec.get.map(_(compIdx)) 213 // shit Mux1H directly returns in(0) if the seq has only 1 elements 214 if (compEnqOH.size == 1) 215 compEntryEnq := Mux(compEnqOH.head, compEnqVec.get.head, 0.U.asTypeOf(compEnqVec.get.head)) 216 else 217 compEntryEnq := Mux1H(compEnqOH, compEnqVec.get) 218 } 219 220 assert(PopCount(simpEntryEnqVec.map(_.valid)) <= params.numEnq.U, "the number of simpEntryEnq is more than numEnq\n") 221 assert(PopCount(compEntryEnqVec.map(_.valid)) <= params.numEnq.U, "the number of compEntryEnq is more than numEnq\n") 222 } 223 224 if(backendParams.debugEn) { 225 dontTouch(othersEntryEnqVec) 226 } 227 228 //issueRespVec 229 if (params.isVecMemIQ) { 230 // vector memory IQ 231 issueRespVec.zip(robIdxVec).zip(uopIdxVec.get).foreach { case ((issueResp, robIdx), uopIdx) => 232 val hitRespsVec = VecInit(resps.flatten.map(x => 233 x.valid && x.bits.robIdx === robIdx && x.bits.uopIdx.get === uopIdx 234 )) 235 issueResp.valid := hitRespsVec.reduce(_ | _) 236 issueResp.bits := Mux1H(hitRespsVec, resps.flatten.map(_.bits)) 237 } 238 } else if (params.isMemAddrIQ) { 239 // scalar memory IQ 240 issueRespVec.zip(robIdxVec).foreach { case (issueResp, robIdx) => 241 val hitRespsVec = VecInit(memEtyResps.map(x => x.valid && (x.bits.robIdx === robIdx)).toSeq) 242 issueResp.valid := hitRespsVec.reduce(_ | _) 243 issueResp.bits := Mux1H(hitRespsVec, memEtyResps.map(_.bits).toSeq) 244 } 245 } 246 else { 247 issueRespVec.zip(issueTimerVec).zip(deqPortIdxReadVec).foreach { case ((issueResp, issueTimer), deqPortIdx) => 248 val Resp = resps(issueTimer)(deqPortIdx) 249 issueResp := Resp 250 } 251 } 252 253 //deq 254 val enqEntryOldest = Wire(Vec(params.numDeq, ValidIO(new EntryBundle))) 255 val simpEntryOldest = OptionWrapper(params.hasCompAndSimp, Wire(Vec(params.numDeq, ValidIO(new EntryBundle)))) 256 val compEntryOldest = OptionWrapper(params.hasCompAndSimp, Wire(Vec(params.numDeq, ValidIO(new EntryBundle)))) 257 val othersEntryOldest = OptionWrapper(params.isAllComp || params.isAllSimp, Wire(Vec(params.numDeq, ValidIO(new EntryBundle)))) 258 val enqEntryOldestCancel = Wire(Vec(params.numDeq, Bool())) 259 val simpEntryOldestCancel = OptionWrapper(params.hasCompAndSimp, Wire(Vec(params.numDeq, Bool()))) 260 val compEntryOldestCancel = OptionWrapper(params.hasCompAndSimp, Wire(Vec(params.numDeq, Bool()))) 261 val othersEntryOldestCancel = OptionWrapper(params.isAllComp || params.isAllSimp, Wire(Vec(params.numDeq, Bool()))) 262 263 io.enqEntryOldestSel.zipWithIndex.map { case (sel, deqIdx) => 264 enqEntryOldest(deqIdx) := Mux1H(sel.bits, entries.take(EnqEntryNum)) 265 enqEntryOldestCancel(deqIdx) := Mux1H(sel.bits, cancelBypassVec.take(EnqEntryNum)) 266 } 267 268 if (params.isAllComp || params.isAllSimp) { 269 io.othersEntryOldestSel.get.zipWithIndex.map { case (sel, deqIdx) => 270 othersEntryOldest.get(deqIdx) := Mux1H(sel.bits, entries.drop(EnqEntryNum)) 271 othersEntryOldestCancel.get(deqIdx) := Mux1H(sel.bits, cancelBypassVec.drop(EnqEntryNum)) 272 } 273 } 274 else { 275 io.simpEntryOldestSel.get.zipWithIndex.map { case (sel, deqIdx) => 276 simpEntryOldest.get(deqIdx) := Mux1H(sel.bits, entries.drop(EnqEntryNum).take(SimpEntryNum)) 277 simpEntryOldestCancel.get(deqIdx) := Mux1H(sel.bits, cancelBypassVec.drop(EnqEntryNum).take(SimpEntryNum)) 278 } 279 io.compEntryOldestSel.get.zipWithIndex.map { case (sel, deqIdx) => 280 compEntryOldest.get(deqIdx) := Mux1H(sel.bits, entries.drop(EnqEntryNum).takeRight(CompEntryNum)) 281 compEntryOldestCancel.get(deqIdx) := Mux1H(sel.bits, cancelBypassVec.drop(EnqEntryNum).takeRight(CompEntryNum)) 282 } 283 } 284 285 if (params.deqFuSame) { 286 val subDeqPolicyEntryVec = Wire(Vec(params.numDeq, ValidIO(new EntryBundle))) 287 val subDeqPolicyValidVec = Wire(Vec(params.numDeq, Bool())) 288 val subDeqPolicyCancelBypassVec = Wire(Vec(params.numDeq, Bool())) 289 290 subDeqPolicyValidVec(0) := PopCount(io.subDeqRequest.get(0)) >= 1.U 291 subDeqPolicyValidVec(1) := PopCount(io.subDeqRequest.get(0)) >= 2.U 292 293 if (params.isAllComp || params.isAllSimp) { 294 subDeqPolicyEntryVec(0) := PriorityMux(io.subDeqRequest.get(0), entries) 295 subDeqPolicyEntryVec(1) := PriorityMux(Reverse(io.subDeqRequest.get(0)), entries.reverse) 296 subDeqPolicyCancelBypassVec(0) := PriorityMux(io.subDeqRequest.get(0), cancelBypassVec) 297 subDeqPolicyCancelBypassVec(1) := PriorityMux(Reverse(io.subDeqRequest.get(0)), cancelBypassVec.reverse) 298 299 io.deqEntry(0) := Mux(io.othersEntryOldestSel.get(0).valid, othersEntryOldest.get(0), subDeqPolicyEntryVec(1)) 300 io.deqEntry(1) := subDeqPolicyEntryVec(0) 301 io.cancelDeqVec(0) := Mux(io.othersEntryOldestSel.get(0).valid, othersEntryOldestCancel.get(0), subDeqPolicyCancelBypassVec(1)) 302 io.cancelDeqVec(1) := subDeqPolicyCancelBypassVec(0) 303 } 304 else { 305 subDeqPolicyEntryVec(0) := PriorityMux(Reverse(io.subDeqRequest.get(0)), entries.reverse) 306 subDeqPolicyEntryVec(1) := PriorityMux(io.subDeqRequest.get(0), entries) 307 subDeqPolicyCancelBypassVec(0) := PriorityMux(Reverse(io.subDeqRequest.get(0)), cancelBypassVec.reverse) 308 subDeqPolicyCancelBypassVec(1) := PriorityMux(io.subDeqRequest.get(0), cancelBypassVec) 309 310 io.deqEntry(0) := Mux(io.compEntryOldestSel.get(0).valid, 311 compEntryOldest.get(0), 312 Mux(io.simpEntryOldestSel.get(0).valid, simpEntryOldest.get(0), subDeqPolicyEntryVec(1))) 313 io.deqEntry(1) := subDeqPolicyEntryVec(0) 314 io.cancelDeqVec(0) := Mux(io.compEntryOldestSel.get(0).valid, 315 compEntryOldestCancel.get(0), 316 Mux(io.simpEntryOldestSel.get(0).valid, simpEntryOldestCancel.get(0), subDeqPolicyCancelBypassVec(1))) 317 io.cancelDeqVec(1) := subDeqPolicyCancelBypassVec(0) 318 } 319 320 when (subDeqPolicyValidVec(0)) { 321 assert(Mux1H(io.subDeqSelOH.get(0), entries).bits.status.robIdx === subDeqPolicyEntryVec(0).bits.status.robIdx, "subDeqSelOH(0) is not the same\n") 322 } 323 when (subDeqPolicyValidVec(1)) { 324 assert(Mux1H(io.subDeqSelOH.get(1), entries).bits.status.robIdx === subDeqPolicyEntryVec(1).bits.status.robIdx, "subDeqSelOH(1) is not the same\n") 325 } 326 } 327 else { 328 if (params.isAllComp || params.isAllSimp) { 329 io.othersEntryOldestSel.get.zipWithIndex.foreach { case (sel, i) => 330 io.deqEntry(i) := Mux(sel.valid, othersEntryOldest.get(i), enqEntryOldest(i)) 331 io.cancelDeqVec(i) := Mux(sel.valid, othersEntryOldestCancel.get(i), enqEntryOldestCancel(i)) 332 } 333 } 334 else { 335 io.compEntryOldestSel.get.zip(io.simpEntryOldestSel.get).zipWithIndex.foreach { case ((compSel, simpSel), i) => 336 io.deqEntry(i) := Mux(compSel.valid, 337 compEntryOldest.get(i), 338 Mux(simpSel.valid, simpEntryOldest.get(i), enqEntryOldest(i))) 339 io.cancelDeqVec(i) := Mux(compSel.valid, 340 compEntryOldestCancel.get(i), 341 Mux(simpSel.valid, simpEntryOldestCancel.get(i), enqEntryOldestCancel(i))) 342 } 343 } 344 } 345 346 if (params.hasIQWakeUp) { 347 cancelBypassVec.zip(srcWakeUpL1ExuOHVec.get).zip(srcTimerVec.get).zip(srcLoadDependencyVec).foreach{ case (((cancelBypass: Bool, l1ExuOH: Vec[Vec[Bool]]), srcTimer: Vec[UInt]), srcLoadDependency: Vec[Vec[UInt]]) => 348 val cancelByOg0 = l1ExuOH.zip(srcTimer).map { 349 case(exuOH, srcTimer) => 350 (exuOH.asUInt & io.og0Cancel.asUInt).orR && srcTimer === 1.U 351 }.reduce(_ | _) 352 val cancelByLd = srcLoadDependency.map(x => LoadShouldCancel(Some(x), io.ldCancel)).reduce(_ | _) 353 cancelBypass := cancelByOg0 || cancelByLd 354 } 355 } else { 356 cancelBypassVec.zip(srcLoadDependencyVec).foreach { case (cancelBypass, srcLoadDependency) => 357 val cancelByLd = srcLoadDependency.map(x => LoadShouldCancel(Some(x), io.ldCancel)).reduce(_ | _) 358 cancelBypass := cancelByLd 359 } 360 } 361 362 io.valid := validVec.asUInt 363 io.canIssue := canIssueVec.asUInt 364 io.fuType := fuTypeVec 365 io.dataSources := dataSourceVec 366 io.srcWakeUpL1ExuOH.foreach(_ := srcWakeUpL1ExuOHVec.get.map(x => VecInit(x.map(_.asUInt)))) 367 io.srcTimer.foreach(_ := srcTimerVec.get) 368 io.loadDependency := loadDependencyVec 369 io.isFirstIssue.zipWithIndex.foreach{ case (isFirstIssue, deqIdx) => 370 isFirstIssue := io.deqSelOH(deqIdx).valid && Mux1H(io.deqSelOH(deqIdx).bits, isFirstIssueVec) 371 } 372 io.simpEntryEnqSelVec.foreach(_ := finalSimpTransSelVec.get.zip(enqEntryTransVec).map(x => x._1 & Fill(SimpEntryNum, x._2.valid))) 373 io.compEntryEnqSelVec.foreach(_ := finalCompTransSelVec.get.zip(compEnqVec.get).map(x => x._1 & Fill(CompEntryNum, x._2.valid))) 374 io.othersEntryEnqSelVec.foreach(_ := finalOthersTransSelVec.get.zip(enqEntryTransVec).map(x => x._1 & Fill(OthersEntryNum, x._2.valid))) 375 io.robIdx.foreach(_ := robIdxVec) 376 io.uopIdx.foreach(_ := uopIdxVec.get) 377 io.rsFeedback := 0.U.asTypeOf(io.rsFeedback) //should be removed 378 io.cancel.foreach(_ := cancelVec.get) //for debug 379 380 def EntriesConnect(in: CommonInBundle, out: CommonOutBundle, entryIdx: Int) = { 381 in.flush := io.flush 382 in.wakeUpFromWB := io.wakeUpFromWB 383 in.wakeUpFromIQ := io.wakeUpFromIQ 384 in.og0Cancel := io.og0Cancel 385 in.og1Cancel := io.og1Cancel 386 in.ldCancel := io.ldCancel 387 in.deqSel := deqSelVec(entryIdx) 388 in.deqPortIdxWrite := deqPortIdxWriteVec(entryIdx) 389 in.issueResp := issueRespVec(entryIdx) 390 if (params.isMemAddrIQ) { 391 in.fromMem.get.stIssuePtr := io.fromMem.get.stIssuePtr 392 in.fromMem.get.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 393 } 394 if (params.isVecMemIQ) { 395 in.fromLsq.get.sqDeqPtr := io.vecMemIn.get.sqDeqPtr 396 in.fromLsq.get.lqDeqPtr := io.vecMemIn.get.lqDeqPtr 397 } 398 validVec(entryIdx) := out.valid 399 canIssueVec(entryIdx) := out.canIssue 400 fuTypeVec(entryIdx) := out.fuType 401 robIdxVec(entryIdx) := out.robIdx 402 dataSourceVec(entryIdx) := out.dataSource 403 isFirstIssueVec(entryIdx) := out.isFirstIssue 404 entries(entryIdx) := out.entry 405 deqPortIdxReadVec(entryIdx) := out.deqPortIdxRead 406 issueTimerVec(entryIdx) := out.issueTimerRead 407 srcLoadDependencyVec(entryIdx) := out.srcLoadDependency 408 loadDependencyVec(entryIdx) := out.entry.bits.status.mergedLoadDependency 409 if (params.hasIQWakeUp) { 410 srcWakeUpL1ExuOHVec.get(entryIdx) := out.srcWakeUpL1ExuOH.get 411 srcTimerVec.get(entryIdx) := out.srcTimer.get 412 cancelVec.get(entryIdx) := out.cancel.get 413 } 414 if (params.isVecMemIQ) { 415 uopIdxVec.get(entryIdx) := out.uopIdx.get 416 } 417 } 418} 419 420class EntriesIO(implicit p: Parameters, params: IssueBlockParams) extends XSBundle { 421 val flush = Flipped(ValidIO(new Redirect)) 422 //enq 423 val enq = Vec(params.numEnq, Flipped(ValidIO(new EntryBundle))) 424 val og0Resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 425 val og1Resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 426 val finalIssueResp = OptionWrapper(params.LdExuCnt > 0, Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle)))) 427 //deq sel 428 val deqReady = Vec(params.numDeq, Input(Bool())) 429 val deqSelOH = Vec(params.numDeq, Flipped(ValidIO(UInt(params.numEntries.W)))) 430 val enqEntryOldestSel = Vec(params.numDeq, Flipped(ValidIO(UInt(params.numEnq.W)))) 431 val simpEntryOldestSel = OptionWrapper(params.hasCompAndSimp, Vec(params.numDeq, Flipped(ValidIO(UInt(params.numSimp.W))))) 432 val compEntryOldestSel = OptionWrapper(params.hasCompAndSimp, Vec(params.numDeq, Flipped(ValidIO(UInt(params.numComp.W))))) 433 val othersEntryOldestSel= OptionWrapper(params.isAllComp || params.isAllSimp, Vec(params.numDeq, Flipped(ValidIO(UInt((params.numEntries - params.numEnq).W))))) 434 val subDeqRequest = OptionWrapper(params.deqFuSame, Vec(params.numDeq, Input(UInt(params.numEntries.W)))) 435 val subDeqSelOH = OptionWrapper(params.deqFuSame, Vec(params.numDeq, Input(UInt(params.numEntries.W)))) 436 // wakeup 437 val wakeUpFromWB: MixedVec[ValidIO[IssueQueueWBWakeUpBundle]] = Flipped(params.genWBWakeUpSinkValidBundle) 438 val wakeUpFromIQ: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpSinkValidBundle) 439 val og0Cancel = Input(ExuOH(backendParams.numExu)) 440 val og1Cancel = Input(ExuOH(backendParams.numExu)) 441 val ldCancel = Vec(backendParams.LdExuCnt, Flipped(new LoadCancelIO)) 442 //entries status 443 val valid = Output(UInt(params.numEntries.W)) 444 val canIssue = Output(UInt(params.numEntries.W)) 445 val fuType = Vec(params.numEntries, Output(FuType())) 446 val dataSources = Vec(params.numEntries, Vec(params.numRegSrc, Output(DataSource()))) 447 val loadDependency = Vec(params.numEntries, Vec(LoadPipelineWidth, UInt(3.W))) 448 val srcWakeUpL1ExuOH = OptionWrapper(params.hasIQWakeUp, Vec(params.numEntries, Vec(params.numRegSrc, Output(ExuOH())))) 449 val srcTimer = OptionWrapper(params.hasIQWakeUp, Vec(params.numEntries, Vec(params.numRegSrc, Output(UInt(3.W))))) 450 //deq status 451 val isFirstIssue = Vec(params.numDeq, Output(Bool())) 452 val deqEntry = Vec(params.numDeq, ValidIO(new EntryBundle)) 453 val cancelDeqVec = Vec(params.numDeq, Output(Bool())) 454 // mem only 455 val fromMem = if (params.isMemAddrIQ) Some(new Bundle { 456 val stIssuePtr = Input(new SqPtr) 457 val memWaitUpdateReq = Flipped(new MemWaitUpdateReq) 458 val slowResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 459 val fastResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 460 }) else None 461 val vecMemIn = OptionWrapper(params.isVecMemIQ, new Bundle { 462 val sqDeqPtr = Input(new SqPtr) 463 val lqDeqPtr = Input(new LqPtr) 464 }) 465 466 val robIdx = OptionWrapper(params.isVecMemIQ, Output(Vec(params.numEntries, new RobPtr))) 467 val uopIdx = OptionWrapper(params.isVecMemIQ, Output(Vec(params.numEntries, UopIdx()))) 468 469 val rsFeedback = Output(Vec(5, Bool())) 470 // trans 471 val simpEntryDeqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Input(UInt(params.numSimp.W)))) 472 val simpEntryEnqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Output(UInt(params.numSimp.W)))) 473 val compEntryEnqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Output(UInt(params.numComp.W)))) 474 val othersEntryEnqSelVec = OptionWrapper(params.isAllComp || params.isAllSimp, Vec(params.numEnq, Output(UInt((params.numEntries - params.numEnq).W)))) 475 476 // debug 477 val cancel = OptionWrapper(params.hasIQWakeUp, Output(Vec(params.numEntries, Bool()))) 478 479 def wakeup = wakeUpFromWB ++ wakeUpFromIQ 480} 481