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