1package xiangshan.backend.issue 2 3import org.chipsalliance.cde.config.Parameters 4import chisel3._ 5import chisel3.util._ 6import utility.HasCircularQueuePtrHelper 7import utils.{MathUtils, OptionWrapper, XSError} 8import xiangshan._ 9import xiangshan.backend.Bundles._ 10import xiangshan.backend.datapath.DataConfig.VAddrData 11import xiangshan.backend.datapath.DataSource 12import xiangshan.backend.fu.FuType 13import xiangshan.backend.fu.vector.Utils.NOnes 14import xiangshan.backend.rob.RobPtr 15import xiangshan.mem.{LqPtr, MemWaitUpdateReq, SqPtr} 16import xiangshan.backend.issue.EntryBundles._ 17 18class Entries(implicit p: Parameters, params: IssueBlockParams) extends XSModule { 19 override def desiredName: String = params.getEntryName 20 21 private val EnqEntryNum = params.numEnq 22 private val OthersEntryNum = params.numEntries - params.numEnq 23 val io = IO(new EntriesIO) 24 25 // only memAddrIQ use it 26 val memEtyResps: MixedVec[ValidIO[EntryDeqRespBundle]] = { 27 if (params.isLdAddrIQ && !params.isStAddrIQ) 28 MixedVecInit(io.og0Resp ++ io.og1Resp ++ io.finalIssueResp.get) 29 else if (params.isLdAddrIQ && params.isStAddrIQ || params.isHyAddrIQ) 30 MixedVecInit(io.og0Resp ++ io.og1Resp ++ io.finalIssueResp.get ++ io.fromMem.get.fastResp ++ io.fromMem.get.slowResp) 31 else if (params.isMemAddrIQ) 32 MixedVecInit(io.og0Resp ++ io.og1Resp ++ io.fromMem.get.fastResp ++ io.fromMem.get.slowResp) 33 else MixedVecInit(Seq()) 34 } 35 36 val resps: Vec[Vec[ValidIO[EntryDeqRespBundle]]] = VecInit(io.og0Resp, io.og1Resp, 0.U.asTypeOf(io.og0Resp), 0.U.asTypeOf(io.og0Resp)) 37 38 //Module 39 val enqEntries = Seq.fill(EnqEntryNum)(Module(EnqEntry(p, params))) 40 val othersEntries = Seq.fill(OthersEntryNum)(Module(OthersEntry(p, params))) 41 val transPolicy = Module(new EnqPolicy) 42 43 //Wire 44 //entries status 45 val entries = Wire(Vec(params.numEntries, ValidIO(new EntryBundle))) 46 val robIdxVec = Wire(Vec(params.numEntries, new RobPtr)) 47 val validVec = Wire(Vec(params.numEntries, Bool())) 48 val canIssueVec = Wire(Vec(params.numEntries, Bool())) 49 val fuTypeVec = Wire(Vec(params.numEntries, FuType())) 50 val isFirstIssueVec = Wire(Vec(params.numEntries, Bool())) 51 val issueTimerVec = Wire(Vec(params.numEntries, UInt(2.W))) 52 //src status 53 val dataSourceVec = Wire(Vec(params.numEntries, Vec(params.numRegSrc, DataSource()))) 54 val srcTimerVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Vec(params.numRegSrc, UInt(3.W))))) 55 val srcWakeUpL1ExuOHVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Vec(params.numRegSrc, ExuVec())))) 56 //deq sel 57 val deqSelVec = Wire(Vec(params.numEntries, Bool())) 58 val issueRespVec = Wire(Vec(params.numEntries, ValidIO(new EntryDeqRespBundle))) 59 val deqPortIdxWriteVec = Wire(Vec(params.numEntries, UInt(1.W))) 60 val deqPortIdxReadVec = Wire(Vec(params.numEntries, UInt(1.W))) 61 //trans sel 62 val transSelVec = Wire(Vec(EnqEntryNum, Vec(OthersEntryNum, Bool()))) 63 val transEntryDeqVec = Wire(Vec(EnqEntryNum, ValidIO(new EntryBundle))) 64 val transEntryEnqVec = Wire(Vec(OthersEntryNum, ValidIO(new EntryBundle))) 65 //debug 66 val cancelVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Bool()))) 67 //og0Cancel bypass 68 val cancelByOg0Vec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Bool()))) 69 val uopIdxVec = OptionWrapper(params.isVecMemIQ, Wire(Vec(params.numEntries, UopIdx()))) 70 71 val canTrans = Wire(Bool()) 72 val enqReadyOthersVec = Wire(Vec(OthersEntryNum, Bool())) 73 val enqTransSelVec = Wire(Vec(EnqEntryNum, Valid(UInt(OthersEntryNum.W)))) 74 75 io.transEntryDeqVec := transEntryDeqVec 76 77 //enqEntries 78 enqEntries.zipWithIndex.foreach { case (enqEntry, entryIdx) => 79 enqEntry.io.commonIn.enq := io.enq(entryIdx) 80 enqEntry.io.commonIn.transSel := canTrans && enqTransSelVec(entryIdx).valid 81 EntriesConnect(enqEntry.io.commonIn, enqEntry.io.commonOut, entryIdx) 82 enqEntry.io.enqDelayWakeUpFromWB := RegNext(io.wakeUpFromWB) 83 enqEntry.io.enqDelayWakeUpFromIQ := RegNext(io.wakeUpFromIQ) 84 enqEntry.io.enqDelayOg0Cancel := RegNext(io.og0Cancel.asUInt) 85 enqEntry.io.enqDelayLdCancel := RegNext(io.ldCancel) 86 transEntryDeqVec(entryIdx) := enqEntry.io.transEntry 87 // TODO: move it into EntriesConnect 88 if (params.isVecMemIQ) { 89 enqEntry.io.commonIn.fromLsq.get.sqDeqPtr := io.vecMemIn.get.sqDeqPtr 90 enqEntry.io.commonIn.fromLsq.get.lqDeqPtr := io.vecMemIn.get.lqDeqPtr 91 } 92 } 93 //othersEntries 94 othersEntries.zipWithIndex.foreach { case (othersEntry, entryIdx) => 95 othersEntry.io.commonIn.enq := transEntryEnqVec(entryIdx) 96 EntriesConnect(othersEntry.io.commonIn, othersEntry.io.commonOut, entryIdx + EnqEntryNum) 97 othersEntry.io.commonIn.transSel := transSelVec.map(x => x(entryIdx)).reduce(_ | _) 98 enqReadyOthersVec(entryIdx) := othersEntry.io.enqReady 99 if (params.isVecMemIQ) { 100 othersEntry.io.commonIn.fromLsq.get.sqDeqPtr := io.vecMemIn.get.sqDeqPtr 101 othersEntry.io.commonIn.fromLsq.get.lqDeqPtr := io.vecMemIn.get.lqDeqPtr 102 } 103 } 104 105 106 deqSelVec.zip(deqPortIdxWriteVec).zipWithIndex.foreach { case ((deqSel, deqPortIdxWrite), i) => 107 val deqVec = io.deqSelOH.zip(io.deqReady).map(x => x._1.valid && x._1.bits(i) && x._2) 108 deqPortIdxWrite := OHToUInt(deqVec) 109 deqSel := deqVec.reduce(_ | _) 110 } 111 112 113 //transPolicy 114 transPolicy.io.canEnq := enqReadyOthersVec.asUInt 115 canTrans := PopCount(validVec.take(EnqEntryNum)) <= PopCount(enqReadyOthersVec) 116 enqTransSelVec(0).valid := transPolicy.io.enqSelOHVec(0).valid 117 enqTransSelVec(0).bits := transPolicy.io.enqSelOHVec(0).bits 118 if (params.numEnq == 2) { 119 enqTransSelVec(1).valid := Mux(!validVec(0), transPolicy.io.enqSelOHVec(0).valid, transPolicy.io.enqSelOHVec(1).valid) 120 enqTransSelVec(1).bits := Mux(!validVec(0), transPolicy.io.enqSelOHVec(0).bits, transPolicy.io.enqSelOHVec(1).bits) 121 } 122 123 transSelVec.zip(enqTransSelVec).zipWithIndex.foreach { case ((selBools, selOH), enqIdx) => 124 selBools.zipWithIndex.foreach { case (selBool, othersIdx) => 125 selBool := canTrans && validVec(enqIdx) && selOH.valid && selOH.bits(othersIdx) 126 } 127 } 128 129 //transEntryEnq 130 transEntryEnqVec.zipWithIndex.foreach { case (transEntryEnq, othersIdx) => 131 val transEnqHit = transSelVec.map(x => x(othersIdx)) 132 transEntryEnq := Mux1H(transEnqHit, transEntryDeqVec) 133 } 134 if(backendParams.debugEn) { 135 dontTouch(transEntryEnqVec) 136 } 137 138 //issueRespVec 139 if (params.isVecMemIQ) { 140 // vector memory IQ 141 issueRespVec.zip(robIdxVec).zip(uopIdxVec.get).foreach { case ((issueResp, robIdx), uopIdx) => 142 val hitRespsVec = VecInit(resps.flatten.map(x => 143 x.valid && x.bits.robIdx === robIdx && x.bits.uopIdx.get === uopIdx 144 )) 145 issueResp.valid := hitRespsVec.reduce(_ | _) 146 issueResp.bits := Mux1H(hitRespsVec, resps.flatten.map(_.bits)) 147 } 148 } else if (params.isMemAddrIQ) { 149 // scalar memory IQ 150 issueRespVec.zip(robIdxVec).foreach { case (issueResp, robIdx) => 151 val hitRespsVec = VecInit(memEtyResps.map(x => x.valid && (x.bits.robIdx === robIdx)).toSeq) 152 issueResp.valid := hitRespsVec.reduce(_ | _) 153 issueResp.bits := Mux1H(hitRespsVec, memEtyResps.map(_.bits).toSeq) 154 } 155 } 156 else { 157 issueRespVec.zip(issueTimerVec).zip(deqPortIdxReadVec).foreach { case ((issueResp, issueTimer), deqPortIdx) => 158 val Resp = resps(issueTimer)(deqPortIdx) 159 issueResp := Resp 160 } 161 } 162 163 //deq 164 val enqEntryOldest = io.enqEntryOldestSel.map { x => 165 Mux1H(x.bits, entries.take(EnqEntryNum)) 166 } 167 val enqEntryOldestCancel = io.enqEntryOldestSel.map { x => 168 Mux1H(x.bits, cancelByOg0Vec.getOrElse(VecInit(Seq.fill(params.numEntries)(false.B))).take(EnqEntryNum)) 169 } 170 val othersEntryOldest = io.othersEntryOldestSel.map { x => 171 Mux1H(x.bits, entries.drop(EnqEntryNum)) 172 } 173 val othersEntryOldestCancel = io.othersEntryOldestSel.map { x => 174 Mux1H(x.bits, cancelByOg0Vec.getOrElse(VecInit(Seq.fill(params.numEntries)(false.B))).drop(EnqEntryNum)) 175 } 176 177 if (params.deqFuSame) { 178 val subDeqPolicyEntryVec = Wire(Vec(params.numDeq, ValidIO(new EntryBundle))) 179 val subDeqPolicyValidVec = Wire(Vec(params.numDeq, Bool())) 180 val subDeqPolicyCancelByOg0Vec = Wire(Vec(params.numDeq, Bool())) 181 182 subDeqPolicyEntryVec(0) := PriorityMux(io.subDeqRequest.get(0), entries) 183 subDeqPolicyEntryVec(1) := PriorityMux(Reverse(io.subDeqRequest.get(0)), entries.reverse) 184 subDeqPolicyValidVec(0) := PopCount(io.subDeqRequest.get(0)) >= 1.U 185 subDeqPolicyValidVec(1) := PopCount(io.subDeqRequest.get(0)) >= 2.U 186 subDeqPolicyCancelByOg0Vec(0) := PriorityMux(io.subDeqRequest.get(0), cancelByOg0Vec.getOrElse(VecInit(Seq.fill(params.numEntries)(false.B)))) 187 subDeqPolicyCancelByOg0Vec(1) := PriorityMux(Reverse(io.subDeqRequest.get(0)), cancelByOg0Vec.getOrElse(VecInit(Seq.fill(params.numEntries)(false.B))).reverse) 188 189 io.deqEntry(0) := Mux(io.othersEntryOldestSel(0).valid, othersEntryOldest(0), subDeqPolicyEntryVec(1)) 190 io.deqEntry(1) := subDeqPolicyEntryVec(0) 191 io.cancelDeqVec(0) := Mux(io.othersEntryOldestSel(0).valid, othersEntryOldestCancel(0), subDeqPolicyCancelByOg0Vec(1)) 192 io.cancelDeqVec(1) := subDeqPolicyCancelByOg0Vec(0) 193 194 when (subDeqPolicyValidVec(0)) { 195 assert(Mux1H(io.subDeqSelOH.get(0), entries).bits.status.robIdx === subDeqPolicyEntryVec(0).bits.status.robIdx, "subDeqSelOH(0) is not the same\n") 196 } 197 when (subDeqPolicyValidVec(1)) { 198 assert(Mux1H(io.subDeqSelOH.get(1), entries).bits.status.robIdx === subDeqPolicyEntryVec(1).bits.status.robIdx, "subDeqSelOH(1) is not the same\n") 199 } 200 } 201 else { 202 io.othersEntryOldestSel.zipWithIndex.foreach { case (x, i) => 203 io.deqEntry(i) := Mux(x.valid, othersEntryOldest(i), enqEntryOldest(i)) 204 io.cancelDeqVec(i) := Mux(x.valid, othersEntryOldestCancel(i), enqEntryOldestCancel(i)) 205 } 206 } 207 208 if (params.hasIQWakeUp) { 209 cancelByOg0Vec.get.zip(srcWakeUpL1ExuOHVec.get).zip(srcTimerVec.get).foreach{ case ((cancelByOg0: Bool, l1ExuOH: Vec[Vec[Bool]]), srcTimer: Vec[UInt]) => 210 cancelByOg0 := l1ExuOH.zip(srcTimer).map { 211 case(exuOH, srcTimer) => 212 (exuOH.asUInt & io.og0Cancel.asUInt).orR && srcTimer === 1.U 213 }.reduce(_ | _) 214 } 215 } 216 217 io.valid := validVec.asUInt 218 io.canIssue := canIssueVec.asUInt 219 io.fuType := fuTypeVec 220 io.dataSources := dataSourceVec 221 io.srcWakeUpL1ExuOH.foreach(_ := srcWakeUpL1ExuOHVec.get.map(x => VecInit(x.map(_.asUInt)))) 222 io.srcTimer.foreach(_ := srcTimerVec.get) 223 io.isFirstIssue.zipWithIndex.foreach{ case (isFirstIssue, deqIdx) => 224 isFirstIssue := io.deqSelOH(deqIdx).valid && Mux1H(io.deqSelOH(deqIdx).bits, isFirstIssueVec) 225 } 226 io.transSelVec.zip(transSelVec).foreach { case (sink, source) => 227 sink := source.asUInt 228 } 229 io.robIdx.foreach(_ := robIdxVec) 230 io.uopIdx.foreach(_ := uopIdxVec.get) 231 io.rsFeedback := 0.U.asTypeOf(io.rsFeedback) //should be removed 232 io.cancel.foreach(_ := cancelVec.get) //for debug 233 234 def EntriesConnect(in: CommonInBundle, out: CommonOutBundle, entryIdx: Int) = { 235 in.flush := io.flush 236 in.wakeUpFromWB := io.wakeUpFromWB 237 in.wakeUpFromIQ := io.wakeUpFromIQ 238 in.og0Cancel := io.og0Cancel 239 in.og1Cancel := io.og1Cancel 240 in.ldCancel := io.ldCancel 241 in.deqSel := deqSelVec(entryIdx) 242 in.deqPortIdxWrite := deqPortIdxWriteVec(entryIdx) 243 in.issueResp := issueRespVec(entryIdx) 244 if (params.isMemAddrIQ) { 245 in.fromMem.get.stIssuePtr := io.fromMem.get.stIssuePtr 246 in.fromMem.get.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 247 } 248 if (params.isVecMemIQ) { 249 in.fromLsq.get.sqDeqPtr := io.vecMemIn.get.sqDeqPtr 250 in.fromLsq.get.lqDeqPtr := io.vecMemIn.get.lqDeqPtr 251 } 252 validVec(entryIdx) := out.valid 253 canIssueVec(entryIdx) := out.canIssue 254 fuTypeVec(entryIdx) := out.fuType 255 robIdxVec(entryIdx) := out.robIdx 256 dataSourceVec(entryIdx) := out.dataSource 257 isFirstIssueVec(entryIdx) := out.isFirstIssue 258 entries(entryIdx) := out.entry 259 deqPortIdxReadVec(entryIdx) := out.deqPortIdxRead 260 issueTimerVec(entryIdx) := out.issueTimerRead 261 if (params.hasIQWakeUp) { 262 srcWakeUpL1ExuOHVec.get(entryIdx) := out.srcWakeUpL1ExuOH.get 263 srcTimerVec.get(entryIdx) := out.srcTimer.get 264 cancelVec.get(entryIdx) := out.cancel.get 265 } 266 if (params.isVecMemIQ) { 267 uopIdxVec.get(entryIdx) := out.uopIdx.get 268 } 269 } 270} 271 272class EntriesIO(implicit p: Parameters, params: IssueBlockParams) extends XSBundle { 273 val flush = Flipped(ValidIO(new Redirect)) 274 //enq 275 val enq = Vec(params.numEnq, Flipped(ValidIO(new EntryBundle))) 276 val og0Resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 277 val og1Resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 278 val finalIssueResp = OptionWrapper(params.LdExuCnt > 0, Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle)))) 279 //deq sel 280 val deqReady = Vec(params.numDeq, Input(Bool())) 281 val deqSelOH = Vec(params.numDeq, Flipped(ValidIO(UInt(params.numEntries.W)))) 282 val enqEntryOldestSel = Vec(params.numDeq, Flipped(ValidIO(UInt(params.numEnq.W)))) 283 val othersEntryOldestSel= Vec(params.numDeq, Flipped(ValidIO(UInt((params.numEntries - params.numEnq).W)))) 284 val subDeqRequest = OptionWrapper(params.deqFuSame, Vec(params.numDeq, Input(UInt(params.numEntries.W)))) 285 val subDeqSelOH = OptionWrapper(params.deqFuSame, Vec(params.numDeq, Input(UInt(params.numEntries.W)))) 286 // wakeup 287 val wakeUpFromWB: MixedVec[ValidIO[IssueQueueWBWakeUpBundle]] = Flipped(params.genWBWakeUpSinkValidBundle) 288 val wakeUpFromIQ: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpSinkValidBundle) 289 val og0Cancel = Input(ExuOH(backendParams.numExu)) 290 val og1Cancel = Input(ExuOH(backendParams.numExu)) 291 val ldCancel = Vec(backendParams.LdExuCnt, Flipped(new LoadCancelIO)) 292 //trans output 293 val transEntryDeqVec = Vec(params.numEnq, ValidIO(new EntryBundle)) 294 val transSelVec = Output(Vec(params.numEnq, UInt((params.numEntries - params.numEnq).W))) 295 //entries status 296 val valid = Output(UInt(params.numEntries.W)) 297 val canIssue = Output(UInt(params.numEntries.W)) 298 val fuType = Vec(params.numEntries, Output(FuType())) 299 val dataSources = Vec(params.numEntries, Vec(params.numRegSrc, Output(DataSource()))) 300 val srcWakeUpL1ExuOH = OptionWrapper(params.hasIQWakeUp, Vec(params.numEntries, Vec(params.numRegSrc, Output(ExuOH())))) 301 val srcTimer = OptionWrapper(params.hasIQWakeUp, Vec(params.numEntries, Vec(params.numRegSrc, Output(UInt(3.W))))) 302 //deq status 303 val isFirstIssue = Vec(params.numDeq, Output(Bool())) 304 val deqEntry = Vec(params.numDeq, ValidIO(new EntryBundle)) 305 val cancelDeqVec = Vec(params.numDeq, Output(Bool())) 306 // mem only 307 val fromMem = if (params.isMemAddrIQ) Some(new Bundle { 308 val stIssuePtr = Input(new SqPtr) 309 val memWaitUpdateReq = Flipped(new MemWaitUpdateReq) 310 val slowResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 311 val fastResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 312 }) else None 313 val vecMemIn = OptionWrapper(params.isVecMemIQ, new Bundle { 314 val sqDeqPtr = Input(new SqPtr) 315 val lqDeqPtr = Input(new LqPtr) 316 }) 317 318 val robIdx = OptionWrapper(params.isVecMemIQ, Output(Vec(params.numEntries, new RobPtr))) 319 val uopIdx = OptionWrapper(params.isVecMemIQ, Output(Vec(params.numEntries, UopIdx()))) 320 321 val rsFeedback = Output(Vec(5, Bool())) 322 323 // debug 324 val cancel = OptionWrapper(params.hasIQWakeUp, Output(Vec(params.numEntries, Bool()))) 325 326 def wakeup = wakeUpFromWB ++ wakeUpFromIQ 327} 328