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.{MemWaitUpdateReq, SqPtr, LqPtr} 16 17class StatusMemPart(implicit p:Parameters, params: IssueBlockParams) extends Bundle { 18 val waitForSqIdx = new SqPtr // generated by store data valid check 19 val waitForRobIdx = new RobPtr // generated by store set 20 val waitForStd = Bool() 21 val strictWait = Bool() 22 val sqIdx = new SqPtr 23} 24 25class StatusVecMemPart(implicit p:Parameters, params: IssueBlockParams) extends Bundle { 26 val sqIdx = new SqPtr 27 val lqIdx = new LqPtr 28} 29 30class Status(implicit p:Parameters, params: IssueBlockParams) extends XSBundle { 31 val srcState = Vec(params.numRegSrc, SrcState()) 32 33 val psrc = Vec(params.numRegSrc, UInt(params.rdPregIdxWidth.W)) 34 val srcType = Vec(params.numRegSrc, SrcType()) 35 val fuType = FuType() 36 val robIdx = new RobPtr 37 val uopIdx = OptionWrapper(params.isVecMemIQ, UopIdx()) 38 val issued = Bool() // for predict issue 39 val firstIssue = Bool() 40 val blocked = Bool() // for some block reason 41 // read reg or get data from bypass network 42 val dataSources = Vec(params.numRegSrc, DataSource()) 43 // if waked up by iq, set when waked up by iq 44 val srcWakeUpL1ExuOH = OptionWrapper(params.hasIQWakeUp, Vec(params.numRegSrc, ExuOH())) 45 // src timer, used by cancel signal. It increases every cycle after wakeup src inst issued. 46 val srcTimer = OptionWrapper(params.hasIQWakeUp, Vec(params.numRegSrc, UInt(3.W))) 47 val issueTimer = UInt(2.W) 48 val deqPortIdx = UInt(1.W) 49 val srcLoadDependency = OptionWrapper(params.hasIQWakeUp, Vec(params.numRegSrc, Vec(LoadPipelineWidth, UInt(3.W)))) 50 51 52 // mem only 53 val mem = if (params.isMemAddrIQ) Some(new StatusMemPart) else None 54 55 // vector mem only 56 val vecMem = if (params.isVecMemIQ) Some(new StatusVecMemPart) else None 57 58 // need pc 59 val pc = if (params.needPc) Some(UInt(VAddrData().dataWidth.W)) else None 60 61 def srcReady: Bool = { 62 VecInit(srcState.map(SrcState.isReady)).asUInt.andR 63 } 64 65 def canIssue: Bool = { 66 srcReady && !issued && !blocked 67 } 68 69 def mergedLoadDependency = { 70 srcLoadDependency.map(_.map(_.toSeq).reduce({ 71 case (l: Vec[UInt], r: Vec[UInt]) => VecInit(l.zip(r).map(x => x._1 | x._2)) 72 }: (Vec[UInt], Vec[UInt]) => Vec[UInt])) 73 } 74} 75 76class EntryDeqRespBundle(implicit p:Parameters, params: IssueBlockParams) extends Bundle { 77 val robIdx = new RobPtr 78 val respType = RSFeedbackType() // update credit if needs replay 79 val dataInvalidSqIdx = new SqPtr 80 val rfWen = Bool() 81 val fuType = FuType() 82} 83 84class EntryBundle(implicit p: Parameters, params: IssueBlockParams) extends XSBundle { 85 val status = new Status() 86 val imm = UInt(XLEN.W) 87 val payload = new DynInst() 88} 89 90class DeqBundle(implicit p:Parameters, params: IssueBlockParams) extends XSBundle { 91 val isFirstIssue = Output(Bool()) 92 val deqSelOH = Flipped(ValidIO(UInt(params.numEntries.W))) 93} 94 95class EntriesIO(implicit p: Parameters, params: IssueBlockParams) extends XSBundle { 96 val flush = Flipped(ValidIO(new Redirect)) 97 // status 98 val valid = Output(UInt(params.numEntries.W)) 99 val canIssue = Output(UInt(params.numEntries.W)) 100 val clear = Output(UInt(params.numEntries.W)) 101 val fuType = Output(Vec(params.numEntries, FuType())) 102 val dataSources = Output(Vec(params.numEntries, Vec(params.numRegSrc, DataSource()))) 103 val srcWakeUpL1ExuOH = OptionWrapper(params.hasIQWakeUp, Output(Vec(params.numEntries, Vec(params.numRegSrc, ExuOH())))) 104 val srcTimer = OptionWrapper(params.hasIQWakeUp, Output(Vec(params.numEntries, Vec(params.numRegSrc, UInt(3.W))))) 105 val robIdx = OptionWrapper(params.isVecMemIQ, Output(Vec(params.numEntries, new RobPtr))) 106 val uopIdx = OptionWrapper(params.isVecMemIQ, Output(Vec(params.numEntries, UopIdx()))) 107 //enq 108 val enq = Vec(params.numEnq, Flipped(ValidIO(new EntryBundle))) 109 // wakeup 110 val wakeUpFromWB: MixedVec[ValidIO[IssueQueueWBWakeUpBundle]] = Flipped(params.genWBWakeUpSinkValidBundle) 111 val wakeUpFromIQ: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpSinkValidBundle) 112 val og0Cancel = Input(ExuOH(backendParams.numExu)) 113 val og1Cancel = Input(ExuOH(backendParams.numExu)) 114 val ldCancel = Vec(backendParams.LduCnt + backendParams.HyuCnt, Flipped(new LoadCancelIO)) 115 //deq 116 val deq = Vec(params.numDeq, new DeqBundle) 117 val deqResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 118 val og0Resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 119 val og1Resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 120 val finalIssueResp = OptionWrapper(params.LdExuCnt > 0, Vec(params.LdExuCnt, Flipped(ValidIO(new EntryDeqRespBundle)))) 121 val memAddrIssueResp = OptionWrapper(params.LdExuCnt > 0, Vec(params.LdExuCnt, Flipped(ValidIO(new EntryDeqRespBundle)))) 122 val transEntryDeqVec = Vec(params.numEnq, ValidIO(new EntryBundle)) 123 val deqEntry = Vec(params.numDeq, ValidIO(new EntryBundle)) 124 val transSelVec = Output(Vec(params.numEnq, UInt((params.numEntries-params.numEnq).W))) 125 126 127 val rsFeedback = Output(Vec(5, Bool())) 128 // mem only 129 val fromMem = if (params.isMemAddrIQ) Some(new Bundle { 130 val stIssuePtr = Input(new SqPtr) 131 val memWaitUpdateReq = Flipped(new MemWaitUpdateReq) 132 val slowResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 133 val fastResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))) 134 }) else None 135 136 // vector mem only 137 val fromLsq = OptionWrapper(params.isVecMemIQ, new Bundle { 138 val sqDeqPtr = Input(new SqPtr) 139 val lqDeqPtr = Input(new LqPtr) 140 }) 141 142 // debug 143 val cancel = OptionWrapper(params.hasIQWakeUp, Output(Vec(params.numEntries, Bool()))) 144 145 def wakeup = wakeUpFromWB ++ wakeUpFromIQ 146} 147 148class Entries(implicit p: Parameters, params: IssueBlockParams) extends XSModule { 149 private val EnqEntryNum = params.numEnq 150 private val OthersEntryNum = params.numEntries - params.numEnq 151 val io = IO(new EntriesIO) 152 153 // only memAddrIQ use it 154 val memEtyResps: MixedVec[ValidIO[EntryDeqRespBundle]] = { 155 if (params.isLdAddrIQ && !params.isStAddrIQ) 156 MixedVecInit(io.deqResp ++ io.og0Resp ++ io.og1Resp ++ io.memAddrIssueResp.get ++ io.finalIssueResp.get) 157 else if (params.isLdAddrIQ && params.isStAddrIQ || params.isHyAddrIQ) 158 MixedVecInit(io.deqResp ++ io.og0Resp ++ io.og1Resp ++ io.memAddrIssueResp.get ++ io.finalIssueResp.get ++ io.fromMem.get.fastResp ++ io.fromMem.get.slowResp) 159 else if (params.isMemAddrIQ) 160 MixedVecInit(io.deqResp ++ io.og0Resp ++ io.og1Resp ++ io.fromMem.get.fastResp ++ io.fromMem.get.slowResp) 161 else MixedVecInit(Seq()) 162 } 163 164 val resps: Vec[Vec[ValidIO[EntryDeqRespBundle]]] = VecInit(io.deqResp, io.og0Resp, io.og1Resp, 0.U.asTypeOf(io.deqResp)) 165 166 //Module 167 val enqEntries = Seq.fill(EnqEntryNum)(Module(EnqEntry(p, params))) 168 val othersEntries = Seq.fill(OthersEntryNum)(Module(OthersEntry(p, params))) 169 val transPolicy = Module(new EnqPolicy) 170 171 //Wire 172 val deqSelVec = Wire(Vec(params.numEntries, Bool())) 173 val transSelVec = Wire(Vec(EnqEntryNum, Vec(OthersEntryNum, Bool()))) 174 val issueRespVec = Wire(Vec(params.numEntries, ValidIO(new EntryDeqRespBundle))) 175 val transEntryDeqVec = Wire(Vec(EnqEntryNum, ValidIO(new EntryBundle))) 176 val transEntryEnqVec = Wire(Vec(OthersEntryNum, ValidIO(new EntryBundle))) 177 val entries = Wire(Vec(params.numEntries, ValidIO(new EntryBundle))) 178 179 val validVec = Wire(Vec(params.numEntries, Bool())) 180 val canIssueVec = Wire(Vec(params.numEntries, Bool())) 181 val clearVec = Wire(Vec(params.numEntries, Bool())) 182 val fuTypeVec = Wire(Vec(params.numEntries, FuType())) 183 val dataSourceVec = Wire(Vec(params.numEntries, Vec(params.numRegSrc, DataSource()))) 184 val srcWakeUpL1ExuOHVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Vec(params.numRegSrc, ExuOH())))) 185 val srcTimerVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Vec(params.numRegSrc, UInt(3.W))))) 186 val isFirstIssueVec = Wire(Vec(params.numEntries, Bool())) 187 val robIdxVec = Wire(Vec(params.numEntries, new RobPtr)) 188 val issueTimerVec = Wire(Vec(params.numEntries, UInt(2.W))) 189 val deqPortIdxWriteVec = Wire(Vec(params.numEntries, UInt(1.W))) 190 val deqPortIdxReadVec = Wire(Vec(params.numEntries, UInt(1.W))) 191 val cancelVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Bool()))) 192 val uopIdxVec = OptionWrapper(params.isVecMemIQ, Wire(Vec(params.numEntries, UopIdx()))) 193 194 io.transEntryDeqVec := transEntryDeqVec 195 196 //enqEntries 197 enqEntries.zipWithIndex.foreach { case (enqEntry, entryIdx) => 198 enqEntry.io.enq := io.enq(entryIdx) 199 enqEntry.io.flush := io.flush 200 enqEntry.io.wakeUpFromWB := io.wakeUpFromWB 201 enqEntry.io.wakeUpFromIQ := io.wakeUpFromIQ 202 enqEntry.io.og0Cancel := io.og0Cancel 203 enqEntry.io.og1Cancel := io.og1Cancel 204 enqEntry.io.ldCancel := io.ldCancel 205 enqEntry.io.deqSel := deqSelVec(entryIdx) 206 enqEntry.io.deqPortIdxWrite := deqPortIdxWriteVec(entryIdx) 207 enqEntry.io.transSel := transSelVec(entryIdx).asUInt.orR 208 enqEntry.io.issueResp := issueRespVec(entryIdx) 209 validVec(entryIdx) := enqEntry.io.valid 210 canIssueVec(entryIdx) := enqEntry.io.canIssue 211 clearVec(entryIdx) := enqEntry.io.clear 212 fuTypeVec(entryIdx) := enqEntry.io.fuType 213 dataSourceVec(entryIdx) := enqEntry.io.dataSource 214 robIdxVec(entryIdx) := enqEntry.io.robIdx 215 issueTimerVec(entryIdx) := enqEntry.io.issueTimerRead 216 deqPortIdxReadVec(entryIdx) := enqEntry.io.deqPortIdxRead 217 if (params.hasIQWakeUp) { 218 srcWakeUpL1ExuOHVec.get(entryIdx) := enqEntry.io.srcWakeUpL1ExuOH.get 219 srcTimerVec.get(entryIdx) := enqEntry.io.srcTimer.get 220 cancelVec.get(entryIdx) := enqEntry.io.cancel.get 221 } 222 transEntryDeqVec(entryIdx) := enqEntry.io.transEntry 223 isFirstIssueVec(entryIdx) := enqEntry.io.isFirstIssue 224 entries(entryIdx) := enqEntry.io.entry 225 //for mem 226 if (params.isMemAddrIQ) { 227 enqEntry.io.fromMem.get.stIssuePtr := io.fromMem.get.stIssuePtr 228 enqEntry.io.fromMem.get.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 229 } 230 if (params.isVecMemIQ) { 231 uopIdxVec.get(entryIdx) := enqEntry.io.uopIdx.get 232 enqEntry.io.fromLsq.get.sqDeqPtr := io.fromLsq.get.sqDeqPtr 233 enqEntry.io.fromLsq.get.lqDeqPtr := io.fromLsq.get.lqDeqPtr 234 } 235 } 236 //othersEntries 237 othersEntries.zipWithIndex.foreach { case (othersEntry, entryIdx) => 238 othersEntry.io.enq := transEntryEnqVec(entryIdx) 239 othersEntry.io.flush := io.flush 240 othersEntry.io.wakeUpFromWB := io.wakeUpFromWB 241 othersEntry.io.wakeUpFromIQ := io.wakeUpFromIQ 242 othersEntry.io.og0Cancel := io.og0Cancel 243 othersEntry.io.og1Cancel := io.og1Cancel 244 othersEntry.io.ldCancel := io.ldCancel 245 othersEntry.io.deqSel := deqSelVec(entryIdx + EnqEntryNum) 246 othersEntry.io.deqPortIdxWrite := deqPortIdxWriteVec(entryIdx + EnqEntryNum) 247 othersEntry.io.transSel := transSelVec.map(x => x(entryIdx)).reduce(_ | _) 248 othersEntry.io.issueResp := issueRespVec(entryIdx + EnqEntryNum) 249 validVec(entryIdx + EnqEntryNum) := othersEntry.io.valid 250 canIssueVec(entryIdx + EnqEntryNum) := othersEntry.io.canIssue 251 clearVec(entryIdx + EnqEntryNum) := othersEntry.io.clear 252 fuTypeVec(entryIdx + EnqEntryNum) := othersEntry.io.fuType 253 dataSourceVec(entryIdx + EnqEntryNum) := othersEntry.io.dataSource 254 robIdxVec(entryIdx + EnqEntryNum) := othersEntry.io.robIdx 255 issueTimerVec(entryIdx + EnqEntryNum) := othersEntry.io.issueTimerRead 256 deqPortIdxReadVec(entryIdx + EnqEntryNum) := othersEntry.io.deqPortIdxRead 257 if (params.hasIQWakeUp) { 258 srcWakeUpL1ExuOHVec.get(entryIdx + EnqEntryNum) := othersEntry.io.srcWakeUpL1ExuOH.get 259 srcTimerVec.get(entryIdx + EnqEntryNum) := othersEntry.io.srcTimer.get 260 cancelVec.get(entryIdx + EnqEntryNum) := othersEntry.io.cancel.get 261 } 262 isFirstIssueVec(entryIdx + EnqEntryNum) := othersEntry.io.isFirstIssue 263 entries(entryIdx + EnqEntryNum) := othersEntry.io.entry 264 //for mem 265 if (params.isMemAddrIQ) { 266 othersEntry.io.fromMem.get.stIssuePtr := io.fromMem.get.stIssuePtr 267 othersEntry.io.fromMem.get.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 268 } 269 if (params.isVecMemIQ) { 270 uopIdxVec.get(entryIdx + EnqEntryNum) := othersEntry.io.uopIdx.get 271 othersEntry.io.fromLsq.get.sqDeqPtr := io.fromLsq.get.sqDeqPtr 272 othersEntry.io.fromLsq.get.lqDeqPtr := io.fromLsq.get.lqDeqPtr 273 } 274 } 275 276 277 deqSelVec.zip(deqPortIdxWriteVec).zipWithIndex.foreach { case ((deqSel, deqPortIdxWrite), i) => 278 val deqVec = io.deq.map(x => x.deqSelOH.valid && x.deqSelOH.bits(i)) 279 deqPortIdxWrite := OHToUInt(deqVec) 280 deqSel := deqVec.reduce(_ | _) 281 } 282 283 284 //transPolicy 285 transPolicy.io.valid := VecInit(validVec.slice(EnqEntryNum, params.numEntries)).asUInt 286 transSelVec.zip(transPolicy.io.enqSelOHVec).foreach { case (selBools, selOH) => 287 selBools.zipWithIndex.foreach { case (selBool, i) => 288 selBool := transPolicy.io.enqSelOHVec.map(_.valid).reduce(_ & _) && selOH.bits(i) 289 } 290 } 291 292 //transEntryEnq 293 transEntryEnqVec.zipWithIndex.foreach { case (transEntryEnq, othersIdx) => 294 val transEnqHit = transSelVec.map(x => x(othersIdx)) 295 transEntryEnq := Mux1H(transEnqHit, transEntryDeqVec) 296 } 297 dontTouch(transEntryEnqVec) 298 299 //issueRespVec 300 if(params.isMemAddrIQ){ 301 issueRespVec.zip(robIdxVec).foreach { case (issueResp, robIdx) => 302 val hitRespsVec = VecInit(memEtyResps.map(x => x.valid && (x.bits.robIdx === robIdx)).toSeq) 303 issueResp.valid := hitRespsVec.reduce(_ | _) 304 issueResp.bits := Mux1H(hitRespsVec, memEtyResps.map(_.bits).toSeq) 305 } 306 } 307 else { 308 issueRespVec.zip(issueTimerVec).zip(deqPortIdxReadVec).foreach { case ((issueResp, issueTimer), deqPortIdx) => 309 val Resp = resps(issueTimer)(deqPortIdx) 310 issueResp := Resp 311 } 312 } 313 314 io.valid := validVec.asUInt 315 io.canIssue := canIssueVec.asUInt 316 io.clear := clearVec.asUInt 317 io.fuType := fuTypeVec 318 io.dataSources := dataSourceVec 319 io.srcWakeUpL1ExuOH.foreach(_ := srcWakeUpL1ExuOHVec.get) 320 io.srcTimer.foreach(_ := srcTimerVec.get) 321 io.cancel.foreach(_ := cancelVec.get) 322 io.robIdx.foreach(_ := robIdxVec) 323 io.uopIdx.foreach(_ := uopIdxVec.get) 324 io.rsFeedback := 0.U.asTypeOf(io.rsFeedback) //todo 325 io.deq.foreach{ x => 326 x.isFirstIssue := Mux(x.deqSelOH.valid, Mux1H(x.deqSelOH.bits, isFirstIssueVec), false.B) 327 } 328 dontTouch(io.deq) 329 io.deqEntry.zip(io.deq.map(_.deqSelOH)).foreach{ case (deqEntry, deqSelOH) => 330 deqEntry.valid := deqSelOH.valid && entries(OHToUInt(deqSelOH.bits)).valid 331 deqEntry.bits := entries(OHToUInt(deqSelOH.bits)).bits 332 } 333 io.transSelVec.zip(transSelVec).foreach { case (sink, source) => 334 sink := source.asUInt 335 } 336} 337