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.LduCnt, 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, ExuOH()))) 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(srcWakeUpByIQVec).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 = io.wakeUpFromIQ.map(x => x.bits.exuIdx).map(x => io.og0Cancel(x)) 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 = io.enqDelayWakeUpFromIQ.map(x => x.bits.exuIdx).map(io.enqDelayOg0Cancel(_)) 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, io.enqDelayWakeUpFromIQ.map(x => MathUtils.IntToOH(x.bits.exuIdx).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.srcWakeUpL1ExuOH.foreach(_ := enqDelaySrcWakeUpL1ExuOH.get) 236 currentStatus.srcTimer.foreach(_ := enqDelaySrcTimer.get) 237 currentStatus.srcLoadDependency.foreach(_ := enqDelaySrcLoadDependency.get) 238 } 239 240 //entryUpdate 241 entryUpdate.status.srcState.zip(currentStatus.srcState).zip(srcWakeUp).zipWithIndex.foreach { case (((stateNext, state), wakeup), srcIdx) => 242 val cancel = srcCancelVec.map(_ (srcIdx)).getOrElse(false.B) 243 stateNext := Mux(cancel, false.B, wakeup | state) 244 if (params.hasIQWakeUp) { 245 cancelVec.get(srcIdx) := cancel 246 } 247 } 248 entryUpdate.status.dataSources.zip(srcWakeUpByIQVec).foreach { 249 case (dataSourceNext: DataSource, wakeUpByIQOH: Vec[Bool]) => 250 when(wakeUpByIQOH.asUInt.orR) { 251 dataSourceNext.value := DataSource.bypass 252 }.otherwise { 253 dataSourceNext.value := DataSource.reg 254 } 255 } 256 if (params.hasIQWakeUp) { 257 entryUpdate.status.srcWakeUpL1ExuOH.get.zip(srcWakeUpByIQVec).zip(srcWakeUp).zipWithIndex.foreach { 258 case (((exuOH: UInt, wakeUpByIQOH: Vec[Bool]), wakeUp: Bool), srcIdx) => 259 when(wakeUpByIQOH.asUInt.orR) { 260 exuOH := Mux1H(wakeUpByIQOH, io.wakeUpFromIQ.toSeq.map(x => MathUtils.IntToOH(x.bits.exuIdx).U(backendParams.numExu.W))) 261 }.elsewhen(wakeUp) { 262 exuOH := 0.U.asTypeOf(exuOH) 263 }.otherwise { 264 exuOH := currentStatus.srcWakeUpL1ExuOH.get(srcIdx) 265 } 266 } 267 srcWakeUpL1ExuOHOut.get.zip(srcWakeUpByIQWithoutCancel).zip(srcWakeUp).zipWithIndex.foreach { 268 case (((exuOH: UInt, wakeUpByIQOH: Vec[Bool]), wakeUp: Bool), srcIdx) => 269 when(wakeUpByIQOH.asUInt.orR) { 270 exuOH := Mux1H(wakeUpByIQOH, io.wakeUpFromIQ.map(x => MathUtils.IntToOH(x.bits.exuIdx).U(backendParams.numExu.W)).toSeq) 271 }.elsewhen(wakeUp) { 272 exuOH := 0.U.asTypeOf(exuOH) 273 }.otherwise { 274 exuOH := currentStatus.srcWakeUpL1ExuOH.get(srcIdx) 275 } 276 } 277 entryUpdate.status.srcTimer.get.zip(currentStatus.srcTimer.get).zip(srcWakeUpByIQVec).zipWithIndex.foreach { 278 case (((srcIssuedTimerNext, srcIssuedTimer), wakeUpByIQOH: Vec[Bool]), srcIdx) => 279 srcIssuedTimerNext := MuxCase(3.U, Seq( 280 // T0: waked up by IQ, T1: reset timer as 1 281 wakeUpByIQOH.asUInt.orR -> 2.U, 282 // do not overflow 283 srcIssuedTimer.andR -> srcIssuedTimer, 284 // T2+: increase if the entry is valid, the src is ready, and the src is woken up by iq 285 (validReg && SrcState.isReady(currentStatus.srcState(srcIdx)) && currentStatus.srcWakeUpL1ExuOH.get.asUInt.orR) -> (srcIssuedTimer + 1.U) 286 )) 287 } 288 entryUpdate.status.srcLoadDependency.get.zip(currentStatus.srcLoadDependency.get).zip(srcWakeUpByIQVec).zip(srcWakeUp).foreach { 289 case (((loadDependencyNext, loadDependency), wakeUpByIQVec), wakeup) => 290 loadDependencyNext := 291 Mux(wakeup, 292 Mux1H(wakeUpByIQVec, shiftedWakeupLoadDependencyByIQVec), 293 Mux(validReg && loadDependency.asUInt.orR, VecInit(loadDependency.map(i => i(i.getWidth - 2, 0) << 1)), loadDependency) 294 ) 295 } 296 srcLoadDependencyOut.get.zip(currentStatus.srcLoadDependency.get).zip(srcWakeUpByIQVec).zip(srcWakeUp).foreach { 297 case (((loadDependencyOut, loadDependency), wakeUpByIQVec), wakeup) => 298 loadDependencyOut := 299 Mux(wakeup, 300 Mux1H(wakeUpByIQVec, shiftedWakeupLoadDependencyByIQBypassVec), 301 loadDependency 302 ) 303 } 304 } 305 306 when(io.deqSel) { 307 entryUpdate.status.issueTimer := 0.U 308 entryUpdate.status.deqPortIdx := io.deqPortIdxWrite 309 }.elsewhen(entryReg.status.issued){ 310 entryUpdate.status.issueTimer := entryReg.status.issueTimer + 1.U 311 entryUpdate.status.deqPortIdx := entryReg.status.deqPortIdx 312 }.otherwise { 313 entryUpdate.status.issueTimer := "b10".U 314 entryUpdate.status.deqPortIdx := 0.U 315 } 316 entryUpdate.status.psrc := entryReg.status.psrc 317 entryUpdate.status.srcType := entryReg.status.srcType 318 entryUpdate.status.fuType := entryReg.status.fuType 319 entryUpdate.status.robIdx := entryReg.status.robIdx 320 when(srcLoadCancelVec.map(_.reduce(_ || _)).getOrElse(false.B) || srcWakeUpButCancel.map(_.fold(false.B)(_ || _)).fold(false.B)(_ || _)) { 321 entryUpdate.status.issued := false.B 322 }.elsewhen(io.deqSel) { 323 entryUpdate.status.issued := true.B 324 }.elsewhen(io.issueResp.valid && RSFeedbackType.isBlocked(io.issueResp.bits.respType)) { 325 entryUpdate.status.issued := false.B 326 }.elsewhen(!currentStatus.srcReady) { 327 entryUpdate.status.issued := false.B 328 }.otherwise { 329 entryUpdate.status.issued := entryReg.status.issued 330 } 331 entryUpdate.status.firstIssue := io.deqSel || entryReg.status.firstIssue 332 entryUpdate.status.blocked := false.B //todo 333 //remain imm and payload 334 entryUpdate.imm.foreach(_ := entryReg.imm.get) 335 entryUpdate.payload := entryReg.payload 336 337 //output 338 val canIssue = currentStatus.canIssue && validReg && !srcCancelVec.getOrElse(false.B).asUInt.orR 339 val canIssueBypass = validReg && !entryReg.status.issued && !entryReg.status.blocked && 340 VecInit(currentStatus.srcState.zip(srcWakeUpByIQWithoutCancel).zipWithIndex.map { case ((state, wakeupVec), srcIdx) => 341 val cancel = srcCancelVec.map(_ (srcIdx)).getOrElse(false.B) 342 Mux(cancel, false.B, wakeupVec.asUInt.orR | state) 343 }).asUInt.andR 344 io.dataSource.zip(currentStatus.dataSources).zip(srcWakeUpByIQVec).zip(srcWakeUp).foreach { 345 case (((dataSourceOut: DataSource, dataSource: DataSource), wakeUpByIQOH: Vec[Bool]), wakeUpAll) => 346 when(wakeUpByIQOH.asUInt.orR) { 347 dataSourceOut.value := DataSource.forward 348 }.elsewhen(wakeUpAll) { 349 dataSourceOut.value := DataSource.reg 350 }.otherwise { 351 dataSourceOut.value := dataSource.value 352 } 353 } 354 if (params.hasIQWakeUp) { 355 io.srcTimer.get.zip(currentStatus.srcTimer.get).zip(srcWakeUpByIQWithoutCancel).zip(srcWakeUp).foreach { 356 case (((srcTimerOut, srcTimer), wakeUpByIQOH: Vec[Bool]), wakeUpAll) => 357 when(wakeUpByIQOH.asUInt.orR) { 358 srcTimerOut := 1.U 359 }.otherwise { 360 srcTimerOut := srcTimer 361 } 362 } 363 io.srcWakeUpL1ExuOH.get := Mux(canIssueBypass && !canIssue, srcWakeUpL1ExuOHOut.get, currentStatus.srcWakeUpL1ExuOH.get) 364 } 365 io.transEntry.valid := validReg && !flushed && !deqSuccess 366 io.transEntry.bits := entryUpdate 367 io.canIssue := (canIssue || canIssueBypass) && !flushed 368 io.clear := clear 369 io.fuType := entryReg.status.fuType 370 io.valid := validReg 371 io.isFirstIssue := !entryReg.status.firstIssue 372 io.entry.valid := validReg 373 io.entry.bits := entryReg 374 io.entry.bits.status := currentStatus 375 io.entry.bits.status.srcLoadDependency.foreach(_ := Mux(canIssueBypass && !canIssue, srcLoadDependencyOut.get, currentStatus.srcLoadDependency.get)) 376 io.robIdx := entryReg.status.robIdx 377 io.uopIdx.foreach(_ := entryReg.status.uopIdx.get) 378 io.issueTimerRead := entryReg.status.issueTimer 379 io.deqPortIdxRead := entryReg.status.deqPortIdx 380 io.cancel.foreach(_ := cancelVec.get.asUInt.orR) 381} 382 383class EnqEntryMem()(implicit p: Parameters, params: IssueBlockParams) extends EnqEntry 384 with HasCircularQueuePtrHelper { 385 val fromMem = io.fromMem.get 386 387 val memStatus = entryReg.status.mem.get 388 println("memStatus" + memStatus) 389 val memStatusNext = entryRegNext.status.mem.get 390 val memStatusUpdate = entryUpdate.status.mem.get 391 392 // load cannot be issued before older store, unless meet some condition 393 val blockedByOlderStore = isAfter(memStatusNext.sqIdx, fromMem.stIssuePtr) 394 395 val deqFailedForStdInvalid = io.issueResp.valid && io.issueResp.bits.respType === RSFeedbackType.dataInvalid 396 397 val staWaitedReleased = Cat( 398 fromMem.memWaitUpdateReq.robIdx.map(x => x.valid && x.bits.value === memStatusNext.waitForRobIdx.value) 399 ).orR 400 val stdWaitedReleased = Cat( 401 fromMem.memWaitUpdateReq.sqIdx.map(x => x.valid && x.bits.value === memStatusNext.waitForSqIdx.value) 402 ).orR 403 val olderStaNotViolate = staWaitedReleased && !memStatusNext.strictWait 404 val olderStdReady = stdWaitedReleased && memStatusNext.waitForStd 405 val waitStd = !olderStdReady 406 val waitSta = !olderStaNotViolate 407 408 when (io.enq.valid && enqReady) { 409 memStatusNext.waitForSqIdx := io.enq.bits.status.mem.get.waitForSqIdx 410 // update by lfst at dispatch stage 411 memStatusNext.waitForRobIdx := io.enq.bits.status.mem.get.waitForRobIdx 412 // new load inst don't known if it is blocked by store data ahead of it 413 memStatusNext.waitForStd := false.B 414 // update by ssit at rename stage 415 memStatusNext.strictWait := io.enq.bits.status.mem.get.strictWait 416 memStatusNext.sqIdx := io.enq.bits.status.mem.get.sqIdx 417 }.otherwise { 418 memStatusNext := memStatusUpdate 419 } 420 421 when(deqFailedForStdInvalid) { 422 memStatusUpdate.waitForSqIdx := io.issueResp.bits.dataInvalidSqIdx 423 memStatusUpdate.waitForRobIdx := memStatus.waitForRobIdx 424 memStatusUpdate.waitForStd := true.B 425 memStatusUpdate.strictWait := memStatus.strictWait 426 memStatusUpdate.sqIdx := memStatus.sqIdx 427 }.otherwise { 428 memStatusUpdate := memStatus 429 } 430 431 val shouldBlock = Mux(io.enq.valid && enqReady, io.enq.bits.status.blocked, entryReg.status.blocked) 432 val blockNotReleased = waitStd || waitSta 433 val respBlock = deqFailedForStdInvalid 434 entryRegNext.status.blocked := shouldBlock && blockNotReleased && blockedByOlderStore || respBlock 435 entryUpdate.status.blocked := shouldBlock && blockNotReleased && blockedByOlderStore || respBlock 436 437} 438 439class EnqEntryVecMemAddr()(implicit p: Parameters, params: IssueBlockParams) extends EnqEntryMem { 440 441 require(params.isVecMemAddrIQ, "EnqEntryVecMemAddr can only be instance of VecMemAddr IQ") 442 443 val vecMemStatus = entryReg.status.vecMem.get 444 val vecMemStatusNext = entryRegNext.status.vecMem.get 445 val vecMemStatusUpdate = entryUpdate.status.vecMem.get 446 val fromLsq = io.fromLsq.get 447 448 when (io.enq.valid && enqReady) { 449 vecMemStatusNext.sqIdx := io.enq.bits.status.vecMem.get.sqIdx 450 vecMemStatusNext.lqIdx := io.enq.bits.status.vecMem.get.lqIdx 451 }.otherwise { 452 vecMemStatusNext := vecMemStatusUpdate 453 } 454 vecMemStatusUpdate := vecMemStatus 455 456 val isLsqHead = { 457 // if (params.isVecLdAddrIQ) 458 entryRegNext.status.vecMem.get.lqIdx <= fromLsq.lqDeqPtr && 459 // else 460 entryRegNext.status.vecMem.get.sqIdx <= fromLsq.sqDeqPtr 461 } 462 463 entryRegNext.status.blocked := shouldBlock && blockNotReleased && blockedByOlderStore || respBlock || !isLsqHead 464 entryUpdate.status.blocked := shouldBlock && blockNotReleased && blockedByOlderStore || respBlock || !isLsqHead 465} 466 467class EnqEntryVecMemData()(implicit p: Parameters, params: IssueBlockParams) extends EnqEntry 468 with HasCircularQueuePtrHelper { 469 470 require(params.isVecStDataIQ, "EnqEntryVecMemData can only be instance of VecMemData IQ") 471 472 val vecMemStatus = entryReg.status.vecMem.get 473 val vecMemStatusNext = entryRegNext.status.vecMem.get 474 val vecMemStatusUpdate = entryUpdate.status.vecMem.get 475 val fromLsq = io.fromLsq.get 476 477 when (io.enq.valid && enqReady) { 478 vecMemStatusNext.sqIdx := io.enq.bits.status.vecMem.get.sqIdx 479 vecMemStatusNext.lqIdx := io.enq.bits.status.vecMem.get.lqIdx 480 }.otherwise { 481 vecMemStatusNext := vecMemStatusUpdate 482 } 483 vecMemStatusUpdate := vecMemStatus 484 485 val isLsqHead = entryRegNext.status.vecMem.get.sqIdx.value === fromLsq.sqDeqPtr.value 486 487 entryRegNext.status.blocked := !isLsqHead 488 entryUpdate.status.blocked := !isLsqHead 489} 490 491object EnqEntry { 492 def apply(implicit p: Parameters, iqParams: IssueBlockParams): EnqEntry = { 493 iqParams.schdType match { 494 case IntScheduler() => new EnqEntry() 495 case MemScheduler() => 496 if (iqParams.isLdAddrIQ || iqParams.isStAddrIQ || iqParams.isHyAddrIQ) new EnqEntryMem() 497 else if (iqParams.isVecMemAddrIQ) new EnqEntryVecMemAddr() 498 else if (iqParams.isVecStDataIQ) new EnqEntryVecMemData() 499 else new EnqEntry() 500 case VfScheduler() => new EnqEntry() 501 case _ => null 502 } 503 } 504}