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.needOg2Resp) 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 := RegEnable(io.wakeUpFromWB, io.enq(entryIdx).valid) 143 enqEntry.io.enqDelayIn1.wakeUpFromIQ := RegEnable(io.wakeUpFromIQ, io.enq(entryIdx).valid) 144 enqEntry.io.enqDelayIn1.srcLoadDependency := RegEnable(VecInit(io.enq(entryIdx).bits.payload.srcLoadDependency.take(params.numRegSrc)), io.enq(entryIdx).valid) 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 = if (!params.isVecMemIQ) resps(issueTimer(0))(deqPortIdx) 277 else resps(issueTimer)(deqPortIdx) 278 val respAfterDatapath = Wire(chiselTypeOf(respInDatapath)) 279 val hitRespsVec = VecInit(memEtyResps.map(x => 280 x.valid && 281 (if (params.needFeedBackSqIdx) x.bits.sqIdx.get === sqIdx else true.B) && 282 (if (params.needFeedBackLqIdx) x.bits.lqIdx.get === lqIdx else true.B) 283 ).toSeq) 284 respAfterDatapath.valid := hitRespsVec.reduce(_ | _) 285 respAfterDatapath.bits := (if (memEtyResps.size == 1) memEtyResps.head.bits 286 else Mux1H(hitRespsVec, memEtyResps.map(_.bits).toSeq)) 287 issueResp := (if (!params.isVecMemIQ) Mux(issueTimer(1), respAfterDatapath, respInDatapath) 288 else Mux(issueTimer === "b11".U, respAfterDatapath, respInDatapath)) 289 } 290 } 291 else { 292 issueRespVec.lazyZip(issueTimerVec.lazyZip(deqPortIdxReadVec)).foreach { case (issueResp, (issueTimer, deqPortIdx)) => 293 val Resp = resps(issueTimer)(deqPortIdx) 294 issueResp := Resp 295 } 296 } 297 298 //deq 299 val enqEntryOldest = Wire(Vec(params.numDeq, ValidIO(new EntryBundle))) 300 val simpEntryOldest = OptionWrapper(params.hasCompAndSimp, Wire(Vec(params.numDeq, ValidIO(new EntryBundle)))) 301 val compEntryOldest = OptionWrapper(params.hasCompAndSimp, Wire(Vec(params.numDeq, ValidIO(new EntryBundle)))) 302 val othersEntryOldest = OptionWrapper(params.isAllComp || params.isAllSimp, Wire(Vec(params.numDeq, ValidIO(new EntryBundle)))) 303 val enqEntryOldestCancel = Wire(Vec(params.numDeq, Bool())) 304 val simpEntryOldestCancel = OptionWrapper(params.hasCompAndSimp, Wire(Vec(params.numDeq, Bool()))) 305 val compEntryOldestCancel = OptionWrapper(params.hasCompAndSimp, Wire(Vec(params.numDeq, Bool()))) 306 val othersEntryOldestCancel = OptionWrapper(params.isAllComp || params.isAllSimp, Wire(Vec(params.numDeq, Bool()))) 307 308 io.enqEntryOldestSel.zipWithIndex.map { case (sel, deqIdx) => 309 enqEntryOldest(deqIdx) := Mux1H(sel.bits, entries.take(EnqEntryNum)) 310 enqEntryOldestCancel(deqIdx) := Mux1H(sel.bits, cancelBypassVec.take(EnqEntryNum)) 311 } 312 313 if (params.isAllComp || params.isAllSimp) { 314 io.othersEntryOldestSel.get.zipWithIndex.map { case (sel, deqIdx) => 315 othersEntryOldest.get(deqIdx) := Mux1H(sel.bits, entries.drop(EnqEntryNum)) 316 othersEntryOldestCancel.get(deqIdx) := Mux1H(sel.bits, cancelBypassVec.drop(EnqEntryNum)) 317 } 318 } 319 else { 320 io.simpEntryOldestSel.get.zipWithIndex.map { case (sel, deqIdx) => 321 simpEntryOldest.get(deqIdx) := Mux1H(sel.bits, entries.drop(EnqEntryNum).take(SimpEntryNum)) 322 simpEntryOldestCancel.get(deqIdx) := Mux1H(sel.bits, cancelBypassVec.drop(EnqEntryNum).take(SimpEntryNum)) 323 } 324 io.compEntryOldestSel.get.zipWithIndex.map { case (sel, deqIdx) => 325 compEntryOldest.get(deqIdx) := Mux1H(sel.bits, entries.drop(EnqEntryNum).takeRight(CompEntryNum)) 326 compEntryOldestCancel.get(deqIdx) := Mux1H(sel.bits, cancelBypassVec.drop(EnqEntryNum).takeRight(CompEntryNum)) 327 } 328 } 329 330 if (params.deqFuSame) { 331 val subDeqPolicyEntryVec = Wire(Vec(params.numDeq, ValidIO(new EntryBundle))) 332 val subDeqPolicyValidVec = Wire(Vec(params.numDeq, Bool())) 333 val subDeqPolicyCancelBypassVec = Wire(Vec(params.numDeq, Bool())) 334 335 subDeqPolicyValidVec(0) := PopCount(io.subDeqRequest.get(0)) >= 1.U 336 subDeqPolicyValidVec(1) := PopCount(io.subDeqRequest.get(0)) >= 2.U 337 338 if (params.isAllComp || params.isAllSimp) { 339 subDeqPolicyEntryVec(0) := PriorityMux(io.subDeqRequest.get(0), entries) 340 subDeqPolicyEntryVec(1) := PriorityMux(Reverse(io.subDeqRequest.get(0)), entries.reverse) 341 subDeqPolicyCancelBypassVec(0) := PriorityMux(io.subDeqRequest.get(0), cancelBypassVec) 342 subDeqPolicyCancelBypassVec(1) := PriorityMux(Reverse(io.subDeqRequest.get(0)), cancelBypassVec.reverse) 343 344 io.deqEntry(0) := Mux(io.othersEntryOldestSel.get(0).valid, othersEntryOldest.get(0), subDeqPolicyEntryVec(1)) 345 io.deqEntry(1) := subDeqPolicyEntryVec(0) 346 io.cancelDeqVec(0) := Mux(io.othersEntryOldestSel.get(0).valid, othersEntryOldestCancel.get(0), subDeqPolicyCancelBypassVec(1)) 347 io.cancelDeqVec(1) := subDeqPolicyCancelBypassVec(0) 348 } 349 else { 350 subDeqPolicyEntryVec(0) := PriorityMux(Reverse(io.subDeqRequest.get(0)), entries.reverse) 351 subDeqPolicyEntryVec(1) := PriorityMux(io.subDeqRequest.get(0), entries) 352 subDeqPolicyCancelBypassVec(0) := PriorityMux(Reverse(io.subDeqRequest.get(0)), cancelBypassVec.reverse) 353 subDeqPolicyCancelBypassVec(1) := PriorityMux(io.subDeqRequest.get(0), cancelBypassVec) 354 355 io.deqEntry(0) := Mux(io.compEntryOldestSel.get(0).valid, 356 compEntryOldest.get(0), 357 Mux(io.simpEntryOldestSel.get(0).valid, simpEntryOldest.get(0), subDeqPolicyEntryVec(1))) 358 io.deqEntry(1) := subDeqPolicyEntryVec(0) 359 io.cancelDeqVec(0) := Mux(io.compEntryOldestSel.get(0).valid, 360 compEntryOldestCancel.get(0), 361 Mux(io.simpEntryOldestSel.get(0).valid, simpEntryOldestCancel.get(0), subDeqPolicyCancelBypassVec(1))) 362 io.cancelDeqVec(1) := subDeqPolicyCancelBypassVec(0) 363 } 364 365 when (subDeqPolicyValidVec(0)) { 366 assert(Mux1H(io.subDeqSelOH.get(0), entries).bits.status.robIdx === subDeqPolicyEntryVec(0).bits.status.robIdx, "subDeqSelOH(0) is not the same\n") 367 } 368 when (subDeqPolicyValidVec(1)) { 369 assert(Mux1H(io.subDeqSelOH.get(1), entries).bits.status.robIdx === subDeqPolicyEntryVec(1).bits.status.robIdx, "subDeqSelOH(1) is not the same\n") 370 } 371 } 372 else { 373 if (params.isAllComp || params.isAllSimp) { 374 io.othersEntryOldestSel.get.zipWithIndex.foreach { case (sel, i) => 375 io.deqEntry(i) := Mux(sel.valid, othersEntryOldest.get(i), enqEntryOldest(i)) 376 io.cancelDeqVec(i) := Mux(sel.valid, othersEntryOldestCancel.get(i), enqEntryOldestCancel(i)) 377 } 378 } 379 else { 380 io.compEntryOldestSel.get.zip(io.simpEntryOldestSel.get).zipWithIndex.foreach { case ((compSel, simpSel), i) => 381 io.deqEntry(i) := Mux(compSel.valid, 382 compEntryOldest.get(i), 383 Mux(simpSel.valid, simpEntryOldest.get(i), enqEntryOldest(i))) 384 io.cancelDeqVec(i) := Mux(compSel.valid, 385 compEntryOldestCancel.get(i), 386 Mux(simpSel.valid, simpEntryOldestCancel.get(i), enqEntryOldestCancel(i))) 387 } 388 } 389 } 390 391 io.valid := validVec.asUInt 392 io.issued := issuedVec.asUInt 393 io.canIssue := canIssueVec.asUInt 394 io.fuType := fuTypeVec 395 io.dataSources := dataSourceVec 396 io.srcWakeUpL1ExuOH.foreach(_ := srcWakeUpL1ExuOHVec.get) 397 io.loadDependency := loadDependencyVec 398 io.isFirstIssue.zipWithIndex.foreach{ case (isFirstIssue, deqIdx) => 399 isFirstIssue := io.deqSelOH(deqIdx).valid && Mux1H(io.deqSelOH(deqIdx).bits, isFirstIssueVec) 400 } 401 io.simpEntryEnqSelVec.foreach(_ := finalSimpTransSelVec.get.zip(enqEntryTransVec).map(x => x._1 & Fill(SimpEntryNum, x._2.valid))) 402 io.compEntryEnqSelVec.foreach(_ := finalCompTransSelVec.get.zip(compEnqVec.get).map(x => x._1 & Fill(CompEntryNum, x._2.valid))) 403 io.othersEntryEnqSelVec.foreach(_ := finalOthersTransSelVec.get.zip(enqEntryTransVec).map(x => x._1 & Fill(OthersEntryNum, x._2.valid))) 404 io.robIdx.foreach(_ := robIdxVec) 405 406 407 def EntriesConnect(in: CommonInBundle, out: CommonOutBundle, entryIdx: Int) = { 408 in.flush := io.flush 409 in.wakeUpFromWB := io.wakeUpFromWB 410 in.wakeUpFromIQ := io.wakeUpFromIQ 411 in.vlIsZero := io.vlIsZero 412 in.vlIsVlmax := io.vlIsVlmax 413 in.og0Cancel := io.og0Cancel 414 in.og1Cancel := io.og1Cancel 415 in.ldCancel := io.ldCancel 416 in.deqSel := deqSelVec(entryIdx) 417 in.deqPortIdxWrite := deqPortIdxWriteVec(entryIdx) 418 in.issueResp := issueRespVec(entryIdx) 419 if (params.isVecMemIQ) { 420 in.fromLsq.get.sqDeqPtr := io.vecMemIn.get.sqDeqPtr 421 in.fromLsq.get.lqDeqPtr := io.vecMemIn.get.lqDeqPtr 422 } 423 validVec(entryIdx) := out.valid 424 issuedVec(entryIdx) := out.issued 425 canIssueVec(entryIdx) := out.canIssue 426 fuTypeVec(entryIdx) := out.fuType 427 robIdxVec(entryIdx) := out.robIdx 428 dataSourceVec(entryIdx) := out.dataSource 429 isFirstIssueVec(entryIdx) := out.isFirstIssue 430 entries(entryIdx) := out.entry 431 deqPortIdxReadVec(entryIdx) := out.deqPortIdxRead 432 issueTimerVec(entryIdx) := out.issueTimerRead 433 loadDependencyVec(entryIdx) := out.entry.bits.status.mergedLoadDependency 434 cancelBypassVec(entryIdx) := out.cancelBypass 435 if (params.hasIQWakeUp) { 436 srcWakeUpL1ExuOHVec.get(entryIdx) := out.srcWakeUpL1ExuOH.get 437 } 438 if (params.needFeedBackSqIdx || params.needFeedBackLqIdx) { 439 sqIdxVec.get(entryIdx) := out.entry.bits.payload.sqIdx 440 lqIdxVec.get(entryIdx) := out.entry.bits.payload.lqIdx 441 } 442 entryInValidVec(entryIdx) := out.entryInValid 443 entryOutDeqValidVec(entryIdx) := out.entryOutDeqValid 444 entryOutTransValidVec(entryIdx) := out.entryOutTransValid 445 perfWakeupByWBVec(entryIdx) := out.perfWakeupByWB 446 if (params.hasIQWakeUp) { 447 perfLdCancelVec.get(entryIdx) := out.perfLdCancel.get 448 perfOg0CancelVec.get(entryIdx) := out.perfOg0Cancel.get 449 perfWakeupByIQVec.get(entryIdx) := out.perfWakeupByIQ.get 450 } 451 } 452 453 io.vecLdIn.foreach(dontTouch(_)) 454 455 // entries perf counter 456 // enq 457 for (i <- 0 until params.numEnq) { 458 XSPerfAccumulate(s"enqEntry_${i}_in_cnt", entryInValidVec(i)) 459 XSPerfAccumulate(s"enqEntry_${i}_out_deq_cnt", entryOutDeqValidVec(i)) 460 XSPerfAccumulate(s"enqEntry_${i}_out_trans_cnt", entryOutTransValidVec(i)) 461 } 462 // simple 463 for (i <- 0 until params.numSimp) { 464 XSPerfAccumulate(s"simpEntry_${i}_in_cnt", entryInValidVec(i + params.numEnq)) 465 XSPerfAccumulate(s"simpEntry_${i}_out_deq_cnt", entryOutDeqValidVec(i + params.numEnq)) 466 XSPerfAccumulate(s"simpEntry_${i}_out_trans_cnt", entryOutTransValidVec(i + params.numEnq)) 467 } 468 // complex 469 for (i <- 0 until params.numComp) { 470 XSPerfAccumulate(s"compEntry_${i}_in_cnt", entryInValidVec(i + params.numEnq + params.numSimp)) 471 XSPerfAccumulate(s"compEntry_${i}_out_deq_cnt", entryOutDeqValidVec(i + params.numEnq + params.numSimp)) 472 XSPerfAccumulate(s"compEntry_${i}_out_trans_cnt", entryOutTransValidVec(i + params.numEnq + params.numSimp)) 473 } 474 // total 475 XSPerfAccumulate(s"enqEntry_all_in_cnt", PopCount(entryInValidVec.take(params.numEnq))) 476 XSPerfAccumulate(s"enqEntry_all_out_deq_cnt", PopCount(entryOutDeqValidVec.take(params.numEnq))) 477 XSPerfAccumulate(s"enqEntry_all_out_trans_cnt", PopCount(entryOutTransValidVec.take(params.numEnq))) 478 for (srcIdx <- 0 until params.numRegSrc) { 479 XSPerfAccumulate(s"enqEntry_all_wakeup_wb_src${srcIdx}_cnt", PopCount(perfWakeupByWBVec.take(params.numEnq).map(_(srcIdx)))) 480 if (params.hasIQWakeUp) { 481 XSPerfAccumulate(s"enqEntry_all_ldCancel_src${srcIdx}_cnt", PopCount(perfLdCancelVec.get.take(params.numEnq).map(_(srcIdx)))) 482 XSPerfAccumulate(s"enqEntry_all_og0Cancel_src${srcIdx}_cnt", PopCount(perfOg0CancelVec.get.take(params.numEnq).map(_(srcIdx)))) 483 for (iqIdx <- 0 until params.numWakeupFromIQ) { 484 XSPerfAccumulate(s"enqEntry_all_wakeup_iq_from_exu${params.wakeUpSourceExuIdx(iqIdx)}_src${srcIdx}_cnt", PopCount(perfWakeupByIQVec.get.take(params.numEnq).map(_(srcIdx)(iqIdx)))) 485 } 486 } 487 } 488 489 XSPerfAccumulate(s"othersEntry_all_in_cnt", PopCount(entryInValidVec.drop(params.numEnq))) 490 XSPerfAccumulate(s"othersEntry_all_out_deq_cnt", PopCount(entryOutDeqValidVec.drop(params.numEnq))) 491 XSPerfAccumulate(s"othersEntry_all_out_trans_cnt", PopCount(entryOutTransValidVec.drop(params.numEnq))) 492 493 for (srcIdx <- 0 until params.numRegSrc) { 494 XSPerfAccumulate(s"othersEntry_all_wakeup_wb_src${srcIdx}_cnt", PopCount(perfWakeupByWBVec.drop(params.numEnq).map(_(srcIdx)))) 495 if (params.hasIQWakeUp) { 496 XSPerfAccumulate(s"othersEntry_all_ldCancel_src${srcIdx}_cnt", PopCount(perfLdCancelVec.get.drop(params.numEnq).map(_(srcIdx)))) 497 XSPerfAccumulate(s"othersEntry_all_og0Cancel_src${srcIdx}_cnt", PopCount(perfOg0CancelVec.get.drop(params.numEnq).map(_(srcIdx)))) 498 for (iqIdx <- 0 until params.numWakeupFromIQ) { 499 XSPerfAccumulate(s"othersEntry_all_wakeup_iq_from_exu${params.wakeUpSourceExuIdx(iqIdx)}_src${srcIdx}_cnt", PopCount(perfWakeupByIQVec.get.drop(params.numEnq).map(_(srcIdx)(iqIdx)))) 500 } 501 } 502 } 503 504 for (t <- FuType.functionNameMap.keys) { 505 val fuName = FuType.functionNameMap(t) 506 if (params.getFuCfgs.map(_.fuType == t).reduce(_ | _) && params.getFuCfgs.size > 1) { 507 for (srcIdx <- 0 until params.numRegSrc) { 508 XSPerfAccumulate(s"allEntry_futype_${fuName}_wakeup_wb_src${srcIdx}_cnt", PopCount(perfWakeupByWBVec.zip(fuTypeVec).map{ case(x, fu) => x(srcIdx) && fu(t.id) })) 509 if (params.hasIQWakeUp) { 510 XSPerfAccumulate(s"allEntry_futype_${fuName}_ldCancel_src${srcIdx}_cnt", PopCount(perfLdCancelVec.get.zip(fuTypeVec).map{ case(x, fu) => x(srcIdx) && fu(t.id) })) 511 XSPerfAccumulate(s"allEntry_futype_${fuName}_og0Cancel_src${srcIdx}_cnt", PopCount(perfOg0CancelVec.get.zip(fuTypeVec).map{ case(x, fu) => x(srcIdx) && fu(t.id) })) 512 for (iqIdx <- 0 until params.numWakeupFromIQ) { 513 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) })) 514 } 515 } 516 } 517 } 518 } 519} 520 521class EntriesIO(implicit p: Parameters, params: IssueBlockParams) extends XSBundle { 522 val flush = Flipped(ValidIO(new Redirect)) 523 //enq 524 val enq = Vec(params.numEnq, Flipped(ValidIO(new EntryBundle))) 525 val og0Resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 526 val og1Resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 527 val og2Resp = OptionWrapper(params.needOg2Resp, Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle)))) 528 //deq sel 529 val deqReady = Vec(params.numDeq, Input(Bool())) 530 val deqSelOH = Vec(params.numDeq, Flipped(ValidIO(UInt(params.numEntries.W)))) 531 val enqEntryOldestSel = Vec(params.numDeq, Flipped(ValidIO(UInt(params.numEnq.W)))) 532 val simpEntryOldestSel = OptionWrapper(params.hasCompAndSimp, Vec(params.numDeq, Flipped(ValidIO(UInt(params.numSimp.W))))) 533 val compEntryOldestSel = OptionWrapper(params.hasCompAndSimp, Vec(params.numDeq, Flipped(ValidIO(UInt(params.numComp.W))))) 534 val othersEntryOldestSel= OptionWrapper(params.isAllComp || params.isAllSimp, Vec(params.numDeq, Flipped(ValidIO(UInt((params.numEntries - params.numEnq).W))))) 535 val subDeqRequest = OptionWrapper(params.deqFuSame, Vec(params.numDeq, Input(UInt(params.numEntries.W)))) 536 val subDeqSelOH = OptionWrapper(params.deqFuSame, Vec(params.numDeq, Input(UInt(params.numEntries.W)))) 537 // wakeup 538 val wakeUpFromWB: MixedVec[ValidIO[IssueQueueWBWakeUpBundle]] = Flipped(params.genWBWakeUpSinkValidBundle) 539 val wakeUpFromIQ: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpSinkValidBundle) 540 val vlIsZero = Input(Bool()) 541 val vlIsVlmax = 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 srcWakeUpL1ExuOH = OptionWrapper(params.hasIQWakeUp, Vec(params.numEntries, Vec(params.numRegSrc, Output(ExuVec())))) 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 resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 575 }) 576 val robIdx = OptionWrapper(params.isVecMemIQ, Output(Vec(params.numEntries, new RobPtr))) 577 578 // trans 579 val simpEntryDeqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Input(UInt(params.numSimp.W)))) 580 val simpEntryEnqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Output(UInt(params.numSimp.W)))) 581 val compEntryEnqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Output(UInt(params.numComp.W)))) 582 val othersEntryEnqSelVec = OptionWrapper(params.isAllComp || params.isAllSimp, Vec(params.numEnq, Output(UInt((params.numEntries - params.numEnq).W)))) 583 584 def wakeup = wakeUpFromWB ++ wakeUpFromIQ 585} 586