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.vlIsZero := io.vlIsZero 413 in.vlIsVlmax := io.vlIsVlmax 414 in.og0Cancel := io.og0Cancel 415 in.og1Cancel := io.og1Cancel 416 in.ldCancel := io.ldCancel 417 in.deqSel := deqSelVec(entryIdx) 418 in.deqPortIdxWrite := deqPortIdxWriteVec(entryIdx) 419 in.issueResp := issueRespVec(entryIdx) 420 if (params.isVecMemIQ) { 421 in.fromLsq.get.sqDeqPtr := io.vecMemIn.get.sqDeqPtr 422 in.fromLsq.get.lqDeqPtr := io.vecMemIn.get.lqDeqPtr 423 } 424 validVec(entryIdx) := out.valid 425 canIssueVec(entryIdx) := out.canIssue 426 fuTypeVec(entryIdx) := out.fuType 427 robIdxVec(entryIdx) := out.robIdx 428 dataSourceVec(entryIdx) := out.dataSource 429 isFirstIssueVec(entryIdx) := out.isFirstIssue 430 entries(entryIdx) := out.entry 431 deqPortIdxReadVec(entryIdx) := out.deqPortIdxRead 432 issueTimerVec(entryIdx) := out.issueTimerRead 433 srcLoadDependencyVec(entryIdx) := out.srcLoadDependency 434 loadDependencyVec(entryIdx) := out.entry.bits.status.mergedLoadDependency 435 if (params.hasIQWakeUp) { 436 srcWakeUpL1ExuOHVec.get(entryIdx) := out.srcWakeUpL1ExuOH.get 437 srcTimerVec.get(entryIdx) := out.srcTimer.get 438 cancelVec.get(entryIdx) := out.cancel.get 439 } 440 if (params.isVecMemIQ) { 441 uopIdxVec.get(entryIdx) := out.uopIdx.get 442 } 443 entryInValidVec(entryIdx) := out.entryInValid 444 entryOutDeqValidVec(entryIdx) := out.entryOutDeqValid 445 entryOutTransValidVec(entryIdx) := out.entryOutTransValid 446 } 447 448 // entries perf counter 449 // enq 450 for (i <- 0 until params.numEnq) { 451 XSPerfAccumulate(s"enqEntry_${i}_in_cnt", entryInValidVec(i)) 452 XSPerfAccumulate(s"enqEntry_${i}_out_deq_cnt", entryOutDeqValidVec(i)) 453 XSPerfAccumulate(s"enqEntry_${i}_out_trans_cnt", entryOutTransValidVec(i)) 454 } 455 // simple 456 for (i <- 0 until params.numSimp) { 457 XSPerfAccumulate(s"simpEntry_${i}_in_cnt", entryInValidVec(i + params.numEnq)) 458 XSPerfAccumulate(s"simpEntry_${i}_out_deq_cnt", entryOutDeqValidVec(i + params.numEnq)) 459 XSPerfAccumulate(s"simpEntry_${i}_out_trans_cnt", entryOutTransValidVec(i + params.numEnq)) 460 } 461 // complex 462 for (i <- 0 until params.numComp) { 463 XSPerfAccumulate(s"compEntry_${i}_in_cnt", entryInValidVec(i + params.numEnq + params.numSimp)) 464 XSPerfAccumulate(s"compEntry_${i}_out_deq_cnt", entryOutDeqValidVec(i + params.numEnq + params.numSimp)) 465 XSPerfAccumulate(s"compEntry_${i}_out_trans_cnt", entryOutTransValidVec(i + params.numEnq + params.numSimp)) 466 } 467 // total 468 XSPerfAccumulate(s"enqEntry_all_in_cnt", PopCount(entryInValidVec.take(params.numEnq))) 469 XSPerfAccumulate(s"enqEntry_all_out_deq_cnt", PopCount(entryOutDeqValidVec.take(params.numEnq))) 470 XSPerfAccumulate(s"enqEntry_all_out_trans_cnt", PopCount(entryOutTransValidVec.take(params.numEnq))) 471 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 476 io.vecLdIn.foreach(dontTouch(_)) 477} 478 479class EntriesIO(implicit p: Parameters, params: IssueBlockParams) extends XSBundle { 480 val flush = Flipped(ValidIO(new Redirect)) 481 //enq 482 val enq = Vec(params.numEnq, Flipped(ValidIO(new EntryBundle))) 483 val og0Resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 484 val og1Resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 485 //deq sel 486 val deqReady = Vec(params.numDeq, Input(Bool())) 487 val deqSelOH = Vec(params.numDeq, Flipped(ValidIO(UInt(params.numEntries.W)))) 488 val enqEntryOldestSel = Vec(params.numDeq, Flipped(ValidIO(UInt(params.numEnq.W)))) 489 val simpEntryOldestSel = OptionWrapper(params.hasCompAndSimp, Vec(params.numDeq, Flipped(ValidIO(UInt(params.numSimp.W))))) 490 val compEntryOldestSel = OptionWrapper(params.hasCompAndSimp, Vec(params.numDeq, Flipped(ValidIO(UInt(params.numComp.W))))) 491 val othersEntryOldestSel= OptionWrapper(params.isAllComp || params.isAllSimp, Vec(params.numDeq, Flipped(ValidIO(UInt((params.numEntries - params.numEnq).W))))) 492 val subDeqRequest = OptionWrapper(params.deqFuSame, Vec(params.numDeq, Input(UInt(params.numEntries.W)))) 493 val subDeqSelOH = OptionWrapper(params.deqFuSame, Vec(params.numDeq, Input(UInt(params.numEntries.W)))) 494 // wakeup 495 val wakeUpFromWB: MixedVec[ValidIO[IssueQueueWBWakeUpBundle]] = Flipped(params.genWBWakeUpSinkValidBundle) 496 val wakeUpFromIQ: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpSinkValidBundle) 497 val vlIsZero = Input(Bool()) 498 val vlIsVlmax = Input(Bool()) 499 val og0Cancel = Input(ExuOH(backendParams.numExu)) 500 val og1Cancel = Input(ExuOH(backendParams.numExu)) 501 val ldCancel = Vec(backendParams.LdExuCnt, Flipped(new LoadCancelIO)) 502 //entries status 503 val valid = Output(UInt(params.numEntries.W)) 504 val canIssue = Output(UInt(params.numEntries.W)) 505 val fuType = Vec(params.numEntries, Output(FuType())) 506 val dataSources = Vec(params.numEntries, Vec(params.numRegSrc, Output(DataSource()))) 507 val loadDependency = Vec(params.numEntries, Vec(LoadPipelineWidth, UInt(3.W))) 508 val srcWakeUpL1ExuOH = OptionWrapper(params.hasIQWakeUp, Vec(params.numEntries, Vec(params.numRegSrc, Output(ExuOH())))) 509 val srcTimer = OptionWrapper(params.hasIQWakeUp, Vec(params.numEntries, Vec(params.numRegSrc, Output(UInt(3.W))))) 510 //deq status 511 val isFirstIssue = Vec(params.numDeq, Output(Bool())) 512 val deqEntry = Vec(params.numDeq, ValidIO(new EntryBundle)) 513 val cancelDeqVec = Vec(params.numDeq, Output(Bool())) 514 515 // load/hybird only 516 val fromLoad = OptionWrapper(params.isLdAddrIQ || params.isHyAddrIQ, new Bundle { 517 val finalIssueResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 518 val memAddrIssueResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 519 }) 520 // mem only 521 val fromMem = OptionWrapper(params.isMemAddrIQ, new Bundle { 522 val slowResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 523 val fastResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 524 }) 525 // vec mem only 526 val vecMemIn = OptionWrapper(params.isVecMemIQ, new Bundle { 527 val sqDeqPtr = Input(new SqPtr) 528 val lqDeqPtr = Input(new LqPtr) 529 }) 530 val vecLdIn = OptionWrapper(params.isVecLduIQ, new Bundle { 531 val resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 532 }) 533 val robIdx = OptionWrapper(params.isVecMemIQ, Output(Vec(params.numEntries, new RobPtr))) 534 val uopIdx = OptionWrapper(params.isVecMemIQ, Output(Vec(params.numEntries, UopIdx()))) 535 536 // trans 537 val simpEntryDeqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Input(UInt(params.numSimp.W)))) 538 val simpEntryEnqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Output(UInt(params.numSimp.W)))) 539 val compEntryEnqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Output(UInt(params.numComp.W)))) 540 val othersEntryEnqSelVec = OptionWrapper(params.isAllComp || params.isAllSimp, Vec(params.numEnq, Output(UInt((params.numEntries - params.numEnq).W)))) 541 542 // debug 543 val cancel = OptionWrapper(params.hasIQWakeUp, Output(Vec(params.numEntries, Bool()))) 544 545 def wakeup = wakeUpFromWB ++ wakeUpFromIQ 546} 547