1730cfbc0SXuan Hupackage xiangshan.backend.issue 2730cfbc0SXuan Hu 383ba63b3SXuan Huimport org.chipsalliance.cde.config.Parameters 4730cfbc0SXuan Huimport chisel3._ 5730cfbc0SXuan Huimport chisel3.util._ 6730cfbc0SXuan Huimport freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp} 74fa00a44SzhanglyGitimport utils.OptionWrapper 8730cfbc0SXuan Huimport xiangshan._ 910fe9778SXuan Huimport xiangshan.backend.Bundles._ 1039c59369SXuan Huimport xiangshan.backend.datapath.DataConfig.{IntData, VAddrData, VecData} 1139c59369SXuan Huimport xiangshan.backend.datapath.WbConfig.{IntWB, VfWB} 12e62b6911SXuan Huimport xiangshan.backend.fu.FuType 13730cfbc0SXuan Huimport xiangshan.backend.regfile.RfWritePortWithConfig 14730cfbc0SXuan Huimport xiangshan.backend.rename.BusyTable 152d270511Ssinsanctionimport xiangshan.mem.{LsqEnqCtrl, LsqEnqIO, MemWaitUpdateReq, SqPtr, LqPtr} 16730cfbc0SXuan Hu 17730cfbc0SXuan Husealed trait SchedulerType 18730cfbc0SXuan Hu 19730cfbc0SXuan Hucase class IntScheduler() extends SchedulerType 20730cfbc0SXuan Hucase class MemScheduler() extends SchedulerType 21730cfbc0SXuan Hucase class VfScheduler() extends SchedulerType 22730cfbc0SXuan Hucase class NoScheduler() extends SchedulerType 23730cfbc0SXuan Hu 24730cfbc0SXuan Huclass Scheduler(val params: SchdBlockParams)(implicit p: Parameters) extends LazyModule with HasXSParameter { 251ca4a39dSXuan Hu override def shouldBeInlined: Boolean = false 261ca4a39dSXuan Hu 2739c59369SXuan Hu val numIntStateWrite = backendParams.numPregWb(IntData()) 2839c59369SXuan Hu val numVfStateWrite = backendParams.numPregWb(VecData()) 29730cfbc0SXuan Hu 30730cfbc0SXuan Hu val dispatch2Iq = LazyModule(new Dispatch2Iq(params)) 31730cfbc0SXuan Hu val issueQueue = params.issueBlockParams.map(x => LazyModule(new IssueQueue(x).suggestName(x.getIQName))) 32730cfbc0SXuan Hu 3383ba63b3SXuan Hu lazy val module: SchedulerImpBase = params.schdType match { 34730cfbc0SXuan Hu case IntScheduler() => new SchedulerArithImp(this)(params, p) 35730cfbc0SXuan Hu case MemScheduler() => new SchedulerMemImp(this)(params, p) 36730cfbc0SXuan Hu case VfScheduler() => new SchedulerArithImp(this)(params, p) 37730cfbc0SXuan Hu case _ => null 38730cfbc0SXuan Hu } 39730cfbc0SXuan Hu} 40730cfbc0SXuan Hu 417f8233d5SHaojin Tangclass SchedulerIO()(implicit params: SchdBlockParams, p: Parameters) extends XSBundle { 4268d13085SXuan Hu // params alias 437f8233d5SHaojin Tang private val LoadQueueSize = VirtualLoadQueueSize 4468d13085SXuan Hu 45730cfbc0SXuan Hu val fromTop = new Bundle { 46730cfbc0SXuan Hu val hartId = Input(UInt(8.W)) 47730cfbc0SXuan Hu } 482e0a7dc5Sfdy val fromWbFuBusyTable = new Bundle{ 492e0a7dc5Sfdy val fuBusyTableRead = MixedVec(params.issueBlockParams.map(x => Input(x.genWbFuBusyTableReadBundle))) 502e0a7dc5Sfdy } 51dd970561SzhanglyGit val wbFuBusyTable = MixedVec(params.issueBlockParams.map(x => Output(x.genWbFuBusyTableWriteBundle))) 52dd970561SzhanglyGit 53730cfbc0SXuan Hu val fromCtrlBlock = new Bundle { 54730cfbc0SXuan Hu val pcVec = Input(Vec(params.numPcReadPort, UInt(VAddrData().dataWidth.W))) 55730cfbc0SXuan Hu val flush = Flipped(ValidIO(new Redirect)) 56730cfbc0SXuan Hu } 57730cfbc0SXuan Hu val fromDispatch = new Bundle { 58730cfbc0SXuan Hu val allocPregs = Vec(RenameWidth, Input(new ResetPregStateReq)) 59730cfbc0SXuan Hu val uops = Vec(params.numUopIn, Flipped(DecoupledIO(new DynInst))) 60730cfbc0SXuan Hu } 6139c59369SXuan Hu val intWriteBack = MixedVec(Vec(backendParams.numPregWb(IntData()), 62730cfbc0SXuan Hu new RfWritePortWithConfig(backendParams.intPregParams.dataCfg, backendParams.intPregParams.addrWidth))) 6339c59369SXuan Hu val vfWriteBack = MixedVec(Vec(backendParams.numPregWb(VecData()), 64730cfbc0SXuan Hu new RfWritePortWithConfig(backendParams.vfPregParams.dataCfg, backendParams.vfPregParams.addrWidth))) 6559ef6009Sxiaofeibao-xjtu val toDataPathAfterDelay: MixedVec[MixedVec[DecoupledIO[IssueQueueIssueBundle]]] = MixedVec(params.issueBlockParams.map(_.genIssueDecoupledBundle)) 66730cfbc0SXuan Hu 67bf35baadSXuan Hu val fromSchedulers = new Bundle { 68c0be7f33SXuan Hu val wakeupVec: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpInValidBundle) 69bf35baadSXuan Hu } 70bf35baadSXuan Hu 71bf35baadSXuan Hu val toSchedulers = new Bundle { 72c0be7f33SXuan Hu val wakeupVec: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = params.genIQWakeUpOutValidBundle 73bf35baadSXuan Hu } 74bf35baadSXuan Hu 75c0be7f33SXuan Hu val fromDataPath = new Bundle { 7610fe9778SXuan Hu val resp: MixedVec[MixedVec[OGRespBundle]] = MixedVec(params.issueBlockParams.map(x => Flipped(x.genOGRespBundle))) 777a96cc7fSHaojin Tang val og0Cancel = Input(ExuOH(backendParams.numExu)) 78ea46c302SXuan Hu // Todo: remove this after no cancel signal from og1 797a96cc7fSHaojin Tang val og1Cancel = Input(ExuOH(backendParams.numExu)) 80bc7d6943SzhanglyGit val cancelToBusyTable = Vec(backendParams.numExu, Flipped(ValidIO(new CancelSignal))) 81c0be7f33SXuan Hu // just be compatible to old code 82c0be7f33SXuan Hu def apply(i: Int)(j: Int) = resp(i)(j) 83c0be7f33SXuan Hu } 84c0be7f33SXuan Hu 858a66c02cSXuan Hu val loadFinalIssueResp = MixedVec(params.issueBlockParams.map(x => MixedVec(Vec(x.LdExuCnt, Flipped(ValidIO(new IssueQueueDeqRespBundle()(p, x))))))) 868a66c02cSXuan Hu val memAddrIssueResp = MixedVec(params.issueBlockParams.map(x => MixedVec(Vec(x.LdExuCnt, Flipped(ValidIO(new IssueQueueDeqRespBundle()(p, x))))))) 870f55a0d3SHaojin Tang 886810d1e8Ssfencevma val ldCancel = Vec(backendParams.LduCnt + backendParams.HyuCnt, Flipped(new LoadCancelIO)) 89c0be7f33SXuan Hu 90730cfbc0SXuan Hu val memIO = if (params.isMemSchd) Some(new Bundle { 91730cfbc0SXuan Hu val lsqEnqIO = Flipped(new LsqEnqIO) 92730cfbc0SXuan Hu }) else None 93730cfbc0SXuan Hu val fromMem = if (params.isMemSchd) Some(new Bundle { 947b753bebSXuan Hu val ldaFeedback = Flipped(Vec(params.LduCnt, new MemRSFeedbackIO)) 957b753bebSXuan Hu val staFeedback = Flipped(Vec(params.StaCnt, new MemRSFeedbackIO)) 968f1fa9b1Ssfencevma val hyuFeedback = Flipped(Vec(params.HyuCnt, new MemRSFeedbackIO)) 97730cfbc0SXuan Hu val stIssuePtr = Input(new SqPtr()) 98730cfbc0SXuan Hu val lcommit = Input(UInt(log2Up(CommitWidth + 1).W)) 99730cfbc0SXuan Hu val scommit = Input(UInt(log2Ceil(EnsbufferWidth + 1).W)) // connected to `memBlock.io.sqDeq` instead of ROB 100*fc45ed13SXuan Hu val wakeup = Vec(params.LdExuCnt, Flipped(Valid(new DynInst))) 1012d270511Ssinsanction val lqDeqPtr = Input(new LqPtr) 1022d270511Ssinsanction val sqDeqPtr = Input(new SqPtr) 103730cfbc0SXuan Hu // from lsq 104730cfbc0SXuan Hu val lqCancelCnt = Input(UInt(log2Up(LoadQueueSize + 1).W)) 105730cfbc0SXuan Hu val sqCancelCnt = Input(UInt(log2Up(StoreQueueSize + 1).W)) 106730cfbc0SXuan Hu val memWaitUpdateReq = Flipped(new MemWaitUpdateReq) 107730cfbc0SXuan Hu }) else None 108730cfbc0SXuan Hu val toMem = if (params.isMemSchd) Some(new Bundle { 109730cfbc0SXuan Hu val loadFastMatch = Output(Vec(params.LduCnt, new IssueQueueLoadBundle)) 110730cfbc0SXuan Hu }) else None 111730cfbc0SXuan Hu} 112730cfbc0SXuan Hu 113730cfbc0SXuan Huabstract class SchedulerImpBase(wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters) 114730cfbc0SXuan Hu extends LazyModuleImp(wrapper) 115730cfbc0SXuan Hu with HasXSParameter 116730cfbc0SXuan Hu{ 117730cfbc0SXuan Hu val io = IO(new SchedulerIO()) 118730cfbc0SXuan Hu 119730cfbc0SXuan Hu // alias 120c0be7f33SXuan Hu private val iqWakeUpInMap: Map[Int, ValidIO[IssueQueueIQWakeUpBundle]] = 121c0be7f33SXuan Hu io.fromSchedulers.wakeupVec.map(x => (x.bits.exuIdx, x)).toMap 122730cfbc0SXuan Hu private val schdType = params.schdType 123730cfbc0SXuan Hu 124730cfbc0SXuan Hu // Modules 125730cfbc0SXuan Hu val dispatch2Iq: Dispatch2IqImp = wrapper.dispatch2Iq.module 126730cfbc0SXuan Hu val issueQueues: Seq[IssueQueueImp] = wrapper.issueQueue.map(_.module) 127730cfbc0SXuan Hu 12856bcaed7SHaojin Tang // valid count 12956bcaed7SHaojin Tang dispatch2Iq.io.iqValidCnt := issueQueues.filter(_.params.StdCnt == 0).map(_.io.status.validCnt) 13056bcaed7SHaojin Tang 131730cfbc0SXuan Hu // BusyTable Modules 132730cfbc0SXuan Hu val intBusyTable = schdType match { 133bc7d6943SzhanglyGit case IntScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numIntStateRead, wrapper.numIntStateWrite, IntPhyRegs, IntWB()))) 134730cfbc0SXuan Hu case _ => None 135730cfbc0SXuan Hu } 136730cfbc0SXuan Hu 137730cfbc0SXuan Hu val vfBusyTable = schdType match { 138bc7d6943SzhanglyGit case VfScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numVfStateRead, wrapper.numVfStateWrite, VfPhyRegs, VfWB()))) 139730cfbc0SXuan Hu case _ => None 140730cfbc0SXuan Hu } 141730cfbc0SXuan Hu 142730cfbc0SXuan Hu dispatch2Iq.io match { case dp2iq => 143730cfbc0SXuan Hu dp2iq.redirect <> io.fromCtrlBlock.flush 144730cfbc0SXuan Hu dp2iq.in <> io.fromDispatch.uops 145730cfbc0SXuan Hu dp2iq.readIntState.foreach(_ <> intBusyTable.get.io.read) 146730cfbc0SXuan Hu dp2iq.readVfState.foreach(_ <> vfBusyTable.get.io.read) 147730cfbc0SXuan Hu } 148730cfbc0SXuan Hu 149730cfbc0SXuan Hu intBusyTable match { 150730cfbc0SXuan Hu case Some(bt) => 151730cfbc0SXuan Hu bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) => 152730cfbc0SXuan Hu btAllocPregs.valid := dpAllocPregs.isInt 153730cfbc0SXuan Hu btAllocPregs.bits := dpAllocPregs.preg 154730cfbc0SXuan Hu } 155730cfbc0SXuan Hu bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) => 156730cfbc0SXuan Hu wb.valid := io.intWriteBack(i).wen && io.intWriteBack(i).intWen 157730cfbc0SXuan Hu wb.bits := io.intWriteBack(i).addr 158730cfbc0SXuan Hu } 159bc7d6943SzhanglyGit bt.io.wakeUp := io.fromSchedulers.wakeupVec 160bc7d6943SzhanglyGit bt.io.cancel := io.fromDataPath.cancelToBusyTable 16113551487SzhanglyGit bt.io.ldCancel := io.ldCancel 162730cfbc0SXuan Hu case None => 163730cfbc0SXuan Hu } 164730cfbc0SXuan Hu 165730cfbc0SXuan Hu vfBusyTable match { 166730cfbc0SXuan Hu case Some(bt) => 167730cfbc0SXuan Hu bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) => 168730cfbc0SXuan Hu btAllocPregs.valid := dpAllocPregs.isFp 169730cfbc0SXuan Hu btAllocPregs.bits := dpAllocPregs.preg 170730cfbc0SXuan Hu } 171730cfbc0SXuan Hu bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) => 172730cfbc0SXuan Hu wb.valid := io.vfWriteBack(i).wen && (io.vfWriteBack(i).fpWen || io.vfWriteBack(i).vecWen) 173730cfbc0SXuan Hu wb.bits := io.vfWriteBack(i).addr 174730cfbc0SXuan Hu } 175bc7d6943SzhanglyGit bt.io.wakeUp := io.fromSchedulers.wakeupVec 176bc7d6943SzhanglyGit bt.io.cancel := io.fromDataPath.cancelToBusyTable 17713551487SzhanglyGit bt.io.ldCancel := io.ldCancel 178730cfbc0SXuan Hu case None => 179730cfbc0SXuan Hu } 180730cfbc0SXuan Hu 181f39a61a1SzhanglyGit val wakeupFromIntWBVec = Wire(params.genIntWBWakeUpSinkValidBundle) 182f39a61a1SzhanglyGit val wakeupFromVfWBVec = Wire(params.genVfWBWakeUpSinkValidBundle) 183f39a61a1SzhanglyGit 184f39a61a1SzhanglyGit wakeupFromIntWBVec.zip(io.intWriteBack).foreach { case (sink, source) => 185f39a61a1SzhanglyGit sink.valid := source.wen 186f39a61a1SzhanglyGit sink.bits.rfWen := source.intWen 187f39a61a1SzhanglyGit sink.bits.fpWen := source.fpWen 188f39a61a1SzhanglyGit sink.bits.vecWen := source.vecWen 189f39a61a1SzhanglyGit sink.bits.pdest := source.addr 190730cfbc0SXuan Hu } 191f39a61a1SzhanglyGit 192f39a61a1SzhanglyGit wakeupFromVfWBVec.zip(io.vfWriteBack).foreach { case (sink, source) => 193730cfbc0SXuan Hu sink.valid := source.wen 194730cfbc0SXuan Hu sink.bits.rfWen := source.intWen 195730cfbc0SXuan Hu sink.bits.fpWen := source.fpWen 196730cfbc0SXuan Hu sink.bits.vecWen := source.vecWen 197730cfbc0SXuan Hu sink.bits.pdest := source.addr 198730cfbc0SXuan Hu } 199730cfbc0SXuan Hu 200bf35baadSXuan Hu // Connect bundles having the same wakeup source 20159ef6009Sxiaofeibao-xjtu issueQueues.zipWithIndex.foreach { case(iq, i) => 202bf35baadSXuan Hu iq.io.wakeupFromIQ.foreach { wakeUp => 2030c7ebb58Sxiaofeibao-xjtu val wakeUpIn = iqWakeUpInMap(wakeUp.bits.exuIdx) 2040c7ebb58Sxiaofeibao-xjtu val exuIdx = wakeUp.bits.exuIdx 2050c7ebb58Sxiaofeibao-xjtu println(s"[Backend] Connect wakeup exuIdx ${exuIdx}") 2060c7ebb58Sxiaofeibao-xjtu connectSamePort(wakeUp,wakeUpIn) 2070c7ebb58Sxiaofeibao-xjtu backendParams.connectWakeup(exuIdx) 2080c7ebb58Sxiaofeibao-xjtu if (backendParams.isCopyPdest(exuIdx)) { 2090c7ebb58Sxiaofeibao-xjtu println(s"[Backend] exuIdx ${exuIdx} use pdestCopy ${backendParams.getCopyPdestIndex(exuIdx)}") 2100c7ebb58Sxiaofeibao-xjtu wakeUp.bits.pdest := wakeUpIn.bits.pdestCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2114c5a0d77Sxiaofeibao-xjtu if (wakeUpIn.bits.rfWenCopy.nonEmpty) wakeUp.bits.rfWen := wakeUpIn.bits.rfWenCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2124c5a0d77Sxiaofeibao-xjtu if (wakeUpIn.bits.fpWenCopy.nonEmpty) wakeUp.bits.fpWen := wakeUpIn.bits.fpWenCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2134c5a0d77Sxiaofeibao-xjtu if (wakeUpIn.bits.vecWenCopy.nonEmpty) wakeUp.bits.vecWen := wakeUpIn.bits.vecWenCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2144c5a0d77Sxiaofeibao-xjtu if (wakeUpIn.bits.loadDependencyCopy.nonEmpty) wakeUp.bits.loadDependency := wakeUpIn.bits.loadDependencyCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2150c7ebb58Sxiaofeibao-xjtu } 21660912d84Sxiaofeibao-xjtu if (iq.params.numIntSrc == 0) wakeUp.bits.rfWen := false.B 21760912d84Sxiaofeibao-xjtu if (iq.params.numFpSrc == 0) wakeUp.bits.fpWen := false.B 21860912d84Sxiaofeibao-xjtu if (iq.params.numVfSrc == 0) wakeUp.bits.vecWen := false.B 219bf35baadSXuan Hu } 220ea46c302SXuan Hu iq.io.og0Cancel := io.fromDataPath.og0Cancel 221ea46c302SXuan Hu iq.io.og1Cancel := io.fromDataPath.og1Cancel 2220f55a0d3SHaojin Tang iq.io.ldCancel := io.ldCancel 223bf35baadSXuan Hu } 224bf35baadSXuan Hu 225c0be7f33SXuan Hu private val iqWakeUpOutMap: Map[Int, ValidIO[IssueQueueIQWakeUpBundle]] = 226bf35baadSXuan Hu issueQueues.flatMap(_.io.wakeupToIQ) 227c0be7f33SXuan Hu .map(x => (x.bits.exuIdx, x)) 228bf35baadSXuan Hu .toMap 229bf35baadSXuan Hu 230bf35baadSXuan Hu // Connect bundles having the same wakeup source 231bf35baadSXuan Hu io.toSchedulers.wakeupVec.foreach { wakeUp => 232c0be7f33SXuan Hu wakeUp := iqWakeUpOutMap(wakeUp.bits.exuIdx) 233bf35baadSXuan Hu } 234bf35baadSXuan Hu 23559ef6009Sxiaofeibao-xjtu io.toDataPathAfterDelay.zipWithIndex.foreach { case (toDpDy, i) => 23659ef6009Sxiaofeibao-xjtu toDpDy <> issueQueues(i).io.deqDelay 23759ef6009Sxiaofeibao-xjtu } 238bf35baadSXuan Hu 239f99b81adSHaojin Tang // Response 240f99b81adSHaojin Tang issueQueues.zipWithIndex.foreach { case (iq, i) => 241f99b81adSHaojin Tang iq.io.og0Resp.zipWithIndex.foreach { case (og0Resp, j) => 242f99b81adSHaojin Tang og0Resp := io.fromDataPath(i)(j).og0resp 243f99b81adSHaojin Tang } 244f99b81adSHaojin Tang iq.io.og1Resp.zipWithIndex.foreach { case (og1Resp, j) => 245f99b81adSHaojin Tang og1Resp := io.fromDataPath(i)(j).og1resp 246f99b81adSHaojin Tang } 247f99b81adSHaojin Tang iq.io.finalIssueResp.foreach(_.zipWithIndex.foreach { case (finalIssueResp, j) => 248670870b3SXuan Hu if (io.loadFinalIssueResp(i).isDefinedAt(j)) { 249f99b81adSHaojin Tang finalIssueResp := io.loadFinalIssueResp(i)(j) 250670870b3SXuan Hu } else { 251670870b3SXuan Hu finalIssueResp := 0.U.asTypeOf(finalIssueResp) 252670870b3SXuan Hu } 253f99b81adSHaojin Tang }) 254e8800897SXuan Hu iq.io.memAddrIssueResp.foreach(_.zipWithIndex.foreach { case (memAddrIssueResp, j) => 255aa2bcc31SzhanglyGit if (io.memAddrIssueResp(i).isDefinedAt(j)) { 256e8800897SXuan Hu memAddrIssueResp := io.memAddrIssueResp(i)(j) 257aa2bcc31SzhanglyGit } else { 258aa2bcc31SzhanglyGit memAddrIssueResp := 0.U.asTypeOf(memAddrIssueResp) 259aa2bcc31SzhanglyGit } 260e8800897SXuan Hu }) 261f99b81adSHaojin Tang iq.io.wbBusyTableRead := io.fromWbFuBusyTable.fuBusyTableRead(i) 262f99b81adSHaojin Tang io.wbFuBusyTable(i) := iq.io.wbBusyTableWrite 263f99b81adSHaojin Tang } 264f99b81adSHaojin Tang 265c0be7f33SXuan Hu println(s"[Scheduler] io.fromSchedulers.wakeupVec: ${io.fromSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}") 266bf35baadSXuan Hu println(s"[Scheduler] iqWakeUpInKeys: ${iqWakeUpInMap.keys}") 267bf35baadSXuan Hu 268bf35baadSXuan Hu println(s"[Scheduler] iqWakeUpOutKeys: ${iqWakeUpOutMap.keys}") 269c0be7f33SXuan Hu println(s"[Scheduler] io.toSchedulers.wakeupVec: ${io.toSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}") 270730cfbc0SXuan Hu} 271730cfbc0SXuan Hu 272730cfbc0SXuan Huclass SchedulerArithImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters) 273730cfbc0SXuan Hu extends SchedulerImpBase(wrapper) 274730cfbc0SXuan Hu with HasXSParameter 275730cfbc0SXuan Hu{ 2762e0a7dc5Sfdy// dontTouch(io.vfWbFuBusyTable) 277730cfbc0SXuan Hu println(s"[SchedulerArithImp] " + 278730cfbc0SXuan Hu s"has intBusyTable: ${intBusyTable.nonEmpty}, " + 279730cfbc0SXuan Hu s"has vfBusyTable: ${vfBusyTable.nonEmpty}") 280730cfbc0SXuan Hu 281730cfbc0SXuan Hu issueQueues.zipWithIndex.foreach { case (iq, i) => 282730cfbc0SXuan Hu iq.io.flush <> io.fromCtrlBlock.flush 283730cfbc0SXuan Hu iq.io.enq <> dispatch2Iq.io.out(i) 284f39a61a1SzhanglyGit val intWBIQ = params.schdType match { 285f39a61a1SzhanglyGit case IntScheduler() => wakeupFromIntWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1) 286f39a61a1SzhanglyGit case VfScheduler() => wakeupFromVfWBVec 287596af5d2SHaojin Tang case _ => null 288f39a61a1SzhanglyGit } 289f39a61a1SzhanglyGit iq.io.wakeupFromWB.zip(intWBIQ).foreach{ case (sink, source) => sink := source} 290730cfbc0SXuan Hu } 291730cfbc0SXuan Hu} 292730cfbc0SXuan Hu 293f99b81adSHaojin Tang// FIXME: Vector mem instructions may not be handled properly! 294730cfbc0SXuan Huclass SchedulerMemImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters) 295730cfbc0SXuan Hu extends SchedulerImpBase(wrapper) 296730cfbc0SXuan Hu with HasXSParameter 297730cfbc0SXuan Hu{ 298730cfbc0SXuan Hu println(s"[SchedulerMemImp] " + 299730cfbc0SXuan Hu s"has intBusyTable: ${intBusyTable.nonEmpty}, " + 300730cfbc0SXuan Hu s"has vfBusyTable: ${vfBusyTable.nonEmpty}") 301730cfbc0SXuan Hu 302559c1710SHaojin Tang val memAddrIQs = issueQueues.filter(_.params.isMemAddrIQ) 3032d270511Ssinsanction val stAddrIQs = issueQueues.filter(iq => iq.params.StaCnt > 0 || iq.params.VstaCnt > 0) // included in memAddrIQs 3042d270511Ssinsanction val ldAddrIQs = issueQueues.filter(iq => iq.params.LduCnt > 0 || iq.params.VlduCnt > 0) 3052d270511Ssinsanction val stDataIQs = issueQueues.filter(iq => iq.params.StdCnt > 0 || iq.params.VstdCnt > 0) 306559c1710SHaojin Tang val vecMemIQs = issueQueues.filter(_.params.isVecMemIQ) 307559c1710SHaojin Tang val (hyuIQs, hyuIQIdxs) = issueQueues.zipWithIndex.filter(_._1.params.HyuCnt > 0).unzip 308499caf4cSXuan Hu 309499caf4cSXuan Hu println(s"[SchedulerMemImp] memAddrIQs.size: ${memAddrIQs.size}, enq.size: ${memAddrIQs.map(_.io.enq.size).sum}") 310499caf4cSXuan Hu println(s"[SchedulerMemImp] stAddrIQs.size: ${stAddrIQs.size }, enq.size: ${stAddrIQs.map(_.io.enq.size).sum}") 311499caf4cSXuan Hu println(s"[SchedulerMemImp] ldAddrIQs.size: ${ldAddrIQs.size }, enq.size: ${ldAddrIQs.map(_.io.enq.size).sum}") 312499caf4cSXuan Hu println(s"[SchedulerMemImp] stDataIQs.size: ${stDataIQs.size }, enq.size: ${stDataIQs.map(_.io.enq.size).sum}") 313499caf4cSXuan Hu println(s"[SchedulerMemImp] hyuIQs.size: ${hyuIQs.size }, enq.size: ${hyuIQs.map(_.io.enq.size).sum}") 314730cfbc0SXuan Hu require(memAddrIQs.nonEmpty && stDataIQs.nonEmpty) 315730cfbc0SXuan Hu 316853cd2d8SHaojin Tang io.toMem.get.loadFastMatch := 0.U.asTypeOf(io.toMem.get.loadFastMatch) // TODO: is still needed? 317853cd2d8SHaojin Tang 318*fc45ed13SXuan Hu private val loadWakeUp = issueQueues.filter(_.params.LdExuCnt > 0).map(_.asInstanceOf[IssueQueueMemAddrImp].io.memIO.get.loadWakeUp).flatten 319596af5d2SHaojin Tang require(loadWakeUp.length == io.fromMem.get.wakeup.length) 320596af5d2SHaojin Tang loadWakeUp.zip(io.fromMem.get.wakeup).foreach(x => x._1 := x._2) 321596af5d2SHaojin Tang 322730cfbc0SXuan Hu memAddrIQs.zipWithIndex.foreach { case (iq, i) => 323730cfbc0SXuan Hu iq.io.flush <> io.fromCtrlBlock.flush 324730cfbc0SXuan Hu iq.io.enq <> dispatch2Iq.io.out(i) 325f39a61a1SzhanglyGit iq.io.wakeupFromWB.zip(wakeupFromIntWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1) ++ wakeupFromVfWBVec).foreach{ case (sink, source) => sink := source} 326730cfbc0SXuan Hu } 327730cfbc0SXuan Hu 328ecfc6f16SXuan Hu ldAddrIQs.zipWithIndex.foreach { 329ecfc6f16SXuan Hu case (imp: IssueQueueMemAddrImp, i) => 330ecfc6f16SXuan Hu imp.io.memIO.get.feedbackIO.head := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO.head) 331c14e89f4SHaojin Tang imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr 332de784418SXuan Hu imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 3337b753bebSXuan Hu case _ => 3347b753bebSXuan Hu } 3357b753bebSXuan Hu 336ecfc6f16SXuan Hu stAddrIQs.zipWithIndex.foreach { 337ecfc6f16SXuan Hu case (imp: IssueQueueMemAddrImp, i) => 338ecfc6f16SXuan Hu imp.io.memIO.get.feedbackIO.head := io.fromMem.get.staFeedback(i) 339c14e89f4SHaojin Tang imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr 340c14e89f4SHaojin Tang imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 3417b753bebSXuan Hu case _ => 3427b753bebSXuan Hu } 343730cfbc0SXuan Hu 344559c1710SHaojin Tang hyuIQs.zip(hyuIQIdxs).foreach { 345559c1710SHaojin Tang case (imp: IssueQueueMemAddrImp, idx) => 346670870b3SXuan Hu imp.io.memIO.get.feedbackIO.head := io.fromMem.get.hyuFeedback.head 347670870b3SXuan Hu imp.io.memIO.get.feedbackIO(1) := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO(1)) 3488f1fa9b1Ssfencevma imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr 3498f1fa9b1Ssfencevma imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 350559c1710SHaojin Tang // TODO: refactor ditry code 351559c1710SHaojin Tang imp.io.deqDelay(1).ready := false.B 352559c1710SHaojin Tang io.toDataPathAfterDelay(idx)(1).valid := false.B 353559c1710SHaojin Tang io.toDataPathAfterDelay(idx)(1).bits := 0.U.asTypeOf(io.toDataPathAfterDelay(idx)(1).bits) 3548f1fa9b1Ssfencevma case _ => 3558f1fa9b1Ssfencevma } 3568f1fa9b1Ssfencevma 357e62b6911SXuan Hu private val staIdxSeq = (stAddrIQs).map(iq => iq.params.idxInSchBlk) 358e62b6911SXuan Hu private val hyaIdxSeq = (hyuIQs).map(iq => iq.params.idxInSchBlk) 359e62b6911SXuan Hu 360e62b6911SXuan Hu println(s"[SchedulerMemImp] sta iq idx in memSchdBlock: $staIdxSeq") 361e62b6911SXuan Hu println(s"[SchedulerMemImp] hya iq idx in memSchdBlock: $hyaIdxSeq") 362e62b6911SXuan Hu 363e62b6911SXuan Hu private val staEnqs = stAddrIQs.map(_.io.enq).flatten 364e62b6911SXuan Hu private val stdEnqs = stDataIQs.map(_.io.enq).flatten.take(staEnqs.size) 365e62b6911SXuan Hu private val hyaEnqs = hyuIQs.map(_.io.enq).flatten 366e62b6911SXuan Hu private val hydEnqs = stDataIQs.map(_.io.enq).flatten.drop(staEnqs.size) 367e62b6911SXuan Hu 368e62b6911SXuan Hu require(staEnqs.size == stdEnqs.size, s"number of enq ports of store address IQs(${staEnqs.size}) " + 369e62b6911SXuan Hu s"should be equal to number of enq ports of store data IQs(${stdEnqs.size})") 370e62b6911SXuan Hu 371e62b6911SXuan Hu require(hyaEnqs.size == hydEnqs.size, s"number of enq ports of hybrid address IQs(${hyaEnqs.size}) " + 372e62b6911SXuan Hu s"should be equal to number of enq ports of hybrid data IQs(${hydEnqs.size})") 3739b258a00Sxgkiri 3749b258a00Sxgkiri for ((idxInSchBlk, i) <- staIdxSeq.zipWithIndex) { 375e62b6911SXuan Hu dispatch2Iq.io.out(idxInSchBlk).zip(staEnqs).zip(stdEnqs).foreach{ case((dp, staIQ), stdIQ) => 376730cfbc0SXuan Hu val isAllReady = staIQ.ready && stdIQ.ready 377e62b6911SXuan Hu dp.ready := isAllReady 378e62b6911SXuan Hu staIQ.valid := dp.valid && isAllReady 3794ec52c44SXuan Hu stdIQ.valid := dp.valid && isAllReady && FuType.isStore(dp.bits.fuType) 380730cfbc0SXuan Hu } 3819b258a00Sxgkiri } 382730cfbc0SXuan Hu 383e62b6911SXuan Hu for ((idxInSchBlk, i) <- hyaIdxSeq.zipWithIndex) { 384e62b6911SXuan Hu dispatch2Iq.io.out(idxInSchBlk).zip(hyaEnqs).zip(hydEnqs).foreach{ case((dp, hyaIQ), hydIQ) => 385e62b6911SXuan Hu val isAllReady = hyaIQ.ready && hydIQ.ready 386e62b6911SXuan Hu dp.ready := isAllReady 387e62b6911SXuan Hu hyaIQ.valid := dp.valid && isAllReady 38856bceacbSHaojin Tang hydIQ.valid := dp.valid && isAllReady && FuType.FuTypeOrR(dp.bits.fuType, FuType.stu, FuType.mou) 389e62b6911SXuan Hu } 390e62b6911SXuan Hu } 391730cfbc0SXuan Hu 392e62b6911SXuan Hu stDataIQs.zipWithIndex.foreach { case (iq, i) => 393e62b6911SXuan Hu iq.io.flush <> io.fromCtrlBlock.flush 394f39a61a1SzhanglyGit iq.io.wakeupFromWB.zip(wakeupFromIntWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq ++ wakeupFromVfWBVec).foreach{ case (sink, source) => sink := source} 395e62b6911SXuan Hu } 396e62b6911SXuan Hu 397e62b6911SXuan Hu (stdEnqs ++ hydEnqs).zip(staEnqs ++ hyaEnqs).zipWithIndex.foreach { case ((stdIQEnq, staIQEnq), i) => 398730cfbc0SXuan Hu stdIQEnq.bits := staIQEnq.bits 399730cfbc0SXuan Hu // Store data reuses store addr src(1) in dispatch2iq 400e62b6911SXuan Hu // [dispatch2iq] --src*------src*(0)--> [staIQ|hyaIQ] 401730cfbc0SXuan Hu // \ 402730cfbc0SXuan Hu // ---src*(1)--> [stdIQ] 403730cfbc0SXuan Hu // Since the src(1) of sta is easier to get, stdIQEnq.bits.src*(0) is assigned to staIQEnq.bits.src*(1) 404730cfbc0SXuan Hu // instead of dispatch2Iq.io.out(x).bits.src*(1) 40597b279b9SXuan Hu val stdIdx = 1 4062d270511Ssinsanction stdIQEnq.bits.srcState(0) := staIQEnq.bits.srcState(stdIdx) 40713551487SzhanglyGit stdIQEnq.bits.srcLoadDependency(0) := staIQEnq.bits.srcLoadDependency(1) 4082d270511Ssinsanction stdIQEnq.bits.srcType(0) := staIQEnq.bits.srcType(stdIdx) 4092d270511Ssinsanction stdIQEnq.bits.psrc(0) := staIQEnq.bits.psrc(stdIdx) 410730cfbc0SXuan Hu stdIQEnq.bits.sqIdx := staIQEnq.bits.sqIdx 411730cfbc0SXuan Hu } 412730cfbc0SXuan Hu 4132d270511Ssinsanction vecMemIQs.foreach { 4142d270511Ssinsanction case imp: IssueQueueVecMemImp => 4152d270511Ssinsanction imp.io.memIO.get.sqDeqPtr.foreach(_ := io.fromMem.get.sqDeqPtr) 4162d270511Ssinsanction imp.io.memIO.get.lqDeqPtr.foreach(_ := io.fromMem.get.lqDeqPtr) 4171f3d1b4dSXuan Hu // not used 4181f3d1b4dSXuan Hu imp.io.memIO.get.feedbackIO := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO) 4191f3d1b4dSXuan Hu // maybe not used 4201f3d1b4dSXuan Hu imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr 4211f3d1b4dSXuan Hu imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 422f39a61a1SzhanglyGit imp.io.wakeupFromWB.zip(wakeupFromIntWBVec.zipWithIndex.filter(x => imp.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq ++ wakeupFromVfWBVec).foreach{ case (sink, source) => sink := source} 423f39a61a1SzhanglyGit 4242d270511Ssinsanction case _ => 4252d270511Ssinsanction } 4262d270511Ssinsanction 427730cfbc0SXuan Hu val lsqEnqCtrl = Module(new LsqEnqCtrl) 428730cfbc0SXuan Hu 429730cfbc0SXuan Hu lsqEnqCtrl.io.redirect <> io.fromCtrlBlock.flush 430730cfbc0SXuan Hu lsqEnqCtrl.io.enq <> dispatch2Iq.io.enqLsqIO.get 431730cfbc0SXuan Hu lsqEnqCtrl.io.lcommit := io.fromMem.get.lcommit 432730cfbc0SXuan Hu lsqEnqCtrl.io.scommit := io.fromMem.get.scommit 433730cfbc0SXuan Hu lsqEnqCtrl.io.lqCancelCnt := io.fromMem.get.lqCancelCnt 434730cfbc0SXuan Hu lsqEnqCtrl.io.sqCancelCnt := io.fromMem.get.sqCancelCnt 435730cfbc0SXuan Hu io.memIO.get.lsqEnqIO <> lsqEnqCtrl.io.enqLsq 436730cfbc0SXuan Hu} 437