1package xiangshan.backend.issue 2 3import org.chipsalliance.cde.config.Parameters 4import chisel3._ 5import chisel3.util._ 6import utility.HasCircularQueuePtrHelper 7import utils.{MathUtils, OptionWrapper} 8import xiangshan._ 9import xiangshan.backend.Bundles._ 10import xiangshan.backend.fu.FuType 11import xiangshan.backend.datapath.DataSource 12import xiangshan.backend.rob.RobPtr 13import xiangshan.mem.{MemWaitUpdateReq, SqPtr, LqPtr} 14 15 16class EnqEntryIO(implicit p: Parameters, params: IssueBlockParams) extends XSBundle { 17 //input 18 val enq = Flipped(ValidIO(new EntryBundle)) 19 val flush = Flipped(ValidIO(new Redirect)) 20 val wakeUpFromWB: MixedVec[ValidIO[IssueQueueWBWakeUpBundle]] = Flipped(params.genWBWakeUpSinkValidBundle) 21 val wakeUpFromIQ: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpSinkValidBundle) 22 val og0Cancel = Input(ExuOH(backendParams.numExu)) 23 val og1Cancel = Input(ExuOH(backendParams.numExu)) 24 val ldCancel = Vec(backendParams.LduCnt + backendParams.HyuCnt, Flipped(new LoadCancelIO)) 25 val enqDelayWakeUpFromWB: MixedVec[ValidIO[IssueQueueWBWakeUpBundle]] = Flipped(params.genWBWakeUpSinkValidBundle) 26 val enqDelayWakeUpFromIQ: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpSinkValidBundle) 27 val enqDelayOg0Cancel = Input(ExuOH(backendParams.numExu)) 28 val enqDelayLdCancel = Vec(backendParams.LdExuCnt, Flipped(new LoadCancelIO)) 29 val deqSel = Input(Bool()) 30 val deqPortIdxWrite = Input(UInt(1.W)) 31 val transSel = Input(Bool()) 32 val issueResp = Flipped(ValidIO(new EntryDeqRespBundle)) 33 //output 34 val valid = Output(Bool()) 35 val canIssue = Output(Bool()) 36 val clear = Output(Bool()) 37 val fuType = Output(FuType()) 38 val dataSource = Output(Vec(params.numRegSrc, DataSource())) 39 val srcWakeUpL1ExuOH = OptionWrapper(params.hasIQWakeUp, Output(Vec(params.numRegSrc, ExuOH()))) 40 val srcTimer = OptionWrapper(params.hasIQWakeUp, Output(Vec(params.numRegSrc, UInt(3.W)))) 41 val transEntry = ValidIO(new EntryBundle) 42 val isFirstIssue = Output(Bool()) 43 val entry = ValidIO(new EntryBundle) 44 val robIdx = Output(new RobPtr) 45 val uopIdx = OptionWrapper(params.isVecMemIQ, Output(UopIdx())) 46 val deqPortIdxRead = Output(UInt(1.W)) 47 val issueTimerRead = Output(UInt(2.W)) 48 // mem only 49 val fromMem = if(params.isMemAddrIQ) Some(new Bundle { 50 val stIssuePtr = Input(new SqPtr) 51 val memWaitUpdateReq = Flipped(new MemWaitUpdateReq) 52 }) else None 53 // vector mem only 54 val fromLsq = OptionWrapper(params.isVecMemIQ, new Bundle { 55 val sqDeqPtr = Input(new SqPtr) 56 val lqDeqPtr = Input(new LqPtr) 57 }) 58 // debug 59 val cancel = OptionWrapper(params.hasIQWakeUp, Output(Bool())) 60 61 def wakeup = wakeUpFromWB ++ wakeUpFromIQ 62} 63 64class EnqEntry(implicit p: Parameters, params: IssueBlockParams) extends XSModule { 65 val io = IO(new EnqEntryIO) 66 67 val validReg = RegInit(false.B) 68 val entryReg = Reg(new EntryBundle) 69 val enqDelayValidReg = RegInit(false.B) 70 71 val validRegNext = Wire(Bool()) 72 val entryRegNext = Wire(new EntryBundle) 73 val entryUpdate = Wire(new EntryBundle) 74 val enqDelayValidRegNext = Wire(Bool()) 75 val enqReady = Wire(Bool()) 76 val clear = Wire(Bool()) 77 val flushed = Wire(Bool()) 78 val deqSuccess = Wire(Bool()) 79 val srcWakeUp = Wire(Vec(params.numRegSrc, Bool())) 80 val srcWakeUpByWB = Wire(Vec(params.numRegSrc, Bool())) 81 val srcCancelVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, Bool()))) 82 val srcLoadCancelVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, Bool()))) 83 val srcWakeUpByIQVec = Wire(Vec(params.numRegSrc, Vec(params.numWakeupFromIQ, Bool()))) 84 val srcWakeUpByIQWithoutCancel = Wire(Vec(params.numRegSrc, Vec(params.numWakeupFromIQ, Bool()))) 85 val srcWakeUpButCancel = Wire(Vec(params.numRegSrc, Vec(params.numWakeupFromIQ, Bool()))) 86 val srcWakeUpL1ExuOHOut = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, ExuVec()))) 87 val srcLoadDependencyOut = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, Vec(LoadPipelineWidth, UInt(3.W))))) 88 val wakeupLoadDependencyByIQVec = Wire(Vec(params.numWakeupFromIQ, Vec(LoadPipelineWidth, UInt(3.W)))) 89 val shiftedWakeupLoadDependencyByIQVec = Wire(Vec(params.numWakeupFromIQ, Vec(LoadPipelineWidth, UInt(3.W)))) 90 val shiftedWakeupLoadDependencyByIQBypassVec = Wire(Vec(params.numWakeupFromIQ, Vec(LoadPipelineWidth, UInt(3.W)))) 91 val cancelVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, Bool()))) 92 93 val currentStatus = Wire(new Status()) 94 val enqDelaySrcState = Wire(Vec(params.numRegSrc, SrcState())) 95 val enqDelayDataSources = Wire(Vec(params.numRegSrc, DataSource())) 96 val enqDelaySrcWakeUpL1ExuOH = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, ExuOH()))) 97 val enqDelaySrcTimer = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, UInt(3.W)))) 98 val enqDelaySrcLoadDependency = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, Vec(LoadPipelineWidth, UInt(3.W))))) 99 100 val enqDelaySrcWakeUpByWB: Vec[UInt] = Wire(Vec(params.numRegSrc, SrcState())) 101 val enqDelaySrcWakeUpByIQ: Vec[UInt] = Wire(Vec(params.numRegSrc, SrcState())) 102 val enqDelaySrcWakeUpByIQVec: Vec[Vec[Bool]] = Wire(Vec(params.numRegSrc, Vec(params.numWakeupFromIQ, Bool()))) 103 val enqDelayShiftedWakeupLoadDependencyByIQVec: Vec[Vec[UInt]] = Wire(Vec(params.numWakeupFromIQ, Vec(LoadPipelineWidth, UInt(3.W)))) 104 105 //Reg 106 validReg := validRegNext 107 entryReg := entryRegNext 108 enqDelayValidReg := enqDelayValidRegNext 109 110 //Wire 111 when(io.enq.valid && enqReady) { 112 validRegNext := true.B 113 }.elsewhen(clear) { 114 validRegNext := false.B 115 }.otherwise { 116 validRegNext := validReg 117 } 118 119 when(io.enq.valid && enqReady) { 120 entryRegNext := io.enq.bits 121 }.otherwise { 122 entryRegNext := entryUpdate 123 } 124 125 when(io.enq.valid && enqReady) { 126 enqDelayValidRegNext := true.B 127 }.otherwise { 128 enqDelayValidRegNext := false.B 129 } 130 131 enqReady := !validReg || clear 132 clear := flushed || io.transSel || deqSuccess 133 flushed := entryReg.status.robIdx.needFlush(io.flush) 134 deqSuccess := io.issueResp.valid && io.issueResp.bits.respType === RSFeedbackType.fuIdle && !srcLoadCancelVec.map(_.reduce(_ || _)).getOrElse(false.B) 135 136 // current wakeup 137 srcWakeUpByWB := io.wakeUpFromWB.map(bundle => bundle.bits.wakeUp(entryReg.status.psrc zip entryReg.status.srcType, bundle.valid)).transpose.map(x => VecInit(x.toSeq).asUInt.orR).toSeq 138 srcWakeUp := srcWakeUpByWB.zip(srcWakeUpByIQVec).map { case (x, y) => x || y.asUInt.orR } 139 140 shiftedWakeupLoadDependencyByIQVec 141 .zip(wakeupLoadDependencyByIQVec) 142 .zip(params.wakeUpInExuSources.map(_.name)).foreach { 143 case ((deps, originalDeps), name) => deps.zip(originalDeps).zipWithIndex.foreach { 144 case ((dep, originalDep), deqPortIdx) => 145 if (params.backendParam.getLdExuIdx(params.backendParam.allExuParams.find(_.name == name).get) == deqPortIdx) 146 dep := (originalDep << 2).asUInt | 2.U 147 else 148 dep := originalDep << 1 149 } 150 } 151 shiftedWakeupLoadDependencyByIQBypassVec 152 .zip(wakeupLoadDependencyByIQVec) 153 .zip(params.wakeUpInExuSources.map(_.name)).foreach { 154 case ((deps, originalDeps), name) => deps.zip(originalDeps).zipWithIndex.foreach { 155 case ((dep, originalDep), deqPortIdx) => 156 if (params.backendParam.getLdExuIdx(params.backendParam.allExuParams.find(_.name == name).get) == deqPortIdx) 157 dep := (originalDep << 1).asUInt | 1.U 158 else 159 dep := originalDep 160 } 161 } 162 163 if (params.hasIQWakeUp) { 164 srcCancelVec.get.zip(srcLoadCancelVec.get).zip(srcWakeUpByIQWithoutCancel).zipWithIndex.foreach { case (((srcCancel, srcLoadCancel), wakeUpByIQVec), srcIdx) => 165 val ldTransCancel = Mux1H(wakeUpByIQVec, wakeupLoadDependencyByIQVec.map(dep => LoadShouldCancel(Some(dep), io.ldCancel))) 166 srcLoadCancel := LoadShouldCancel(currentStatus.srcLoadDependency.map(_(srcIdx)), io.ldCancel) 167 srcCancel := srcLoadCancel || ldTransCancel 168 } 169 } 170 171 if (io.wakeUpFromIQ.isEmpty) { 172 srcWakeUpByIQVec := 0.U.asTypeOf(srcWakeUpByIQVec) 173 wakeupLoadDependencyByIQVec := 0.U.asTypeOf(wakeupLoadDependencyByIQVec) 174 } else { 175 val wakeupVec: IndexedSeq[IndexedSeq[Bool]] = io.wakeUpFromIQ.map((bundle: ValidIO[IssueQueueIQWakeUpBundle]) => 176 bundle.bits.wakeUp(entryReg.status.psrc zip entryReg.status.srcType, bundle.valid) 177 ).toIndexedSeq.transpose 178 val cancelSel = params.wakeUpSourceExuIdx.zip(io.wakeUpFromIQ).map{ case (x, y) => io.og0Cancel(x) && y.bits.is0Lat} 179 srcWakeUpByIQVec := wakeupVec.map(x => VecInit(x.zip(cancelSel).map { case (wakeup, cancel) => wakeup && !cancel })) 180 srcWakeUpButCancel := wakeupVec.map(x => VecInit(x.zip(cancelSel).map { case (wakeup, cancel) => wakeup && cancel })) 181 srcWakeUpByIQWithoutCancel := wakeupVec.map(x => VecInit(x)) 182 wakeupLoadDependencyByIQVec := io.wakeUpFromIQ.map(_.bits.loadDependency).toSeq 183 } 184 185 // enq delay wakeup 186 enqDelaySrcWakeUpByWB.zipWithIndex.foreach { case (wakeup, i) => 187 wakeup := io.enqDelayWakeUpFromWB.map(x => x.bits.wakeUp(Seq((entryReg.status.psrc(i), entryReg.status.srcType(i))), x.valid).head 188 ).reduce(_ || _) 189 } 190 191 if (params.hasIQWakeUp) { 192 val wakeupVec: IndexedSeq[IndexedSeq[Bool]] = io.enqDelayWakeUpFromIQ.map( x => 193 x.bits.wakeUp(entryReg.status.psrc.zip(entryReg.status.srcType), x.valid) 194 ).toIndexedSeq.transpose 195 val cancelSel = params.wakeUpSourceExuIdx.zip(io.enqDelayWakeUpFromIQ).map{ case (x, y) => io.enqDelayOg0Cancel(x) && y.bits.is0Lat} 196 enqDelaySrcWakeUpByIQVec := wakeupVec.map(x => VecInit(x.zip(cancelSel).map { case (wakeup, cancel) => wakeup && !cancel })) 197 } else { 198 enqDelaySrcWakeUpByIQVec := 0.U.asTypeOf(enqDelaySrcWakeUpByIQVec) 199 } 200 201 if (params.hasIQWakeUp) { 202 enqDelaySrcWakeUpByIQ.zipWithIndex.foreach { case (wakeup, i) => 203 val ldTransCancel = Mux1H(enqDelaySrcWakeUpByIQVec(i), io.enqDelayWakeUpFromIQ.map(_.bits.loadDependency).map(dp => LoadShouldCancel(Some(dp), io.enqDelayLdCancel)).toSeq) 204 wakeup := enqDelaySrcWakeUpByIQVec(i).asUInt.orR && !ldTransCancel 205 } 206 } else { 207 enqDelaySrcWakeUpByIQ := 0.U.asTypeOf(enqDelaySrcWakeUpByIQ) 208 } 209 210 enqDelayShiftedWakeupLoadDependencyByIQVec.zip(io.enqDelayWakeUpFromIQ.map(_.bits.loadDependency)) 211 .zip(params.wakeUpInExuSources.map(_.name)).foreach { case ((dps, ldps), name) => 212 dps.zip(ldps).zipWithIndex.foreach { case ((dp, ldp), deqPortIdx) => 213 if (params.backendParam.getLdExuIdx(params.backendParam.allExuParams.find(_.name == name).get) == deqPortIdx) 214 dp := (ldp << 2).asUInt | 2.U 215 else 216 dp := ldp << 1 217 } 218 } 219 220 for (i <- 0 until params.numRegSrc) { 221 enqDelaySrcState(i) := entryReg.status.srcState(i) | enqDelaySrcWakeUpByWB(i) | enqDelaySrcWakeUpByIQ(i) 222 enqDelayDataSources(i).value := Mux(enqDelaySrcWakeUpByIQ(i).asBool, DataSource.bypass, DataSource.reg) 223 if (params.hasIQWakeUp) { 224 val wakeUpValid = enqDelaySrcWakeUpByIQVec(i).asUInt.orR 225 val wakeUpOH = enqDelaySrcWakeUpByIQVec(i) 226 enqDelaySrcWakeUpL1ExuOH.get(i) := Mux1H(wakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W)).toSeq) 227 enqDelaySrcTimer.get(i) := Mux(wakeUpValid, 2.U, 3.U) 228 enqDelaySrcLoadDependency.get(i) := Mux(wakeUpValid, Mux1H(wakeUpOH, enqDelayShiftedWakeupLoadDependencyByIQVec), entryReg.status.srcLoadDependency.get(i)) 229 } 230 } 231 currentStatus := entryReg.status 232 when (enqDelayValidReg) { 233 currentStatus.srcState := enqDelaySrcState 234 currentStatus.dataSources := enqDelayDataSources 235 currentStatus.srcTimer.foreach(_ := enqDelaySrcTimer.get) 236 currentStatus.srcLoadDependency.foreach(_ := enqDelaySrcLoadDependency.get) 237 } 238 239 if (params.hasIQWakeUp) { 240 currentStatus.srcWakeUpL1ExuOH.get.zip(entryReg.status.srcWakeUpL1ExuOH.get).zip(enqDelaySrcWakeUpL1ExuOH.get).foreach { 241 case ((currExuOH, regExuOH), enqDelayExuOH) => 242 currExuOH := 0.U.asTypeOf(currExuOH) 243 params.wakeUpSourceExuIdx.foreach(x => currExuOH(x) := Mux(enqDelayValidReg, enqDelayExuOH(x), regExuOH(x))) 244 } 245 } 246 247 //entryUpdate 248 entryUpdate.status.srcState.zip(currentStatus.srcState).zip(srcWakeUp).zipWithIndex.foreach { case (((stateNext, state), wakeup), srcIdx) => 249 val cancel = srcCancelVec.map(_ (srcIdx)).getOrElse(false.B) 250 stateNext := Mux(cancel, false.B, wakeup | state) 251 if (params.hasIQWakeUp) { 252 cancelVec.get(srcIdx) := cancel 253 } 254 } 255 entryUpdate.status.dataSources.zip(srcWakeUpByIQVec).foreach { 256 case (dataSourceNext: DataSource, wakeUpByIQOH: Vec[Bool]) => 257 when(wakeUpByIQOH.asUInt.orR) { 258 dataSourceNext.value := DataSource.bypass 259 }.otherwise { 260 dataSourceNext.value := DataSource.reg 261 } 262 } 263 if (params.hasIQWakeUp) { 264 entryUpdate.status.srcWakeUpL1ExuOH.get.zip(srcWakeUpByIQVec).zip(srcWakeUp).zipWithIndex.foreach { 265 case (((exuOH: Vec[Bool], wakeUpByIQOH: Vec[Bool]), wakeUp: Bool), srcIdx) => 266 val origExuOH = 0.U.asTypeOf(exuOH) 267 when(wakeUpByIQOH.asUInt.orR) { 268 origExuOH := Mux1H(wakeUpByIQOH, params.wakeUpSourceExuIdx.toSeq.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W))).asBools 269 }.elsewhen(wakeUp) { 270 origExuOH := 0.U.asTypeOf(origExuOH) 271 }.otherwise { 272 origExuOH := currentStatus.srcWakeUpL1ExuOH.get(srcIdx) 273 } 274 exuOH := 0.U.asTypeOf(exuOH) 275 params.wakeUpSourceExuIdx.foreach(x => exuOH(x) := origExuOH(x)) 276 } 277 srcWakeUpL1ExuOHOut.get.zip(srcWakeUpByIQWithoutCancel).zip(srcWakeUp).zipWithIndex.foreach { 278 case (((exuOH: Vec[Bool], wakeUpByIQOH: Vec[Bool]), wakeUp: Bool), srcIdx) => 279 val origExuOH = 0.U.asTypeOf(exuOH) 280 when(wakeUpByIQOH.asUInt.orR) { 281 origExuOH := VecInit(Mux1H(wakeUpByIQOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W)).toSeq).asBools) 282 }.otherwise { 283 origExuOH := currentStatus.srcWakeUpL1ExuOH.get(srcIdx) 284 } 285 exuOH := 0.U.asTypeOf(exuOH) 286 params.wakeUpSourceExuIdx.foreach(x => exuOH(x) := origExuOH(x)) 287 } 288 entryUpdate.status.srcTimer.get.zip(currentStatus.srcTimer.get).zip(srcWakeUpByIQVec).zipWithIndex.foreach { 289 case (((srcIssuedTimerNext, srcIssuedTimer), wakeUpByIQOH: Vec[Bool]), srcIdx) => 290 srcIssuedTimerNext := MuxCase(3.U, Seq( 291 // T0: waked up by IQ, T1: reset timer as 1 292 wakeUpByIQOH.asUInt.orR -> 2.U, 293 // do not overflow 294 srcIssuedTimer.andR -> srcIssuedTimer, 295 // T2+: increase if the entry is valid, the src is ready, and the src is woken up by iq 296 (validReg && SrcState.isReady(currentStatus.srcState(srcIdx)) && currentStatus.srcWakeUpL1ExuOH.get(srcIdx).asUInt.orR) -> (srcIssuedTimer + 1.U) 297 )) 298 } 299 entryUpdate.status.srcLoadDependency.get.zip(currentStatus.srcLoadDependency.get).zip(srcWakeUpByIQVec).zip(srcWakeUp).foreach { 300 case (((loadDependencyNext, loadDependency), wakeUpByIQVec), wakeup) => 301 loadDependencyNext := 302 Mux(wakeup, 303 Mux1H(wakeUpByIQVec, shiftedWakeupLoadDependencyByIQVec), 304 Mux(validReg && loadDependency.asUInt.orR, VecInit(loadDependency.map(i => i(i.getWidth - 2, 0) << 1)), loadDependency) 305 ) 306 } 307 srcLoadDependencyOut.get.zip(currentStatus.srcLoadDependency.get).zip(srcWakeUpByIQVec).zip(srcWakeUp).foreach { 308 case (((loadDependencyOut, loadDependency), wakeUpByIQVec), wakeup) => 309 loadDependencyOut := Mux1H(wakeUpByIQVec, shiftedWakeupLoadDependencyByIQBypassVec) 310 } 311 } 312 313 when(io.deqSel) { 314 entryUpdate.status.issueTimer := 0.U 315 entryUpdate.status.deqPortIdx := io.deqPortIdxWrite 316 }.elsewhen(entryReg.status.issued){ 317 entryUpdate.status.issueTimer := entryReg.status.issueTimer + 1.U 318 entryUpdate.status.deqPortIdx := entryReg.status.deqPortIdx 319 }.otherwise { 320 entryUpdate.status.issueTimer := "b10".U 321 entryUpdate.status.deqPortIdx := 0.U 322 } 323 entryUpdate.status.psrc := entryReg.status.psrc 324 entryUpdate.status.srcType := entryReg.status.srcType 325 entryUpdate.status.fuType := entryReg.status.fuType 326 entryUpdate.status.robIdx := entryReg.status.robIdx 327 when(srcLoadCancelVec.map(_.reduce(_ || _)).getOrElse(false.B) || srcWakeUpButCancel.map(_.fold(false.B)(_ || _)).fold(false.B)(_ || _)) { 328 entryUpdate.status.issued := false.B 329 }.elsewhen(io.deqSel) { 330 entryUpdate.status.issued := true.B 331 }.elsewhen(io.issueResp.valid && RSFeedbackType.isBlocked(io.issueResp.bits.respType)) { 332 entryUpdate.status.issued := false.B 333 }.elsewhen(!currentStatus.srcReady) { 334 entryUpdate.status.issued := false.B 335 }.otherwise { 336 entryUpdate.status.issued := entryReg.status.issued 337 } 338 entryUpdate.status.firstIssue := io.deqSel || entryReg.status.firstIssue 339 entryUpdate.status.blocked := false.B //todo 340 //remain imm and payload 341 entryUpdate.imm.foreach(_ := entryReg.imm.get) 342 entryUpdate.payload := entryReg.payload 343 344 //output 345 val canIssue = currentStatus.canIssue && validReg && !srcCancelVec.getOrElse(false.B).asUInt.orR 346 val canIssueBypass = validReg && !entryReg.status.issued && !entryReg.status.blocked && 347 VecInit(currentStatus.srcState.zip(srcWakeUpByIQWithoutCancel).zipWithIndex.map { case ((state, wakeupVec), srcIdx) => 348 val cancel = srcCancelVec.map(_ (srcIdx)).getOrElse(false.B) 349 Mux(cancel, false.B, wakeupVec.asUInt.orR | state) 350 }).asUInt.andR 351 io.dataSource.zip(currentStatus.dataSources).zip(srcWakeUpByIQVec).zip(srcWakeUp).foreach { 352 case (((dataSourceOut: DataSource, dataSource: DataSource), wakeUpByIQOH: Vec[Bool]), wakeUpAll) => 353 when(wakeUpByIQOH.asUInt.orR) { 354 dataSourceOut.value := DataSource.forward 355 }.otherwise { 356 dataSourceOut.value := dataSource.value 357 } 358 } 359 if (params.hasIQWakeUp) { 360 io.srcTimer.get.zip(currentStatus.srcTimer.get).zip(srcWakeUpByIQWithoutCancel).zip(srcWakeUp).foreach { 361 case (((srcTimerOut, srcTimer), wakeUpByIQOH: Vec[Bool]), wakeUpAll) => 362 when(wakeUpByIQOH.asUInt.orR) { 363 srcTimerOut := Mux1H(wakeUpByIQOH, io.wakeUpFromIQ.map(_.bits.is0Lat).toSeq).asUInt 364 }.otherwise { 365 srcTimerOut := srcTimer 366 } 367 } 368 io.srcWakeUpL1ExuOH.get := Mux(canIssueBypass && !canIssue, srcWakeUpL1ExuOHOut.get, currentStatus.srcWakeUpL1ExuOH.get).map(_.asUInt) 369 } 370 io.transEntry.valid := validReg && !flushed && !deqSuccess 371 io.transEntry.bits := entryUpdate 372 io.canIssue := (canIssue || canIssueBypass) && !flushed 373 io.clear := clear 374 io.fuType := entryReg.status.fuType 375 io.valid := validReg 376 io.isFirstIssue := !entryReg.status.firstIssue 377 io.entry.valid := validReg 378 io.entry.bits := entryReg 379 io.entry.bits.status := currentStatus 380 io.entry.bits.status.srcLoadDependency.foreach(_ := Mux(canIssueBypass && !canIssue, srcLoadDependencyOut.get, currentStatus.srcLoadDependency.get)) 381 io.robIdx := entryReg.status.robIdx 382 io.uopIdx.foreach(_ := entryReg.status.uopIdx.get) 383 io.issueTimerRead := entryReg.status.issueTimer 384 io.deqPortIdxRead := entryReg.status.deqPortIdx 385 io.cancel.foreach(_ := cancelVec.get.asUInt.orR) 386} 387 388class EnqEntryMem()(implicit p: Parameters, params: IssueBlockParams) extends EnqEntry 389 with HasCircularQueuePtrHelper { 390 val fromMem = io.fromMem.get 391 392 val memStatus = entryReg.status.mem.get 393 println("memStatus" + memStatus) 394 val memStatusNext = entryRegNext.status.mem.get 395 val memStatusUpdate = entryUpdate.status.mem.get 396 397 // load cannot be issued before older store, unless meet some condition 398 val blockedByOlderStore = isAfter(memStatusNext.sqIdx, fromMem.stIssuePtr) 399 400 val deqFailedForStdInvalid = io.issueResp.valid && io.issueResp.bits.respType === RSFeedbackType.dataInvalid 401 402 val staWaitedReleased = Cat( 403 fromMem.memWaitUpdateReq.robIdx.map(x => x.valid && x.bits.value === memStatusNext.waitForRobIdx.value) 404 ).orR 405 val stdWaitedReleased = Cat( 406 fromMem.memWaitUpdateReq.sqIdx.map(x => x.valid && x.bits.value === memStatusNext.waitForSqIdx.value) 407 ).orR 408 val olderStaNotViolate = staWaitedReleased && !memStatusNext.strictWait 409 val olderStdReady = stdWaitedReleased && memStatusNext.waitForStd 410 val waitStd = !olderStdReady 411 val waitSta = !olderStaNotViolate 412 413 when (io.enq.valid && enqReady) { 414 memStatusNext.waitForSqIdx := io.enq.bits.status.mem.get.waitForSqIdx 415 // update by lfst at dispatch stage 416 memStatusNext.waitForRobIdx := io.enq.bits.status.mem.get.waitForRobIdx 417 // new load inst don't known if it is blocked by store data ahead of it 418 memStatusNext.waitForStd := false.B 419 // update by ssit at rename stage 420 memStatusNext.strictWait := io.enq.bits.status.mem.get.strictWait 421 memStatusNext.sqIdx := io.enq.bits.status.mem.get.sqIdx 422 }.otherwise { 423 memStatusNext := memStatusUpdate 424 } 425 426 when(deqFailedForStdInvalid) { 427 memStatusUpdate.waitForSqIdx := io.issueResp.bits.dataInvalidSqIdx 428 memStatusUpdate.waitForRobIdx := memStatus.waitForRobIdx 429 memStatusUpdate.waitForStd := true.B 430 memStatusUpdate.strictWait := memStatus.strictWait 431 memStatusUpdate.sqIdx := memStatus.sqIdx 432 }.otherwise { 433 memStatusUpdate := memStatus 434 } 435 436 val shouldBlock = Mux(io.enq.valid && enqReady, io.enq.bits.status.blocked, entryReg.status.blocked) 437 val blockNotReleased = waitStd || waitSta 438 val respBlock = deqFailedForStdInvalid 439 entryRegNext.status.blocked := shouldBlock && blockNotReleased && blockedByOlderStore || respBlock 440 entryUpdate.status.blocked := shouldBlock && blockNotReleased && blockedByOlderStore || respBlock 441 442} 443 444class EnqEntryVecMemAddr()(implicit p: Parameters, params: IssueBlockParams) extends EnqEntryMem { 445 446 require(params.isVecMemAddrIQ, "EnqEntryVecMemAddr can only be instance of VecMemAddr IQ") 447 448 val vecMemStatus = entryReg.status.vecMem.get 449 val vecMemStatusNext = entryRegNext.status.vecMem.get 450 val vecMemStatusUpdate = entryUpdate.status.vecMem.get 451 val fromLsq = io.fromLsq.get 452 453 when (io.enq.valid && enqReady) { 454 vecMemStatusNext.sqIdx := io.enq.bits.status.vecMem.get.sqIdx 455 vecMemStatusNext.lqIdx := io.enq.bits.status.vecMem.get.lqIdx 456 }.otherwise { 457 vecMemStatusNext := vecMemStatusUpdate 458 } 459 vecMemStatusUpdate := vecMemStatus 460 461 val isLsqHead = { 462 // if (params.isVecLdAddrIQ) 463 entryRegNext.status.vecMem.get.lqIdx <= fromLsq.lqDeqPtr && 464 // else 465 entryRegNext.status.vecMem.get.sqIdx <= fromLsq.sqDeqPtr 466 } 467 468 entryRegNext.status.blocked := shouldBlock && blockNotReleased && blockedByOlderStore || respBlock || !isLsqHead 469 entryUpdate.status.blocked := shouldBlock && blockNotReleased && blockedByOlderStore || respBlock || !isLsqHead 470 entryUpdate.status.uopIdx.get := entryReg.status.uopIdx.get 471} 472 473class EnqEntryVecMemData()(implicit p: Parameters, params: IssueBlockParams) extends EnqEntry 474 with HasCircularQueuePtrHelper { 475 476 require(params.isVecStDataIQ, "EnqEntryVecMemData can only be instance of VecMemData IQ") 477 478 val vecMemStatus = entryReg.status.vecMem.get 479 val vecMemStatusNext = entryRegNext.status.vecMem.get 480 val vecMemStatusUpdate = entryUpdate.status.vecMem.get 481 val fromLsq = io.fromLsq.get 482 483 when (io.enq.valid && enqReady) { 484 vecMemStatusNext.sqIdx := io.enq.bits.status.vecMem.get.sqIdx 485 vecMemStatusNext.lqIdx := io.enq.bits.status.vecMem.get.lqIdx 486 }.otherwise { 487 vecMemStatusNext := vecMemStatusUpdate 488 } 489 vecMemStatusUpdate := vecMemStatus 490 491 val isLsqHead = entryRegNext.status.vecMem.get.sqIdx.value === fromLsq.sqDeqPtr.value 492 493 entryRegNext.status.blocked := !isLsqHead 494 entryUpdate.status.blocked := !isLsqHead 495 entryUpdate.status.uopIdx.get := entryReg.status.uopIdx.get 496} 497 498object EnqEntry { 499 def apply(implicit p: Parameters, iqParams: IssueBlockParams): EnqEntry = { 500 iqParams.schdType match { 501 case IntScheduler() => new EnqEntry() 502 case MemScheduler() => 503 if (iqParams.isLdAddrIQ || iqParams.isStAddrIQ || iqParams.isHyAddrIQ) new EnqEntryMem() 504 else if (iqParams.isVecMemAddrIQ) new EnqEntryVecMemAddr() 505 else if (iqParams.isVecStDataIQ) new EnqEntryVecMemData() 506 else new EnqEntry() 507 case VfScheduler() => new EnqEntry() 508 case _ => null 509 } 510 } 511}