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