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.backend.issue.EntryBundles._ 17import xiangshan.mem.{LqPtr, SqPtr} 18import xiangshan.mem.Bundles.MemWaitUpdateReqBundle 19 20class Entries(implicit p: Parameters, params: IssueBlockParams) extends XSModule { 21 override def desiredName: String = params.getEntryName 22 23 require(params.numEnq <= 2, "number of enq should be no more than 2") 24 25 private val EnqEntryNum = params.numEnq 26 private val OthersEntryNum = params.numEntries - params.numEnq 27 private val SimpEntryNum = params.numSimp 28 private val CompEntryNum = params.numComp 29 val io = IO(new EntriesIO) 30 31 // only memAddrIQ use it 32 val memEtyResps: Seq[ValidIO[EntryDeqRespBundle]] = { 33 val resps = 34 if (params.isLdAddrIQ && !params.isStAddrIQ) //LDU 35 Seq(io.fromLoad.get.finalIssueResp, io.fromLoad.get.memAddrIssueResp) 36 else if (params.isLdAddrIQ && params.isStAddrIQ || params.isHyAddrIQ) //HYU 37 Seq(io.fromLoad.get.finalIssueResp, io.fromLoad.get.memAddrIssueResp, io.fromMem.get.fastResp, io.fromMem.get.slowResp) 38 else if (params.isStAddrIQ) //STU 39 Seq(io.fromMem.get.slowResp) 40 else if (params.isVecLduIQ && params.isVecStuIQ) // Vector store IQ need no vecLdIn.resp, but for now vector store share the vector load IQ 41 Seq(io.vecLdIn.get.resp, io.fromMem.get.slowResp, io.vecLdIn.get.finalIssueResp) 42 else Seq() 43 if (params.isMemAddrIQ) { 44 println(s"[${this.desiredName}] resp: {" + 45 s"og0Resp: ${resps.contains(io.og0Resp)}, " + 46 s"og1Resp: ${resps.contains(io.og1Resp)}, " + 47 s"finalResp: ${io.fromLoad.nonEmpty && resps.contains(io.fromLoad.get.finalIssueResp)}, " + 48 s"loadBorderResp: ${io.fromLoad.nonEmpty && resps.contains(io.fromLoad.get.memAddrIssueResp)}, " + 49 s"memFastResp: ${io.fromMem.nonEmpty && resps.contains(io.fromMem.get.fastResp)}, " + 50 s"memSlowResp: ${io.fromMem.nonEmpty && resps.contains(io.fromMem.get.slowResp)}, " + 51 s"vecLoadBorderResp: ${io.vecLdIn.nonEmpty && resps.contains(io.vecLdIn.get.resp)}, " + 52 s"}" 53 ) 54 } 55 resps.flatten 56 } 57 58 val resps: Vec[Vec[ValidIO[EntryDeqRespBundle]]] = Wire(Vec(4, chiselTypeOf(io.og0Resp))) 59 60 if (params.needOg2Resp) 61 resps := Seq(io.og0Resp, io.og1Resp, io.og2Resp.get, WireDefault(0.U.asTypeOf(io.og0Resp))) 62 else 63 resps := Seq(io.og0Resp, io.og1Resp, WireDefault(0.U.asTypeOf(io.og0Resp)), WireDefault(0.U.asTypeOf(io.og0Resp))) 64 65 66 67 //Module 68 val enqEntries = Seq.fill(EnqEntryNum)(Module(EnqEntry(isComp = true)(p, params))) 69 val othersEntriesSimp = Seq.fill(SimpEntryNum)(Module(OthersEntry(isComp = false)(p, params))) 70 val othersEntriesComp = Seq.fill(CompEntryNum)(Module(OthersEntry(isComp = true)(p, params))) 71 val othersEntries = othersEntriesSimp ++ othersEntriesComp 72 val othersTransPolicy = OptionWrapper(params.isAllComp || params.isAllSimp, Module(new EnqPolicy)) 73 val simpTransPolicy = OptionWrapper(params.hasCompAndSimp, Module(new EnqPolicy)) 74 val compTransPolicy = OptionWrapper(params.hasCompAndSimp, Module(new EnqPolicy)) 75 76 //Wire 77 //entries status 78 val entries = Wire(Vec(params.numEntries, ValidIO(new EntryBundle))) 79 val robIdxVec = Wire(Vec(params.numEntries, new RobPtr)) 80 val validVec = Wire(Vec(params.numEntries, Bool())) 81 val issuedVec = Wire(Vec(params.numEntries, Bool())) 82 val validForTrans = VecInit(validVec.zip(issuedVec).map(x => x._1 && !x._2)) 83 val canIssueVec = Wire(Vec(params.numEntries, Bool())) 84 val fuTypeVec = Wire(Vec(params.numEntries, FuType())) 85 val isFirstIssueVec = Wire(Vec(params.numEntries, Bool())) 86 val issueTimerVec = Wire(Vec(params.numEntries, UInt(2.W))) 87 val sqIdxVec = OptionWrapper(params.needFeedBackSqIdx || params.needFeedBackLqIdx, Wire(Vec(params.numEntries, new SqPtr()))) 88 val lqIdxVec = OptionWrapper(params.needFeedBackSqIdx || params.needFeedBackLqIdx, Wire(Vec(params.numEntries, new LqPtr()))) 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 exuSourceVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Vec(params.numRegSrc, ExuSource())))) 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 := io.wakeUpFromWBDelayed 140 enqEntry.io.enqDelayIn1.wakeUpFromIQ := io.wakeUpFromIQDelayed 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) 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, 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 && validForTrans(0) 184 othersTransSelVec.get(0).bits := othersTransPolicy.get.io.enqSelOHVec(0).bits 185 if (params.numEnq == 2) { 186 othersTransSelVec.get(1).valid := Mux(!validForTrans(0), othersTransPolicy.get.io.enqSelOHVec(0).valid, othersTransPolicy.get.io.enqSelOHVec(1).valid) && validForTrans(1) 187 othersTransSelVec.get(1).bits := Mux(!validForTrans(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 && validForTrans(0) 222 simpTransSelVec.get(0).bits := simpTransPolicy.get.io.enqSelOHVec(0).bits 223 compTransSelVec.get(0).valid := compTransPolicy.get.io.enqSelOHVec(0).valid && validForTrans(0) 224 compTransSelVec.get(0).bits := compTransPolicy.get.io.enqSelOHVec(0).bits 225 if (params.numEnq == 2) { 226 simpTransSelVec.get(1).valid := Mux(!validForTrans(0), simpTransPolicy.get.io.enqSelOHVec(0).valid, simpTransPolicy.get.io.enqSelOHVec(1).valid) && validForTrans(1) 227 simpTransSelVec.get(1).bits := Mux(!validForTrans(0), simpTransPolicy.get.io.enqSelOHVec(0).bits, simpTransPolicy.get.io.enqSelOHVec(1).bits) 228 compTransSelVec.get(1).valid := Mux(!validForTrans(0), compTransPolicy.get.io.enqSelOHVec(0).valid, compTransPolicy.get.io.enqSelOHVec(1).valid) && validForTrans(1) 229 compTransSelVec.get(1).bits := Mux(!validForTrans(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.needFeedBackSqIdx || params.needFeedBackLqIdx) { 272 issueRespVec.lazyZip(sqIdxVec.get.zip(lqIdxVec.get)).lazyZip(issueTimerVec.lazyZip(deqPortIdxReadVec)).foreach { case (issueResp, (sqIdx, lqIdx), (issueTimer, deqPortIdx)) => 273 val respInDatapath = if (!params.isVecMemIQ) resps(issueTimer(0))(deqPortIdx) 274 else resps(issueTimer)(deqPortIdx) 275 val respAfterDatapath = Wire(chiselTypeOf(respInDatapath)) 276 val hitRespsVec = VecInit(memEtyResps.map(x => 277 x.valid && 278 (if (params.needFeedBackSqIdx) x.bits.sqIdx.get === sqIdx else true.B) && 279 (if (params.needFeedBackLqIdx) x.bits.lqIdx.get === lqIdx else true.B) 280 ).toSeq) 281 respAfterDatapath.valid := hitRespsVec.reduce(_ | _) 282 respAfterDatapath.bits := (if (memEtyResps.size == 1) memEtyResps.head.bits 283 else Mux1H(hitRespsVec, memEtyResps.map(_.bits).toSeq)) 284 issueResp := (if (!params.isVecMemIQ) Mux(issueTimer(1), respAfterDatapath, respInDatapath) 285 else Mux(issueTimer === "b11".U, respAfterDatapath, respInDatapath)) 286 } 287 } 288 else { 289 issueRespVec.lazyZip(issueTimerVec.lazyZip(deqPortIdxReadVec)).foreach { case (issueResp, (issueTimer, deqPortIdx)) => 290 val Resp = resps(issueTimer)(deqPortIdx) 291 issueResp := Resp 292 } 293 } 294 295 //deq 296 val enqEntryOldest = Wire(Vec(params.numDeq, ValidIO(new EntryBundle))) 297 val simpEntryOldest = OptionWrapper(params.hasCompAndSimp, Wire(Vec(params.numDeq, ValidIO(new EntryBundle)))) 298 val compEntryOldest = OptionWrapper(params.hasCompAndSimp, Wire(Vec(params.numDeq, ValidIO(new EntryBundle)))) 299 val othersEntryOldest = OptionWrapper(params.isAllComp || params.isAllSimp, Wire(Vec(params.numDeq, ValidIO(new EntryBundle)))) 300 val enqEntryOldestCancel = Wire(Vec(params.numDeq, Bool())) 301 val simpEntryOldestCancel = OptionWrapper(params.hasCompAndSimp, Wire(Vec(params.numDeq, Bool()))) 302 val compEntryOldestCancel = OptionWrapper(params.hasCompAndSimp, Wire(Vec(params.numDeq, Bool()))) 303 val othersEntryOldestCancel = OptionWrapper(params.isAllComp || params.isAllSimp, Wire(Vec(params.numDeq, Bool()))) 304 305 io.enqEntryOldestSel.zipWithIndex.map { case (sel, deqIdx) => 306 enqEntryOldest(deqIdx) := Mux1H(sel.bits, entries.take(EnqEntryNum)) 307 enqEntryOldestCancel(deqIdx) := Mux1H(sel.bits, cancelBypassVec.take(EnqEntryNum)) 308 } 309 310 if (params.isAllComp || params.isAllSimp) { 311 io.othersEntryOldestSel.get.zipWithIndex.map { case (sel, deqIdx) => 312 othersEntryOldest.get(deqIdx) := Mux1H(sel.bits, entries.drop(EnqEntryNum)) 313 othersEntryOldestCancel.get(deqIdx) := Mux1H(sel.bits, cancelBypassVec.drop(EnqEntryNum)) 314 } 315 } 316 else { 317 io.simpEntryOldestSel.get.zipWithIndex.map { case (sel, deqIdx) => 318 simpEntryOldest.get(deqIdx) := Mux1H(sel.bits, entries.drop(EnqEntryNum).take(SimpEntryNum)) 319 simpEntryOldestCancel.get(deqIdx) := Mux1H(sel.bits, cancelBypassVec.drop(EnqEntryNum).take(SimpEntryNum)) 320 } 321 io.compEntryOldestSel.get.zipWithIndex.map { case (sel, deqIdx) => 322 compEntryOldest.get(deqIdx) := Mux1H(sel.bits, entries.drop(EnqEntryNum).takeRight(CompEntryNum)) 323 compEntryOldestCancel.get(deqIdx) := Mux1H(sel.bits, cancelBypassVec.drop(EnqEntryNum).takeRight(CompEntryNum)) 324 } 325 } 326 327 if (params.deqFuSame) { 328 val subDeqPolicyEntryVec = Wire(Vec(params.numDeq, ValidIO(new EntryBundle))) 329 val subDeqPolicyValidVec = Wire(Vec(params.numDeq, Bool())) 330 val subDeqPolicyCancelBypassVec = Wire(Vec(params.numDeq, Bool())) 331 332 subDeqPolicyValidVec(0) := PopCount(io.subDeqRequest.get(0)) >= 1.U 333 subDeqPolicyValidVec(1) := PopCount(io.subDeqRequest.get(0)) >= 2.U 334 335 if (params.isAllComp || params.isAllSimp) { 336 subDeqPolicyEntryVec(0) := PriorityMux(io.subDeqRequest.get(0), entries) 337 subDeqPolicyEntryVec(1) := PriorityMux(Reverse(io.subDeqRequest.get(0)), entries.reverse) 338 subDeqPolicyCancelBypassVec(0) := PriorityMux(io.subDeqRequest.get(0), cancelBypassVec) 339 subDeqPolicyCancelBypassVec(1) := PriorityMux(Reverse(io.subDeqRequest.get(0)), cancelBypassVec.reverse) 340 341 io.deqEntry(0) := Mux(io.othersEntryOldestSel.get(0).valid, othersEntryOldest.get(0), subDeqPolicyEntryVec(1)) 342 io.deqEntry(1) := subDeqPolicyEntryVec(0) 343 io.cancelDeqVec(0) := Mux(io.othersEntryOldestSel.get(0).valid, othersEntryOldestCancel.get(0), subDeqPolicyCancelBypassVec(1)) 344 io.cancelDeqVec(1) := subDeqPolicyCancelBypassVec(0) 345 } 346 else { 347 subDeqPolicyEntryVec(0) := PriorityMux(Reverse(io.subDeqRequest.get(0)), entries.reverse) 348 subDeqPolicyEntryVec(1) := PriorityMux(io.subDeqRequest.get(0), entries) 349 subDeqPolicyCancelBypassVec(0) := PriorityMux(Reverse(io.subDeqRequest.get(0)), cancelBypassVec.reverse) 350 subDeqPolicyCancelBypassVec(1) := PriorityMux(io.subDeqRequest.get(0), cancelBypassVec) 351 352 io.deqEntry(0) := Mux(io.compEntryOldestSel.get(0).valid, 353 compEntryOldest.get(0), 354 Mux(io.simpEntryOldestSel.get(0).valid, simpEntryOldest.get(0), subDeqPolicyEntryVec(1))) 355 io.deqEntry(1) := subDeqPolicyEntryVec(0) 356 io.cancelDeqVec(0) := Mux(io.compEntryOldestSel.get(0).valid, 357 compEntryOldestCancel.get(0), 358 Mux(io.simpEntryOldestSel.get(0).valid, simpEntryOldestCancel.get(0), subDeqPolicyCancelBypassVec(1))) 359 io.cancelDeqVec(1) := subDeqPolicyCancelBypassVec(0) 360 } 361 362 when (subDeqPolicyValidVec(0)) { 363 assert(Mux1H(io.subDeqSelOH.get(0), entries).bits.status.robIdx === subDeqPolicyEntryVec(0).bits.status.robIdx, "subDeqSelOH(0) is not the same\n") 364 } 365 when (subDeqPolicyValidVec(1)) { 366 assert(Mux1H(io.subDeqSelOH.get(1), entries).bits.status.robIdx === subDeqPolicyEntryVec(1).bits.status.robIdx, "subDeqSelOH(1) is not the same\n") 367 } 368 } 369 else { 370 if (params.isAllComp || params.isAllSimp) { 371 io.othersEntryOldestSel.get.zipWithIndex.foreach { case (sel, i) => 372 io.deqEntry(i) := Mux(sel.valid, othersEntryOldest.get(i), enqEntryOldest(i)) 373 io.cancelDeqVec(i) := Mux(sel.valid, othersEntryOldestCancel.get(i), enqEntryOldestCancel(i)) 374 } 375 } 376 else { 377 io.compEntryOldestSel.get.zip(io.simpEntryOldestSel.get).zipWithIndex.foreach { case ((compSel, simpSel), i) => 378 io.deqEntry(i) := Mux(compSel.valid, 379 compEntryOldest.get(i), 380 Mux(simpSel.valid, simpEntryOldest.get(i), enqEntryOldest(i))) 381 io.cancelDeqVec(i) := Mux(compSel.valid, 382 compEntryOldestCancel.get(i), 383 Mux(simpSel.valid, simpEntryOldestCancel.get(i), enqEntryOldestCancel(i))) 384 } 385 } 386 } 387 388 io.valid := validVec.asUInt 389 io.issued := issuedVec.asUInt 390 io.canIssue := canIssueVec.asUInt 391 io.fuType := fuTypeVec 392 io.dataSources := dataSourceVec 393 io.exuSources.foreach(_ := exuSourceVec.get) 394 io.loadDependency := loadDependencyVec 395 io.isFirstIssue.zipWithIndex.foreach{ case (isFirstIssue, deqIdx) => 396 isFirstIssue := io.deqSelOH(deqIdx).valid && Mux1H(io.deqSelOH(deqIdx).bits, isFirstIssueVec) 397 } 398 io.simpEntryEnqSelVec.foreach(_ := finalSimpTransSelVec.get.zip(enqEntryTransVec).map(x => x._1 & Fill(SimpEntryNum, x._2.valid))) 399 io.compEntryEnqSelVec.foreach(_ := finalCompTransSelVec.get.zip(compEnqVec.get).map(x => x._1 & Fill(CompEntryNum, x._2.valid))) 400 io.othersEntryEnqSelVec.foreach(_ := finalOthersTransSelVec.get.zip(enqEntryTransVec).map(x => x._1 & Fill(OthersEntryNum, x._2.valid))) 401 io.robIdx.foreach(_ := robIdxVec) 402 403 404 def EntriesConnect(in: CommonInBundle, out: CommonOutBundle, entryIdx: Int) = { 405 in.flush := io.flush 406 in.wakeUpFromWB := io.wakeUpFromWB 407 in.wakeUpFromIQ := io.wakeUpFromIQ 408 in.vlFromIntIsZero := io.vlFromIntIsZero 409 in.vlFromIntIsVlmax := io.vlFromIntIsVlmax 410 in.vlFromVfIsZero := io.vlFromVfIsZero 411 in.vlFromVfIsVlmax := io.vlFromVfIsVlmax 412 in.og0Cancel := io.og0Cancel 413 in.og1Cancel := io.og1Cancel 414 in.ldCancel := io.ldCancel 415 in.deqSel := deqSelVec(entryIdx) 416 in.deqPortIdxWrite := deqPortIdxWriteVec(entryIdx) 417 in.issueResp := issueRespVec(entryIdx) 418 if (params.isVecMemIQ) { 419 in.fromLsq.get.sqDeqPtr := io.vecMemIn.get.sqDeqPtr 420 in.fromLsq.get.lqDeqPtr := io.vecMemIn.get.lqDeqPtr 421 } 422 validVec(entryIdx) := out.valid 423 issuedVec(entryIdx) := out.issued 424 canIssueVec(entryIdx) := out.canIssue 425 fuTypeVec(entryIdx) := out.fuType 426 robIdxVec(entryIdx) := out.robIdx 427 dataSourceVec(entryIdx) := out.dataSources 428 isFirstIssueVec(entryIdx) := out.isFirstIssue 429 entries(entryIdx) := out.entry 430 deqPortIdxReadVec(entryIdx) := out.deqPortIdxRead 431 issueTimerVec(entryIdx) := out.issueTimerRead 432 loadDependencyVec(entryIdx) := out.entry.bits.status.mergedLoadDependency 433 cancelBypassVec(entryIdx) := out.cancelBypass 434 exuSourceVec.foreach(_(entryIdx) := out.exuSources.get) 435 if (params.needFeedBackSqIdx || params.needFeedBackLqIdx) { 436 sqIdxVec.get(entryIdx) := out.entry.bits.payload.sqIdx 437 lqIdxVec.get(entryIdx) := out.entry.bits.payload.lqIdx 438 } 439 entryInValidVec(entryIdx) := out.entryInValid 440 entryOutDeqValidVec(entryIdx) := out.entryOutDeqValid 441 entryOutTransValidVec(entryIdx) := out.entryOutTransValid 442 perfWakeupByWBVec(entryIdx) := out.perfWakeupByWB 443 if (params.hasIQWakeUp) { 444 perfLdCancelVec.get(entryIdx) := out.perfLdCancel.get 445 perfOg0CancelVec.get(entryIdx) := out.perfOg0Cancel.get 446 perfWakeupByIQVec.get(entryIdx) := out.perfWakeupByIQ.get 447 } 448 } 449 450 io.vecLdIn.foreach(dontTouch(_)) 451 452 // entries perf counter 453 // enq 454 for (i <- 0 until params.numEnq) { 455 XSPerfAccumulate(s"enqEntry_${i}_in_cnt", entryInValidVec(i)) 456 XSPerfAccumulate(s"enqEntry_${i}_out_deq_cnt", entryOutDeqValidVec(i)) 457 XSPerfAccumulate(s"enqEntry_${i}_out_trans_cnt", entryOutTransValidVec(i)) 458 } 459 // simple 460 for (i <- 0 until params.numSimp) { 461 XSPerfAccumulate(s"simpEntry_${i}_in_cnt", entryInValidVec(i + params.numEnq)) 462 XSPerfAccumulate(s"simpEntry_${i}_out_deq_cnt", entryOutDeqValidVec(i + params.numEnq)) 463 XSPerfAccumulate(s"simpEntry_${i}_out_trans_cnt", entryOutTransValidVec(i + params.numEnq)) 464 } 465 // complex 466 for (i <- 0 until params.numComp) { 467 XSPerfAccumulate(s"compEntry_${i}_in_cnt", entryInValidVec(i + params.numEnq + params.numSimp)) 468 XSPerfAccumulate(s"compEntry_${i}_out_deq_cnt", entryOutDeqValidVec(i + params.numEnq + params.numSimp)) 469 XSPerfAccumulate(s"compEntry_${i}_out_trans_cnt", entryOutTransValidVec(i + params.numEnq + params.numSimp)) 470 } 471 // total 472 XSPerfAccumulate(s"enqEntry_all_in_cnt", PopCount(entryInValidVec.take(params.numEnq))) 473 XSPerfAccumulate(s"enqEntry_all_out_deq_cnt", PopCount(entryOutDeqValidVec.take(params.numEnq))) 474 XSPerfAccumulate(s"enqEntry_all_out_trans_cnt", PopCount(entryOutTransValidVec.take(params.numEnq))) 475 for (srcIdx <- 0 until params.numRegSrc) { 476 XSPerfAccumulate(s"enqEntry_all_wakeup_wb_src${srcIdx}_cnt", PopCount(perfWakeupByWBVec.take(params.numEnq).map(_(srcIdx)))) 477 if (params.hasIQWakeUp) { 478 XSPerfAccumulate(s"enqEntry_all_ldCancel_src${srcIdx}_cnt", PopCount(perfLdCancelVec.get.take(params.numEnq).map(_(srcIdx)))) 479 XSPerfAccumulate(s"enqEntry_all_og0Cancel_src${srcIdx}_cnt", PopCount(perfOg0CancelVec.get.take(params.numEnq).map(_(srcIdx)))) 480 for (iqIdx <- 0 until params.numWakeupFromIQ) { 481 XSPerfAccumulate(s"enqEntry_all_wakeup_iq_from_exu${params.wakeUpSourceExuIdx(iqIdx)}_src${srcIdx}_cnt", PopCount(perfWakeupByIQVec.get.take(params.numEnq).map(_(srcIdx)(iqIdx)))) 482 } 483 } 484 } 485 486 XSPerfAccumulate(s"othersEntry_all_in_cnt", PopCount(entryInValidVec.drop(params.numEnq))) 487 XSPerfAccumulate(s"othersEntry_all_out_deq_cnt", PopCount(entryOutDeqValidVec.drop(params.numEnq))) 488 XSPerfAccumulate(s"othersEntry_all_out_trans_cnt", PopCount(entryOutTransValidVec.drop(params.numEnq))) 489 490 for (srcIdx <- 0 until params.numRegSrc) { 491 XSPerfAccumulate(s"othersEntry_all_wakeup_wb_src${srcIdx}_cnt", PopCount(perfWakeupByWBVec.drop(params.numEnq).map(_(srcIdx)))) 492 if (params.hasIQWakeUp) { 493 XSPerfAccumulate(s"othersEntry_all_ldCancel_src${srcIdx}_cnt", PopCount(perfLdCancelVec.get.drop(params.numEnq).map(_(srcIdx)))) 494 XSPerfAccumulate(s"othersEntry_all_og0Cancel_src${srcIdx}_cnt", PopCount(perfOg0CancelVec.get.drop(params.numEnq).map(_(srcIdx)))) 495 for (iqIdx <- 0 until params.numWakeupFromIQ) { 496 XSPerfAccumulate(s"othersEntry_all_wakeup_iq_from_exu${params.wakeUpSourceExuIdx(iqIdx)}_src${srcIdx}_cnt", PopCount(perfWakeupByIQVec.get.drop(params.numEnq).map(_(srcIdx)(iqIdx)))) 497 } 498 } 499 } 500 501 for (t <- FuType.functionNameMap.keys) { 502 val fuName = FuType.functionNameMap(t) 503 if (params.getFuCfgs.map(_.fuType == t).reduce(_ | _) && params.getFuCfgs.size > 1) { 504 for (srcIdx <- 0 until params.numRegSrc) { 505 XSPerfAccumulate(s"allEntry_futype_${fuName}_wakeup_wb_src${srcIdx}_cnt", PopCount(perfWakeupByWBVec.zip(fuTypeVec).map{ case(x, fu) => x(srcIdx) && fu(t.id) })) 506 if (params.hasIQWakeUp) { 507 XSPerfAccumulate(s"allEntry_futype_${fuName}_ldCancel_src${srcIdx}_cnt", PopCount(perfLdCancelVec.get.zip(fuTypeVec).map{ case(x, fu) => x(srcIdx) && fu(t.id) })) 508 XSPerfAccumulate(s"allEntry_futype_${fuName}_og0Cancel_src${srcIdx}_cnt", PopCount(perfOg0CancelVec.get.zip(fuTypeVec).map{ case(x, fu) => x(srcIdx) && fu(t.id) })) 509 for (iqIdx <- 0 until params.numWakeupFromIQ) { 510 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) })) 511 } 512 } 513 } 514 } 515 } 516} 517 518class EntriesIO(implicit p: Parameters, params: IssueBlockParams) extends XSBundle { 519 val flush = Flipped(ValidIO(new Redirect)) 520 //enq 521 val enq = Vec(params.numEnq, Flipped(ValidIO(new EntryBundle))) 522 val og0Resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 523 val og1Resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 524 val og2Resp = OptionWrapper(params.needOg2Resp, Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle)))) 525 //deq sel 526 val deqReady = Vec(params.numDeq, Input(Bool())) 527 val deqSelOH = Vec(params.numDeq, Flipped(ValidIO(UInt(params.numEntries.W)))) 528 val enqEntryOldestSel = Vec(params.numDeq, Flipped(ValidIO(UInt(params.numEnq.W)))) 529 val simpEntryOldestSel = OptionWrapper(params.hasCompAndSimp, Vec(params.numDeq, Flipped(ValidIO(UInt(params.numSimp.W))))) 530 val compEntryOldestSel = OptionWrapper(params.hasCompAndSimp, Vec(params.numDeq, Flipped(ValidIO(UInt(params.numComp.W))))) 531 val othersEntryOldestSel= OptionWrapper(params.isAllComp || params.isAllSimp, Vec(params.numDeq, Flipped(ValidIO(UInt((params.numEntries - params.numEnq).W))))) 532 val subDeqRequest = OptionWrapper(params.deqFuSame, Vec(params.numDeq, Input(UInt(params.numEntries.W)))) 533 val subDeqSelOH = OptionWrapper(params.deqFuSame, Vec(params.numDeq, Input(UInt(params.numEntries.W)))) 534 // wakeup 535 val wakeUpFromWB: MixedVec[ValidIO[IssueQueueWBWakeUpBundle]] = Flipped(params.genWBWakeUpSinkValidBundle) 536 val wakeUpFromIQ: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpSinkValidBundle) 537 val wakeUpFromWBDelayed: MixedVec[ValidIO[IssueQueueWBWakeUpBundle]] = Flipped(params.genWBWakeUpSinkValidBundle) 538 val wakeUpFromIQDelayed: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpSinkValidBundle) 539 val vlFromIntIsZero = Input(Bool()) 540 val vlFromIntIsVlmax = Input(Bool()) 541 val vlFromVfIsZero = Input(Bool()) 542 val vlFromVfIsVlmax = Input(Bool()) 543 val og0Cancel = Input(ExuVec()) 544 val og1Cancel = Input(ExuVec()) 545 val ldCancel = Vec(backendParams.LdExuCnt, Flipped(new LoadCancelIO)) 546 //entries status 547 val valid = Output(UInt(params.numEntries.W)) 548 val issued = Output(UInt(params.numEntries.W)) 549 val canIssue = Output(UInt(params.numEntries.W)) 550 val fuType = Vec(params.numEntries, Output(FuType())) 551 val dataSources = Vec(params.numEntries, Vec(params.numRegSrc, Output(DataSource()))) 552 val loadDependency = Vec(params.numEntries, Vec(LoadPipelineWidth, UInt(LoadDependencyWidth.W))) 553 val exuSources = OptionWrapper(params.hasIQWakeUp, Vec(params.numEntries, Vec(params.numRegSrc, Output(ExuSource())))) 554 //deq status 555 val isFirstIssue = Vec(params.numDeq, Output(Bool())) 556 val deqEntry = Vec(params.numDeq, ValidIO(new EntryBundle)) 557 val cancelDeqVec = Vec(params.numDeq, Output(Bool())) 558 559 // load/hybird only 560 val fromLoad = OptionWrapper(params.isLdAddrIQ || params.isHyAddrIQ, new Bundle { 561 val finalIssueResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 562 val memAddrIssueResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 563 }) 564 // mem only 565 val fromMem = OptionWrapper(params.isMemAddrIQ, new Bundle { 566 val slowResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 567 val fastResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 568 }) 569 // vec mem only 570 val vecMemIn = OptionWrapper(params.isVecMemIQ, new Bundle { 571 val sqDeqPtr = Input(new SqPtr) 572 val lqDeqPtr = Input(new LqPtr) 573 }) 574 val vecLdIn = OptionWrapper(params.isVecLduIQ, new Bundle { 575 val finalIssueResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 576 val resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 577 }) 578 val robIdx = OptionWrapper(params.isVecMemIQ, Output(Vec(params.numEntries, new RobPtr))) 579 580 // trans 581 val simpEntryDeqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Input(UInt(params.numSimp.W)))) 582 val simpEntryEnqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Output(UInt(params.numSimp.W)))) 583 val compEntryEnqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Output(UInt(params.numComp.W)))) 584 val othersEntryEnqSelVec = OptionWrapper(params.isAllComp || params.isAllSimp, Vec(params.numEnq, Output(UInt((params.numEntries - params.numEnq).W)))) 585 586 def wakeup = wakeUpFromWB ++ wakeUpFromIQ 587} 588