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.vlFromIntIsZero := io.vlFromIntIsZero 412 in.vlFromIntIsVlmax := io.vlFromIntIsVlmax 413 in.vlFromVfIsZero := io.vlFromVfIsZero 414 in.vlFromVfIsVlmax := io.vlFromVfIsVlmax 415 in.og0Cancel := io.og0Cancel 416 in.og1Cancel := io.og1Cancel 417 in.ldCancel := io.ldCancel 418 in.deqSel := deqSelVec(entryIdx) 419 in.deqPortIdxWrite := deqPortIdxWriteVec(entryIdx) 420 in.issueResp := issueRespVec(entryIdx) 421 if (params.isVecMemIQ) { 422 in.fromLsq.get.sqDeqPtr := io.vecMemIn.get.sqDeqPtr 423 in.fromLsq.get.lqDeqPtr := io.vecMemIn.get.lqDeqPtr 424 } 425 validVec(entryIdx) := out.valid 426 issuedVec(entryIdx) := out.issued 427 canIssueVec(entryIdx) := out.canIssue 428 fuTypeVec(entryIdx) := out.fuType 429 robIdxVec(entryIdx) := out.robIdx 430 dataSourceVec(entryIdx) := out.dataSource 431 isFirstIssueVec(entryIdx) := out.isFirstIssue 432 entries(entryIdx) := out.entry 433 deqPortIdxReadVec(entryIdx) := out.deqPortIdxRead 434 issueTimerVec(entryIdx) := out.issueTimerRead 435 loadDependencyVec(entryIdx) := out.entry.bits.status.mergedLoadDependency 436 cancelBypassVec(entryIdx) := out.cancelBypass 437 if (params.hasIQWakeUp) { 438 srcWakeUpL1ExuOHVec.get(entryIdx) := out.srcWakeUpL1ExuOH.get 439 } 440 if (params.needFeedBackSqIdx || params.needFeedBackLqIdx) { 441 sqIdxVec.get(entryIdx) := out.entry.bits.payload.sqIdx 442 lqIdxVec.get(entryIdx) := out.entry.bits.payload.lqIdx 443 } 444 entryInValidVec(entryIdx) := out.entryInValid 445 entryOutDeqValidVec(entryIdx) := out.entryOutDeqValid 446 entryOutTransValidVec(entryIdx) := out.entryOutTransValid 447 perfWakeupByWBVec(entryIdx) := out.perfWakeupByWB 448 if (params.hasIQWakeUp) { 449 perfLdCancelVec.get(entryIdx) := out.perfLdCancel.get 450 perfOg0CancelVec.get(entryIdx) := out.perfOg0Cancel.get 451 perfWakeupByIQVec.get(entryIdx) := out.perfWakeupByIQ.get 452 } 453 } 454 455 io.vecLdIn.foreach(dontTouch(_)) 456 457 // entries perf counter 458 // enq 459 for (i <- 0 until params.numEnq) { 460 XSPerfAccumulate(s"enqEntry_${i}_in_cnt", entryInValidVec(i)) 461 XSPerfAccumulate(s"enqEntry_${i}_out_deq_cnt", entryOutDeqValidVec(i)) 462 XSPerfAccumulate(s"enqEntry_${i}_out_trans_cnt", entryOutTransValidVec(i)) 463 } 464 // simple 465 for (i <- 0 until params.numSimp) { 466 XSPerfAccumulate(s"simpEntry_${i}_in_cnt", entryInValidVec(i + params.numEnq)) 467 XSPerfAccumulate(s"simpEntry_${i}_out_deq_cnt", entryOutDeqValidVec(i + params.numEnq)) 468 XSPerfAccumulate(s"simpEntry_${i}_out_trans_cnt", entryOutTransValidVec(i + params.numEnq)) 469 } 470 // complex 471 for (i <- 0 until params.numComp) { 472 XSPerfAccumulate(s"compEntry_${i}_in_cnt", entryInValidVec(i + params.numEnq + params.numSimp)) 473 XSPerfAccumulate(s"compEntry_${i}_out_deq_cnt", entryOutDeqValidVec(i + params.numEnq + params.numSimp)) 474 XSPerfAccumulate(s"compEntry_${i}_out_trans_cnt", entryOutTransValidVec(i + params.numEnq + params.numSimp)) 475 } 476 // total 477 XSPerfAccumulate(s"enqEntry_all_in_cnt", PopCount(entryInValidVec.take(params.numEnq))) 478 XSPerfAccumulate(s"enqEntry_all_out_deq_cnt", PopCount(entryOutDeqValidVec.take(params.numEnq))) 479 XSPerfAccumulate(s"enqEntry_all_out_trans_cnt", PopCount(entryOutTransValidVec.take(params.numEnq))) 480 for (srcIdx <- 0 until params.numRegSrc) { 481 XSPerfAccumulate(s"enqEntry_all_wakeup_wb_src${srcIdx}_cnt", PopCount(perfWakeupByWBVec.take(params.numEnq).map(_(srcIdx)))) 482 if (params.hasIQWakeUp) { 483 XSPerfAccumulate(s"enqEntry_all_ldCancel_src${srcIdx}_cnt", PopCount(perfLdCancelVec.get.take(params.numEnq).map(_(srcIdx)))) 484 XSPerfAccumulate(s"enqEntry_all_og0Cancel_src${srcIdx}_cnt", PopCount(perfOg0CancelVec.get.take(params.numEnq).map(_(srcIdx)))) 485 for (iqIdx <- 0 until params.numWakeupFromIQ) { 486 XSPerfAccumulate(s"enqEntry_all_wakeup_iq_from_exu${params.wakeUpSourceExuIdx(iqIdx)}_src${srcIdx}_cnt", PopCount(perfWakeupByIQVec.get.take(params.numEnq).map(_(srcIdx)(iqIdx)))) 487 } 488 } 489 } 490 491 XSPerfAccumulate(s"othersEntry_all_in_cnt", PopCount(entryInValidVec.drop(params.numEnq))) 492 XSPerfAccumulate(s"othersEntry_all_out_deq_cnt", PopCount(entryOutDeqValidVec.drop(params.numEnq))) 493 XSPerfAccumulate(s"othersEntry_all_out_trans_cnt", PopCount(entryOutTransValidVec.drop(params.numEnq))) 494 495 for (srcIdx <- 0 until params.numRegSrc) { 496 XSPerfAccumulate(s"othersEntry_all_wakeup_wb_src${srcIdx}_cnt", PopCount(perfWakeupByWBVec.drop(params.numEnq).map(_(srcIdx)))) 497 if (params.hasIQWakeUp) { 498 XSPerfAccumulate(s"othersEntry_all_ldCancel_src${srcIdx}_cnt", PopCount(perfLdCancelVec.get.drop(params.numEnq).map(_(srcIdx)))) 499 XSPerfAccumulate(s"othersEntry_all_og0Cancel_src${srcIdx}_cnt", PopCount(perfOg0CancelVec.get.drop(params.numEnq).map(_(srcIdx)))) 500 for (iqIdx <- 0 until params.numWakeupFromIQ) { 501 XSPerfAccumulate(s"othersEntry_all_wakeup_iq_from_exu${params.wakeUpSourceExuIdx(iqIdx)}_src${srcIdx}_cnt", PopCount(perfWakeupByIQVec.get.drop(params.numEnq).map(_(srcIdx)(iqIdx)))) 502 } 503 } 504 } 505 506 for (t <- FuType.functionNameMap.keys) { 507 val fuName = FuType.functionNameMap(t) 508 if (params.getFuCfgs.map(_.fuType == t).reduce(_ | _) && params.getFuCfgs.size > 1) { 509 for (srcIdx <- 0 until params.numRegSrc) { 510 XSPerfAccumulate(s"allEntry_futype_${fuName}_wakeup_wb_src${srcIdx}_cnt", PopCount(perfWakeupByWBVec.zip(fuTypeVec).map{ case(x, fu) => x(srcIdx) && fu(t.id) })) 511 if (params.hasIQWakeUp) { 512 XSPerfAccumulate(s"allEntry_futype_${fuName}_ldCancel_src${srcIdx}_cnt", PopCount(perfLdCancelVec.get.zip(fuTypeVec).map{ case(x, fu) => x(srcIdx) && fu(t.id) })) 513 XSPerfAccumulate(s"allEntry_futype_${fuName}_og0Cancel_src${srcIdx}_cnt", PopCount(perfOg0CancelVec.get.zip(fuTypeVec).map{ case(x, fu) => x(srcIdx) && fu(t.id) })) 514 for (iqIdx <- 0 until params.numWakeupFromIQ) { 515 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) })) 516 } 517 } 518 } 519 } 520 } 521} 522 523class EntriesIO(implicit p: Parameters, params: IssueBlockParams) extends XSBundle { 524 val flush = Flipped(ValidIO(new Redirect)) 525 //enq 526 val enq = Vec(params.numEnq, Flipped(ValidIO(new EntryBundle))) 527 val og0Resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 528 val og1Resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 529 val og2Resp = OptionWrapper(params.needOg2Resp, Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle)))) 530 //deq sel 531 val deqReady = Vec(params.numDeq, Input(Bool())) 532 val deqSelOH = Vec(params.numDeq, Flipped(ValidIO(UInt(params.numEntries.W)))) 533 val enqEntryOldestSel = Vec(params.numDeq, Flipped(ValidIO(UInt(params.numEnq.W)))) 534 val simpEntryOldestSel = OptionWrapper(params.hasCompAndSimp, Vec(params.numDeq, Flipped(ValidIO(UInt(params.numSimp.W))))) 535 val compEntryOldestSel = OptionWrapper(params.hasCompAndSimp, Vec(params.numDeq, Flipped(ValidIO(UInt(params.numComp.W))))) 536 val othersEntryOldestSel= OptionWrapper(params.isAllComp || params.isAllSimp, Vec(params.numDeq, Flipped(ValidIO(UInt((params.numEntries - params.numEnq).W))))) 537 val subDeqRequest = OptionWrapper(params.deqFuSame, Vec(params.numDeq, Input(UInt(params.numEntries.W)))) 538 val subDeqSelOH = OptionWrapper(params.deqFuSame, Vec(params.numDeq, Input(UInt(params.numEntries.W)))) 539 // wakeup 540 val wakeUpFromWB: MixedVec[ValidIO[IssueQueueWBWakeUpBundle]] = Flipped(params.genWBWakeUpSinkValidBundle) 541 val wakeUpFromIQ: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpSinkValidBundle) 542 val vlFromIntIsZero = Input(Bool()) 543 val vlFromIntIsVlmax = Input(Bool()) 544 val vlFromVfIsZero = Input(Bool()) 545 val vlFromVfIsVlmax = Input(Bool()) 546 val og0Cancel = Input(ExuVec()) 547 val og1Cancel = Input(ExuVec()) 548 val ldCancel = Vec(backendParams.LdExuCnt, Flipped(new LoadCancelIO)) 549 //entries status 550 val valid = Output(UInt(params.numEntries.W)) 551 val issued = Output(UInt(params.numEntries.W)) 552 val canIssue = Output(UInt(params.numEntries.W)) 553 val fuType = Vec(params.numEntries, Output(FuType())) 554 val dataSources = Vec(params.numEntries, Vec(params.numRegSrc, Output(DataSource()))) 555 val loadDependency = Vec(params.numEntries, Vec(LoadPipelineWidth, UInt(LoadDependencyWidth.W))) 556 val srcWakeUpL1ExuOH = OptionWrapper(params.hasIQWakeUp, Vec(params.numEntries, Vec(params.numRegSrc, Output(ExuVec())))) 557 //deq status 558 val isFirstIssue = Vec(params.numDeq, Output(Bool())) 559 val deqEntry = Vec(params.numDeq, ValidIO(new EntryBundle)) 560 val cancelDeqVec = Vec(params.numDeq, Output(Bool())) 561 562 // load/hybird only 563 val fromLoad = OptionWrapper(params.isLdAddrIQ || params.isHyAddrIQ, new Bundle { 564 val finalIssueResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 565 val memAddrIssueResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 566 }) 567 // mem only 568 val fromMem = OptionWrapper(params.isMemAddrIQ, new Bundle { 569 val slowResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 570 val fastResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 571 }) 572 // vec mem only 573 val vecMemIn = OptionWrapper(params.isVecMemIQ, new Bundle { 574 val sqDeqPtr = Input(new SqPtr) 575 val lqDeqPtr = Input(new LqPtr) 576 }) 577 val vecLdIn = OptionWrapper(params.isVecLduIQ, new Bundle { 578 val resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 579 }) 580 val robIdx = OptionWrapper(params.isVecMemIQ, Output(Vec(params.numEntries, new RobPtr))) 581 582 // trans 583 val simpEntryDeqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Input(UInt(params.numSimp.W)))) 584 val simpEntryEnqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Output(UInt(params.numSimp.W)))) 585 val compEntryEnqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Output(UInt(params.numComp.W)))) 586 val othersEntryEnqSelVec = OptionWrapper(params.isAllComp || params.isAllSimp, Vec(params.numEnq, Output(UInt((params.numEntries - params.numEnq).W)))) 587 588 def wakeup = wakeUpFromWB ++ wakeUpFromIQ 589} 590