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 OthersEntryIO(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 deqSel = Input(Bool()) 26 val transSel = Input(Bool()) 27 val issueResp = Flipped(ValidIO(new EntryDeqRespBundle)) 28 val deqPortIdxWrite = Input(UInt(1.W)) 29 //output 30 val valid = Output(Bool()) 31 val canIssue = Output(Bool()) 32 val clear = Output(Bool()) 33 val enqReady = Output(Bool()) 34 val fuType = Output(FuType()) 35 val dataSource = Output(Vec(params.numRegSrc, DataSource())) 36 val srcWakeUpL1ExuOH = OptionWrapper(params.hasIQWakeUp, Output(Vec(params.numRegSrc, ExuOH()))) 37 val srcTimer = OptionWrapper(params.hasIQWakeUp, Output(Vec(params.numRegSrc, UInt(3.W)))) 38 val isFirstIssue = Output(Bool()) 39 val entry = ValidIO(new EntryBundle) 40 val robIdx = Output(new RobPtr) 41 val uopIdx = OptionWrapper(params.isVecMemIQ, Output(UopIdx())) 42 val deqPortIdxRead = Output(UInt(1.W)) 43 val issueTimerRead = Output(UInt(2.W)) 44 // mem only 45 val fromMem = if(params.isMemAddrIQ) Some(new Bundle { 46 val stIssuePtr = Input(new SqPtr) 47 val memWaitUpdateReq = Flipped(new MemWaitUpdateReq) 48 }) else None 49 // vector mem only 50 val fromLsq = OptionWrapper(params.isVecMemIQ, new Bundle { 51 val sqDeqPtr = Input(new SqPtr) 52 val lqDeqPtr = Input(new LqPtr) 53 }) 54 // debug 55 val cancel = OptionWrapper(params.hasIQWakeUp, Output(Bool())) 56 57 def wakeup = wakeUpFromWB ++ wakeUpFromIQ 58} 59 60class OthersEntry(implicit p: Parameters, params: IssueBlockParams) extends XSModule { 61 val io = IO(new OthersEntryIO) 62 63 val validReg = RegInit(false.B) 64 val entryReg = Reg(new EntryBundle) 65 66 val validRegNext = Wire(Bool()) 67 val entryRegNext = Wire(new EntryBundle) 68 val enqReady = Wire(Bool()) 69 val flushed = Wire(Bool()) 70 val clear = Wire(Bool()) 71 val deqSuccess = Wire(Bool()) 72 val srcWakeUp = Wire(Vec(params.numRegSrc, Bool())) 73 val srcWakeUpByWB = Wire(Vec(params.numRegSrc, Bool())) 74 val srcCancelVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, Bool()))) 75 val srcLoadCancelVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, Bool()))) 76 val srcWakeUpByIQVec = Wire(Vec(params.numRegSrc, Vec(params.numWakeupFromIQ, Bool()))) 77 val srcWakeUpByIQWithoutCancel = Wire(Vec(params.numRegSrc, Vec(params.numWakeupFromIQ, Bool()))) 78 val srcWakeUpL1ExuOHOut = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, ExuVec()))) 79 val srcLoadDependencyOut = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, Vec(LoadPipelineWidth, UInt(3.W))))) 80 val srcWakeUpButCancel = Wire(Vec(params.numRegSrc, Vec(params.numWakeupFromIQ, Bool()))) 81 val wakeupLoadDependencyByIQVec = Wire(Vec(params.numWakeupFromIQ, Vec(LoadPipelineWidth, UInt(3.W)))) 82 val shiftedWakeupLoadDependencyByIQVec = Wire(Vec(params.numWakeupFromIQ, Vec(LoadPipelineWidth, UInt(3.W)))) 83 val shiftedWakeupLoadDependencyByIQBypassVec = Wire(Vec(params.numWakeupFromIQ, Vec(LoadPipelineWidth, UInt(3.W)))) 84 val cancelVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, Bool()))) 85 86 //Reg 87 validReg := validRegNext 88 entryReg := entryRegNext 89 90 //Wire 91 enqReady := !validReg || clear 92 flushed := entryReg.status.robIdx.needFlush(io.flush) 93 clear := flushed || deqSuccess 94 deqSuccess := io.issueResp.valid && io.issueResp.bits.respType === RSFeedbackType.fuIdle && !srcLoadCancelVec.map(_.reduce(_ || _)).getOrElse(false.B) 95 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 96 srcWakeUp := srcWakeUpByWB.zip(srcWakeUpByIQVec).map { case (x, y) => x || y.asUInt.orR } 97 98 shiftedWakeupLoadDependencyByIQVec 99 .zip(wakeupLoadDependencyByIQVec) 100 .zip(params.wakeUpInExuSources.map(_.name)).foreach { 101 case ((deps, originalDeps), name) => deps.zip(originalDeps).zipWithIndex.foreach { 102 case ((dep, originalDep), deqPortIdx) => 103 if (params.backendParam.getLdExuIdx(params.backendParam.allExuParams.find(_.name == name).get) == deqPortIdx) 104 dep := (originalDep << 2).asUInt | 2.U 105 else 106 dep := originalDep << 1 107 } 108 } 109 shiftedWakeupLoadDependencyByIQBypassVec 110 .zip(wakeupLoadDependencyByIQVec) 111 .zip(params.wakeUpInExuSources.map(_.name)).foreach { 112 case ((deps, originalDeps), name) => deps.zip(originalDeps).zipWithIndex.foreach { 113 case ((dep, originalDep), deqPortIdx) => 114 if (params.backendParam.getLdExuIdx(params.backendParam.allExuParams.find(_.name == name).get) == deqPortIdx) 115 dep := (originalDep << 2).asUInt | 2.U 116 else 117 dep := originalDep << 1 118 } 119 } 120 121 when(io.enq.valid && io.transSel) { 122 validRegNext := true.B 123 }.elsewhen(clear) { 124 validRegNext := false.B 125 }.otherwise { 126 validRegNext := validReg 127 } 128 129 if (params.hasIQWakeUp) { 130 srcCancelVec.get.zip(srcLoadCancelVec.get).zip(srcWakeUpByIQWithoutCancel).zipWithIndex.foreach { case (((srcCancel, srcLoadCancel), wakeUpByIQVec), srcIdx) => 131 val ldTransCancel = Mux1H(wakeUpByIQVec, wakeupLoadDependencyByIQVec.map(dep => LoadShouldCancel(Some(dep), io.ldCancel))) 132 srcLoadCancel := LoadShouldCancel(entryReg.status.srcLoadDependency.map(_(srcIdx)), io.ldCancel) 133 srcCancel := srcLoadCancel || ldTransCancel 134 } 135 cancelVec.get.foreach(_ := false.B) 136 } 137 138 if (io.wakeUpFromIQ.isEmpty) { 139 srcWakeUpByIQVec := 0.U.asTypeOf(srcWakeUpByIQVec) 140 wakeupLoadDependencyByIQVec := 0.U.asTypeOf(wakeupLoadDependencyByIQVec) 141 } else { 142 val wakeupVec: Seq[Seq[Bool]] = io.wakeUpFromIQ.map((bundle: ValidIO[IssueQueueIQWakeUpBundle]) => 143 bundle.bits.wakeUpFromIQ(entryReg.status.psrc zip entryReg.status.srcType) 144 ).toSeq.transpose 145 val cancelSel = params.wakeUpSourceExuIdx.zip(io.wakeUpFromIQ).map{ case (x, y) => io.og0Cancel(x) && y.bits.is0Lat} 146 srcWakeUpByIQVec := wakeupVec.map(x => VecInit(x.zip(cancelSel).map { case (wakeup, cancel) => wakeup && !cancel })) 147 srcWakeUpButCancel := wakeupVec.map(x => VecInit(x.zip(cancelSel).map { case (wakeup, cancel) => wakeup && cancel })) 148 srcWakeUpByIQWithoutCancel := wakeupVec.map(x => VecInit(x)) 149 wakeupLoadDependencyByIQVec := io.wakeUpFromIQ.map(_.bits.loadDependency).toSeq 150 } 151 152 val regSrcWakeUpL1ExuOH = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, ExuVec()))) 153 if (params.hasIQWakeUp) { 154 regSrcWakeUpL1ExuOH.get.zip(entryReg.status.srcWakeUpL1ExuOH.get).foreach { 155 case (exuOH, regExuOH) => 156 exuOH := 0.U.asTypeOf(exuOH) 157 params.wakeUpSourceExuIdx.foreach(x => exuOH(x) := regExuOH(x)) 158 } 159 } 160 161 when(io.enq.valid && io.transSel) { 162 entryRegNext := io.enq.bits 163 }.otherwise { 164 //update status 165 entryRegNext.status.srcState.zip(entryReg.status.srcState).zip(srcWakeUp).zipWithIndex.foreach { case (((stateNext, state), wakeup), srcIdx) => 166 val cancel = srcCancelVec.map(_ (srcIdx)).getOrElse(false.B) 167 stateNext := Mux(cancel, false.B, wakeup | state) 168 if (params.hasIQWakeUp) { 169 cancelVec.get(srcIdx) := cancel 170 } 171 } 172 entryRegNext.status.dataSources.zip(entryReg.status.dataSources).zip(srcWakeUpByIQVec).foreach { 173 case ((dataSourceNext: DataSource, dataSource: DataSource), wakeUpByIQOH: Vec[Bool]) => 174 when(wakeUpByIQOH.asUInt.orR) { 175 dataSourceNext.value := DataSource.bypass 176 }.otherwise { 177 dataSourceNext.value := DataSource.reg 178 } 179 } 180 if (params.hasIQWakeUp) { 181 entryRegNext.status.srcWakeUpL1ExuOH.get.zip(srcWakeUpByIQVec).zip(srcWakeUp).zipWithIndex.foreach { 182 case (((exuOH: Vec[Bool], wakeUpByIQOH: Vec[Bool]), wakeUp: Bool), srcIdx) => 183 val origExuOH = 0.U.asTypeOf(exuOH) 184 when(wakeUpByIQOH.asUInt.orR) { 185 origExuOH := VecInit(Mux1H(wakeUpByIQOH, params.wakeUpSourceExuIdx.toSeq.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W))).asBools) 186 }.elsewhen(wakeUp) { 187 origExuOH := 0.U.asTypeOf(origExuOH) 188 }.otherwise { 189 origExuOH := regSrcWakeUpL1ExuOH.get(srcIdx) 190 } 191 exuOH := 0.U.asTypeOf(exuOH) 192 params.wakeUpSourceExuIdx.foreach(x => exuOH(x) := origExuOH(x)) 193 } 194 entryRegNext.status.srcTimer.get.zip(entryReg.status.srcTimer.get).zip(srcWakeUpByIQVec).zipWithIndex.foreach { 195 case (((srcIssuedTimerNext, srcIssuedTimer), wakeUpByIQOH: Vec[Bool]), srcIdx) => 196 srcIssuedTimerNext := MuxCase(3.U, Seq( 197 // T0: waked up by IQ, T1: reset timer as 1 198 wakeUpByIQOH.asUInt.orR -> 2.U, 199 // do not overflow 200 srcIssuedTimer.andR -> srcIssuedTimer, 201 // T2+: increase if the entry is valid, the src is ready, and the src is woken up by iq 202 (validReg && SrcState.isReady(entryReg.status.srcState(srcIdx)) && regSrcWakeUpL1ExuOH.get(srcIdx).asUInt.orR) -> (srcIssuedTimer + 1.U) 203 )) 204 } 205 entryRegNext.status.srcLoadDependency.get.zip(entryReg.status.srcLoadDependency.get).zip(srcWakeUpByIQVec).zip(srcWakeUp).foreach { 206 case (((loadDependencyNext, loadDependency), wakeUpByIQVec), wakeup) => 207 loadDependencyNext := 208 Mux(wakeup, 209 Mux1H(wakeUpByIQVec, shiftedWakeupLoadDependencyByIQVec), 210 Mux(validReg && loadDependency.asUInt.orR, VecInit(loadDependency.map(i => i(i.getWidth - 2, 0) << 1)), loadDependency) 211 ) 212 } 213 } 214 when (io.deqSel) { 215 entryRegNext.status.issueTimer := 0.U 216 entryRegNext.status.deqPortIdx := io.deqPortIdxWrite 217 }.elsewhen (entryReg.status.issued) { 218 entryRegNext.status.issueTimer := entryReg.status.issueTimer + 1.U 219 entryRegNext.status.deqPortIdx := entryReg.status.deqPortIdx 220 }.otherwise { 221 entryRegNext.status.issueTimer := "b10".U 222 entryRegNext.status.deqPortIdx := 0.U 223 } 224 entryRegNext.status.psrc := entryReg.status.psrc 225 entryRegNext.status.srcType := entryReg.status.srcType 226 entryRegNext.status.fuType := IQFuType.readFuType(entryReg.status.fuType, params.getFuCfgs.map(_.fuType)) 227 entryRegNext.status.robIdx := entryReg.status.robIdx 228 entryRegNext.status.uopIdx.foreach(_ := entryReg.status.uopIdx.get) 229 when(srcLoadCancelVec.map(_.reduce(_ || _)).getOrElse(false.B) || srcWakeUpButCancel.map(_.fold(false.B)(_ || _)).fold(false.B)(_ || _)) { 230 entryRegNext.status.issued := false.B 231 }.elsewhen(io.deqSel) { 232 entryRegNext.status.issued := true.B 233 }.elsewhen(io.issueResp.valid && RSFeedbackType.isBlocked(io.issueResp.bits.respType)) { 234 entryRegNext.status.issued := false.B 235 }.elsewhen(!entryReg.status.srcReady) { 236 entryRegNext.status.issued := false.B 237 }.otherwise { 238 entryRegNext.status.issued := entryReg.status.issued 239 } 240 entryRegNext.status.firstIssue := io.deqSel || entryReg.status.firstIssue 241 entryRegNext.status.blocked := false.B //todo 242 //remain imm and payload 243 entryRegNext.imm.foreach(_ := entryReg.imm.get) 244 entryRegNext.payload := entryReg.payload 245 } 246 247 //output 248 val canIssue = entryReg.status.canIssue && validReg && !srcCancelVec.getOrElse(false.B).asUInt.orR 249 val canIssueBypass = validReg && !entryReg.status.issued && !entryReg.status.blocked && 250 VecInit(entryReg.status.srcState.zip(srcWakeUpByIQWithoutCancel).zipWithIndex.map { case ((state, wakeupVec), srcIdx) => 251 val cancel = srcCancelVec.map(_ (srcIdx)).getOrElse(false.B) 252 Mux(cancel, false.B, wakeupVec.asUInt.orR | state) 253 }).asUInt.andR 254 io.dataSource.zip(entryReg.status.dataSources).zip(srcWakeUpByIQVec).zip(srcWakeUp).foreach { 255 case (((dataSourceOut: DataSource, dataSource: DataSource), wakeUpByIQOH: Vec[Bool]), wakeUpAll) => 256 when(wakeUpByIQOH.asUInt.orR) { 257 dataSourceOut.value := DataSource.forward 258 }.otherwise { 259 dataSourceOut.value := dataSource.value 260 } 261 } 262 if (params.hasIQWakeUp) { 263 srcWakeUpL1ExuOHOut.get.zip(srcWakeUpByIQWithoutCancel).zip(srcWakeUp).zipWithIndex.foreach { 264 case (((exuOH: Vec[Bool], wakeUpByIQOH: Vec[Bool]), wakeUp: Bool), srcIdx) => 265 val origExuOH = 0.U.asTypeOf(exuOH) 266 when(wakeUpByIQOH.asUInt.orR) { 267 origExuOH := VecInit(Mux1H(wakeUpByIQOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W)).toSeq).asBools) 268 }.otherwise { 269 origExuOH := regSrcWakeUpL1ExuOH.get(srcIdx) 270 } 271 exuOH := 0.U.asTypeOf(exuOH) 272 params.wakeUpSourceExuIdx.foreach(x => exuOH(x) := origExuOH(x)) 273 } 274 srcLoadDependencyOut.get.zip(entryReg.status.srcLoadDependency.get).zip(srcWakeUpByIQVec).zip(srcWakeUp).foreach { 275 case (((loadDependencyOut, loadDependency), wakeUpByIQVec), wakeup) => 276 loadDependencyOut := Mux1H(wakeUpByIQVec, shiftedWakeupLoadDependencyByIQBypassVec) 277 } 278 io.srcTimer.get.zip(entryReg.status.srcTimer.get).zip(srcWakeUpByIQWithoutCancel).zip(srcWakeUp).foreach { 279 case (((srcTimerOut, srcTimer), wakeUpByIQOH: Vec[Bool]), wakeUpAll) => 280 when(wakeUpByIQOH.asUInt.orR) { 281 srcTimerOut := Mux1H(wakeUpByIQOH, io.wakeUpFromIQ.map(_.bits.is0Lat).toSeq).asUInt 282 }.otherwise { 283 srcTimerOut := srcTimer 284 } 285 } 286 io.srcWakeUpL1ExuOH.get := Mux(canIssueBypass && !canIssue, srcWakeUpL1ExuOHOut.get, regSrcWakeUpL1ExuOH.get).map(_.asUInt) 287 } 288 io.canIssue := (canIssue || canIssueBypass) && !flushed 289 io.clear := clear 290 io.fuType := IQFuType.readFuType(entryReg.status.fuType, params.getFuCfgs.map(_.fuType)).asUInt 291 io.valid := validReg 292 io.enqReady := enqReady 293 io.isFirstIssue := !entryReg.status.firstIssue 294 io.entry.valid := validReg 295 io.entry.bits := entryReg 296 io.entry.bits.status.srcLoadDependency.foreach(_ := Mux(canIssueBypass && !canIssue, srcLoadDependencyOut.get, entryReg.status.srcLoadDependency.get)) 297 io.robIdx := entryReg.status.robIdx 298 io.uopIdx.foreach(_ := entryReg.status.uopIdx.get) 299 io.issueTimerRead := entryReg.status.issueTimer 300 io.deqPortIdxRead := entryReg.status.deqPortIdx 301 io.cancel.foreach(_ := cancelVec.get.asUInt.orR) 302} 303 304class OthersEntryMem()(implicit p: Parameters, params: IssueBlockParams) extends OthersEntry 305 with HasCircularQueuePtrHelper { 306 307 val fromMem = io.fromMem.get 308 309 val memStatus = entryReg.status.mem.get 310 val memStatusNext = entryRegNext.status.mem.get 311 // load cannot be issued before older store, unless meet some condition 312 val blockedByOlderStore = isAfter(memStatusNext.sqIdx, fromMem.stIssuePtr) 313 314 val deqFailedForStdInvalid = io.issueResp.valid && io.issueResp.bits.respType === RSFeedbackType.dataInvalid 315 316 val staWaitedReleased = Cat( 317 fromMem.memWaitUpdateReq.robIdx.map(x => x.valid && x.bits.value === memStatusNext.waitForRobIdx.value) 318 ).orR 319 val stdWaitedReleased = Cat( 320 fromMem.memWaitUpdateReq.sqIdx.map(x => x.valid && x.bits.value === memStatusNext.waitForSqIdx.value) 321 ).orR 322 val olderStaNotViolate = staWaitedReleased && !memStatusNext.strictWait 323 val olderStdReady = stdWaitedReleased && memStatusNext.waitForStd 324 val waitStd = !olderStdReady 325 val waitSta = !olderStaNotViolate 326 327 when(io.enq.valid && io.transSel) { 328 memStatusNext.waitForSqIdx := io.enq.bits.status.mem.get.waitForSqIdx 329 // update by lfst at dispatch stage 330 memStatusNext.waitForRobIdx := io.enq.bits.status.mem.get.waitForRobIdx 331 // new load inst don't known if it is blocked by store data ahead of it 332 memStatusNext.waitForStd := false.B 333 // update by ssit at rename stage 334 memStatusNext.strictWait := io.enq.bits.status.mem.get.strictWait 335 memStatusNext.sqIdx := io.enq.bits.status.mem.get.sqIdx 336 }.elsewhen(deqFailedForStdInvalid) { 337 // Todo: check if need assign statusNext.block 338 memStatusNext.waitForSqIdx := io.issueResp.bits.dataInvalidSqIdx 339 memStatusNext.waitForRobIdx := memStatus.waitForRobIdx 340 memStatusNext.waitForStd := true.B 341 memStatusNext.strictWait := memStatus.strictWait 342 memStatusNext.sqIdx := memStatus.sqIdx 343 }.otherwise { 344 memStatusNext := memStatus 345 } 346 347 val shouldBlock = Mux(io.enq.valid && io.transSel, io.enq.bits.status.blocked, entryReg.status.blocked) 348 val blockNotReleased = waitStd || waitSta 349 val respBlock = deqFailedForStdInvalid 350 entryRegNext.status.blocked := shouldBlock && blockNotReleased && blockedByOlderStore || respBlock 351} 352 353class OthersEntryVecMemAddr()(implicit p: Parameters, params: IssueBlockParams) extends OthersEntryMem { 354 355 require(params.isVecMemAddrIQ, "OthersEntryVecMemAddr can only be instance of VecMemAddr IQ") 356 357 val vecMemStatus = entryReg.status.vecMem.get 358 val vecMemStatusNext = entryRegNext.status.vecMem.get 359 val fromLsq = io.fromLsq.get 360 361 when(io.enq.valid && io.transSel) { 362 vecMemStatusNext.sqIdx := io.enq.bits.status.vecMem.get.sqIdx 363 vecMemStatusNext.lqIdx := io.enq.bits.status.vecMem.get.lqIdx 364 }.otherwise { 365 vecMemStatusNext := vecMemStatus 366 } 367 368 val isLsqHead = { 369 // if (params.isVecLdAddrIQ) 370 entryRegNext.status.vecMem.get.lqIdx <= fromLsq.lqDeqPtr && 371 // else 372 entryRegNext.status.vecMem.get.sqIdx <= fromLsq.sqDeqPtr 373 } 374 dontTouch(shouldBlock) 375 dontTouch(blockNotReleased) 376 dontTouch(blockedByOlderStore) 377 dontTouch(respBlock) 378 dontTouch(isLsqHead) 379 dontTouch(waitStd) 380 dontTouch(waitSta) 381 dontTouch(memStatusNext) 382 dontTouch(fromMem) 383 dontTouch(io.issueResp) 384 dontTouch(isLsqHead) 385 386 entryRegNext.status.blocked := shouldBlock && blockNotReleased && blockedByOlderStore || respBlock || !isLsqHead 387} 388 389class OthersEntryVecMemData()(implicit p: Parameters, params: IssueBlockParams) extends OthersEntry 390 with HasCircularQueuePtrHelper { 391 392 require(params.isVecStDataIQ, "OthersEntryVecMemData can only be instance of VecMemData IQ") 393 394 val vecMemStatus = entryReg.status.vecMem.get 395 val vecMemStatusNext = entryRegNext.status.vecMem.get 396 val fromLsq = io.fromLsq.get 397 398 when(io.enq.valid && io.transSel) { 399 vecMemStatusNext.sqIdx := io.enq.bits.status.vecMem.get.sqIdx 400 vecMemStatusNext.lqIdx := io.enq.bits.status.vecMem.get.lqIdx 401 }.otherwise { 402 vecMemStatusNext := vecMemStatus 403 } 404 405 val isLsqHead = entryRegNext.status.vecMem.get.sqIdx.value === fromLsq.sqDeqPtr.value 406 407 entryRegNext.status.blocked := !isLsqHead 408} 409 410object OthersEntry { 411 def apply(implicit p: Parameters, iqParams: IssueBlockParams): OthersEntry = { 412 iqParams.schdType match { 413 case IntScheduler() => new OthersEntry() 414 case MemScheduler() => 415 if (iqParams.isLdAddrIQ || iqParams.isStAddrIQ || iqParams.isHyAddrIQ) new OthersEntryMem() 416 else if (iqParams.isVecMemAddrIQ) new OthersEntryVecMemAddr() 417 else if (iqParams.isVecStDataIQ) new OthersEntryVecMemData() 418 else new OthersEntry() 419 case VfScheduler() => new OthersEntry() 420 case _ => null 421 } 422 } 423}