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