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 sqIdxVec = OptionWrapper(params.needFeedBackSqIdx, Wire(Vec(params.numEntries, new SqPtr()))) 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.needFeedBackSqIdx) { 272 // vector memory IQ 273 issueRespVec.lazyZip(sqIdxVec.get).lazyZip(issueTimerVec.lazyZip(deqPortIdxReadVec)).foreach { case (issueResp, sqIdx, (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.sqIdx.get === sqIdx) 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 410 411 def EntriesConnect(in: CommonInBundle, out: CommonOutBundle, entryIdx: Int) = { 412 in.flush := io.flush 413 in.wakeUpFromWB := io.wakeUpFromWB 414 in.wakeUpFromIQ := io.wakeUpFromIQ 415 in.vlIsZero := io.vlIsZero 416 in.vlIsVlmax := io.vlIsVlmax 417 in.og0Cancel := io.og0Cancel 418 in.og1Cancel := io.og1Cancel 419 in.ldCancel := io.ldCancel 420 in.deqSel := deqSelVec(entryIdx) 421 in.deqPortIdxWrite := deqPortIdxWriteVec(entryIdx) 422 in.issueResp := issueRespVec(entryIdx) 423 if (params.isVecMemIQ) { 424 in.fromLsq.get.sqDeqPtr := io.vecMemIn.get.sqDeqPtr 425 in.fromLsq.get.lqDeqPtr := io.vecMemIn.get.lqDeqPtr 426 } 427 validVec(entryIdx) := out.valid 428 canIssueVec(entryIdx) := out.canIssue 429 fuTypeVec(entryIdx) := out.fuType 430 robIdxVec(entryIdx) := out.robIdx 431 dataSourceVec(entryIdx) := out.dataSource 432 isFirstIssueVec(entryIdx) := out.isFirstIssue 433 entries(entryIdx) := out.entry 434 deqPortIdxReadVec(entryIdx) := out.deqPortIdxRead 435 issueTimerVec(entryIdx) := out.issueTimerRead 436 loadDependencyVec(entryIdx) := out.entry.bits.status.mergedLoadDependency 437 cancelBypassVec(entryIdx) := out.cancelBypass 438 if (params.hasIQWakeUp) { 439 srcWakeUpL1ExuOHVec.get(entryIdx) := out.srcWakeUpL1ExuOH.get 440 } 441 if (params.isVecMemIQ || params.isStAddrIQ) { 442 sqIdxVec.get(entryIdx) := out.entry.bits.payload.sqIdx 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.inVfSchd, 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 vlIsZero = Input(Bool()) 543 val vlIsVlmax = Input(Bool()) 544 val og0Cancel = Input(ExuOH(backendParams.numExu)) 545 val og1Cancel = Input(ExuOH(backendParams.numExu)) 546 val ldCancel = Vec(backendParams.LdExuCnt, Flipped(new LoadCancelIO)) 547 //entries status 548 val valid = 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 srcWakeUpL1ExuOH = OptionWrapper(params.hasIQWakeUp, Vec(params.numEntries, Vec(params.numRegSrc, Output(ExuVec())))) 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 resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 576 }) 577 val robIdx = OptionWrapper(params.isVecMemIQ, Output(Vec(params.numEntries, new RobPtr))) 578 579 // trans 580 val simpEntryDeqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Input(UInt(params.numSimp.W)))) 581 val simpEntryEnqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Output(UInt(params.numSimp.W)))) 582 val compEntryEnqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Output(UInt(params.numComp.W)))) 583 val othersEntryEnqSelVec = OptionWrapper(params.isAllComp || params.isAllSimp, Vec(params.numEnq, Output(UInt((params.numEntries - params.numEnq).W)))) 584 585 def wakeup = wakeUpFromWB ++ wakeUpFromIQ 586} 587