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))) 52*ff3fcdf1Sxiaofeibao-xjtu val IQValidNumVec = Output(Vec(4, Vec(2,UInt(6.W)))) 53dd970561SzhanglyGit 54730cfbc0SXuan Hu val fromCtrlBlock = new Bundle { 55730cfbc0SXuan Hu val pcVec = Input(Vec(params.numPcReadPort, UInt(VAddrData().dataWidth.W))) 56730cfbc0SXuan Hu val flush = Flipped(ValidIO(new Redirect)) 57730cfbc0SXuan Hu } 58730cfbc0SXuan Hu val fromDispatch = new Bundle { 59730cfbc0SXuan Hu val allocPregs = Vec(RenameWidth, Input(new ResetPregStateReq)) 60730cfbc0SXuan Hu val uops = Vec(params.numUopIn, Flipped(DecoupledIO(new DynInst))) 61730cfbc0SXuan Hu } 6239c59369SXuan Hu val intWriteBack = MixedVec(Vec(backendParams.numPregWb(IntData()), 63730cfbc0SXuan Hu new RfWritePortWithConfig(backendParams.intPregParams.dataCfg, backendParams.intPregParams.addrWidth))) 6439c59369SXuan Hu val vfWriteBack = MixedVec(Vec(backendParams.numPregWb(VecData()), 65730cfbc0SXuan Hu new RfWritePortWithConfig(backendParams.vfPregParams.dataCfg, backendParams.vfPregParams.addrWidth))) 6659ef6009Sxiaofeibao-xjtu val toDataPathAfterDelay: MixedVec[MixedVec[DecoupledIO[IssueQueueIssueBundle]]] = MixedVec(params.issueBlockParams.map(_.genIssueDecoupledBundle)) 67730cfbc0SXuan Hu 68bf35baadSXuan Hu val fromSchedulers = new Bundle { 69c0be7f33SXuan Hu val wakeupVec: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpInValidBundle) 70bf35baadSXuan Hu } 71bf35baadSXuan Hu 72bf35baadSXuan Hu val toSchedulers = new Bundle { 73c0be7f33SXuan Hu val wakeupVec: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = params.genIQWakeUpOutValidBundle 74bf35baadSXuan Hu } 75bf35baadSXuan Hu 76c0be7f33SXuan Hu val fromDataPath = new Bundle { 7710fe9778SXuan Hu val resp: MixedVec[MixedVec[OGRespBundle]] = MixedVec(params.issueBlockParams.map(x => Flipped(x.genOGRespBundle))) 787a96cc7fSHaojin Tang val og0Cancel = Input(ExuOH(backendParams.numExu)) 79ea46c302SXuan Hu // Todo: remove this after no cancel signal from og1 807a96cc7fSHaojin Tang val og1Cancel = Input(ExuOH(backendParams.numExu)) 81bc7d6943SzhanglyGit val cancelToBusyTable = Vec(backendParams.numExu, Flipped(ValidIO(new CancelSignal))) 82c0be7f33SXuan Hu // just be compatible to old code 83c0be7f33SXuan Hu def apply(i: Int)(j: Int) = resp(i)(j) 84c0be7f33SXuan Hu } 85c0be7f33SXuan Hu 868a66c02cSXuan Hu val loadFinalIssueResp = MixedVec(params.issueBlockParams.map(x => MixedVec(Vec(x.LdExuCnt, Flipped(ValidIO(new IssueQueueDeqRespBundle()(p, x))))))) 878a66c02cSXuan Hu val memAddrIssueResp = MixedVec(params.issueBlockParams.map(x => MixedVec(Vec(x.LdExuCnt, Flipped(ValidIO(new IssueQueueDeqRespBundle()(p, x))))))) 880f55a0d3SHaojin Tang 896810d1e8Ssfencevma val ldCancel = Vec(backendParams.LduCnt + backendParams.HyuCnt, Flipped(new LoadCancelIO)) 90c0be7f33SXuan Hu 91730cfbc0SXuan Hu val memIO = if (params.isMemSchd) Some(new Bundle { 92730cfbc0SXuan Hu val lsqEnqIO = Flipped(new LsqEnqIO) 93730cfbc0SXuan Hu }) else None 94730cfbc0SXuan Hu val fromMem = if (params.isMemSchd) Some(new Bundle { 957b753bebSXuan Hu val ldaFeedback = Flipped(Vec(params.LduCnt, new MemRSFeedbackIO)) 967b753bebSXuan Hu val staFeedback = Flipped(Vec(params.StaCnt, new MemRSFeedbackIO)) 978f1fa9b1Ssfencevma val hyuFeedback = Flipped(Vec(params.HyuCnt, new MemRSFeedbackIO)) 98730cfbc0SXuan Hu val stIssuePtr = Input(new SqPtr()) 99730cfbc0SXuan Hu val lcommit = Input(UInt(log2Up(CommitWidth + 1).W)) 100730cfbc0SXuan Hu val scommit = Input(UInt(log2Ceil(EnsbufferWidth + 1).W)) // connected to `memBlock.io.sqDeq` instead of ROB 101fc45ed13SXuan Hu val wakeup = Vec(params.LdExuCnt, Flipped(Valid(new DynInst))) 1022d270511Ssinsanction val lqDeqPtr = Input(new LqPtr) 1032d270511Ssinsanction val sqDeqPtr = Input(new SqPtr) 104730cfbc0SXuan Hu // from lsq 105730cfbc0SXuan Hu val lqCancelCnt = Input(UInt(log2Up(LoadQueueSize + 1).W)) 106730cfbc0SXuan Hu val sqCancelCnt = Input(UInt(log2Up(StoreQueueSize + 1).W)) 107730cfbc0SXuan Hu val memWaitUpdateReq = Flipped(new MemWaitUpdateReq) 108730cfbc0SXuan Hu }) else None 109730cfbc0SXuan Hu val toMem = if (params.isMemSchd) Some(new Bundle { 110730cfbc0SXuan Hu val loadFastMatch = Output(Vec(params.LduCnt, new IssueQueueLoadBundle)) 111730cfbc0SXuan Hu }) else None 112730cfbc0SXuan Hu} 113730cfbc0SXuan Hu 114730cfbc0SXuan Huabstract class SchedulerImpBase(wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters) 115730cfbc0SXuan Hu extends LazyModuleImp(wrapper) 116730cfbc0SXuan Hu with HasXSParameter 117730cfbc0SXuan Hu{ 118730cfbc0SXuan Hu val io = IO(new SchedulerIO()) 119730cfbc0SXuan Hu 120730cfbc0SXuan Hu // alias 121c0be7f33SXuan Hu private val iqWakeUpInMap: Map[Int, ValidIO[IssueQueueIQWakeUpBundle]] = 122c0be7f33SXuan Hu io.fromSchedulers.wakeupVec.map(x => (x.bits.exuIdx, x)).toMap 123730cfbc0SXuan Hu private val schdType = params.schdType 124730cfbc0SXuan Hu 125730cfbc0SXuan Hu // Modules 126730cfbc0SXuan Hu val dispatch2Iq: Dispatch2IqImp = wrapper.dispatch2Iq.module 127730cfbc0SXuan Hu val issueQueues: Seq[IssueQueueImp] = wrapper.issueQueue.map(_.module) 128*ff3fcdf1Sxiaofeibao-xjtu if (params.isIntSchd) { 129*ff3fcdf1Sxiaofeibao-xjtu dispatch2Iq.io.IQValidNumVec.get := io.IQValidNumVec 130*ff3fcdf1Sxiaofeibao-xjtu io.IQValidNumVec := VecInit(issueQueues.take(4).map(_.io.validCntDeqVec)) 131*ff3fcdf1Sxiaofeibao-xjtu } 132*ff3fcdf1Sxiaofeibao-xjtu else io.IQValidNumVec := 0.U.asTypeOf(io.IQValidNumVec) 133730cfbc0SXuan Hu 13456bcaed7SHaojin Tang // valid count 13556bcaed7SHaojin Tang dispatch2Iq.io.iqValidCnt := issueQueues.filter(_.params.StdCnt == 0).map(_.io.status.validCnt) 13656bcaed7SHaojin Tang 137730cfbc0SXuan Hu // BusyTable Modules 138730cfbc0SXuan Hu val intBusyTable = schdType match { 139bc7d6943SzhanglyGit case IntScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numIntStateRead, wrapper.numIntStateWrite, IntPhyRegs, IntWB()))) 140730cfbc0SXuan Hu case _ => None 141730cfbc0SXuan Hu } 142730cfbc0SXuan Hu 143730cfbc0SXuan Hu val vfBusyTable = schdType match { 144bc7d6943SzhanglyGit case VfScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numVfStateRead, wrapper.numVfStateWrite, VfPhyRegs, VfWB()))) 145730cfbc0SXuan Hu case _ => None 146730cfbc0SXuan Hu } 147730cfbc0SXuan Hu 148730cfbc0SXuan Hu dispatch2Iq.io match { case dp2iq => 149730cfbc0SXuan Hu dp2iq.redirect <> io.fromCtrlBlock.flush 150730cfbc0SXuan Hu dp2iq.in <> io.fromDispatch.uops 151730cfbc0SXuan Hu dp2iq.readIntState.foreach(_ <> intBusyTable.get.io.read) 152730cfbc0SXuan Hu dp2iq.readVfState.foreach(_ <> vfBusyTable.get.io.read) 153730cfbc0SXuan Hu } 154730cfbc0SXuan Hu 155730cfbc0SXuan Hu intBusyTable match { 156730cfbc0SXuan Hu case Some(bt) => 157730cfbc0SXuan Hu bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) => 158730cfbc0SXuan Hu btAllocPregs.valid := dpAllocPregs.isInt 159730cfbc0SXuan Hu btAllocPregs.bits := dpAllocPregs.preg 160730cfbc0SXuan Hu } 161730cfbc0SXuan Hu bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) => 162730cfbc0SXuan Hu wb.valid := io.intWriteBack(i).wen && io.intWriteBack(i).intWen 163730cfbc0SXuan Hu wb.bits := io.intWriteBack(i).addr 164730cfbc0SXuan Hu } 165bc7d6943SzhanglyGit bt.io.wakeUp := io.fromSchedulers.wakeupVec 166bc7d6943SzhanglyGit bt.io.cancel := io.fromDataPath.cancelToBusyTable 16713551487SzhanglyGit bt.io.ldCancel := io.ldCancel 168730cfbc0SXuan Hu case None => 169730cfbc0SXuan Hu } 170730cfbc0SXuan Hu 171730cfbc0SXuan Hu vfBusyTable match { 172730cfbc0SXuan Hu case Some(bt) => 173730cfbc0SXuan Hu bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) => 174730cfbc0SXuan Hu btAllocPregs.valid := dpAllocPregs.isFp 175730cfbc0SXuan Hu btAllocPregs.bits := dpAllocPregs.preg 176730cfbc0SXuan Hu } 177730cfbc0SXuan Hu bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) => 178730cfbc0SXuan Hu wb.valid := io.vfWriteBack(i).wen && (io.vfWriteBack(i).fpWen || io.vfWriteBack(i).vecWen) 179730cfbc0SXuan Hu wb.bits := io.vfWriteBack(i).addr 180730cfbc0SXuan Hu } 181bc7d6943SzhanglyGit bt.io.wakeUp := io.fromSchedulers.wakeupVec 182bc7d6943SzhanglyGit bt.io.cancel := io.fromDataPath.cancelToBusyTable 18313551487SzhanglyGit bt.io.ldCancel := io.ldCancel 184730cfbc0SXuan Hu case None => 185730cfbc0SXuan Hu } 186730cfbc0SXuan Hu 187f39a61a1SzhanglyGit val wakeupFromIntWBVec = Wire(params.genIntWBWakeUpSinkValidBundle) 188f39a61a1SzhanglyGit val wakeupFromVfWBVec = Wire(params.genVfWBWakeUpSinkValidBundle) 189f39a61a1SzhanglyGit 190f39a61a1SzhanglyGit wakeupFromIntWBVec.zip(io.intWriteBack).foreach { case (sink, source) => 191f39a61a1SzhanglyGit sink.valid := source.wen 192f39a61a1SzhanglyGit sink.bits.rfWen := source.intWen 193f39a61a1SzhanglyGit sink.bits.fpWen := source.fpWen 194f39a61a1SzhanglyGit sink.bits.vecWen := source.vecWen 195f39a61a1SzhanglyGit sink.bits.pdest := source.addr 196730cfbc0SXuan Hu } 197f39a61a1SzhanglyGit 198f39a61a1SzhanglyGit wakeupFromVfWBVec.zip(io.vfWriteBack).foreach { case (sink, source) => 199730cfbc0SXuan Hu sink.valid := source.wen 200730cfbc0SXuan Hu sink.bits.rfWen := source.intWen 201730cfbc0SXuan Hu sink.bits.fpWen := source.fpWen 202730cfbc0SXuan Hu sink.bits.vecWen := source.vecWen 203730cfbc0SXuan Hu sink.bits.pdest := source.addr 204730cfbc0SXuan Hu } 205730cfbc0SXuan Hu 206bf35baadSXuan Hu // Connect bundles having the same wakeup source 20759ef6009Sxiaofeibao-xjtu issueQueues.zipWithIndex.foreach { case(iq, i) => 208bf35baadSXuan Hu iq.io.wakeupFromIQ.foreach { wakeUp => 2090c7ebb58Sxiaofeibao-xjtu val wakeUpIn = iqWakeUpInMap(wakeUp.bits.exuIdx) 2100c7ebb58Sxiaofeibao-xjtu val exuIdx = wakeUp.bits.exuIdx 2110c7ebb58Sxiaofeibao-xjtu println(s"[Backend] Connect wakeup exuIdx ${exuIdx}") 2120c7ebb58Sxiaofeibao-xjtu connectSamePort(wakeUp,wakeUpIn) 2130c7ebb58Sxiaofeibao-xjtu backendParams.connectWakeup(exuIdx) 2140c7ebb58Sxiaofeibao-xjtu if (backendParams.isCopyPdest(exuIdx)) { 2150c7ebb58Sxiaofeibao-xjtu println(s"[Backend] exuIdx ${exuIdx} use pdestCopy ${backendParams.getCopyPdestIndex(exuIdx)}") 2160c7ebb58Sxiaofeibao-xjtu wakeUp.bits.pdest := wakeUpIn.bits.pdestCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2174c5a0d77Sxiaofeibao-xjtu if (wakeUpIn.bits.rfWenCopy.nonEmpty) wakeUp.bits.rfWen := wakeUpIn.bits.rfWenCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2184c5a0d77Sxiaofeibao-xjtu if (wakeUpIn.bits.fpWenCopy.nonEmpty) wakeUp.bits.fpWen := wakeUpIn.bits.fpWenCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2194c5a0d77Sxiaofeibao-xjtu if (wakeUpIn.bits.vecWenCopy.nonEmpty) wakeUp.bits.vecWen := wakeUpIn.bits.vecWenCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2204c5a0d77Sxiaofeibao-xjtu if (wakeUpIn.bits.loadDependencyCopy.nonEmpty) wakeUp.bits.loadDependency := wakeUpIn.bits.loadDependencyCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2210c7ebb58Sxiaofeibao-xjtu } 22260912d84Sxiaofeibao-xjtu if (iq.params.numIntSrc == 0) wakeUp.bits.rfWen := false.B 22360912d84Sxiaofeibao-xjtu if (iq.params.numFpSrc == 0) wakeUp.bits.fpWen := false.B 22460912d84Sxiaofeibao-xjtu if (iq.params.numVfSrc == 0) wakeUp.bits.vecWen := false.B 225bf35baadSXuan Hu } 226ea46c302SXuan Hu iq.io.og0Cancel := io.fromDataPath.og0Cancel 227ea46c302SXuan Hu iq.io.og1Cancel := io.fromDataPath.og1Cancel 2280f55a0d3SHaojin Tang iq.io.ldCancel := io.ldCancel 229bf35baadSXuan Hu } 230bf35baadSXuan Hu 231c0be7f33SXuan Hu private val iqWakeUpOutMap: Map[Int, ValidIO[IssueQueueIQWakeUpBundle]] = 232bf35baadSXuan Hu issueQueues.flatMap(_.io.wakeupToIQ) 233c0be7f33SXuan Hu .map(x => (x.bits.exuIdx, x)) 234bf35baadSXuan Hu .toMap 235bf35baadSXuan Hu 236bf35baadSXuan Hu // Connect bundles having the same wakeup source 237bf35baadSXuan Hu io.toSchedulers.wakeupVec.foreach { wakeUp => 238c0be7f33SXuan Hu wakeUp := iqWakeUpOutMap(wakeUp.bits.exuIdx) 239bf35baadSXuan Hu } 240bf35baadSXuan Hu 24159ef6009Sxiaofeibao-xjtu io.toDataPathAfterDelay.zipWithIndex.foreach { case (toDpDy, i) => 24259ef6009Sxiaofeibao-xjtu toDpDy <> issueQueues(i).io.deqDelay 24359ef6009Sxiaofeibao-xjtu } 244bf35baadSXuan Hu 245f99b81adSHaojin Tang // Response 246f99b81adSHaojin Tang issueQueues.zipWithIndex.foreach { case (iq, i) => 247f99b81adSHaojin Tang iq.io.og0Resp.zipWithIndex.foreach { case (og0Resp, j) => 248f99b81adSHaojin Tang og0Resp := io.fromDataPath(i)(j).og0resp 249f99b81adSHaojin Tang } 250f99b81adSHaojin Tang iq.io.og1Resp.zipWithIndex.foreach { case (og1Resp, j) => 251f99b81adSHaojin Tang og1Resp := io.fromDataPath(i)(j).og1resp 252f99b81adSHaojin Tang } 253f99b81adSHaojin Tang iq.io.finalIssueResp.foreach(_.zipWithIndex.foreach { case (finalIssueResp, j) => 254670870b3SXuan Hu if (io.loadFinalIssueResp(i).isDefinedAt(j)) { 255f99b81adSHaojin Tang finalIssueResp := io.loadFinalIssueResp(i)(j) 256670870b3SXuan Hu } else { 257670870b3SXuan Hu finalIssueResp := 0.U.asTypeOf(finalIssueResp) 258670870b3SXuan Hu } 259f99b81adSHaojin Tang }) 260e8800897SXuan Hu iq.io.memAddrIssueResp.foreach(_.zipWithIndex.foreach { case (memAddrIssueResp, j) => 261aa2bcc31SzhanglyGit if (io.memAddrIssueResp(i).isDefinedAt(j)) { 262e8800897SXuan Hu memAddrIssueResp := io.memAddrIssueResp(i)(j) 263aa2bcc31SzhanglyGit } else { 264aa2bcc31SzhanglyGit memAddrIssueResp := 0.U.asTypeOf(memAddrIssueResp) 265aa2bcc31SzhanglyGit } 266e8800897SXuan Hu }) 267f99b81adSHaojin Tang iq.io.wbBusyTableRead := io.fromWbFuBusyTable.fuBusyTableRead(i) 268f99b81adSHaojin Tang io.wbFuBusyTable(i) := iq.io.wbBusyTableWrite 269f99b81adSHaojin Tang } 270f99b81adSHaojin Tang 271c0be7f33SXuan Hu println(s"[Scheduler] io.fromSchedulers.wakeupVec: ${io.fromSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}") 272bf35baadSXuan Hu println(s"[Scheduler] iqWakeUpInKeys: ${iqWakeUpInMap.keys}") 273bf35baadSXuan Hu 274bf35baadSXuan Hu println(s"[Scheduler] iqWakeUpOutKeys: ${iqWakeUpOutMap.keys}") 275c0be7f33SXuan Hu println(s"[Scheduler] io.toSchedulers.wakeupVec: ${io.toSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}") 276730cfbc0SXuan Hu} 277730cfbc0SXuan Hu 278730cfbc0SXuan Huclass SchedulerArithImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters) 279730cfbc0SXuan Hu extends SchedulerImpBase(wrapper) 280730cfbc0SXuan Hu with HasXSParameter 281730cfbc0SXuan Hu{ 2822e0a7dc5Sfdy// dontTouch(io.vfWbFuBusyTable) 283730cfbc0SXuan Hu println(s"[SchedulerArithImp] " + 284730cfbc0SXuan Hu s"has intBusyTable: ${intBusyTable.nonEmpty}, " + 285730cfbc0SXuan Hu s"has vfBusyTable: ${vfBusyTable.nonEmpty}") 286730cfbc0SXuan Hu 287730cfbc0SXuan Hu issueQueues.zipWithIndex.foreach { case (iq, i) => 288730cfbc0SXuan Hu iq.io.flush <> io.fromCtrlBlock.flush 289730cfbc0SXuan Hu iq.io.enq <> dispatch2Iq.io.out(i) 290f39a61a1SzhanglyGit val intWBIQ = params.schdType match { 291f39a61a1SzhanglyGit case IntScheduler() => wakeupFromIntWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1) 292f39a61a1SzhanglyGit case VfScheduler() => wakeupFromVfWBVec 293596af5d2SHaojin Tang case _ => null 294f39a61a1SzhanglyGit } 295f39a61a1SzhanglyGit iq.io.wakeupFromWB.zip(intWBIQ).foreach{ case (sink, source) => sink := source} 296730cfbc0SXuan Hu } 297730cfbc0SXuan Hu} 298730cfbc0SXuan Hu 299f99b81adSHaojin Tang// FIXME: Vector mem instructions may not be handled properly! 300730cfbc0SXuan Huclass SchedulerMemImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters) 301730cfbc0SXuan Hu extends SchedulerImpBase(wrapper) 302730cfbc0SXuan Hu with HasXSParameter 303730cfbc0SXuan Hu{ 304730cfbc0SXuan Hu println(s"[SchedulerMemImp] " + 305730cfbc0SXuan Hu s"has intBusyTable: ${intBusyTable.nonEmpty}, " + 306730cfbc0SXuan Hu s"has vfBusyTable: ${vfBusyTable.nonEmpty}") 307730cfbc0SXuan Hu 308559c1710SHaojin Tang val memAddrIQs = issueQueues.filter(_.params.isMemAddrIQ) 3092d270511Ssinsanction val stAddrIQs = issueQueues.filter(iq => iq.params.StaCnt > 0 || iq.params.VstaCnt > 0) // included in memAddrIQs 3102d270511Ssinsanction val ldAddrIQs = issueQueues.filter(iq => iq.params.LduCnt > 0 || iq.params.VlduCnt > 0) 3112d270511Ssinsanction val stDataIQs = issueQueues.filter(iq => iq.params.StdCnt > 0 || iq.params.VstdCnt > 0) 312559c1710SHaojin Tang val vecMemIQs = issueQueues.filter(_.params.isVecMemIQ) 313559c1710SHaojin Tang val (hyuIQs, hyuIQIdxs) = issueQueues.zipWithIndex.filter(_._1.params.HyuCnt > 0).unzip 314499caf4cSXuan Hu 315499caf4cSXuan Hu println(s"[SchedulerMemImp] memAddrIQs.size: ${memAddrIQs.size}, enq.size: ${memAddrIQs.map(_.io.enq.size).sum}") 316499caf4cSXuan Hu println(s"[SchedulerMemImp] stAddrIQs.size: ${stAddrIQs.size }, enq.size: ${stAddrIQs.map(_.io.enq.size).sum}") 317499caf4cSXuan Hu println(s"[SchedulerMemImp] ldAddrIQs.size: ${ldAddrIQs.size }, enq.size: ${ldAddrIQs.map(_.io.enq.size).sum}") 318499caf4cSXuan Hu println(s"[SchedulerMemImp] stDataIQs.size: ${stDataIQs.size }, enq.size: ${stDataIQs.map(_.io.enq.size).sum}") 319499caf4cSXuan Hu println(s"[SchedulerMemImp] hyuIQs.size: ${hyuIQs.size }, enq.size: ${hyuIQs.map(_.io.enq.size).sum}") 320730cfbc0SXuan Hu require(memAddrIQs.nonEmpty && stDataIQs.nonEmpty) 321730cfbc0SXuan Hu 322853cd2d8SHaojin Tang io.toMem.get.loadFastMatch := 0.U.asTypeOf(io.toMem.get.loadFastMatch) // TODO: is still needed? 323853cd2d8SHaojin Tang 324fc45ed13SXuan Hu private val loadWakeUp = issueQueues.filter(_.params.LdExuCnt > 0).map(_.asInstanceOf[IssueQueueMemAddrImp].io.memIO.get.loadWakeUp).flatten 325596af5d2SHaojin Tang require(loadWakeUp.length == io.fromMem.get.wakeup.length) 326596af5d2SHaojin Tang loadWakeUp.zip(io.fromMem.get.wakeup).foreach(x => x._1 := x._2) 327596af5d2SHaojin Tang 328730cfbc0SXuan Hu memAddrIQs.zipWithIndex.foreach { case (iq, i) => 329730cfbc0SXuan Hu iq.io.flush <> io.fromCtrlBlock.flush 330730cfbc0SXuan Hu iq.io.enq <> dispatch2Iq.io.out(i) 331f39a61a1SzhanglyGit 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} 332730cfbc0SXuan Hu } 333730cfbc0SXuan Hu 334ecfc6f16SXuan Hu ldAddrIQs.zipWithIndex.foreach { 335ecfc6f16SXuan Hu case (imp: IssueQueueMemAddrImp, i) => 336ecfc6f16SXuan Hu imp.io.memIO.get.feedbackIO.head := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO.head) 337c14e89f4SHaojin Tang imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr 338de784418SXuan Hu imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 3397b753bebSXuan Hu case _ => 3407b753bebSXuan Hu } 3417b753bebSXuan Hu 342ecfc6f16SXuan Hu stAddrIQs.zipWithIndex.foreach { 343ecfc6f16SXuan Hu case (imp: IssueQueueMemAddrImp, i) => 344ecfc6f16SXuan Hu imp.io.memIO.get.feedbackIO.head := io.fromMem.get.staFeedback(i) 345c14e89f4SHaojin Tang imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr 346c14e89f4SHaojin Tang imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 3477b753bebSXuan Hu case _ => 3487b753bebSXuan Hu } 349730cfbc0SXuan Hu 350559c1710SHaojin Tang hyuIQs.zip(hyuIQIdxs).foreach { 351559c1710SHaojin Tang case (imp: IssueQueueMemAddrImp, idx) => 352670870b3SXuan Hu imp.io.memIO.get.feedbackIO.head := io.fromMem.get.hyuFeedback.head 353670870b3SXuan Hu imp.io.memIO.get.feedbackIO(1) := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO(1)) 3548f1fa9b1Ssfencevma imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr 3558f1fa9b1Ssfencevma imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 356559c1710SHaojin Tang // TODO: refactor ditry code 357559c1710SHaojin Tang imp.io.deqDelay(1).ready := false.B 358559c1710SHaojin Tang io.toDataPathAfterDelay(idx)(1).valid := false.B 359559c1710SHaojin Tang io.toDataPathAfterDelay(idx)(1).bits := 0.U.asTypeOf(io.toDataPathAfterDelay(idx)(1).bits) 3608f1fa9b1Ssfencevma case _ => 3618f1fa9b1Ssfencevma } 3628f1fa9b1Ssfencevma 363e62b6911SXuan Hu private val staIdxSeq = (stAddrIQs).map(iq => iq.params.idxInSchBlk) 364e62b6911SXuan Hu private val hyaIdxSeq = (hyuIQs).map(iq => iq.params.idxInSchBlk) 365e62b6911SXuan Hu 366e62b6911SXuan Hu println(s"[SchedulerMemImp] sta iq idx in memSchdBlock: $staIdxSeq") 367e62b6911SXuan Hu println(s"[SchedulerMemImp] hya iq idx in memSchdBlock: $hyaIdxSeq") 368e62b6911SXuan Hu 369e62b6911SXuan Hu private val staEnqs = stAddrIQs.map(_.io.enq).flatten 370e62b6911SXuan Hu private val stdEnqs = stDataIQs.map(_.io.enq).flatten.take(staEnqs.size) 371e62b6911SXuan Hu private val hyaEnqs = hyuIQs.map(_.io.enq).flatten 372e62b6911SXuan Hu private val hydEnqs = stDataIQs.map(_.io.enq).flatten.drop(staEnqs.size) 373e62b6911SXuan Hu 374e62b6911SXuan Hu require(staEnqs.size == stdEnqs.size, s"number of enq ports of store address IQs(${staEnqs.size}) " + 375e62b6911SXuan Hu s"should be equal to number of enq ports of store data IQs(${stdEnqs.size})") 376e62b6911SXuan Hu 377e62b6911SXuan Hu require(hyaEnqs.size == hydEnqs.size, s"number of enq ports of hybrid address IQs(${hyaEnqs.size}) " + 378e62b6911SXuan Hu s"should be equal to number of enq ports of hybrid data IQs(${hydEnqs.size})") 3799b258a00Sxgkiri 3809b258a00Sxgkiri for ((idxInSchBlk, i) <- staIdxSeq.zipWithIndex) { 381e62b6911SXuan Hu dispatch2Iq.io.out(idxInSchBlk).zip(staEnqs).zip(stdEnqs).foreach{ case((dp, staIQ), stdIQ) => 382730cfbc0SXuan Hu val isAllReady = staIQ.ready && stdIQ.ready 383e62b6911SXuan Hu dp.ready := isAllReady 384e62b6911SXuan Hu staIQ.valid := dp.valid && isAllReady 3854ec52c44SXuan Hu stdIQ.valid := dp.valid && isAllReady && FuType.isStore(dp.bits.fuType) 386730cfbc0SXuan Hu } 3879b258a00Sxgkiri } 388730cfbc0SXuan Hu 389e62b6911SXuan Hu for ((idxInSchBlk, i) <- hyaIdxSeq.zipWithIndex) { 390e62b6911SXuan Hu dispatch2Iq.io.out(idxInSchBlk).zip(hyaEnqs).zip(hydEnqs).foreach{ case((dp, hyaIQ), hydIQ) => 391e62b6911SXuan Hu val isAllReady = hyaIQ.ready && hydIQ.ready 392e62b6911SXuan Hu dp.ready := isAllReady 393e62b6911SXuan Hu hyaIQ.valid := dp.valid && isAllReady 39456bceacbSHaojin Tang hydIQ.valid := dp.valid && isAllReady && FuType.FuTypeOrR(dp.bits.fuType, FuType.stu, FuType.mou) 395e62b6911SXuan Hu } 396e62b6911SXuan Hu } 397730cfbc0SXuan Hu 398e62b6911SXuan Hu stDataIQs.zipWithIndex.foreach { case (iq, i) => 399e62b6911SXuan Hu iq.io.flush <> io.fromCtrlBlock.flush 400f39a61a1SzhanglyGit 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} 401e62b6911SXuan Hu } 402e62b6911SXuan Hu 403e62b6911SXuan Hu (stdEnqs ++ hydEnqs).zip(staEnqs ++ hyaEnqs).zipWithIndex.foreach { case ((stdIQEnq, staIQEnq), i) => 404730cfbc0SXuan Hu stdIQEnq.bits := staIQEnq.bits 405730cfbc0SXuan Hu // Store data reuses store addr src(1) in dispatch2iq 406e62b6911SXuan Hu // [dispatch2iq] --src*------src*(0)--> [staIQ|hyaIQ] 407730cfbc0SXuan Hu // \ 408730cfbc0SXuan Hu // ---src*(1)--> [stdIQ] 409730cfbc0SXuan Hu // Since the src(1) of sta is easier to get, stdIQEnq.bits.src*(0) is assigned to staIQEnq.bits.src*(1) 410730cfbc0SXuan Hu // instead of dispatch2Iq.io.out(x).bits.src*(1) 41197b279b9SXuan Hu val stdIdx = 1 4122d270511Ssinsanction stdIQEnq.bits.srcState(0) := staIQEnq.bits.srcState(stdIdx) 41313551487SzhanglyGit stdIQEnq.bits.srcLoadDependency(0) := staIQEnq.bits.srcLoadDependency(1) 4142d270511Ssinsanction stdIQEnq.bits.srcType(0) := staIQEnq.bits.srcType(stdIdx) 4152d270511Ssinsanction stdIQEnq.bits.psrc(0) := staIQEnq.bits.psrc(stdIdx) 416730cfbc0SXuan Hu stdIQEnq.bits.sqIdx := staIQEnq.bits.sqIdx 417730cfbc0SXuan Hu } 418730cfbc0SXuan Hu 4192d270511Ssinsanction vecMemIQs.foreach { 4202d270511Ssinsanction case imp: IssueQueueVecMemImp => 4212d270511Ssinsanction imp.io.memIO.get.sqDeqPtr.foreach(_ := io.fromMem.get.sqDeqPtr) 4222d270511Ssinsanction imp.io.memIO.get.lqDeqPtr.foreach(_ := io.fromMem.get.lqDeqPtr) 4231f3d1b4dSXuan Hu // not used 4241f3d1b4dSXuan Hu imp.io.memIO.get.feedbackIO := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO) 4251f3d1b4dSXuan Hu // maybe not used 4261f3d1b4dSXuan Hu imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr 4271f3d1b4dSXuan Hu imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 428f39a61a1SzhanglyGit 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} 429f39a61a1SzhanglyGit 4302d270511Ssinsanction case _ => 4312d270511Ssinsanction } 4322d270511Ssinsanction 433730cfbc0SXuan Hu val lsqEnqCtrl = Module(new LsqEnqCtrl) 434730cfbc0SXuan Hu 435730cfbc0SXuan Hu lsqEnqCtrl.io.redirect <> io.fromCtrlBlock.flush 436730cfbc0SXuan Hu lsqEnqCtrl.io.enq <> dispatch2Iq.io.enqLsqIO.get 437730cfbc0SXuan Hu lsqEnqCtrl.io.lcommit := io.fromMem.get.lcommit 438730cfbc0SXuan Hu lsqEnqCtrl.io.scommit := io.fromMem.get.scommit 439730cfbc0SXuan Hu lsqEnqCtrl.io.lqCancelCnt := io.fromMem.get.lqCancelCnt 440730cfbc0SXuan Hu lsqEnqCtrl.io.sqCancelCnt := io.fromMem.get.sqCancelCnt 441730cfbc0SXuan Hu io.memIO.get.lsqEnqIO <> lsqEnqCtrl.io.enqLsq 442730cfbc0SXuan Hu} 443