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))) 52c1e19666Sxiaofeibao-xjtu val IQValidNumVec = Output(MixedVec(backendParams.genIQValidNumBundle)) 53dd970561SzhanglyGit 54730cfbc0SXuan Hu val fromCtrlBlock = new Bundle { 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 100fc45ed13SXuan 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) 127ff3fcdf1Sxiaofeibao-xjtu if (params.isIntSchd) { 128ff3fcdf1Sxiaofeibao-xjtu dispatch2Iq.io.IQValidNumVec.get := io.IQValidNumVec 129c1e19666Sxiaofeibao-xjtu io.IQValidNumVec := MixedVecInit(issueQueues.map(_.io.validCntDeqVec)) 130ff3fcdf1Sxiaofeibao-xjtu } 131ff3fcdf1Sxiaofeibao-xjtu else io.IQValidNumVec := 0.U.asTypeOf(io.IQValidNumVec) 132730cfbc0SXuan Hu 13356bcaed7SHaojin Tang // valid count 13456bcaed7SHaojin Tang dispatch2Iq.io.iqValidCnt := issueQueues.filter(_.params.StdCnt == 0).map(_.io.status.validCnt) 13556bcaed7SHaojin Tang 136730cfbc0SXuan Hu // BusyTable Modules 137730cfbc0SXuan Hu val intBusyTable = schdType match { 138bc7d6943SzhanglyGit case IntScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numIntStateRead, wrapper.numIntStateWrite, IntPhyRegs, IntWB()))) 139730cfbc0SXuan Hu case _ => None 140730cfbc0SXuan Hu } 141730cfbc0SXuan Hu 142730cfbc0SXuan Hu val vfBusyTable = schdType match { 143bc7d6943SzhanglyGit case VfScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numVfStateRead, wrapper.numVfStateWrite, VfPhyRegs, VfWB()))) 144730cfbc0SXuan Hu case _ => None 145730cfbc0SXuan Hu } 146730cfbc0SXuan Hu 147730cfbc0SXuan Hu dispatch2Iq.io match { case dp2iq => 148730cfbc0SXuan Hu dp2iq.redirect <> io.fromCtrlBlock.flush 149730cfbc0SXuan Hu dp2iq.in <> io.fromDispatch.uops 150730cfbc0SXuan Hu dp2iq.readIntState.foreach(_ <> intBusyTable.get.io.read) 151730cfbc0SXuan Hu dp2iq.readVfState.foreach(_ <> vfBusyTable.get.io.read) 152730cfbc0SXuan Hu } 153730cfbc0SXuan Hu 154730cfbc0SXuan Hu intBusyTable match { 155730cfbc0SXuan Hu case Some(bt) => 156730cfbc0SXuan Hu bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) => 157730cfbc0SXuan Hu btAllocPregs.valid := dpAllocPregs.isInt 158730cfbc0SXuan Hu btAllocPregs.bits := dpAllocPregs.preg 159730cfbc0SXuan Hu } 160730cfbc0SXuan Hu bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) => 161730cfbc0SXuan Hu wb.valid := io.intWriteBack(i).wen && io.intWriteBack(i).intWen 162730cfbc0SXuan Hu wb.bits := io.intWriteBack(i).addr 163730cfbc0SXuan Hu } 164bc7d6943SzhanglyGit bt.io.wakeUp := io.fromSchedulers.wakeupVec 165bc7d6943SzhanglyGit bt.io.cancel := io.fromDataPath.cancelToBusyTable 16613551487SzhanglyGit bt.io.ldCancel := io.ldCancel 167730cfbc0SXuan Hu case None => 168730cfbc0SXuan Hu } 169730cfbc0SXuan Hu 170730cfbc0SXuan Hu vfBusyTable match { 171730cfbc0SXuan Hu case Some(bt) => 172730cfbc0SXuan Hu bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) => 173730cfbc0SXuan Hu btAllocPregs.valid := dpAllocPregs.isFp 174730cfbc0SXuan Hu btAllocPregs.bits := dpAllocPregs.preg 175730cfbc0SXuan Hu } 176730cfbc0SXuan Hu bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) => 177730cfbc0SXuan Hu wb.valid := io.vfWriteBack(i).wen && (io.vfWriteBack(i).fpWen || io.vfWriteBack(i).vecWen) 178730cfbc0SXuan Hu wb.bits := io.vfWriteBack(i).addr 179730cfbc0SXuan Hu } 180bc7d6943SzhanglyGit bt.io.wakeUp := io.fromSchedulers.wakeupVec 181bc7d6943SzhanglyGit bt.io.cancel := io.fromDataPath.cancelToBusyTable 18213551487SzhanglyGit bt.io.ldCancel := io.ldCancel 183730cfbc0SXuan Hu case None => 184730cfbc0SXuan Hu } 185730cfbc0SXuan Hu 186f39a61a1SzhanglyGit val wakeupFromIntWBVec = Wire(params.genIntWBWakeUpSinkValidBundle) 187f39a61a1SzhanglyGit val wakeupFromVfWBVec = Wire(params.genVfWBWakeUpSinkValidBundle) 188f39a61a1SzhanglyGit 189f39a61a1SzhanglyGit wakeupFromIntWBVec.zip(io.intWriteBack).foreach { case (sink, source) => 190f39a61a1SzhanglyGit sink.valid := source.wen 191f39a61a1SzhanglyGit sink.bits.rfWen := source.intWen 192f39a61a1SzhanglyGit sink.bits.fpWen := source.fpWen 193f39a61a1SzhanglyGit sink.bits.vecWen := source.vecWen 194f39a61a1SzhanglyGit sink.bits.pdest := source.addr 195730cfbc0SXuan Hu } 196f39a61a1SzhanglyGit 197f39a61a1SzhanglyGit wakeupFromVfWBVec.zip(io.vfWriteBack).foreach { case (sink, source) => 198730cfbc0SXuan Hu sink.valid := source.wen 199730cfbc0SXuan Hu sink.bits.rfWen := source.intWen 200730cfbc0SXuan Hu sink.bits.fpWen := source.fpWen 201730cfbc0SXuan Hu sink.bits.vecWen := source.vecWen 202730cfbc0SXuan Hu sink.bits.pdest := source.addr 203730cfbc0SXuan Hu } 204730cfbc0SXuan Hu 205bf35baadSXuan Hu // Connect bundles having the same wakeup source 20659ef6009Sxiaofeibao-xjtu issueQueues.zipWithIndex.foreach { case(iq, i) => 207bf35baadSXuan Hu iq.io.wakeupFromIQ.foreach { wakeUp => 2080c7ebb58Sxiaofeibao-xjtu val wakeUpIn = iqWakeUpInMap(wakeUp.bits.exuIdx) 2090c7ebb58Sxiaofeibao-xjtu val exuIdx = wakeUp.bits.exuIdx 2100c7ebb58Sxiaofeibao-xjtu println(s"[Backend] Connect wakeup exuIdx ${exuIdx}") 2110c7ebb58Sxiaofeibao-xjtu connectSamePort(wakeUp,wakeUpIn) 2120c7ebb58Sxiaofeibao-xjtu backendParams.connectWakeup(exuIdx) 2130c7ebb58Sxiaofeibao-xjtu if (backendParams.isCopyPdest(exuIdx)) { 2140c7ebb58Sxiaofeibao-xjtu println(s"[Backend] exuIdx ${exuIdx} use pdestCopy ${backendParams.getCopyPdestIndex(exuIdx)}") 2150c7ebb58Sxiaofeibao-xjtu wakeUp.bits.pdest := wakeUpIn.bits.pdestCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2164c5a0d77Sxiaofeibao-xjtu if (wakeUpIn.bits.rfWenCopy.nonEmpty) wakeUp.bits.rfWen := wakeUpIn.bits.rfWenCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2174c5a0d77Sxiaofeibao-xjtu if (wakeUpIn.bits.fpWenCopy.nonEmpty) wakeUp.bits.fpWen := wakeUpIn.bits.fpWenCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2184c5a0d77Sxiaofeibao-xjtu if (wakeUpIn.bits.vecWenCopy.nonEmpty) wakeUp.bits.vecWen := wakeUpIn.bits.vecWenCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2194c5a0d77Sxiaofeibao-xjtu if (wakeUpIn.bits.loadDependencyCopy.nonEmpty) wakeUp.bits.loadDependency := wakeUpIn.bits.loadDependencyCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2200c7ebb58Sxiaofeibao-xjtu } 22160912d84Sxiaofeibao-xjtu if (iq.params.numIntSrc == 0) wakeUp.bits.rfWen := false.B 22260912d84Sxiaofeibao-xjtu if (iq.params.numFpSrc == 0) wakeUp.bits.fpWen := false.B 22360912d84Sxiaofeibao-xjtu if (iq.params.numVfSrc == 0) wakeUp.bits.vecWen := false.B 224bf35baadSXuan Hu } 225ea46c302SXuan Hu iq.io.og0Cancel := io.fromDataPath.og0Cancel 226ea46c302SXuan Hu iq.io.og1Cancel := io.fromDataPath.og1Cancel 2270f55a0d3SHaojin Tang iq.io.ldCancel := io.ldCancel 228bf35baadSXuan Hu } 229bf35baadSXuan Hu 230c0be7f33SXuan Hu private val iqWakeUpOutMap: Map[Int, ValidIO[IssueQueueIQWakeUpBundle]] = 231bf35baadSXuan Hu issueQueues.flatMap(_.io.wakeupToIQ) 232c0be7f33SXuan Hu .map(x => (x.bits.exuIdx, x)) 233bf35baadSXuan Hu .toMap 234bf35baadSXuan Hu 235bf35baadSXuan Hu // Connect bundles having the same wakeup source 236bf35baadSXuan Hu io.toSchedulers.wakeupVec.foreach { wakeUp => 237c0be7f33SXuan Hu wakeUp := iqWakeUpOutMap(wakeUp.bits.exuIdx) 238bf35baadSXuan Hu } 239bf35baadSXuan Hu 24059ef6009Sxiaofeibao-xjtu io.toDataPathAfterDelay.zipWithIndex.foreach { case (toDpDy, i) => 24159ef6009Sxiaofeibao-xjtu toDpDy <> issueQueues(i).io.deqDelay 24259ef6009Sxiaofeibao-xjtu } 243bf35baadSXuan Hu 244f99b81adSHaojin Tang // Response 245f99b81adSHaojin Tang issueQueues.zipWithIndex.foreach { case (iq, i) => 246f99b81adSHaojin Tang iq.io.og0Resp.zipWithIndex.foreach { case (og0Resp, j) => 247f99b81adSHaojin Tang og0Resp := io.fromDataPath(i)(j).og0resp 248f99b81adSHaojin Tang } 249f99b81adSHaojin Tang iq.io.og1Resp.zipWithIndex.foreach { case (og1Resp, j) => 250f99b81adSHaojin Tang og1Resp := io.fromDataPath(i)(j).og1resp 251f99b81adSHaojin Tang } 252f99b81adSHaojin Tang iq.io.finalIssueResp.foreach(_.zipWithIndex.foreach { case (finalIssueResp, j) => 253670870b3SXuan Hu if (io.loadFinalIssueResp(i).isDefinedAt(j)) { 254f99b81adSHaojin Tang finalIssueResp := io.loadFinalIssueResp(i)(j) 255670870b3SXuan Hu } else { 256670870b3SXuan Hu finalIssueResp := 0.U.asTypeOf(finalIssueResp) 257670870b3SXuan Hu } 258f99b81adSHaojin Tang }) 259e8800897SXuan Hu iq.io.memAddrIssueResp.foreach(_.zipWithIndex.foreach { case (memAddrIssueResp, j) => 260aa2bcc31SzhanglyGit if (io.memAddrIssueResp(i).isDefinedAt(j)) { 261e8800897SXuan Hu memAddrIssueResp := io.memAddrIssueResp(i)(j) 262aa2bcc31SzhanglyGit } else { 263aa2bcc31SzhanglyGit memAddrIssueResp := 0.U.asTypeOf(memAddrIssueResp) 264aa2bcc31SzhanglyGit } 265e8800897SXuan Hu }) 266f99b81adSHaojin Tang iq.io.wbBusyTableRead := io.fromWbFuBusyTable.fuBusyTableRead(i) 267f99b81adSHaojin Tang io.wbFuBusyTable(i) := iq.io.wbBusyTableWrite 268f99b81adSHaojin Tang } 269f99b81adSHaojin Tang 270c0be7f33SXuan Hu println(s"[Scheduler] io.fromSchedulers.wakeupVec: ${io.fromSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}") 271bf35baadSXuan Hu println(s"[Scheduler] iqWakeUpInKeys: ${iqWakeUpInMap.keys}") 272bf35baadSXuan Hu 273bf35baadSXuan Hu println(s"[Scheduler] iqWakeUpOutKeys: ${iqWakeUpOutMap.keys}") 274c0be7f33SXuan Hu println(s"[Scheduler] io.toSchedulers.wakeupVec: ${io.toSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}") 275730cfbc0SXuan Hu} 276730cfbc0SXuan Hu 277730cfbc0SXuan Huclass SchedulerArithImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters) 278730cfbc0SXuan Hu extends SchedulerImpBase(wrapper) 279730cfbc0SXuan Hu with HasXSParameter 280730cfbc0SXuan Hu{ 2812e0a7dc5Sfdy// dontTouch(io.vfWbFuBusyTable) 282730cfbc0SXuan Hu println(s"[SchedulerArithImp] " + 283730cfbc0SXuan Hu s"has intBusyTable: ${intBusyTable.nonEmpty}, " + 284730cfbc0SXuan Hu s"has vfBusyTable: ${vfBusyTable.nonEmpty}") 285730cfbc0SXuan Hu 286730cfbc0SXuan Hu issueQueues.zipWithIndex.foreach { case (iq, i) => 287730cfbc0SXuan Hu iq.io.flush <> io.fromCtrlBlock.flush 288730cfbc0SXuan Hu iq.io.enq <> dispatch2Iq.io.out(i) 289f39a61a1SzhanglyGit val intWBIQ = params.schdType match { 290f39a61a1SzhanglyGit case IntScheduler() => wakeupFromIntWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1) 291f39a61a1SzhanglyGit case VfScheduler() => wakeupFromVfWBVec 292596af5d2SHaojin Tang case _ => null 293f39a61a1SzhanglyGit } 294f39a61a1SzhanglyGit iq.io.wakeupFromWB.zip(intWBIQ).foreach{ case (sink, source) => sink := source} 295730cfbc0SXuan Hu } 296730cfbc0SXuan Hu} 297730cfbc0SXuan Hu 298f99b81adSHaojin Tang// FIXME: Vector mem instructions may not be handled properly! 299730cfbc0SXuan Huclass SchedulerMemImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters) 300730cfbc0SXuan Hu extends SchedulerImpBase(wrapper) 301730cfbc0SXuan Hu with HasXSParameter 302730cfbc0SXuan Hu{ 303730cfbc0SXuan Hu println(s"[SchedulerMemImp] " + 304730cfbc0SXuan Hu s"has intBusyTable: ${intBusyTable.nonEmpty}, " + 305730cfbc0SXuan Hu s"has vfBusyTable: ${vfBusyTable.nonEmpty}") 306730cfbc0SXuan Hu 307559c1710SHaojin Tang val memAddrIQs = issueQueues.filter(_.params.isMemAddrIQ) 308e07131b2Ssinsanction val stAddrIQs = issueQueues.filter(iq => iq.params.StaCnt > 0) // included in memAddrIQs 309e07131b2Ssinsanction val ldAddrIQs = issueQueues.filter(iq => iq.params.LduCnt > 0) 310e07131b2Ssinsanction val stDataIQs = issueQueues.filter(iq => iq.params.StdCnt > 0) 311559c1710SHaojin Tang val vecMemIQs = issueQueues.filter(_.params.isVecMemIQ) 312559c1710SHaojin Tang val (hyuIQs, hyuIQIdxs) = issueQueues.zipWithIndex.filter(_._1.params.HyuCnt > 0).unzip 313499caf4cSXuan Hu 314499caf4cSXuan Hu println(s"[SchedulerMemImp] memAddrIQs.size: ${memAddrIQs.size}, enq.size: ${memAddrIQs.map(_.io.enq.size).sum}") 315499caf4cSXuan Hu println(s"[SchedulerMemImp] stAddrIQs.size: ${stAddrIQs.size }, enq.size: ${stAddrIQs.map(_.io.enq.size).sum}") 316499caf4cSXuan Hu println(s"[SchedulerMemImp] ldAddrIQs.size: ${ldAddrIQs.size }, enq.size: ${ldAddrIQs.map(_.io.enq.size).sum}") 317499caf4cSXuan Hu println(s"[SchedulerMemImp] stDataIQs.size: ${stDataIQs.size }, enq.size: ${stDataIQs.map(_.io.enq.size).sum}") 318499caf4cSXuan Hu println(s"[SchedulerMemImp] hyuIQs.size: ${hyuIQs.size }, enq.size: ${hyuIQs.map(_.io.enq.size).sum}") 319730cfbc0SXuan Hu require(memAddrIQs.nonEmpty && stDataIQs.nonEmpty) 320730cfbc0SXuan Hu 321853cd2d8SHaojin Tang io.toMem.get.loadFastMatch := 0.U.asTypeOf(io.toMem.get.loadFastMatch) // TODO: is still needed? 322853cd2d8SHaojin Tang 323fc45ed13SXuan Hu private val loadWakeUp = issueQueues.filter(_.params.LdExuCnt > 0).map(_.asInstanceOf[IssueQueueMemAddrImp].io.memIO.get.loadWakeUp).flatten 324596af5d2SHaojin Tang require(loadWakeUp.length == io.fromMem.get.wakeup.length) 325596af5d2SHaojin Tang loadWakeUp.zip(io.fromMem.get.wakeup).foreach(x => x._1 := x._2) 326596af5d2SHaojin Tang 327730cfbc0SXuan Hu memAddrIQs.zipWithIndex.foreach { case (iq, i) => 328730cfbc0SXuan Hu iq.io.flush <> io.fromCtrlBlock.flush 329730cfbc0SXuan Hu iq.io.enq <> dispatch2Iq.io.out(i) 330f39a61a1SzhanglyGit 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} 331730cfbc0SXuan Hu } 332730cfbc0SXuan Hu 333ecfc6f16SXuan Hu ldAddrIQs.zipWithIndex.foreach { 334ecfc6f16SXuan Hu case (imp: IssueQueueMemAddrImp, i) => 335ecfc6f16SXuan Hu imp.io.memIO.get.feedbackIO.head := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO.head) 336c14e89f4SHaojin Tang imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr 337de784418SXuan Hu imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 3387b753bebSXuan Hu case _ => 3397b753bebSXuan Hu } 3407b753bebSXuan Hu 341ecfc6f16SXuan Hu stAddrIQs.zipWithIndex.foreach { 342ecfc6f16SXuan Hu case (imp: IssueQueueMemAddrImp, i) => 343ecfc6f16SXuan Hu imp.io.memIO.get.feedbackIO.head := io.fromMem.get.staFeedback(i) 344c14e89f4SHaojin Tang imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr 345c14e89f4SHaojin Tang imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 3467b753bebSXuan Hu case _ => 3477b753bebSXuan Hu } 348730cfbc0SXuan Hu 349559c1710SHaojin Tang hyuIQs.zip(hyuIQIdxs).foreach { 350559c1710SHaojin Tang case (imp: IssueQueueMemAddrImp, idx) => 351670870b3SXuan Hu imp.io.memIO.get.feedbackIO.head := io.fromMem.get.hyuFeedback.head 352670870b3SXuan Hu imp.io.memIO.get.feedbackIO(1) := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO(1)) 3538f1fa9b1Ssfencevma imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr 3548f1fa9b1Ssfencevma imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 355559c1710SHaojin Tang // TODO: refactor ditry code 356559c1710SHaojin Tang imp.io.deqDelay(1).ready := false.B 357559c1710SHaojin Tang io.toDataPathAfterDelay(idx)(1).valid := false.B 358559c1710SHaojin Tang io.toDataPathAfterDelay(idx)(1).bits := 0.U.asTypeOf(io.toDataPathAfterDelay(idx)(1).bits) 3598f1fa9b1Ssfencevma case _ => 3608f1fa9b1Ssfencevma } 3618f1fa9b1Ssfencevma 362e62b6911SXuan Hu private val staIdxSeq = (stAddrIQs).map(iq => iq.params.idxInSchBlk) 363e62b6911SXuan Hu private val hyaIdxSeq = (hyuIQs).map(iq => iq.params.idxInSchBlk) 364e62b6911SXuan Hu 365e62b6911SXuan Hu println(s"[SchedulerMemImp] sta iq idx in memSchdBlock: $staIdxSeq") 366e62b6911SXuan Hu println(s"[SchedulerMemImp] hya iq idx in memSchdBlock: $hyaIdxSeq") 367e62b6911SXuan Hu 368e62b6911SXuan Hu private val staEnqs = stAddrIQs.map(_.io.enq).flatten 369e62b6911SXuan Hu private val stdEnqs = stDataIQs.map(_.io.enq).flatten.take(staEnqs.size) 370e62b6911SXuan Hu private val hyaEnqs = hyuIQs.map(_.io.enq).flatten 371e62b6911SXuan Hu private val hydEnqs = stDataIQs.map(_.io.enq).flatten.drop(staEnqs.size) 372e62b6911SXuan Hu 373e62b6911SXuan Hu require(staEnqs.size == stdEnqs.size, s"number of enq ports of store address IQs(${staEnqs.size}) " + 374e62b6911SXuan Hu s"should be equal to number of enq ports of store data IQs(${stdEnqs.size})") 375e62b6911SXuan Hu 376e62b6911SXuan Hu require(hyaEnqs.size == hydEnqs.size, s"number of enq ports of hybrid address IQs(${hyaEnqs.size}) " + 377e62b6911SXuan Hu s"should be equal to number of enq ports of hybrid data IQs(${hydEnqs.size})") 3789b258a00Sxgkiri 3790438e8f4SHaojin Tang val d2IqStaOut = dispatch2Iq.io.out.zipWithIndex.filter(staIdxSeq contains _._2).unzip._1.flatten 3800438e8f4SHaojin Tang d2IqStaOut.zip(staEnqs).zip(stdEnqs).foreach{ case((dp, staIQ), stdIQ) => 381730cfbc0SXuan Hu val isAllReady = staIQ.ready && stdIQ.ready 382e62b6911SXuan Hu dp.ready := isAllReady 383e62b6911SXuan Hu staIQ.valid := dp.valid && isAllReady 3840438e8f4SHaojin Tang stdIQ.valid := dp.valid && isAllReady && FuType.FuTypeOrR(dp.bits.fuType, FuType.stu, FuType.mou) 3859b258a00Sxgkiri } 386730cfbc0SXuan Hu 3870438e8f4SHaojin Tang val d2IqHyaOut = dispatch2Iq.io.out.zipWithIndex.filter(hyaIdxSeq contains _._2).unzip._1.flatten 3880438e8f4SHaojin Tang d2IqHyaOut.zip(hyaEnqs).zip(hydEnqs).foreach{ case((dp, hyaIQ), hydIQ) => 389e62b6911SXuan Hu val isAllReady = hyaIQ.ready && hydIQ.ready 390e62b6911SXuan Hu dp.ready := isAllReady 391e62b6911SXuan Hu hyaIQ.valid := dp.valid && isAllReady 39256bceacbSHaojin Tang hydIQ.valid := dp.valid && isAllReady && FuType.FuTypeOrR(dp.bits.fuType, FuType.stu, FuType.mou) 393e62b6911SXuan Hu } 394730cfbc0SXuan Hu 395e62b6911SXuan Hu stDataIQs.zipWithIndex.foreach { case (iq, i) => 396e62b6911SXuan Hu iq.io.flush <> io.fromCtrlBlock.flush 397f39a61a1SzhanglyGit 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} 398e62b6911SXuan Hu } 399e62b6911SXuan Hu 400e62b6911SXuan Hu (stdEnqs ++ hydEnqs).zip(staEnqs ++ hyaEnqs).zipWithIndex.foreach { case ((stdIQEnq, staIQEnq), i) => 401730cfbc0SXuan Hu stdIQEnq.bits := staIQEnq.bits 402730cfbc0SXuan Hu // Store data reuses store addr src(1) in dispatch2iq 403e62b6911SXuan Hu // [dispatch2iq] --src*------src*(0)--> [staIQ|hyaIQ] 404730cfbc0SXuan Hu // \ 405730cfbc0SXuan Hu // ---src*(1)--> [stdIQ] 406730cfbc0SXuan Hu // Since the src(1) of sta is easier to get, stdIQEnq.bits.src*(0) is assigned to staIQEnq.bits.src*(1) 407730cfbc0SXuan Hu // instead of dispatch2Iq.io.out(x).bits.src*(1) 40897b279b9SXuan Hu val stdIdx = 1 4092d270511Ssinsanction stdIQEnq.bits.srcState(0) := staIQEnq.bits.srcState(stdIdx) 41013551487SzhanglyGit stdIQEnq.bits.srcLoadDependency(0) := staIQEnq.bits.srcLoadDependency(1) 4112d270511Ssinsanction stdIQEnq.bits.srcType(0) := staIQEnq.bits.srcType(stdIdx) 4122d270511Ssinsanction stdIQEnq.bits.psrc(0) := staIQEnq.bits.psrc(stdIdx) 413730cfbc0SXuan Hu stdIQEnq.bits.sqIdx := staIQEnq.bits.sqIdx 414730cfbc0SXuan Hu } 415730cfbc0SXuan Hu 4162d270511Ssinsanction vecMemIQs.foreach { 4172d270511Ssinsanction case imp: IssueQueueVecMemImp => 4182d270511Ssinsanction imp.io.memIO.get.sqDeqPtr.foreach(_ := io.fromMem.get.sqDeqPtr) 4192d270511Ssinsanction imp.io.memIO.get.lqDeqPtr.foreach(_ := io.fromMem.get.lqDeqPtr) 4201f3d1b4dSXuan Hu // not used 4211f3d1b4dSXuan Hu imp.io.memIO.get.feedbackIO := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO) 4221f3d1b4dSXuan Hu // maybe not used 4231f3d1b4dSXuan Hu imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr 4241f3d1b4dSXuan Hu imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 425f39a61a1SzhanglyGit 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} 426f39a61a1SzhanglyGit 4272d270511Ssinsanction case _ => 4282d270511Ssinsanction } 4292d270511Ssinsanction 430730cfbc0SXuan Hu val lsqEnqCtrl = Module(new LsqEnqCtrl) 431730cfbc0SXuan Hu 432730cfbc0SXuan Hu lsqEnqCtrl.io.redirect <> io.fromCtrlBlock.flush 433730cfbc0SXuan Hu lsqEnqCtrl.io.enq <> dispatch2Iq.io.enqLsqIO.get 434730cfbc0SXuan Hu lsqEnqCtrl.io.lcommit := io.fromMem.get.lcommit 435730cfbc0SXuan Hu lsqEnqCtrl.io.scommit := io.fromMem.get.scommit 436730cfbc0SXuan Hu lsqEnqCtrl.io.lqCancelCnt := io.fromMem.get.lqCancelCnt 437730cfbc0SXuan Hu lsqEnqCtrl.io.sqCancelCnt := io.fromMem.get.sqCancelCnt 438*f3a9fb05SAnzo dispatch2Iq.io.lqFreeCount.get := lsqEnqCtrl.io.lqFreeCount 439*f3a9fb05SAnzo dispatch2Iq.io.sqFreeCount.get := lsqEnqCtrl.io.sqFreeCount 440730cfbc0SXuan Hu io.memIO.get.lsqEnqIO <> lsqEnqCtrl.io.enqLsq 441730cfbc0SXuan Hu} 442