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))))))) 87*7e471bf8SXuan Hu val vecLoadIssueResp = MixedVec(params.issueBlockParams.map(x => MixedVec(Vec(x.VlduCnt, 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)) 98fd490615Sweiding liu val vstuFeedback = Flipped(Vec(params.VstuCnt, new MemRSFeedbackIO(isVector = true))) 99fd490615Sweiding liu val vlduFeedback = Flipped(Vec(params.VlduCnt, new MemRSFeedbackIO(isVector = true))) 100730cfbc0SXuan Hu val stIssuePtr = Input(new SqPtr()) 101730cfbc0SXuan Hu val lcommit = Input(UInt(log2Up(CommitWidth + 1).W)) 102730cfbc0SXuan Hu val scommit = Input(UInt(log2Ceil(EnsbufferWidth + 1).W)) // connected to `memBlock.io.sqDeq` instead of ROB 103fc45ed13SXuan Hu val wakeup = Vec(params.LdExuCnt, Flipped(Valid(new DynInst))) 1042d270511Ssinsanction val lqDeqPtr = Input(new LqPtr) 1052d270511Ssinsanction val sqDeqPtr = Input(new SqPtr) 106730cfbc0SXuan Hu // from lsq 107730cfbc0SXuan Hu val lqCancelCnt = Input(UInt(log2Up(LoadQueueSize + 1).W)) 108730cfbc0SXuan Hu val sqCancelCnt = Input(UInt(log2Up(StoreQueueSize + 1).W)) 109730cfbc0SXuan Hu val memWaitUpdateReq = Flipped(new MemWaitUpdateReq) 110730cfbc0SXuan Hu }) else None 111730cfbc0SXuan Hu val toMem = if (params.isMemSchd) Some(new Bundle { 112730cfbc0SXuan Hu val loadFastMatch = Output(Vec(params.LduCnt, new IssueQueueLoadBundle)) 113730cfbc0SXuan Hu }) else None 114730cfbc0SXuan Hu} 115730cfbc0SXuan Hu 116730cfbc0SXuan Huabstract class SchedulerImpBase(wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters) 117730cfbc0SXuan Hu extends LazyModuleImp(wrapper) 118730cfbc0SXuan Hu with HasXSParameter 119730cfbc0SXuan Hu{ 120730cfbc0SXuan Hu val io = IO(new SchedulerIO()) 121730cfbc0SXuan Hu 122730cfbc0SXuan Hu // alias 123c0be7f33SXuan Hu private val iqWakeUpInMap: Map[Int, ValidIO[IssueQueueIQWakeUpBundle]] = 124c0be7f33SXuan Hu io.fromSchedulers.wakeupVec.map(x => (x.bits.exuIdx, x)).toMap 125730cfbc0SXuan Hu private val schdType = params.schdType 126730cfbc0SXuan Hu 127730cfbc0SXuan Hu // Modules 128730cfbc0SXuan Hu val dispatch2Iq: Dispatch2IqImp = wrapper.dispatch2Iq.module 129730cfbc0SXuan Hu val issueQueues: Seq[IssueQueueImp] = wrapper.issueQueue.map(_.module) 130ff3fcdf1Sxiaofeibao-xjtu if (params.isIntSchd) { 131ff3fcdf1Sxiaofeibao-xjtu dispatch2Iq.io.IQValidNumVec.get := io.IQValidNumVec 132c1e19666Sxiaofeibao-xjtu io.IQValidNumVec := MixedVecInit(issueQueues.map(_.io.validCntDeqVec)) 133ff3fcdf1Sxiaofeibao-xjtu } 134ff3fcdf1Sxiaofeibao-xjtu else io.IQValidNumVec := 0.U.asTypeOf(io.IQValidNumVec) 135730cfbc0SXuan Hu 13656bcaed7SHaojin Tang // valid count 13756bcaed7SHaojin Tang dispatch2Iq.io.iqValidCnt := issueQueues.filter(_.params.StdCnt == 0).map(_.io.status.validCnt) 13856bcaed7SHaojin Tang 139730cfbc0SXuan Hu // BusyTable Modules 140730cfbc0SXuan Hu val intBusyTable = schdType match { 141bc7d6943SzhanglyGit case IntScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numIntStateRead, wrapper.numIntStateWrite, IntPhyRegs, IntWB()))) 142730cfbc0SXuan Hu case _ => None 143730cfbc0SXuan Hu } 144730cfbc0SXuan Hu 145730cfbc0SXuan Hu val vfBusyTable = schdType match { 146bc7d6943SzhanglyGit case VfScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numVfStateRead, wrapper.numVfStateWrite, VfPhyRegs, VfWB()))) 147730cfbc0SXuan Hu case _ => None 148730cfbc0SXuan Hu } 149730cfbc0SXuan Hu 150730cfbc0SXuan Hu dispatch2Iq.io match { case dp2iq => 151730cfbc0SXuan Hu dp2iq.redirect <> io.fromCtrlBlock.flush 152730cfbc0SXuan Hu dp2iq.in <> io.fromDispatch.uops 153730cfbc0SXuan Hu dp2iq.readIntState.foreach(_ <> intBusyTable.get.io.read) 154730cfbc0SXuan Hu dp2iq.readVfState.foreach(_ <> vfBusyTable.get.io.read) 155730cfbc0SXuan Hu } 156730cfbc0SXuan Hu 157730cfbc0SXuan Hu intBusyTable match { 158730cfbc0SXuan Hu case Some(bt) => 159730cfbc0SXuan Hu bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) => 160730cfbc0SXuan Hu btAllocPregs.valid := dpAllocPregs.isInt 161730cfbc0SXuan Hu btAllocPregs.bits := dpAllocPregs.preg 162730cfbc0SXuan Hu } 163730cfbc0SXuan Hu bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) => 164730cfbc0SXuan Hu wb.valid := io.intWriteBack(i).wen && io.intWriteBack(i).intWen 165730cfbc0SXuan Hu wb.bits := io.intWriteBack(i).addr 166730cfbc0SXuan Hu } 167bc7d6943SzhanglyGit bt.io.wakeUp := io.fromSchedulers.wakeupVec 168bc7d6943SzhanglyGit bt.io.cancel := io.fromDataPath.cancelToBusyTable 16913551487SzhanglyGit bt.io.ldCancel := io.ldCancel 170730cfbc0SXuan Hu case None => 171730cfbc0SXuan Hu } 172730cfbc0SXuan Hu 173730cfbc0SXuan Hu vfBusyTable match { 174730cfbc0SXuan Hu case Some(bt) => 175730cfbc0SXuan Hu bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) => 176730cfbc0SXuan Hu btAllocPregs.valid := dpAllocPregs.isFp 177730cfbc0SXuan Hu btAllocPregs.bits := dpAllocPregs.preg 178730cfbc0SXuan Hu } 179730cfbc0SXuan Hu bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) => 180730cfbc0SXuan Hu wb.valid := io.vfWriteBack(i).wen && (io.vfWriteBack(i).fpWen || io.vfWriteBack(i).vecWen) 181730cfbc0SXuan Hu wb.bits := io.vfWriteBack(i).addr 182730cfbc0SXuan Hu } 183bc7d6943SzhanglyGit bt.io.wakeUp := io.fromSchedulers.wakeupVec 184bc7d6943SzhanglyGit bt.io.cancel := io.fromDataPath.cancelToBusyTable 18513551487SzhanglyGit bt.io.ldCancel := io.ldCancel 186730cfbc0SXuan Hu case None => 187730cfbc0SXuan Hu } 188730cfbc0SXuan Hu 189f39a61a1SzhanglyGit val wakeupFromIntWBVec = Wire(params.genIntWBWakeUpSinkValidBundle) 190f39a61a1SzhanglyGit val wakeupFromVfWBVec = Wire(params.genVfWBWakeUpSinkValidBundle) 191f39a61a1SzhanglyGit 192f39a61a1SzhanglyGit wakeupFromIntWBVec.zip(io.intWriteBack).foreach { case (sink, source) => 193f39a61a1SzhanglyGit sink.valid := source.wen 194f39a61a1SzhanglyGit sink.bits.rfWen := source.intWen 195f39a61a1SzhanglyGit sink.bits.fpWen := source.fpWen 196f39a61a1SzhanglyGit sink.bits.vecWen := source.vecWen 197f39a61a1SzhanglyGit sink.bits.pdest := source.addr 198730cfbc0SXuan Hu } 199f39a61a1SzhanglyGit 200f39a61a1SzhanglyGit wakeupFromVfWBVec.zip(io.vfWriteBack).foreach { case (sink, source) => 201730cfbc0SXuan Hu sink.valid := source.wen 202730cfbc0SXuan Hu sink.bits.rfWen := source.intWen 203730cfbc0SXuan Hu sink.bits.fpWen := source.fpWen 204730cfbc0SXuan Hu sink.bits.vecWen := source.vecWen 205730cfbc0SXuan Hu sink.bits.pdest := source.addr 206730cfbc0SXuan Hu } 207730cfbc0SXuan Hu 208bf35baadSXuan Hu // Connect bundles having the same wakeup source 20959ef6009Sxiaofeibao-xjtu issueQueues.zipWithIndex.foreach { case(iq, i) => 210bf35baadSXuan Hu iq.io.wakeupFromIQ.foreach { wakeUp => 2110c7ebb58Sxiaofeibao-xjtu val wakeUpIn = iqWakeUpInMap(wakeUp.bits.exuIdx) 2120c7ebb58Sxiaofeibao-xjtu val exuIdx = wakeUp.bits.exuIdx 2130c7ebb58Sxiaofeibao-xjtu println(s"[Backend] Connect wakeup exuIdx ${exuIdx}") 2140c7ebb58Sxiaofeibao-xjtu connectSamePort(wakeUp,wakeUpIn) 2150c7ebb58Sxiaofeibao-xjtu backendParams.connectWakeup(exuIdx) 2160c7ebb58Sxiaofeibao-xjtu if (backendParams.isCopyPdest(exuIdx)) { 2170c7ebb58Sxiaofeibao-xjtu println(s"[Backend] exuIdx ${exuIdx} use pdestCopy ${backendParams.getCopyPdestIndex(exuIdx)}") 2180c7ebb58Sxiaofeibao-xjtu wakeUp.bits.pdest := wakeUpIn.bits.pdestCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2194c5a0d77Sxiaofeibao-xjtu if (wakeUpIn.bits.rfWenCopy.nonEmpty) wakeUp.bits.rfWen := wakeUpIn.bits.rfWenCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2204c5a0d77Sxiaofeibao-xjtu if (wakeUpIn.bits.fpWenCopy.nonEmpty) wakeUp.bits.fpWen := wakeUpIn.bits.fpWenCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2214c5a0d77Sxiaofeibao-xjtu if (wakeUpIn.bits.vecWenCopy.nonEmpty) wakeUp.bits.vecWen := wakeUpIn.bits.vecWenCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2224c5a0d77Sxiaofeibao-xjtu if (wakeUpIn.bits.loadDependencyCopy.nonEmpty) wakeUp.bits.loadDependency := wakeUpIn.bits.loadDependencyCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2230c7ebb58Sxiaofeibao-xjtu } 22460912d84Sxiaofeibao-xjtu if (iq.params.numIntSrc == 0) wakeUp.bits.rfWen := false.B 22560912d84Sxiaofeibao-xjtu if (iq.params.numFpSrc == 0) wakeUp.bits.fpWen := false.B 22660912d84Sxiaofeibao-xjtu if (iq.params.numVfSrc == 0) wakeUp.bits.vecWen := false.B 227bf35baadSXuan Hu } 228ea46c302SXuan Hu iq.io.og0Cancel := io.fromDataPath.og0Cancel 229ea46c302SXuan Hu iq.io.og1Cancel := io.fromDataPath.og1Cancel 2300f55a0d3SHaojin Tang iq.io.ldCancel := io.ldCancel 231bf35baadSXuan Hu } 232bf35baadSXuan Hu 233c0be7f33SXuan Hu private val iqWakeUpOutMap: Map[Int, ValidIO[IssueQueueIQWakeUpBundle]] = 234bf35baadSXuan Hu issueQueues.flatMap(_.io.wakeupToIQ) 235c0be7f33SXuan Hu .map(x => (x.bits.exuIdx, x)) 236bf35baadSXuan Hu .toMap 237bf35baadSXuan Hu 238bf35baadSXuan Hu // Connect bundles having the same wakeup source 239bf35baadSXuan Hu io.toSchedulers.wakeupVec.foreach { wakeUp => 240c0be7f33SXuan Hu wakeUp := iqWakeUpOutMap(wakeUp.bits.exuIdx) 241bf35baadSXuan Hu } 242bf35baadSXuan Hu 24359ef6009Sxiaofeibao-xjtu io.toDataPathAfterDelay.zipWithIndex.foreach { case (toDpDy, i) => 24459ef6009Sxiaofeibao-xjtu toDpDy <> issueQueues(i).io.deqDelay 24559ef6009Sxiaofeibao-xjtu } 246bf35baadSXuan Hu 247f99b81adSHaojin Tang // Response 248f99b81adSHaojin Tang issueQueues.zipWithIndex.foreach { case (iq, i) => 249f99b81adSHaojin Tang iq.io.og0Resp.zipWithIndex.foreach { case (og0Resp, j) => 250f99b81adSHaojin Tang og0Resp := io.fromDataPath(i)(j).og0resp 251f99b81adSHaojin Tang } 252f99b81adSHaojin Tang iq.io.og1Resp.zipWithIndex.foreach { case (og1Resp, j) => 253f99b81adSHaojin Tang og1Resp := io.fromDataPath(i)(j).og1resp 254f99b81adSHaojin Tang } 255f99b81adSHaojin Tang iq.io.finalIssueResp.foreach(_.zipWithIndex.foreach { case (finalIssueResp, j) => 256670870b3SXuan Hu if (io.loadFinalIssueResp(i).isDefinedAt(j)) { 257f99b81adSHaojin Tang finalIssueResp := io.loadFinalIssueResp(i)(j) 258670870b3SXuan Hu } else { 259670870b3SXuan Hu finalIssueResp := 0.U.asTypeOf(finalIssueResp) 260670870b3SXuan Hu } 261f99b81adSHaojin Tang }) 262e8800897SXuan Hu iq.io.memAddrIssueResp.foreach(_.zipWithIndex.foreach { case (memAddrIssueResp, j) => 263aa2bcc31SzhanglyGit if (io.memAddrIssueResp(i).isDefinedAt(j)) { 264e8800897SXuan Hu memAddrIssueResp := io.memAddrIssueResp(i)(j) 265aa2bcc31SzhanglyGit } else { 266aa2bcc31SzhanglyGit memAddrIssueResp := 0.U.asTypeOf(memAddrIssueResp) 267aa2bcc31SzhanglyGit } 268e8800897SXuan Hu }) 269*7e471bf8SXuan Hu iq.io.vecLoadIssueResp.foreach(_.zipWithIndex.foreach { case (resp, deqIdx) => 270*7e471bf8SXuan Hu resp := io.vecLoadIssueResp(i)(deqIdx) 271*7e471bf8SXuan Hu }) 272f99b81adSHaojin Tang iq.io.wbBusyTableRead := io.fromWbFuBusyTable.fuBusyTableRead(i) 273f99b81adSHaojin Tang io.wbFuBusyTable(i) := iq.io.wbBusyTableWrite 274f99b81adSHaojin Tang } 275f99b81adSHaojin Tang 276c0be7f33SXuan Hu println(s"[Scheduler] io.fromSchedulers.wakeupVec: ${io.fromSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}") 277bf35baadSXuan Hu println(s"[Scheduler] iqWakeUpInKeys: ${iqWakeUpInMap.keys}") 278bf35baadSXuan Hu 279bf35baadSXuan Hu println(s"[Scheduler] iqWakeUpOutKeys: ${iqWakeUpOutMap.keys}") 280c0be7f33SXuan Hu println(s"[Scheduler] io.toSchedulers.wakeupVec: ${io.toSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}") 281730cfbc0SXuan Hu} 282730cfbc0SXuan Hu 283730cfbc0SXuan Huclass SchedulerArithImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters) 284730cfbc0SXuan Hu extends SchedulerImpBase(wrapper) 285730cfbc0SXuan Hu with HasXSParameter 286730cfbc0SXuan Hu{ 2872e0a7dc5Sfdy// dontTouch(io.vfWbFuBusyTable) 288730cfbc0SXuan Hu println(s"[SchedulerArithImp] " + 289730cfbc0SXuan Hu s"has intBusyTable: ${intBusyTable.nonEmpty}, " + 290730cfbc0SXuan Hu s"has vfBusyTable: ${vfBusyTable.nonEmpty}") 291730cfbc0SXuan Hu 292730cfbc0SXuan Hu issueQueues.zipWithIndex.foreach { case (iq, i) => 293730cfbc0SXuan Hu iq.io.flush <> io.fromCtrlBlock.flush 294730cfbc0SXuan Hu iq.io.enq <> dispatch2Iq.io.out(i) 295f39a61a1SzhanglyGit val intWBIQ = params.schdType match { 296f39a61a1SzhanglyGit case IntScheduler() => wakeupFromIntWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1) 297f39a61a1SzhanglyGit case VfScheduler() => wakeupFromVfWBVec 298596af5d2SHaojin Tang case _ => null 299f39a61a1SzhanglyGit } 300f39a61a1SzhanglyGit iq.io.wakeupFromWB.zip(intWBIQ).foreach{ case (sink, source) => sink := source} 301730cfbc0SXuan Hu } 302730cfbc0SXuan Hu} 303730cfbc0SXuan Hu 304f99b81adSHaojin Tang// FIXME: Vector mem instructions may not be handled properly! 305730cfbc0SXuan Huclass SchedulerMemImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters) 306730cfbc0SXuan Hu extends SchedulerImpBase(wrapper) 307730cfbc0SXuan Hu with HasXSParameter 308730cfbc0SXuan Hu{ 309730cfbc0SXuan Hu println(s"[SchedulerMemImp] " + 310730cfbc0SXuan Hu s"has intBusyTable: ${intBusyTable.nonEmpty}, " + 311730cfbc0SXuan Hu s"has vfBusyTable: ${vfBusyTable.nonEmpty}") 312730cfbc0SXuan Hu 313559c1710SHaojin Tang val memAddrIQs = issueQueues.filter(_.params.isMemAddrIQ) 314e07131b2Ssinsanction val stAddrIQs = issueQueues.filter(iq => iq.params.StaCnt > 0) // included in memAddrIQs 315e07131b2Ssinsanction val ldAddrIQs = issueQueues.filter(iq => iq.params.LduCnt > 0) 316e07131b2Ssinsanction val stDataIQs = issueQueues.filter(iq => iq.params.StdCnt > 0) 317559c1710SHaojin Tang val vecMemIQs = issueQueues.filter(_.params.isVecMemIQ) 318559c1710SHaojin Tang val (hyuIQs, hyuIQIdxs) = issueQueues.zipWithIndex.filter(_._1.params.HyuCnt > 0).unzip 319499caf4cSXuan Hu 320499caf4cSXuan Hu println(s"[SchedulerMemImp] memAddrIQs.size: ${memAddrIQs.size}, enq.size: ${memAddrIQs.map(_.io.enq.size).sum}") 321499caf4cSXuan Hu println(s"[SchedulerMemImp] stAddrIQs.size: ${stAddrIQs.size }, enq.size: ${stAddrIQs.map(_.io.enq.size).sum}") 322499caf4cSXuan Hu println(s"[SchedulerMemImp] ldAddrIQs.size: ${ldAddrIQs.size }, enq.size: ${ldAddrIQs.map(_.io.enq.size).sum}") 323499caf4cSXuan Hu println(s"[SchedulerMemImp] stDataIQs.size: ${stDataIQs.size }, enq.size: ${stDataIQs.map(_.io.enq.size).sum}") 324499caf4cSXuan Hu println(s"[SchedulerMemImp] hyuIQs.size: ${hyuIQs.size }, enq.size: ${hyuIQs.map(_.io.enq.size).sum}") 325730cfbc0SXuan Hu require(memAddrIQs.nonEmpty && stDataIQs.nonEmpty) 326730cfbc0SXuan Hu 327853cd2d8SHaojin Tang io.toMem.get.loadFastMatch := 0.U.asTypeOf(io.toMem.get.loadFastMatch) // TODO: is still needed? 328853cd2d8SHaojin Tang 329fc45ed13SXuan Hu private val loadWakeUp = issueQueues.filter(_.params.LdExuCnt > 0).map(_.asInstanceOf[IssueQueueMemAddrImp].io.memIO.get.loadWakeUp).flatten 330596af5d2SHaojin Tang require(loadWakeUp.length == io.fromMem.get.wakeup.length) 331596af5d2SHaojin Tang loadWakeUp.zip(io.fromMem.get.wakeup).foreach(x => x._1 := x._2) 332596af5d2SHaojin Tang 333730cfbc0SXuan Hu memAddrIQs.zipWithIndex.foreach { case (iq, i) => 334730cfbc0SXuan Hu iq.io.flush <> io.fromCtrlBlock.flush 335730cfbc0SXuan Hu iq.io.enq <> dispatch2Iq.io.out(i) 336f39a61a1SzhanglyGit 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} 337730cfbc0SXuan Hu } 338730cfbc0SXuan Hu 339ecfc6f16SXuan Hu ldAddrIQs.zipWithIndex.foreach { 340ecfc6f16SXuan Hu case (imp: IssueQueueMemAddrImp, i) => 341ecfc6f16SXuan Hu imp.io.memIO.get.feedbackIO.head := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO.head) 342c14e89f4SHaojin Tang imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr 343de784418SXuan Hu imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 3447b753bebSXuan Hu case _ => 3457b753bebSXuan Hu } 3467b753bebSXuan Hu 347ecfc6f16SXuan Hu stAddrIQs.zipWithIndex.foreach { 348ecfc6f16SXuan Hu case (imp: IssueQueueMemAddrImp, i) => 349ecfc6f16SXuan Hu imp.io.memIO.get.feedbackIO.head := io.fromMem.get.staFeedback(i) 350c14e89f4SHaojin Tang imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr 351c14e89f4SHaojin Tang imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 3527b753bebSXuan Hu case _ => 3537b753bebSXuan Hu } 354730cfbc0SXuan Hu 355559c1710SHaojin Tang hyuIQs.zip(hyuIQIdxs).foreach { 356559c1710SHaojin Tang case (imp: IssueQueueMemAddrImp, idx) => 357670870b3SXuan Hu imp.io.memIO.get.feedbackIO.head := io.fromMem.get.hyuFeedback.head 358670870b3SXuan Hu imp.io.memIO.get.feedbackIO(1) := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO(1)) 3598f1fa9b1Ssfencevma imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr 3608f1fa9b1Ssfencevma imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 361559c1710SHaojin Tang // TODO: refactor ditry code 362559c1710SHaojin Tang imp.io.deqDelay(1).ready := false.B 363559c1710SHaojin Tang io.toDataPathAfterDelay(idx)(1).valid := false.B 364559c1710SHaojin Tang io.toDataPathAfterDelay(idx)(1).bits := 0.U.asTypeOf(io.toDataPathAfterDelay(idx)(1).bits) 3658f1fa9b1Ssfencevma case _ => 3668f1fa9b1Ssfencevma } 3678f1fa9b1Ssfencevma 368e62b6911SXuan Hu private val staIdxSeq = (stAddrIQs).map(iq => iq.params.idxInSchBlk) 369e62b6911SXuan Hu private val hyaIdxSeq = (hyuIQs).map(iq => iq.params.idxInSchBlk) 370e62b6911SXuan Hu 371e62b6911SXuan Hu println(s"[SchedulerMemImp] sta iq idx in memSchdBlock: $staIdxSeq") 372e62b6911SXuan Hu println(s"[SchedulerMemImp] hya iq idx in memSchdBlock: $hyaIdxSeq") 373e62b6911SXuan Hu 374e62b6911SXuan Hu private val staEnqs = stAddrIQs.map(_.io.enq).flatten 375e62b6911SXuan Hu private val stdEnqs = stDataIQs.map(_.io.enq).flatten.take(staEnqs.size) 376e62b6911SXuan Hu private val hyaEnqs = hyuIQs.map(_.io.enq).flatten 377e62b6911SXuan Hu private val hydEnqs = stDataIQs.map(_.io.enq).flatten.drop(staEnqs.size) 378e62b6911SXuan Hu 379e62b6911SXuan Hu require(staEnqs.size == stdEnqs.size, s"number of enq ports of store address IQs(${staEnqs.size}) " + 380e62b6911SXuan Hu s"should be equal to number of enq ports of store data IQs(${stdEnqs.size})") 381e62b6911SXuan Hu 382e62b6911SXuan Hu require(hyaEnqs.size == hydEnqs.size, s"number of enq ports of hybrid address IQs(${hyaEnqs.size}) " + 383e62b6911SXuan Hu s"should be equal to number of enq ports of hybrid data IQs(${hydEnqs.size})") 3849b258a00Sxgkiri 3850438e8f4SHaojin Tang val d2IqStaOut = dispatch2Iq.io.out.zipWithIndex.filter(staIdxSeq contains _._2).unzip._1.flatten 3860438e8f4SHaojin Tang d2IqStaOut.zip(staEnqs).zip(stdEnqs).foreach{ case((dp, staIQ), stdIQ) => 387730cfbc0SXuan Hu val isAllReady = staIQ.ready && stdIQ.ready 388e62b6911SXuan Hu dp.ready := isAllReady 389e62b6911SXuan Hu staIQ.valid := dp.valid && isAllReady 3900438e8f4SHaojin Tang stdIQ.valid := dp.valid && isAllReady && FuType.FuTypeOrR(dp.bits.fuType, FuType.stu, FuType.mou) 3919b258a00Sxgkiri } 392730cfbc0SXuan Hu 3930438e8f4SHaojin Tang val d2IqHyaOut = dispatch2Iq.io.out.zipWithIndex.filter(hyaIdxSeq contains _._2).unzip._1.flatten 3940438e8f4SHaojin Tang d2IqHyaOut.zip(hyaEnqs).zip(hydEnqs).foreach{ case((dp, hyaIQ), hydIQ) => 395e62b6911SXuan Hu val isAllReady = hyaIQ.ready && hydIQ.ready 396e62b6911SXuan Hu dp.ready := isAllReady 397e62b6911SXuan Hu hyaIQ.valid := dp.valid && isAllReady 39856bceacbSHaojin Tang hydIQ.valid := dp.valid && isAllReady && FuType.FuTypeOrR(dp.bits.fuType, FuType.stu, FuType.mou) 399e62b6911SXuan Hu } 400730cfbc0SXuan Hu 401e62b6911SXuan Hu stDataIQs.zipWithIndex.foreach { case (iq, i) => 402e62b6911SXuan Hu iq.io.flush <> io.fromCtrlBlock.flush 403f39a61a1SzhanglyGit 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} 404e62b6911SXuan Hu } 405e62b6911SXuan Hu 406e62b6911SXuan Hu (stdEnqs ++ hydEnqs).zip(staEnqs ++ hyaEnqs).zipWithIndex.foreach { case ((stdIQEnq, staIQEnq), i) => 407730cfbc0SXuan Hu stdIQEnq.bits := staIQEnq.bits 408730cfbc0SXuan Hu // Store data reuses store addr src(1) in dispatch2iq 409e62b6911SXuan Hu // [dispatch2iq] --src*------src*(0)--> [staIQ|hyaIQ] 410730cfbc0SXuan Hu // \ 411730cfbc0SXuan Hu // ---src*(1)--> [stdIQ] 412730cfbc0SXuan Hu // Since the src(1) of sta is easier to get, stdIQEnq.bits.src*(0) is assigned to staIQEnq.bits.src*(1) 413730cfbc0SXuan Hu // instead of dispatch2Iq.io.out(x).bits.src*(1) 41497b279b9SXuan Hu val stdIdx = 1 4152d270511Ssinsanction stdIQEnq.bits.srcState(0) := staIQEnq.bits.srcState(stdIdx) 41613551487SzhanglyGit stdIQEnq.bits.srcLoadDependency(0) := staIQEnq.bits.srcLoadDependency(1) 4172d270511Ssinsanction stdIQEnq.bits.srcType(0) := staIQEnq.bits.srcType(stdIdx) 4182d270511Ssinsanction stdIQEnq.bits.psrc(0) := staIQEnq.bits.psrc(stdIdx) 419730cfbc0SXuan Hu stdIQEnq.bits.sqIdx := staIQEnq.bits.sqIdx 420730cfbc0SXuan Hu } 421730cfbc0SXuan Hu 4222d270511Ssinsanction vecMemIQs.foreach { 4232d270511Ssinsanction case imp: IssueQueueVecMemImp => 4242d270511Ssinsanction imp.io.memIO.get.sqDeqPtr.foreach(_ := io.fromMem.get.sqDeqPtr) 4252d270511Ssinsanction imp.io.memIO.get.lqDeqPtr.foreach(_ := io.fromMem.get.lqDeqPtr) 4261f3d1b4dSXuan Hu // not used 427ebb914e7Sweiding liu imp.io.memIO.get.feedbackIO.head := io.fromMem.get.vstuFeedback.head // only vector store replay 4281f3d1b4dSXuan Hu // maybe not used 4291f3d1b4dSXuan Hu imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr 4301f3d1b4dSXuan Hu imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 431f39a61a1SzhanglyGit 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} 432f39a61a1SzhanglyGit 4332d270511Ssinsanction case _ => 4342d270511Ssinsanction } 4352d270511Ssinsanction 436730cfbc0SXuan Hu val lsqEnqCtrl = Module(new LsqEnqCtrl) 437730cfbc0SXuan Hu 438730cfbc0SXuan Hu lsqEnqCtrl.io.redirect <> io.fromCtrlBlock.flush 439730cfbc0SXuan Hu lsqEnqCtrl.io.enq <> dispatch2Iq.io.enqLsqIO.get 440730cfbc0SXuan Hu lsqEnqCtrl.io.lcommit := io.fromMem.get.lcommit 441730cfbc0SXuan Hu lsqEnqCtrl.io.scommit := io.fromMem.get.scommit 442730cfbc0SXuan Hu lsqEnqCtrl.io.lqCancelCnt := io.fromMem.get.lqCancelCnt 443730cfbc0SXuan Hu lsqEnqCtrl.io.sqCancelCnt := io.fromMem.get.sqCancelCnt 444f3a9fb05SAnzo dispatch2Iq.io.lqFreeCount.get := lsqEnqCtrl.io.lqFreeCount 445f3a9fb05SAnzo dispatch2Iq.io.sqFreeCount.get := lsqEnqCtrl.io.sqFreeCount 446730cfbc0SXuan Hu io.memIO.get.lsqEnqIO <> lsqEnqCtrl.io.enqLsq 447*7e471bf8SXuan Hu 448*7e471bf8SXuan Hu dontTouch(io.vecLoadIssueResp) 449730cfbc0SXuan Hu} 450