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