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