1package xiangshan.backend.issue 2 3import org.chipsalliance.cde.config.Parameters 4import chisel3._ 5import chisel3.util._ 6import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp} 7import utils.OptionWrapper 8import xiangshan._ 9import xiangshan.backend.Bundles._ 10import xiangshan.backend.datapath.DataConfig.{IntData, VAddrData, VecData, FpData} 11import xiangshan.backend.datapath.WbConfig.{IntWB, FpWB, VfWB} 12import xiangshan.backend.fu.FuType 13import xiangshan.backend.regfile.RfWritePortWithConfig 14import xiangshan.backend.rename.BusyTable 15import xiangshan.mem.{LsqEnqCtrl, LsqEnqIO, MemWaitUpdateReq, SqPtr, LqPtr} 16 17sealed trait SchedulerType 18 19case class IntScheduler() extends SchedulerType 20case class FpScheduler() extends SchedulerType 21case class MemScheduler() extends SchedulerType 22case class VfScheduler() extends SchedulerType 23case class NoScheduler() extends SchedulerType 24 25class Scheduler(val params: SchdBlockParams)(implicit p: Parameters) extends LazyModule with HasXSParameter { 26 override def shouldBeInlined: Boolean = false 27 28 val numIntStateWrite = backendParams.numPregWb(IntData()) 29 val numFpStateWrite = backendParams.numPregWb(FpData()) 30 val numVfStateWrite = backendParams.numPregWb(VecData()) 31 32 val dispatch2Iq = LazyModule(new Dispatch2Iq(params)) 33 val issueQueue = params.issueBlockParams.map(x => LazyModule(new IssueQueue(x).suggestName(x.getIQName))) 34 35 lazy val module: SchedulerImpBase = params.schdType match { 36 case IntScheduler() => new SchedulerArithImp(this)(params, p) 37 case FpScheduler() => new SchedulerArithImp(this)(params, p) 38 case MemScheduler() => new SchedulerMemImp(this)(params, p) 39 case VfScheduler() => new SchedulerArithImp(this)(params, p) 40 case _ => null 41 } 42} 43 44class SchedulerIO()(implicit params: SchdBlockParams, p: Parameters) extends XSBundle { 45 // params alias 46 private val LoadQueueSize = VirtualLoadQueueSize 47 48 val fromTop = new Bundle { 49 val hartId = Input(UInt(8.W)) 50 } 51 val fromWbFuBusyTable = new Bundle{ 52 val fuBusyTableRead = MixedVec(params.issueBlockParams.map(x => Input(x.genWbFuBusyTableReadBundle))) 53 } 54 val wbFuBusyTable = MixedVec(params.issueBlockParams.map(x => Output(x.genWbFuBusyTableWriteBundle))) 55 val IQValidNumVec = Output(MixedVec(backendParams.genIQValidNumBundle)) 56 57 val fromCtrlBlock = new Bundle { 58 val flush = Flipped(ValidIO(new Redirect)) 59 } 60 val fromDispatch = new Bundle { 61 val allocPregs = Vec(RenameWidth, Input(new ResetPregStateReq)) 62 val uops = Vec(params.numUopIn, Flipped(DecoupledIO(new DynInst))) 63 } 64 val intWriteBack = MixedVec(Vec(backendParams.numPregWb(IntData()), 65 new RfWritePortWithConfig(backendParams.intPregParams.dataCfg, backendParams.intPregParams.addrWidth))) 66 val fpWriteBack = MixedVec(Vec(backendParams.numPregWb(FpData()), 67 new RfWritePortWithConfig(backendParams.fpPregParams.dataCfg, backendParams.fpPregParams.addrWidth))) 68 val vfWriteBack = MixedVec(Vec(backendParams.numPregWb(VecData()), 69 new RfWritePortWithConfig(backendParams.vfPregParams.dataCfg, backendParams.vfPregParams.addrWidth))) 70 val toDataPathAfterDelay: MixedVec[MixedVec[DecoupledIO[IssueQueueIssueBundle]]] = MixedVec(params.issueBlockParams.map(_.genIssueDecoupledBundle)) 71 72 val fromSchedulers = new Bundle { 73 val wakeupVec: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpInValidBundle) 74 } 75 76 val toSchedulers = new Bundle { 77 val wakeupVec: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = params.genIQWakeUpOutValidBundle 78 } 79 80 val fromDataPath = new Bundle { 81 val resp: MixedVec[MixedVec[OGRespBundle]] = MixedVec(params.issueBlockParams.map(x => Flipped(x.genOGRespBundle))) 82 val og0Cancel = Input(ExuOH(backendParams.numExu)) 83 // Todo: remove this after no cancel signal from og1 84 val og1Cancel = Input(ExuOH(backendParams.numExu)) 85 val cancelToBusyTable = Vec(backendParams.numExu, Flipped(ValidIO(new CancelSignal))) 86 // just be compatible to old code 87 def apply(i: Int)(j: Int) = resp(i)(j) 88 } 89 90 val loadFinalIssueResp = MixedVec(params.issueBlockParams.map(x => MixedVec(Vec(x.LdExuCnt, Flipped(ValidIO(new IssueQueueDeqRespBundle()(p, x))))))) 91 val memAddrIssueResp = MixedVec(params.issueBlockParams.map(x => MixedVec(Vec(x.LdExuCnt, Flipped(ValidIO(new IssueQueueDeqRespBundle()(p, x))))))) 92 93 val ldCancel = Vec(backendParams.LduCnt + backendParams.HyuCnt, Flipped(new LoadCancelIO)) 94 95 val memIO = if (params.isMemSchd) Some(new Bundle { 96 val lsqEnqIO = Flipped(new LsqEnqIO) 97 }) else None 98 val fromMem = if (params.isMemSchd) Some(new Bundle { 99 val ldaFeedback = Flipped(Vec(params.LduCnt, new MemRSFeedbackIO)) 100 val staFeedback = Flipped(Vec(params.StaCnt, new MemRSFeedbackIO)) 101 val hyuFeedback = Flipped(Vec(params.HyuCnt, new MemRSFeedbackIO)) 102 val stIssuePtr = Input(new SqPtr()) 103 val lcommit = Input(UInt(log2Up(CommitWidth + 1).W)) 104 val scommit = Input(UInt(log2Ceil(EnsbufferWidth + 1).W)) // connected to `memBlock.io.sqDeq` instead of ROB 105 val wakeup = Vec(params.LdExuCnt, Flipped(Valid(new DynInst))) 106 val lqDeqPtr = Input(new LqPtr) 107 val sqDeqPtr = Input(new SqPtr) 108 // from lsq 109 val lqCancelCnt = Input(UInt(log2Up(LoadQueueSize + 1).W)) 110 val sqCancelCnt = Input(UInt(log2Up(StoreQueueSize + 1).W)) 111 val memWaitUpdateReq = Flipped(new MemWaitUpdateReq) 112 }) else None 113 val toMem = if (params.isMemSchd) Some(new Bundle { 114 val loadFastMatch = Output(Vec(params.LduCnt, new IssueQueueLoadBundle)) 115 }) else None 116 val fromOg2 = if(params.isVfSchd) Some(MixedVec(params.issueBlockParams.map(x => Flipped(x.genOG2RespBundle)))) else None 117} 118 119abstract class SchedulerImpBase(wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters) 120 extends LazyModuleImp(wrapper) 121 with HasXSParameter 122{ 123 val io = IO(new SchedulerIO()) 124 125 // alias 126 private val iqWakeUpInMap: Map[Int, ValidIO[IssueQueueIQWakeUpBundle]] = 127 io.fromSchedulers.wakeupVec.map(x => (x.bits.exuIdx, x)).toMap 128 private val schdType = params.schdType 129 130 // Modules 131 val dispatch2Iq: Dispatch2IqImp = wrapper.dispatch2Iq.module 132 val issueQueues: Seq[IssueQueueImp] = wrapper.issueQueue.map(_.module) 133 if (params.isIntSchd) { 134 dispatch2Iq.io.IQValidNumVec.get := io.IQValidNumVec 135 io.IQValidNumVec := MixedVecInit(issueQueues.map(_.io.validCntDeqVec)) 136 } 137 else io.IQValidNumVec := 0.U.asTypeOf(io.IQValidNumVec) 138 139 // valid count 140 dispatch2Iq.io.iqValidCnt := issueQueues.filter(_.params.StdCnt == 0).map(_.io.status.validCnt) 141 142 // BusyTable Modules 143 val intBusyTable = schdType match { 144 case IntScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numIntStateRead, wrapper.numIntStateWrite, IntPhyRegs, IntWB()))) 145 case _ => None 146 } 147 val fpBusyTable = schdType match { 148 case FpScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numFpStateRead, wrapper.numFpStateWrite, FpPhyRegs, FpWB()))) 149 case _ => None 150 } 151 val vfBusyTable = schdType match { 152 case VfScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numVfStateRead, wrapper.numVfStateWrite, VfPhyRegs, VfWB()))) 153 case _ => None 154 } 155 156 dispatch2Iq.io match { case dp2iq => 157 dp2iq.redirect <> io.fromCtrlBlock.flush 158 dp2iq.in <> io.fromDispatch.uops 159 dp2iq.readIntState.foreach(_ <> intBusyTable.get.io.read) 160 dp2iq.readFpState.foreach(_ <> fpBusyTable.get.io.read) 161 dp2iq.readVfState.foreach(_ <> vfBusyTable.get.io.read) 162 } 163 164 intBusyTable match { 165 case Some(bt) => 166 bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) => 167 btAllocPregs.valid := dpAllocPregs.isInt 168 btAllocPregs.bits := dpAllocPregs.preg 169 } 170 bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) => 171 wb.valid := io.intWriteBack(i).wen && io.intWriteBack(i).intWen 172 wb.bits := io.intWriteBack(i).addr 173 } 174 bt.io.wakeUp := io.fromSchedulers.wakeupVec 175 bt.io.cancel := io.fromDataPath.cancelToBusyTable 176 bt.io.ldCancel := io.ldCancel 177 case None => 178 } 179 180 fpBusyTable match { 181 case Some(bt) => 182 bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) => 183 btAllocPregs.valid := dpAllocPregs.isFp 184 btAllocPregs.bits := dpAllocPregs.preg 185 } 186 bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) => 187 wb.valid := io.fpWriteBack(i).wen && io.fpWriteBack(i).fpWen 188 wb.bits := io.fpWriteBack(i).addr 189 } 190 bt.io.wakeUp := io.fromSchedulers.wakeupVec 191 bt.io.cancel := io.fromDataPath.cancelToBusyTable 192 bt.io.ldCancel := io.ldCancel 193 case None => 194 } 195 196 vfBusyTable match { 197 case Some(bt) => 198 bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) => 199 btAllocPregs.valid := dpAllocPregs.isVec 200 btAllocPregs.bits := dpAllocPregs.preg 201 } 202 bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) => 203 wb.valid := io.vfWriteBack(i).wen && io.vfWriteBack(i).vecWen 204 wb.bits := io.vfWriteBack(i).addr 205 } 206 bt.io.wakeUp := io.fromSchedulers.wakeupVec 207 bt.io.cancel := io.fromDataPath.cancelToBusyTable 208 bt.io.ldCancel := io.ldCancel 209 case None => 210 } 211 212 val wakeupFromIntWBVec = Wire(params.genIntWBWakeUpSinkValidBundle) 213 val wakeupFromFpWBVec = Wire(params.genFpWBWakeUpSinkValidBundle) 214 val wakeupFromVfWBVec = Wire(params.genVfWBWakeUpSinkValidBundle) 215 216 wakeupFromIntWBVec.zip(io.intWriteBack).foreach { case (sink, source) => 217 sink.valid := source.wen 218 sink.bits.rfWen := source.intWen 219 sink.bits.fpWen := source.fpWen 220 sink.bits.vecWen := source.vecWen 221 sink.bits.pdest := source.addr 222 } 223 224 wakeupFromFpWBVec.zip(io.fpWriteBack).foreach { case (sink, source) => 225 sink.valid := source.wen 226 sink.bits.rfWen := source.intWen 227 sink.bits.fpWen := source.fpWen 228 sink.bits.vecWen := source.vecWen 229 sink.bits.pdest := source.addr 230 } 231 232 wakeupFromVfWBVec.zip(io.vfWriteBack).foreach { case (sink, source) => 233 sink.valid := source.wen 234 sink.bits.rfWen := source.intWen 235 sink.bits.fpWen := source.fpWen 236 sink.bits.vecWen := source.vecWen 237 sink.bits.pdest := source.addr 238 } 239 240 // Connect bundles having the same wakeup source 241 issueQueues.zipWithIndex.foreach { case(iq, i) => 242 iq.io.wakeupFromIQ.foreach { wakeUp => 243 val wakeUpIn = iqWakeUpInMap(wakeUp.bits.exuIdx) 244 val exuIdx = wakeUp.bits.exuIdx 245 println(s"[Backend] Connect wakeup exuIdx ${exuIdx}") 246 connectSamePort(wakeUp,wakeUpIn) 247 backendParams.connectWakeup(exuIdx) 248 if (backendParams.isCopyPdest(exuIdx)) { 249 println(s"[Backend] exuIdx ${exuIdx} use pdestCopy ${backendParams.getCopyPdestIndex(exuIdx)}") 250 wakeUp.bits.pdest := wakeUpIn.bits.pdestCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 251 if (wakeUpIn.bits.rfWenCopy.nonEmpty) wakeUp.bits.rfWen := wakeUpIn.bits.rfWenCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 252 if (wakeUpIn.bits.fpWenCopy.nonEmpty) wakeUp.bits.fpWen := wakeUpIn.bits.fpWenCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 253 if (wakeUpIn.bits.vecWenCopy.nonEmpty) wakeUp.bits.vecWen := wakeUpIn.bits.vecWenCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 254 if (wakeUpIn.bits.loadDependencyCopy.nonEmpty) wakeUp.bits.loadDependency := wakeUpIn.bits.loadDependencyCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 255 } 256 if (iq.params.numIntSrc == 0) wakeUp.bits.rfWen := false.B 257 if (iq.params.numFpSrc == 0) wakeUp.bits.fpWen := false.B 258 if (iq.params.numVfSrc == 0) wakeUp.bits.vecWen := false.B 259 } 260 iq.io.og0Cancel := io.fromDataPath.og0Cancel 261 iq.io.og1Cancel := io.fromDataPath.og1Cancel 262 iq.io.ldCancel := io.ldCancel 263 } 264 265 private val iqWakeUpOutMap: Map[Int, ValidIO[IssueQueueIQWakeUpBundle]] = 266 issueQueues.flatMap(_.io.wakeupToIQ) 267 .map(x => (x.bits.exuIdx, x)) 268 .toMap 269 270 // Connect bundles having the same wakeup source 271 io.toSchedulers.wakeupVec.foreach { wakeUp => 272 wakeUp := iqWakeUpOutMap(wakeUp.bits.exuIdx) 273 } 274 275 io.toDataPathAfterDelay.zipWithIndex.foreach { case (toDpDy, i) => 276 toDpDy <> issueQueues(i).io.deqDelay 277 } 278 279 // Response 280 issueQueues.zipWithIndex.foreach { case (iq, i) => 281 iq.io.og0Resp.zipWithIndex.foreach { case (og0Resp, j) => 282 og0Resp := io.fromDataPath(i)(j).og0resp 283 } 284 iq.io.og1Resp.zipWithIndex.foreach { case (og1Resp, j) => 285 og1Resp := io.fromDataPath(i)(j).og1resp 286 } 287 iq.io.finalIssueResp.foreach(_.zipWithIndex.foreach { case (finalIssueResp, j) => 288 if (io.loadFinalIssueResp(i).isDefinedAt(j)) { 289 finalIssueResp := io.loadFinalIssueResp(i)(j) 290 } else { 291 finalIssueResp := 0.U.asTypeOf(finalIssueResp) 292 } 293 }) 294 iq.io.memAddrIssueResp.foreach(_.zipWithIndex.foreach { case (memAddrIssueResp, j) => 295 if (io.memAddrIssueResp(i).isDefinedAt(j)) { 296 memAddrIssueResp := io.memAddrIssueResp(i)(j) 297 } else { 298 memAddrIssueResp := 0.U.asTypeOf(memAddrIssueResp) 299 } 300 }) 301 if(params.isVfSchd) { 302 iq.io.og2Resp.get.zipWithIndex.foreach { case (og2Resp, exuIdx) => 303 og2Resp := io.fromOg2.get(i)(exuIdx) 304 } 305 } 306 iq.io.wbBusyTableRead := io.fromWbFuBusyTable.fuBusyTableRead(i) 307 io.wbFuBusyTable(i) := iq.io.wbBusyTableWrite 308 } 309 310 println(s"[Scheduler] io.fromSchedulers.wakeupVec: ${io.fromSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}") 311 println(s"[Scheduler] iqWakeUpInKeys: ${iqWakeUpInMap.keys}") 312 313 println(s"[Scheduler] iqWakeUpOutKeys: ${iqWakeUpOutMap.keys}") 314 println(s"[Scheduler] io.toSchedulers.wakeupVec: ${io.toSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}") 315} 316 317class SchedulerArithImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters) 318 extends SchedulerImpBase(wrapper) 319 with HasXSParameter 320{ 321// dontTouch(io.vfWbFuBusyTable) 322 println(s"[SchedulerArithImp] " + 323 s"has intBusyTable: ${intBusyTable.nonEmpty}, " + 324 s"has vfBusyTable: ${vfBusyTable.nonEmpty}") 325 326 issueQueues.zipWithIndex.foreach { case (iq, i) => 327 iq.io.flush <> io.fromCtrlBlock.flush 328 iq.io.enq <> dispatch2Iq.io.out(i) 329 val intWBIQ = params.schdType match { 330 case IntScheduler() => wakeupFromIntWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1) 331 case FpScheduler() => wakeupFromFpWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromFpWBPort.keys.toSeq.contains(x._2)).map(_._1) 332 case VfScheduler() => wakeupFromVfWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromVfWBPort.keys.toSeq.contains(x._2)).map(_._1) 333 case _ => null 334 } 335 iq.io.wakeupFromWB.zip(intWBIQ).foreach{ case (sink, source) => sink := source} 336 } 337} 338 339// FIXME: Vector mem instructions may not be handled properly! 340class SchedulerMemImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters) 341 extends SchedulerImpBase(wrapper) 342 with HasXSParameter 343{ 344 println(s"[SchedulerMemImp] " + 345 s"has intBusyTable: ${intBusyTable.nonEmpty}, " + 346 s"has vfBusyTable: ${vfBusyTable.nonEmpty}") 347 348 val memAddrIQs = issueQueues.filter(_.params.isMemAddrIQ) 349 val stAddrIQs = issueQueues.filter(iq => iq.params.StaCnt > 0) // included in memAddrIQs 350 val ldAddrIQs = issueQueues.filter(iq => iq.params.LduCnt > 0) 351 val stDataIQs = issueQueues.filter(iq => iq.params.StdCnt > 0) 352 val vecMemIQs = issueQueues.filter(_.params.isVecMemIQ) 353 val (hyuIQs, hyuIQIdxs) = issueQueues.zipWithIndex.filter(_._1.params.HyuCnt > 0).unzip 354 355 println(s"[SchedulerMemImp] memAddrIQs.size: ${memAddrIQs.size}, enq.size: ${memAddrIQs.map(_.io.enq.size).sum}") 356 println(s"[SchedulerMemImp] stAddrIQs.size: ${stAddrIQs.size }, enq.size: ${stAddrIQs.map(_.io.enq.size).sum}") 357 println(s"[SchedulerMemImp] ldAddrIQs.size: ${ldAddrIQs.size }, enq.size: ${ldAddrIQs.map(_.io.enq.size).sum}") 358 println(s"[SchedulerMemImp] stDataIQs.size: ${stDataIQs.size }, enq.size: ${stDataIQs.map(_.io.enq.size).sum}") 359 println(s"[SchedulerMemImp] hyuIQs.size: ${hyuIQs.size }, enq.size: ${hyuIQs.map(_.io.enq.size).sum}") 360 require(memAddrIQs.nonEmpty && stDataIQs.nonEmpty) 361 362 io.toMem.get.loadFastMatch := 0.U.asTypeOf(io.toMem.get.loadFastMatch) // TODO: is still needed? 363 364 private val loadWakeUp = issueQueues.filter(_.params.LdExuCnt > 0).map(_.asInstanceOf[IssueQueueMemAddrImp].io.memIO.get.loadWakeUp).flatten 365 require(loadWakeUp.length == io.fromMem.get.wakeup.length) 366 loadWakeUp.zip(io.fromMem.get.wakeup).foreach(x => x._1 := x._2) 367 368 memAddrIQs.zipWithIndex.foreach { case (iq, i) => 369 iq.io.flush <> io.fromCtrlBlock.flush 370 iq.io.enq <> dispatch2Iq.io.out(i) 371 iq.io.wakeupFromWB.zip( 372 wakeupFromIntWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1) ++ 373 wakeupFromFpWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromFpWBPort.keys.toSeq.contains(x._2)).map(_._1) ++ 374 wakeupFromVfWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromVfWBPort.keys.toSeq.contains(x._2)).map(_._1) 375 ).foreach{ case (sink, source) => sink := source} 376 } 377 378 ldAddrIQs.zipWithIndex.foreach { 379 case (imp: IssueQueueMemAddrImp, i) => 380 imp.io.memIO.get.feedbackIO.head := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO.head) 381 imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr 382 imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 383 case _ => 384 } 385 386 stAddrIQs.zipWithIndex.foreach { 387 case (imp: IssueQueueMemAddrImp, i) => 388 imp.io.memIO.get.feedbackIO.head := io.fromMem.get.staFeedback(i) 389 imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr 390 imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 391 case _ => 392 } 393 394 hyuIQs.zip(hyuIQIdxs).foreach { 395 case (imp: IssueQueueMemAddrImp, idx) => 396 imp.io.memIO.get.feedbackIO.head := io.fromMem.get.hyuFeedback.head 397 imp.io.memIO.get.feedbackIO(1) := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO(1)) 398 imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr 399 imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 400 // TODO: refactor ditry code 401 imp.io.deqDelay(1).ready := false.B 402 io.toDataPathAfterDelay(idx)(1).valid := false.B 403 io.toDataPathAfterDelay(idx)(1).bits := 0.U.asTypeOf(io.toDataPathAfterDelay(idx)(1).bits) 404 case _ => 405 } 406 407 private val staIdxSeq = (stAddrIQs).map(iq => iq.params.idxInSchBlk) 408 private val hyaIdxSeq = (hyuIQs).map(iq => iq.params.idxInSchBlk) 409 410 println(s"[SchedulerMemImp] sta iq idx in memSchdBlock: $staIdxSeq") 411 println(s"[SchedulerMemImp] hya iq idx in memSchdBlock: $hyaIdxSeq") 412 413 private val staEnqs = stAddrIQs.map(_.io.enq).flatten 414 private val stdEnqs = stDataIQs.map(_.io.enq).flatten.take(staEnqs.size) 415 private val hyaEnqs = hyuIQs.map(_.io.enq).flatten 416 private val hydEnqs = stDataIQs.map(_.io.enq).flatten.drop(staEnqs.size) 417 418 require(staEnqs.size == stdEnqs.size, s"number of enq ports of store address IQs(${staEnqs.size}) " + 419 s"should be equal to number of enq ports of store data IQs(${stdEnqs.size})") 420 421 require(hyaEnqs.size == hydEnqs.size, s"number of enq ports of hybrid address IQs(${hyaEnqs.size}) " + 422 s"should be equal to number of enq ports of hybrid data IQs(${hydEnqs.size})") 423 424 val d2IqStaOut = dispatch2Iq.io.out.zipWithIndex.filter(staIdxSeq contains _._2).unzip._1.flatten 425 d2IqStaOut.zip(staEnqs).zip(stdEnqs).foreach{ case((dp, staIQ), stdIQ) => 426 val isAllReady = staIQ.ready && stdIQ.ready 427 dp.ready := isAllReady 428 staIQ.valid := dp.valid && isAllReady 429 stdIQ.valid := dp.valid && isAllReady && FuType.FuTypeOrR(dp.bits.fuType, FuType.stu, FuType.mou) 430 } 431 432 val d2IqHyaOut = dispatch2Iq.io.out.zipWithIndex.filter(hyaIdxSeq contains _._2).unzip._1.flatten 433 d2IqHyaOut.zip(hyaEnqs).zip(hydEnqs).foreach{ case((dp, hyaIQ), hydIQ) => 434 val isAllReady = hyaIQ.ready && hydIQ.ready 435 dp.ready := isAllReady 436 hyaIQ.valid := dp.valid && isAllReady 437 hydIQ.valid := dp.valid && isAllReady && FuType.FuTypeOrR(dp.bits.fuType, FuType.stu, FuType.mou) 438 } 439 440 stDataIQs.zipWithIndex.foreach { case (iq, i) => 441 iq.io.flush <> io.fromCtrlBlock.flush 442 iq.io.wakeupFromWB.zip( 443 wakeupFromIntWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq ++ 444 wakeupFromFpWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromFpWBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq ++ 445 wakeupFromVfWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromVfWBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq 446 ).foreach{ case (sink, source) => sink := source} 447 } 448 449 (stdEnqs ++ hydEnqs).zip(staEnqs ++ hyaEnqs).zipWithIndex.foreach { case ((stdIQEnq, staIQEnq), i) => 450 stdIQEnq.bits := staIQEnq.bits 451 // Store data reuses store addr src(1) in dispatch2iq 452 // [dispatch2iq] --src*------src*(0)--> [staIQ|hyaIQ] 453 // \ 454 // ---src*(1)--> [stdIQ] 455 // Since the src(1) of sta is easier to get, stdIQEnq.bits.src*(0) is assigned to staIQEnq.bits.src*(1) 456 // instead of dispatch2Iq.io.out(x).bits.src*(1) 457 val stdIdx = 1 458 stdIQEnq.bits.srcState(0) := staIQEnq.bits.srcState(stdIdx) 459 stdIQEnq.bits.srcLoadDependency(0) := staIQEnq.bits.srcLoadDependency(1) 460 stdIQEnq.bits.srcType(0) := staIQEnq.bits.srcType(stdIdx) 461 stdIQEnq.bits.psrc(0) := staIQEnq.bits.psrc(stdIdx) 462 stdIQEnq.bits.sqIdx := staIQEnq.bits.sqIdx 463 } 464 465 vecMemIQs.foreach { 466 case imp: IssueQueueVecMemImp => 467 imp.io.memIO.get.sqDeqPtr.foreach(_ := io.fromMem.get.sqDeqPtr) 468 imp.io.memIO.get.lqDeqPtr.foreach(_ := io.fromMem.get.lqDeqPtr) 469 // not used 470 imp.io.memIO.get.feedbackIO := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO) 471 // maybe not used 472 imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr 473 imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 474 imp.io.wakeupFromWB.zip( 475 wakeupFromIntWBVec.zipWithIndex.filter(x => imp.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq ++ 476 wakeupFromFpWBVec.zipWithIndex.filter(x => imp.params.needWakeupFromFpWBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq ++ 477 wakeupFromVfWBVec.zipWithIndex.filter(x => imp.params.needWakeupFromVfWBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq 478 ).foreach{ case (sink, source) => sink := source} 479 480 case _ => 481 } 482 483 val lsqEnqCtrl = Module(new LsqEnqCtrl) 484 485 lsqEnqCtrl.io.redirect <> io.fromCtrlBlock.flush 486 lsqEnqCtrl.io.enq <> dispatch2Iq.io.enqLsqIO.get 487 lsqEnqCtrl.io.lcommit := io.fromMem.get.lcommit 488 lsqEnqCtrl.io.scommit := io.fromMem.get.scommit 489 lsqEnqCtrl.io.lqCancelCnt := io.fromMem.get.lqCancelCnt 490 lsqEnqCtrl.io.sqCancelCnt := io.fromMem.get.sqCancelCnt 491 io.memIO.get.lsqEnqIO <> lsqEnqCtrl.io.enqLsq 492} 493