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