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