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, io.vecLdIn.get.finalIssueResp) 41 else Seq() 42 if (params.isMemAddrIQ) { 43 println(s"[${this.desiredName}] resp: {" + 44 s"og0Resp: ${resps.contains(io.og0Resp)}, " + 45 s"og1Resp: ${resps.contains(io.og1Resp)}, " + 46 s"finalResp: ${io.fromLoad.nonEmpty && resps.contains(io.fromLoad.get.finalIssueResp)}, " + 47 s"loadBorderResp: ${io.fromLoad.nonEmpty && resps.contains(io.fromLoad.get.memAddrIssueResp)}, " + 48 s"memFastResp: ${io.fromMem.nonEmpty && resps.contains(io.fromMem.get.fastResp)}, " + 49 s"memSlowResp: ${io.fromMem.nonEmpty && resps.contains(io.fromMem.get.slowResp)}, " + 50 s"vecLoadBorderResp: ${io.vecLdIn.nonEmpty && resps.contains(io.vecLdIn.get.resp)}, " + 51 s"}" 52 ) 53 } 54 resps.flatten 55 } 56 57 val resps: Vec[Vec[ValidIO[EntryDeqRespBundle]]] = Wire(Vec(4, chiselTypeOf(io.og0Resp))) 58 59 if (params.needOg2Resp) 60 resps := Seq(io.og0Resp, io.og1Resp, io.og2Resp.get, WireDefault(0.U.asTypeOf(io.og0Resp))) 61 else 62 resps := Seq(io.og0Resp, io.og1Resp, WireDefault(0.U.asTypeOf(io.og0Resp)), WireDefault(0.U.asTypeOf(io.og0Resp))) 63 64 65 66 //Module 67 val enqEntries = Seq.fill(EnqEntryNum)(Module(EnqEntry(isComp = true)(p, params))) 68 val othersEntriesSimp = Seq.fill(SimpEntryNum)(Module(OthersEntry(isComp = false)(p, params))) 69 val othersEntriesComp = Seq.fill(CompEntryNum)(Module(OthersEntry(isComp = true)(p, params))) 70 val othersEntries = othersEntriesSimp ++ othersEntriesComp 71 val othersTransPolicy = OptionWrapper(params.isAllComp || params.isAllSimp, Module(new EnqPolicy)) 72 val simpTransPolicy = OptionWrapper(params.hasCompAndSimp, Module(new EnqPolicy)) 73 val compTransPolicy = OptionWrapper(params.hasCompAndSimp, Module(new EnqPolicy)) 74 75 //Wire 76 //entries status 77 val entries = Wire(Vec(params.numEntries, ValidIO(new EntryBundle))) 78 val robIdxVec = Wire(Vec(params.numEntries, new RobPtr)) 79 val validVec = Wire(Vec(params.numEntries, Bool())) 80 val issuedVec = Wire(Vec(params.numEntries, Bool())) 81 val validForTrans = VecInit(validVec.zip(issuedVec).map(x => x._1 && !x._2)) 82 val canIssueVec = Wire(Vec(params.numEntries, Bool())) 83 val fuTypeVec = Wire(Vec(params.numEntries, FuType())) 84 val isFirstIssueVec = Wire(Vec(params.numEntries, Bool())) 85 val issueTimerVec = Wire(Vec(params.numEntries, UInt(2.W))) 86 val sqIdxVec = OptionWrapper(params.needFeedBackSqIdx || params.needFeedBackLqIdx, Wire(Vec(params.numEntries, new SqPtr()))) 87 val lqIdxVec = OptionWrapper(params.needFeedBackSqIdx || params.needFeedBackLqIdx, Wire(Vec(params.numEntries, new LqPtr()))) 88 //src status 89 val dataSourceVec = Wire(Vec(params.numEntries, Vec(params.numRegSrc, DataSource()))) 90 val loadDependencyVec = Wire(Vec(params.numEntries, Vec(LoadPipelineWidth, UInt(LoadDependencyWidth.W)))) 91 val exuSourceVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Vec(params.numRegSrc, ExuSource())))) 92 //deq sel 93 val deqSelVec = Wire(Vec(params.numEntries, Bool())) 94 val issueRespVec = Wire(Vec(params.numEntries, ValidIO(new EntryDeqRespBundle))) 95 val deqPortIdxWriteVec = Wire(Vec(params.numEntries, UInt(1.W))) 96 val deqPortIdxReadVec = Wire(Vec(params.numEntries, UInt(1.W))) 97 //trans sel 98 val othersEntryEnqReadyVec = Wire(Vec(OthersEntryNum, Bool())) 99 val othersEntryEnqVec = Wire(Vec(OthersEntryNum, Valid(new EntryBundle))) 100 val enqEntryTransVec = Wire(Vec(EnqEntryNum, Valid(new EntryBundle))) 101 val simpEntryTransVec = OptionWrapper(params.hasCompAndSimp, Wire(Vec(SimpEntryNum, Valid(new EntryBundle)))) 102 val compEnqVec = OptionWrapper(params.hasCompAndSimp, Wire(Vec(EnqEntryNum, Valid(new EntryBundle)))) 103 104 val enqCanTrans2Simp = OptionWrapper(params.hasCompAndSimp, Wire(Bool())) 105 val enqCanTrans2Comp = OptionWrapper(params.hasCompAndSimp, Wire(Bool())) 106 val simpCanTrans2Comp = OptionWrapper(params.hasCompAndSimp, Wire(Vec(EnqEntryNum, Bool()))) 107 val simpTransSelVec = OptionWrapper(params.hasCompAndSimp, Wire(Vec(EnqEntryNum, Valid(UInt(SimpEntryNum.W))))) 108 val compTransSelVec = OptionWrapper(params.hasCompAndSimp, Wire(Vec(EnqEntryNum, Valid(UInt(CompEntryNum.W))))) 109 val finalSimpTransSelVec = OptionWrapper(params.hasCompAndSimp, Wire(Vec(EnqEntryNum, UInt(SimpEntryNum.W)))) 110 val finalCompTransSelVec = OptionWrapper(params.hasCompAndSimp, Wire(Vec(EnqEntryNum, UInt(CompEntryNum.W)))) 111 112 val enqCanTrans2Others = OptionWrapper(params.isAllComp || params.isAllSimp, Wire(Bool())) 113 val othersTransSelVec = OptionWrapper(params.isAllComp || params.isAllSimp, Wire(Vec(EnqEntryNum, Valid(UInt(OthersEntryNum.W))))) 114 val finalOthersTransSelVec = OptionWrapper(params.isAllComp || params.isAllSimp, Wire(Vec(EnqEntryNum, UInt(OthersEntryNum.W)))) 115 116 val simpEntryEnqReadyVec = othersEntryEnqReadyVec.take(SimpEntryNum) 117 val compEntryEnqReadyVec = othersEntryEnqReadyVec.takeRight(CompEntryNum) 118 val simpEntryEnqVec = othersEntryEnqVec.take(SimpEntryNum) 119 val compEntryEnqVec = othersEntryEnqVec.takeRight(CompEntryNum) 120 //debug 121 val entryInValidVec = Wire(Vec(params.numEntries, Bool())) 122 val entryOutDeqValidVec = Wire(Vec(params.numEntries, Bool())) 123 val entryOutTransValidVec = Wire(Vec(params.numEntries, Bool())) 124 val perfLdCancelVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Vec(params.numRegSrc, Bool())))) 125 val perfOg0CancelVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Vec(params.numRegSrc, Bool())))) 126 val perfWakeupByWBVec = Wire(Vec(params.numEntries, Vec(params.numRegSrc, Bool()))) 127 val perfWakeupByIQVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Vec(params.numRegSrc, Vec(params.numWakeupFromIQ, Bool()))))) 128 //cancel bypass 129 val cancelBypassVec = Wire(Vec(params.numEntries, Bool())) 130 131 132 //enqEntries 133 enqEntries.zipWithIndex.foreach { case (enqEntry, entryIdx) => 134 enqEntry.io.commonIn.enq := io.enq(entryIdx) 135 enqEntry.io.commonIn.transSel := (if (params.isAllComp || params.isAllSimp) enqCanTrans2Others.get && othersTransSelVec.get(entryIdx).valid 136 else enqCanTrans2Simp.get && simpTransSelVec.get(entryIdx).valid || enqCanTrans2Comp.get && compTransSelVec.get(entryIdx).valid) 137 EntriesConnect(enqEntry.io.commonIn, enqEntry.io.commonOut, entryIdx) 138 enqEntry.io.enqDelayIn1.wakeUpFromWB := io.wakeUpFromWBDelayed 139 enqEntry.io.enqDelayIn1.wakeUpFromIQ := io.wakeUpFromIQDelayed 140 enqEntry.io.enqDelayIn1.srcLoadDependency := RegEnable(VecInit(io.enq(entryIdx).bits.payload.srcLoadDependency.take(params.numRegSrc)), io.enq(entryIdx).valid) 141 enqEntry.io.enqDelayIn1.og0Cancel := RegNext(io.og0Cancel) 142 enqEntry.io.enqDelayIn1.ldCancel := RegNext(io.ldCancel) 143 // note: these signals with 2 cycle delay should not be enabled by io.enq.valid 144 enqEntry.io.enqDelayIn2.wakeUpFromWB := DelayN(io.wakeUpFromWB, 2) 145 enqEntry.io.enqDelayIn2.wakeUpFromIQ := DelayN(io.wakeUpFromIQ, 2) 146 enqEntry.io.enqDelayIn2.srcLoadDependency := DelayN(VecInit(io.enq(entryIdx).bits.payload.srcLoadDependency.take(params.numRegSrc)), 2) 147 enqEntry.io.enqDelayIn2.og0Cancel := DelayN(io.og0Cancel, 2) 148 enqEntry.io.enqDelayIn2.ldCancel := DelayN(io.ldCancel, 2) 149 enqEntryTransVec(entryIdx) := enqEntry.io.commonOut.transEntry 150 } 151 //othersEntries 152 othersEntries.zipWithIndex.foreach { case (othersEntry, entryIdx) => 153 othersEntry.io.commonIn.enq := othersEntryEnqVec(entryIdx) 154 othersEntry.io.commonIn.transSel := (if (params.hasCompAndSimp && (entryIdx < SimpEntryNum)) 155 io.simpEntryDeqSelVec.get.zip(simpCanTrans2Comp.get).map(x => x._1(entryIdx) && x._2).reduce(_ | _) 156 else false.B) 157 EntriesConnect(othersEntry.io.commonIn, othersEntry.io.commonOut, entryIdx + EnqEntryNum) 158 othersEntryEnqReadyVec(entryIdx) := othersEntry.io.commonOut.enqReady 159 if (params.hasCompAndSimp && (entryIdx < SimpEntryNum)) { 160 simpEntryTransVec.get(entryIdx) := othersEntry.io.commonOut.transEntry 161 } 162 } 163 164 165 deqSelVec.zip(deqPortIdxWriteVec).zipWithIndex.foreach { case ((deqSel, deqPortIdxWrite), i) => 166 val deqVec = io.deqSelOH.zip(io.deqReady).map(x => x._1.valid && x._1.bits(i) && x._2) 167 deqPortIdxWrite := OHToUInt(deqVec) 168 deqSel := deqVec.reduce(_ | _) 169 } 170 171 172 if (params.isAllComp || params.isAllSimp) { 173 //transPolicy 174 othersTransPolicy.get.io.canEnq := VecInit(validVec.takeRight(OthersEntryNum).map(!_)).asUInt 175 176 // we only allow all or none of the enq entries transfering to others entries. 177 enqCanTrans2Others.get := PopCount(validVec.take(EnqEntryNum)) <= PopCount(validVec.takeRight(OthersEntryNum).map(!_)) 178 // othersTransSelVec(i) is the target others entry for enq entry [i]. 179 // note that dispatch does not guarantee the validity of enq entries with low index. 180 // that means in some cases enq entry [0] is invalid while enq entry [1] is valid. 181 // in this case, enq entry [1] should use result [0] of TransPolicy. 182 othersTransSelVec.get(0).valid := othersTransPolicy.get.io.enqSelOHVec(0).valid && validForTrans(0) 183 othersTransSelVec.get(0).bits := othersTransPolicy.get.io.enqSelOHVec(0).bits 184 if (params.numEnq == 2) { 185 othersTransSelVec.get(1).valid := Mux(!validForTrans(0), othersTransPolicy.get.io.enqSelOHVec(0).valid, othersTransPolicy.get.io.enqSelOHVec(1).valid) && validForTrans(1) 186 othersTransSelVec.get(1).bits := Mux(!validForTrans(0), othersTransPolicy.get.io.enqSelOHVec(0).bits, othersTransPolicy.get.io.enqSelOHVec(1).bits) 187 } 188 189 finalOthersTransSelVec.get.zip(othersTransSelVec.get).zipWithIndex.foreach { case ((finalOH, selOH), enqIdx) => 190 finalOH := Fill(OthersEntryNum, enqCanTrans2Others.get && selOH.valid) & selOH.bits 191 } 192 193 //othersEntryEnq 194 othersEntryEnqVec.zipWithIndex.foreach { case (othersEntryEnq, othersIdx) => 195 val othersEnqOH = finalOthersTransSelVec.get.map(_(othersIdx)) 196 if (othersEnqOH.size == 1) 197 othersEntryEnq := Mux(othersEnqOH.head, enqEntryTransVec.head, 0.U.asTypeOf(enqEntryTransVec.head)) 198 else 199 othersEntryEnq := Mux1H(othersEnqOH, enqEntryTransVec) 200 } 201 } 202 else { 203 //transPolicy 204 simpTransPolicy.get.io.canEnq := VecInit(simpEntryEnqReadyVec).asUInt 205 compTransPolicy.get.io.canEnq := VecInit(validVec.takeRight(CompEntryNum).map(!_)).asUInt 206 207 // we only allow all or none of the enq entries transfering to comp/simp entries. 208 // when all of simp entries are empty and comp entries are enough, transfer to comp entries. 209 // otherwise, transfer to simp entries. 210 enqCanTrans2Comp.get := PopCount(validVec.take(EnqEntryNum)) <= PopCount(validVec.takeRight(CompEntryNum).map(!_)) && !validVec.drop(EnqEntryNum).take(SimpEntryNum).reduce(_ || _) 211 enqCanTrans2Simp.get := !enqCanTrans2Comp.get && PopCount(validVec.take(EnqEntryNum)) <= PopCount(simpEntryEnqReadyVec) 212 simpCanTrans2Comp.get.zipWithIndex.foreach { case (canTrans, idx) => 213 canTrans := !enqCanTrans2Comp.get && PopCount(validVec.takeRight(CompEntryNum).map(!_)) >= (idx + 1).U 214 } 215 216 // simp/compTransSelVec(i) is the target simp/comp entry for enq entry [i]. 217 // note that dispatch does not guarantee the validity of enq entries with low index. 218 // that means in some cases enq entry [0] is invalid while enq entry [1] is valid. 219 // in this case, enq entry [1] should use result [0] of TransPolicy. 220 simpTransSelVec.get(0).valid := simpTransPolicy.get.io.enqSelOHVec(0).valid && validForTrans(0) 221 simpTransSelVec.get(0).bits := simpTransPolicy.get.io.enqSelOHVec(0).bits 222 compTransSelVec.get(0).valid := compTransPolicy.get.io.enqSelOHVec(0).valid && validForTrans(0) 223 compTransSelVec.get(0).bits := compTransPolicy.get.io.enqSelOHVec(0).bits 224 if (params.numEnq == 2) { 225 simpTransSelVec.get(1).valid := Mux(!validForTrans(0), simpTransPolicy.get.io.enqSelOHVec(0).valid, simpTransPolicy.get.io.enqSelOHVec(1).valid) && validForTrans(1) 226 simpTransSelVec.get(1).bits := Mux(!validForTrans(0), simpTransPolicy.get.io.enqSelOHVec(0).bits, simpTransPolicy.get.io.enqSelOHVec(1).bits) 227 compTransSelVec.get(1).valid := Mux(!validForTrans(0), compTransPolicy.get.io.enqSelOHVec(0).valid, compTransPolicy.get.io.enqSelOHVec(1).valid) && validForTrans(1) 228 compTransSelVec.get(1).bits := Mux(!validForTrans(0), compTransPolicy.get.io.enqSelOHVec(0).bits, compTransPolicy.get.io.enqSelOHVec(1).bits) 229 } 230 231 finalSimpTransSelVec.get.zip(simpTransSelVec.get).zipWithIndex.foreach { case ((finalOH, selOH), enqIdx) => 232 finalOH := Fill(SimpEntryNum, enqCanTrans2Simp.get && selOH.valid) & selOH.bits 233 } 234 finalCompTransSelVec.get.zip(compTransSelVec.get).zip(compTransPolicy.get.io.enqSelOHVec).zipWithIndex.foreach { 235 case (((finalOH, selOH), origSelOH), enqIdx) => 236 finalOH := Mux(enqCanTrans2Comp.get, Fill(CompEntryNum, selOH.valid) & selOH.bits, Fill(CompEntryNum, origSelOH.valid) & origSelOH.bits) 237 } 238 239 //othersEntryEnq 240 simpEntryEnqVec.zipWithIndex.foreach { case (simpEntryEnq, simpIdx) => 241 val simpEnqOH = finalSimpTransSelVec.get.map(_(simpIdx)) 242 // shit Mux1H directly returns in(0) if the seq has only 1 elements 243 if (simpEnqOH.size == 1) 244 simpEntryEnq := Mux(simpEnqOH.head, enqEntryTransVec.head, 0.U.asTypeOf(enqEntryTransVec.head)) 245 else 246 simpEntryEnq := Mux1H(simpEnqOH, enqEntryTransVec) 247 } 248 249 compEnqVec.get.zip(enqEntryTransVec).zip(io.simpEntryDeqSelVec.get).foreach { case ((compEnq, enqEntry), deqSel) => 250 compEnq := Mux(enqCanTrans2Comp.get, enqEntry, Mux1H(deqSel, simpEntryTransVec.get)) 251 } 252 compEntryEnqVec.zipWithIndex.foreach { case (compEntryEnq, compIdx) => 253 val compEnqOH = finalCompTransSelVec.get.map(_(compIdx)) 254 // shit Mux1H directly returns in(0) if the seq has only 1 elements 255 if (compEnqOH.size == 1) 256 compEntryEnq := Mux(compEnqOH.head, compEnqVec.get.head, 0.U.asTypeOf(compEnqVec.get.head)) 257 else 258 compEntryEnq := Mux1H(compEnqOH, compEnqVec.get) 259 } 260 261 assert(PopCount(simpEntryEnqVec.map(_.valid)) <= params.numEnq.U, "the number of simpEntryEnq is more than numEnq\n") 262 assert(PopCount(compEntryEnqVec.map(_.valid)) <= params.numEnq.U, "the number of compEntryEnq is more than numEnq\n") 263 } 264 265 if(backendParams.debugEn) { 266 dontTouch(othersEntryEnqVec) 267 } 268 269 //issueRespVec 270 if (params.needFeedBackSqIdx || params.needFeedBackLqIdx) { 271 issueRespVec.lazyZip(sqIdxVec.get.zip(lqIdxVec.get)).lazyZip(issueTimerVec.lazyZip(deqPortIdxReadVec)).foreach { case (issueResp, (sqIdx, lqIdx), (issueTimer, deqPortIdx)) => 272 val respInDatapath = if (!params.isVecMemIQ) resps(issueTimer(0))(deqPortIdx) 273 else resps(issueTimer)(deqPortIdx) 274 val respAfterDatapath = Wire(chiselTypeOf(respInDatapath)) 275 val hitRespsVec = VecInit(memEtyResps.map(x => 276 x.valid && 277 (if (params.needFeedBackSqIdx) x.bits.sqIdx.get === sqIdx else true.B) && 278 (if (params.needFeedBackLqIdx) x.bits.lqIdx.get === lqIdx else true.B) 279 ).toSeq) 280 respAfterDatapath.valid := hitRespsVec.reduce(_ | _) 281 respAfterDatapath.bits := (if (memEtyResps.size == 1) memEtyResps.head.bits 282 else Mux1H(hitRespsVec, memEtyResps.map(_.bits).toSeq)) 283 issueResp := (if (!params.isVecMemIQ) Mux(issueTimer(1), respAfterDatapath, respInDatapath) 284 else Mux(issueTimer === "b11".U, 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.issued := issuedVec.asUInt 389 io.canIssue := canIssueVec.asUInt 390 io.fuType := fuTypeVec 391 io.dataSources := dataSourceVec 392 io.exuSources.foreach(_ := exuSourceVec.get) 393 io.loadDependency := loadDependencyVec 394 io.isFirstIssue.zipWithIndex.foreach{ case (isFirstIssue, deqIdx) => 395 isFirstIssue := io.deqSelOH(deqIdx).valid && Mux1H(io.deqSelOH(deqIdx).bits, isFirstIssueVec) 396 } 397 io.simpEntryEnqSelVec.foreach(_ := finalSimpTransSelVec.get.zip(enqEntryTransVec).map(x => x._1 & Fill(SimpEntryNum, x._2.valid))) 398 io.compEntryEnqSelVec.foreach(_ := finalCompTransSelVec.get.zip(compEnqVec.get).map(x => x._1 & Fill(CompEntryNum, x._2.valid))) 399 io.othersEntryEnqSelVec.foreach(_ := finalOthersTransSelVec.get.zip(enqEntryTransVec).map(x => x._1 & Fill(OthersEntryNum, x._2.valid))) 400 io.robIdx.foreach(_ := robIdxVec) 401 402 403 def EntriesConnect(in: CommonInBundle, out: CommonOutBundle, entryIdx: Int) = { 404 in.flush := io.flush 405 in.wakeUpFromWB := io.wakeUpFromWB 406 in.wakeUpFromIQ := io.wakeUpFromIQ 407 in.vlFromIntIsZero := io.vlFromIntIsZero 408 in.vlFromIntIsVlmax := io.vlFromIntIsVlmax 409 in.vlFromVfIsZero := io.vlFromVfIsZero 410 in.vlFromVfIsVlmax := io.vlFromVfIsVlmax 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.dataSources 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 exuSourceVec.foreach(_(entryIdx) := out.exuSources.get) 434 if (params.needFeedBackSqIdx || params.needFeedBackLqIdx) { 435 sqIdxVec.get(entryIdx) := out.entry.bits.payload.sqIdx 436 lqIdxVec.get(entryIdx) := out.entry.bits.payload.lqIdx 437 } 438 entryInValidVec(entryIdx) := out.entryInValid 439 entryOutDeqValidVec(entryIdx) := out.entryOutDeqValid 440 entryOutTransValidVec(entryIdx) := out.entryOutTransValid 441 perfWakeupByWBVec(entryIdx) := out.perfWakeupByWB 442 if (params.hasIQWakeUp) { 443 perfLdCancelVec.get(entryIdx) := out.perfLdCancel.get 444 perfOg0CancelVec.get(entryIdx) := out.perfOg0Cancel.get 445 perfWakeupByIQVec.get(entryIdx) := out.perfWakeupByIQ.get 446 } 447 } 448 449 io.vecLdIn.foreach(dontTouch(_)) 450 451 // entries perf counter 452 // enq 453 for (i <- 0 until params.numEnq) { 454 XSPerfAccumulate(s"enqEntry_${i}_in_cnt", entryInValidVec(i)) 455 XSPerfAccumulate(s"enqEntry_${i}_out_deq_cnt", entryOutDeqValidVec(i)) 456 XSPerfAccumulate(s"enqEntry_${i}_out_trans_cnt", entryOutTransValidVec(i)) 457 } 458 // simple 459 for (i <- 0 until params.numSimp) { 460 XSPerfAccumulate(s"simpEntry_${i}_in_cnt", entryInValidVec(i + params.numEnq)) 461 XSPerfAccumulate(s"simpEntry_${i}_out_deq_cnt", entryOutDeqValidVec(i + params.numEnq)) 462 XSPerfAccumulate(s"simpEntry_${i}_out_trans_cnt", entryOutTransValidVec(i + params.numEnq)) 463 } 464 // complex 465 for (i <- 0 until params.numComp) { 466 XSPerfAccumulate(s"compEntry_${i}_in_cnt", entryInValidVec(i + params.numEnq + params.numSimp)) 467 XSPerfAccumulate(s"compEntry_${i}_out_deq_cnt", entryOutDeqValidVec(i + params.numEnq + params.numSimp)) 468 XSPerfAccumulate(s"compEntry_${i}_out_trans_cnt", entryOutTransValidVec(i + params.numEnq + params.numSimp)) 469 } 470 // total 471 XSPerfAccumulate(s"enqEntry_all_in_cnt", PopCount(entryInValidVec.take(params.numEnq))) 472 XSPerfAccumulate(s"enqEntry_all_out_deq_cnt", PopCount(entryOutDeqValidVec.take(params.numEnq))) 473 XSPerfAccumulate(s"enqEntry_all_out_trans_cnt", PopCount(entryOutTransValidVec.take(params.numEnq))) 474 for (srcIdx <- 0 until params.numRegSrc) { 475 XSPerfAccumulate(s"enqEntry_all_wakeup_wb_src${srcIdx}_cnt", PopCount(perfWakeupByWBVec.take(params.numEnq).map(_(srcIdx)))) 476 if (params.hasIQWakeUp) { 477 XSPerfAccumulate(s"enqEntry_all_ldCancel_src${srcIdx}_cnt", PopCount(perfLdCancelVec.get.take(params.numEnq).map(_(srcIdx)))) 478 XSPerfAccumulate(s"enqEntry_all_og0Cancel_src${srcIdx}_cnt", PopCount(perfOg0CancelVec.get.take(params.numEnq).map(_(srcIdx)))) 479 for (iqIdx <- 0 until params.numWakeupFromIQ) { 480 XSPerfAccumulate(s"enqEntry_all_wakeup_iq_from_exu${params.wakeUpSourceExuIdx(iqIdx)}_src${srcIdx}_cnt", PopCount(perfWakeupByIQVec.get.take(params.numEnq).map(_(srcIdx)(iqIdx)))) 481 } 482 } 483 } 484 485 XSPerfAccumulate(s"othersEntry_all_in_cnt", PopCount(entryInValidVec.drop(params.numEnq))) 486 XSPerfAccumulate(s"othersEntry_all_out_deq_cnt", PopCount(entryOutDeqValidVec.drop(params.numEnq))) 487 XSPerfAccumulate(s"othersEntry_all_out_trans_cnt", PopCount(entryOutTransValidVec.drop(params.numEnq))) 488 489 for (srcIdx <- 0 until params.numRegSrc) { 490 XSPerfAccumulate(s"othersEntry_all_wakeup_wb_src${srcIdx}_cnt", PopCount(perfWakeupByWBVec.drop(params.numEnq).map(_(srcIdx)))) 491 if (params.hasIQWakeUp) { 492 XSPerfAccumulate(s"othersEntry_all_ldCancel_src${srcIdx}_cnt", PopCount(perfLdCancelVec.get.drop(params.numEnq).map(_(srcIdx)))) 493 XSPerfAccumulate(s"othersEntry_all_og0Cancel_src${srcIdx}_cnt", PopCount(perfOg0CancelVec.get.drop(params.numEnq).map(_(srcIdx)))) 494 for (iqIdx <- 0 until params.numWakeupFromIQ) { 495 XSPerfAccumulate(s"othersEntry_all_wakeup_iq_from_exu${params.wakeUpSourceExuIdx(iqIdx)}_src${srcIdx}_cnt", PopCount(perfWakeupByIQVec.get.drop(params.numEnq).map(_(srcIdx)(iqIdx)))) 496 } 497 } 498 } 499 500 for (t <- FuType.functionNameMap.keys) { 501 val fuName = FuType.functionNameMap(t) 502 if (params.getFuCfgs.map(_.fuType == t).reduce(_ | _) && params.getFuCfgs.size > 1) { 503 for (srcIdx <- 0 until params.numRegSrc) { 504 XSPerfAccumulate(s"allEntry_futype_${fuName}_wakeup_wb_src${srcIdx}_cnt", PopCount(perfWakeupByWBVec.zip(fuTypeVec).map{ case(x, fu) => x(srcIdx) && fu(t.id) })) 505 if (params.hasIQWakeUp) { 506 XSPerfAccumulate(s"allEntry_futype_${fuName}_ldCancel_src${srcIdx}_cnt", PopCount(perfLdCancelVec.get.zip(fuTypeVec).map{ case(x, fu) => x(srcIdx) && fu(t.id) })) 507 XSPerfAccumulate(s"allEntry_futype_${fuName}_og0Cancel_src${srcIdx}_cnt", PopCount(perfOg0CancelVec.get.zip(fuTypeVec).map{ case(x, fu) => x(srcIdx) && fu(t.id) })) 508 for (iqIdx <- 0 until params.numWakeupFromIQ) { 509 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) })) 510 } 511 } 512 } 513 } 514 } 515} 516 517class EntriesIO(implicit p: Parameters, params: IssueBlockParams) extends XSBundle { 518 val flush = Flipped(ValidIO(new Redirect)) 519 //enq 520 val enq = Vec(params.numEnq, Flipped(ValidIO(new EntryBundle))) 521 val og0Resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 522 val og1Resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 523 val og2Resp = OptionWrapper(params.needOg2Resp, Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle)))) 524 //deq sel 525 val deqReady = Vec(params.numDeq, Input(Bool())) 526 val deqSelOH = Vec(params.numDeq, Flipped(ValidIO(UInt(params.numEntries.W)))) 527 val enqEntryOldestSel = Vec(params.numDeq, Flipped(ValidIO(UInt(params.numEnq.W)))) 528 val simpEntryOldestSel = OptionWrapper(params.hasCompAndSimp, Vec(params.numDeq, Flipped(ValidIO(UInt(params.numSimp.W))))) 529 val compEntryOldestSel = OptionWrapper(params.hasCompAndSimp, Vec(params.numDeq, Flipped(ValidIO(UInt(params.numComp.W))))) 530 val othersEntryOldestSel= OptionWrapper(params.isAllComp || params.isAllSimp, Vec(params.numDeq, Flipped(ValidIO(UInt((params.numEntries - params.numEnq).W))))) 531 val subDeqRequest = OptionWrapper(params.deqFuSame, Vec(params.numDeq, Input(UInt(params.numEntries.W)))) 532 val subDeqSelOH = OptionWrapper(params.deqFuSame, Vec(params.numDeq, Input(UInt(params.numEntries.W)))) 533 // wakeup 534 val wakeUpFromWB: MixedVec[ValidIO[IssueQueueWBWakeUpBundle]] = Flipped(params.genWBWakeUpSinkValidBundle) 535 val wakeUpFromIQ: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpSinkValidBundle) 536 val wakeUpFromWBDelayed: MixedVec[ValidIO[IssueQueueWBWakeUpBundle]] = Flipped(params.genWBWakeUpSinkValidBundle) 537 val wakeUpFromIQDelayed: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpSinkValidBundle) 538 val vlFromIntIsZero = Input(Bool()) 539 val vlFromIntIsVlmax = Input(Bool()) 540 val vlFromVfIsZero = Input(Bool()) 541 val vlFromVfIsVlmax = Input(Bool()) 542 val og0Cancel = Input(ExuVec()) 543 val og1Cancel = Input(ExuVec()) 544 val ldCancel = Vec(backendParams.LdExuCnt, Flipped(new LoadCancelIO)) 545 //entries status 546 val valid = Output(UInt(params.numEntries.W)) 547 val issued = Output(UInt(params.numEntries.W)) 548 val canIssue = Output(UInt(params.numEntries.W)) 549 val fuType = Vec(params.numEntries, Output(FuType())) 550 val dataSources = Vec(params.numEntries, Vec(params.numRegSrc, Output(DataSource()))) 551 val loadDependency = Vec(params.numEntries, Vec(LoadPipelineWidth, UInt(LoadDependencyWidth.W))) 552 val exuSources = OptionWrapper(params.hasIQWakeUp, Vec(params.numEntries, Vec(params.numRegSrc, Output(ExuSource())))) 553 //deq status 554 val isFirstIssue = Vec(params.numDeq, Output(Bool())) 555 val deqEntry = Vec(params.numDeq, ValidIO(new EntryBundle)) 556 val cancelDeqVec = Vec(params.numDeq, Output(Bool())) 557 558 // load/hybird only 559 val fromLoad = OptionWrapper(params.isLdAddrIQ || params.isHyAddrIQ, new Bundle { 560 val finalIssueResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 561 val memAddrIssueResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 562 }) 563 // mem only 564 val fromMem = OptionWrapper(params.isMemAddrIQ, new Bundle { 565 val slowResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 566 val fastResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 567 }) 568 // vec mem only 569 val vecMemIn = OptionWrapper(params.isVecMemIQ, new Bundle { 570 val sqDeqPtr = Input(new SqPtr) 571 val lqDeqPtr = Input(new LqPtr) 572 }) 573 val vecLdIn = OptionWrapper(params.isVecLduIQ, new Bundle { 574 val finalIssueResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 575 val resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 576 }) 577 val robIdx = OptionWrapper(params.isVecMemIQ, Output(Vec(params.numEntries, new RobPtr))) 578 579 // trans 580 val simpEntryDeqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Input(UInt(params.numSimp.W)))) 581 val simpEntryEnqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Output(UInt(params.numSimp.W)))) 582 val compEntryEnqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Output(UInt(params.numComp.W)))) 583 val othersEntryEnqSelVec = OptionWrapper(params.isAllComp || params.isAllSimp, Vec(params.numEnq, Output(UInt((params.numEntries - params.numEnq).W)))) 584 585 def wakeup = wakeUpFromWB ++ wakeUpFromIQ 586} 587