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._ 10*60f0c5aeSxiaofeibaoimport xiangshan.backend.datapath.DataConfig.{IntData, VAddrData, VecData, FpData} 11*60f0c5aeSxiaofeibaoimport xiangshan.backend.datapath.WbConfig.{IntWB, FpWB, 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 20*60f0c5aeSxiaofeibaocase class FpScheduler() extends SchedulerType 21730cfbc0SXuan Hucase class MemScheduler() extends SchedulerType 22730cfbc0SXuan Hucase class VfScheduler() extends SchedulerType 23730cfbc0SXuan Hucase class NoScheduler() extends SchedulerType 24730cfbc0SXuan Hu 25730cfbc0SXuan Huclass Scheduler(val params: SchdBlockParams)(implicit p: Parameters) extends LazyModule with HasXSParameter { 261ca4a39dSXuan Hu override def shouldBeInlined: Boolean = false 271ca4a39dSXuan Hu 2839c59369SXuan Hu val numIntStateWrite = backendParams.numPregWb(IntData()) 29*60f0c5aeSxiaofeibao val numFpStateWrite = backendParams.numPregWb(FpData()) 3039c59369SXuan Hu val numVfStateWrite = backendParams.numPregWb(VecData()) 31730cfbc0SXuan Hu 32730cfbc0SXuan Hu val dispatch2Iq = LazyModule(new Dispatch2Iq(params)) 33730cfbc0SXuan Hu val issueQueue = params.issueBlockParams.map(x => LazyModule(new IssueQueue(x).suggestName(x.getIQName))) 34730cfbc0SXuan Hu 3583ba63b3SXuan Hu lazy val module: SchedulerImpBase = params.schdType match { 36730cfbc0SXuan Hu case IntScheduler() => new SchedulerArithImp(this)(params, p) 37*60f0c5aeSxiaofeibao case FpScheduler() => new SchedulerArithImp(this)(params, p) 38730cfbc0SXuan Hu case MemScheduler() => new SchedulerMemImp(this)(params, p) 39730cfbc0SXuan Hu case VfScheduler() => new SchedulerArithImp(this)(params, p) 40730cfbc0SXuan Hu case _ => null 41730cfbc0SXuan Hu } 42730cfbc0SXuan Hu} 43730cfbc0SXuan Hu 447f8233d5SHaojin Tangclass SchedulerIO()(implicit params: SchdBlockParams, p: Parameters) extends XSBundle { 4568d13085SXuan Hu // params alias 467f8233d5SHaojin Tang private val LoadQueueSize = VirtualLoadQueueSize 4768d13085SXuan Hu 48730cfbc0SXuan Hu val fromTop = new Bundle { 49730cfbc0SXuan Hu val hartId = Input(UInt(8.W)) 50730cfbc0SXuan Hu } 512e0a7dc5Sfdy val fromWbFuBusyTable = new Bundle{ 522e0a7dc5Sfdy val fuBusyTableRead = MixedVec(params.issueBlockParams.map(x => Input(x.genWbFuBusyTableReadBundle))) 532e0a7dc5Sfdy } 54dd970561SzhanglyGit val wbFuBusyTable = MixedVec(params.issueBlockParams.map(x => Output(x.genWbFuBusyTableWriteBundle))) 55c1e19666Sxiaofeibao-xjtu val IQValidNumVec = Output(MixedVec(backendParams.genIQValidNumBundle)) 56dd970561SzhanglyGit 57730cfbc0SXuan Hu val fromCtrlBlock = new Bundle { 58730cfbc0SXuan Hu val flush = Flipped(ValidIO(new Redirect)) 59730cfbc0SXuan Hu } 60730cfbc0SXuan Hu val fromDispatch = new Bundle { 61730cfbc0SXuan Hu val allocPregs = Vec(RenameWidth, Input(new ResetPregStateReq)) 62730cfbc0SXuan Hu val uops = Vec(params.numUopIn, Flipped(DecoupledIO(new DynInst))) 63730cfbc0SXuan Hu } 6439c59369SXuan Hu val intWriteBack = MixedVec(Vec(backendParams.numPregWb(IntData()), 65730cfbc0SXuan Hu new RfWritePortWithConfig(backendParams.intPregParams.dataCfg, backendParams.intPregParams.addrWidth))) 66*60f0c5aeSxiaofeibao val fpWriteBack = MixedVec(Vec(backendParams.numPregWb(FpData()), 67*60f0c5aeSxiaofeibao new RfWritePortWithConfig(backendParams.fpPregParams.dataCfg, backendParams.fpPregParams.addrWidth))) 6839c59369SXuan Hu val vfWriteBack = MixedVec(Vec(backendParams.numPregWb(VecData()), 69730cfbc0SXuan Hu new RfWritePortWithConfig(backendParams.vfPregParams.dataCfg, backendParams.vfPregParams.addrWidth))) 7059ef6009Sxiaofeibao-xjtu val toDataPathAfterDelay: MixedVec[MixedVec[DecoupledIO[IssueQueueIssueBundle]]] = MixedVec(params.issueBlockParams.map(_.genIssueDecoupledBundle)) 71730cfbc0SXuan Hu 72bf35baadSXuan Hu val fromSchedulers = new Bundle { 73c0be7f33SXuan Hu val wakeupVec: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpInValidBundle) 74bf35baadSXuan Hu } 75bf35baadSXuan Hu 76bf35baadSXuan Hu val toSchedulers = new Bundle { 77c0be7f33SXuan Hu val wakeupVec: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = params.genIQWakeUpOutValidBundle 78bf35baadSXuan Hu } 79bf35baadSXuan Hu 80c0be7f33SXuan Hu val fromDataPath = new Bundle { 8110fe9778SXuan Hu val resp: MixedVec[MixedVec[OGRespBundle]] = MixedVec(params.issueBlockParams.map(x => Flipped(x.genOGRespBundle))) 827a96cc7fSHaojin Tang val og0Cancel = Input(ExuOH(backendParams.numExu)) 83ea46c302SXuan Hu // Todo: remove this after no cancel signal from og1 847a96cc7fSHaojin Tang val og1Cancel = Input(ExuOH(backendParams.numExu)) 85bc7d6943SzhanglyGit val cancelToBusyTable = Vec(backendParams.numExu, Flipped(ValidIO(new CancelSignal))) 86c0be7f33SXuan Hu // just be compatible to old code 87c0be7f33SXuan Hu def apply(i: Int)(j: Int) = resp(i)(j) 88c0be7f33SXuan Hu } 89c0be7f33SXuan Hu 908a66c02cSXuan Hu val loadFinalIssueResp = MixedVec(params.issueBlockParams.map(x => MixedVec(Vec(x.LdExuCnt, Flipped(ValidIO(new IssueQueueDeqRespBundle()(p, x))))))) 918a66c02cSXuan Hu val memAddrIssueResp = MixedVec(params.issueBlockParams.map(x => MixedVec(Vec(x.LdExuCnt, Flipped(ValidIO(new IssueQueueDeqRespBundle()(p, x))))))) 920f55a0d3SHaojin Tang 936810d1e8Ssfencevma val ldCancel = Vec(backendParams.LduCnt + backendParams.HyuCnt, Flipped(new LoadCancelIO)) 94c0be7f33SXuan Hu 95730cfbc0SXuan Hu val memIO = if (params.isMemSchd) Some(new Bundle { 96730cfbc0SXuan Hu val lsqEnqIO = Flipped(new LsqEnqIO) 97730cfbc0SXuan Hu }) else None 98730cfbc0SXuan Hu val fromMem = if (params.isMemSchd) Some(new Bundle { 997b753bebSXuan Hu val ldaFeedback = Flipped(Vec(params.LduCnt, new MemRSFeedbackIO)) 1007b753bebSXuan Hu val staFeedback = Flipped(Vec(params.StaCnt, new MemRSFeedbackIO)) 1018f1fa9b1Ssfencevma val hyuFeedback = Flipped(Vec(params.HyuCnt, new MemRSFeedbackIO)) 102730cfbc0SXuan Hu val stIssuePtr = Input(new SqPtr()) 103730cfbc0SXuan Hu val lcommit = Input(UInt(log2Up(CommitWidth + 1).W)) 104730cfbc0SXuan Hu val scommit = Input(UInt(log2Ceil(EnsbufferWidth + 1).W)) // connected to `memBlock.io.sqDeq` instead of ROB 105fc45ed13SXuan Hu val wakeup = Vec(params.LdExuCnt, Flipped(Valid(new DynInst))) 1062d270511Ssinsanction val lqDeqPtr = Input(new LqPtr) 1072d270511Ssinsanction val sqDeqPtr = Input(new SqPtr) 108730cfbc0SXuan Hu // from lsq 109730cfbc0SXuan Hu val lqCancelCnt = Input(UInt(log2Up(LoadQueueSize + 1).W)) 110730cfbc0SXuan Hu val sqCancelCnt = Input(UInt(log2Up(StoreQueueSize + 1).W)) 111730cfbc0SXuan Hu val memWaitUpdateReq = Flipped(new MemWaitUpdateReq) 112730cfbc0SXuan Hu }) else None 113730cfbc0SXuan Hu val toMem = if (params.isMemSchd) Some(new Bundle { 114730cfbc0SXuan Hu val loadFastMatch = Output(Vec(params.LduCnt, new IssueQueueLoadBundle)) 115730cfbc0SXuan Hu }) else None 116c38df446SzhanglyGit val fromOg2 = if(params.isVfSchd) Some(MixedVec(params.issueBlockParams.map(x => Flipped(x.genOG2RespBundle)))) else None 117730cfbc0SXuan Hu} 118730cfbc0SXuan Hu 119730cfbc0SXuan Huabstract class SchedulerImpBase(wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters) 120730cfbc0SXuan Hu extends LazyModuleImp(wrapper) 121730cfbc0SXuan Hu with HasXSParameter 122730cfbc0SXuan Hu{ 123730cfbc0SXuan Hu val io = IO(new SchedulerIO()) 124730cfbc0SXuan Hu 125730cfbc0SXuan Hu // alias 126c0be7f33SXuan Hu private val iqWakeUpInMap: Map[Int, ValidIO[IssueQueueIQWakeUpBundle]] = 127c0be7f33SXuan Hu io.fromSchedulers.wakeupVec.map(x => (x.bits.exuIdx, x)).toMap 128730cfbc0SXuan Hu private val schdType = params.schdType 129730cfbc0SXuan Hu 130730cfbc0SXuan Hu // Modules 131730cfbc0SXuan Hu val dispatch2Iq: Dispatch2IqImp = wrapper.dispatch2Iq.module 132730cfbc0SXuan Hu val issueQueues: Seq[IssueQueueImp] = wrapper.issueQueue.map(_.module) 133ff3fcdf1Sxiaofeibao-xjtu if (params.isIntSchd) { 134ff3fcdf1Sxiaofeibao-xjtu dispatch2Iq.io.IQValidNumVec.get := io.IQValidNumVec 135c1e19666Sxiaofeibao-xjtu io.IQValidNumVec := MixedVecInit(issueQueues.map(_.io.validCntDeqVec)) 136ff3fcdf1Sxiaofeibao-xjtu } 137ff3fcdf1Sxiaofeibao-xjtu else io.IQValidNumVec := 0.U.asTypeOf(io.IQValidNumVec) 138730cfbc0SXuan Hu 13956bcaed7SHaojin Tang // valid count 14056bcaed7SHaojin Tang dispatch2Iq.io.iqValidCnt := issueQueues.filter(_.params.StdCnt == 0).map(_.io.status.validCnt) 14156bcaed7SHaojin Tang 142730cfbc0SXuan Hu // BusyTable Modules 143730cfbc0SXuan Hu val intBusyTable = schdType match { 144bc7d6943SzhanglyGit case IntScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numIntStateRead, wrapper.numIntStateWrite, IntPhyRegs, IntWB()))) 145730cfbc0SXuan Hu case _ => None 146730cfbc0SXuan Hu } 147*60f0c5aeSxiaofeibao val fpBusyTable = schdType match { 148*60f0c5aeSxiaofeibao case FpScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numFpStateRead, wrapper.numFpStateWrite, FpPhyRegs, FpWB()))) 149*60f0c5aeSxiaofeibao case _ => None 150*60f0c5aeSxiaofeibao } 151730cfbc0SXuan Hu val vfBusyTable = schdType match { 152bc7d6943SzhanglyGit case VfScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numVfStateRead, wrapper.numVfStateWrite, VfPhyRegs, VfWB()))) 153730cfbc0SXuan Hu case _ => None 154730cfbc0SXuan Hu } 155730cfbc0SXuan Hu 156730cfbc0SXuan Hu dispatch2Iq.io match { case dp2iq => 157730cfbc0SXuan Hu dp2iq.redirect <> io.fromCtrlBlock.flush 158730cfbc0SXuan Hu dp2iq.in <> io.fromDispatch.uops 159730cfbc0SXuan Hu dp2iq.readIntState.foreach(_ <> intBusyTable.get.io.read) 160*60f0c5aeSxiaofeibao dp2iq.readFpState.foreach(_ <> fpBusyTable.get.io.read) 161730cfbc0SXuan Hu dp2iq.readVfState.foreach(_ <> vfBusyTable.get.io.read) 162730cfbc0SXuan Hu } 163730cfbc0SXuan Hu 164730cfbc0SXuan Hu intBusyTable match { 165730cfbc0SXuan Hu case Some(bt) => 166730cfbc0SXuan Hu bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) => 167730cfbc0SXuan Hu btAllocPregs.valid := dpAllocPregs.isInt 168730cfbc0SXuan Hu btAllocPregs.bits := dpAllocPregs.preg 169730cfbc0SXuan Hu } 170730cfbc0SXuan Hu bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) => 171730cfbc0SXuan Hu wb.valid := io.intWriteBack(i).wen && io.intWriteBack(i).intWen 172730cfbc0SXuan Hu wb.bits := io.intWriteBack(i).addr 173730cfbc0SXuan Hu } 174bc7d6943SzhanglyGit bt.io.wakeUp := io.fromSchedulers.wakeupVec 175bc7d6943SzhanglyGit bt.io.cancel := io.fromDataPath.cancelToBusyTable 17613551487SzhanglyGit bt.io.ldCancel := io.ldCancel 177730cfbc0SXuan Hu case None => 178730cfbc0SXuan Hu } 179730cfbc0SXuan Hu 180*60f0c5aeSxiaofeibao fpBusyTable match { 181730cfbc0SXuan Hu case Some(bt) => 182730cfbc0SXuan Hu bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) => 183730cfbc0SXuan Hu btAllocPregs.valid := dpAllocPregs.isFp 184730cfbc0SXuan Hu btAllocPregs.bits := dpAllocPregs.preg 185730cfbc0SXuan Hu } 186730cfbc0SXuan Hu bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) => 187*60f0c5aeSxiaofeibao wb.valid := io.fpWriteBack(i).wen && io.fpWriteBack(i).fpWen 188*60f0c5aeSxiaofeibao wb.bits := io.fpWriteBack(i).addr 189*60f0c5aeSxiaofeibao } 190*60f0c5aeSxiaofeibao bt.io.wakeUp := io.fromSchedulers.wakeupVec 191*60f0c5aeSxiaofeibao bt.io.cancel := io.fromDataPath.cancelToBusyTable 192*60f0c5aeSxiaofeibao bt.io.ldCancel := io.ldCancel 193*60f0c5aeSxiaofeibao case None => 194*60f0c5aeSxiaofeibao } 195*60f0c5aeSxiaofeibao 196*60f0c5aeSxiaofeibao vfBusyTable match { 197*60f0c5aeSxiaofeibao case Some(bt) => 198*60f0c5aeSxiaofeibao bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) => 199*60f0c5aeSxiaofeibao btAllocPregs.valid := dpAllocPregs.isVec 200*60f0c5aeSxiaofeibao btAllocPregs.bits := dpAllocPregs.preg 201*60f0c5aeSxiaofeibao } 202*60f0c5aeSxiaofeibao bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) => 203*60f0c5aeSxiaofeibao wb.valid := io.vfWriteBack(i).wen && io.vfWriteBack(i).vecWen 204730cfbc0SXuan Hu wb.bits := io.vfWriteBack(i).addr 205730cfbc0SXuan Hu } 206bc7d6943SzhanglyGit bt.io.wakeUp := io.fromSchedulers.wakeupVec 207bc7d6943SzhanglyGit bt.io.cancel := io.fromDataPath.cancelToBusyTable 20813551487SzhanglyGit bt.io.ldCancel := io.ldCancel 209730cfbc0SXuan Hu case None => 210730cfbc0SXuan Hu } 211730cfbc0SXuan Hu 212f39a61a1SzhanglyGit val wakeupFromIntWBVec = Wire(params.genIntWBWakeUpSinkValidBundle) 213*60f0c5aeSxiaofeibao val wakeupFromFpWBVec = Wire(params.genFpWBWakeUpSinkValidBundle) 214f39a61a1SzhanglyGit val wakeupFromVfWBVec = Wire(params.genVfWBWakeUpSinkValidBundle) 215f39a61a1SzhanglyGit 216f39a61a1SzhanglyGit wakeupFromIntWBVec.zip(io.intWriteBack).foreach { case (sink, source) => 217f39a61a1SzhanglyGit sink.valid := source.wen 218f39a61a1SzhanglyGit sink.bits.rfWen := source.intWen 219f39a61a1SzhanglyGit sink.bits.fpWen := source.fpWen 220f39a61a1SzhanglyGit sink.bits.vecWen := source.vecWen 221f39a61a1SzhanglyGit sink.bits.pdest := source.addr 222730cfbc0SXuan Hu } 223f39a61a1SzhanglyGit 224*60f0c5aeSxiaofeibao wakeupFromFpWBVec.zip(io.fpWriteBack).foreach { case (sink, source) => 225*60f0c5aeSxiaofeibao sink.valid := source.wen 226*60f0c5aeSxiaofeibao sink.bits.rfWen := source.intWen 227*60f0c5aeSxiaofeibao sink.bits.fpWen := source.fpWen 228*60f0c5aeSxiaofeibao sink.bits.vecWen := source.vecWen 229*60f0c5aeSxiaofeibao sink.bits.pdest := source.addr 230*60f0c5aeSxiaofeibao } 231*60f0c5aeSxiaofeibao 232f39a61a1SzhanglyGit wakeupFromVfWBVec.zip(io.vfWriteBack).foreach { case (sink, source) => 233730cfbc0SXuan Hu sink.valid := source.wen 234730cfbc0SXuan Hu sink.bits.rfWen := source.intWen 235730cfbc0SXuan Hu sink.bits.fpWen := source.fpWen 236730cfbc0SXuan Hu sink.bits.vecWen := source.vecWen 237730cfbc0SXuan Hu sink.bits.pdest := source.addr 238730cfbc0SXuan Hu } 239730cfbc0SXuan Hu 240bf35baadSXuan Hu // Connect bundles having the same wakeup source 24159ef6009Sxiaofeibao-xjtu issueQueues.zipWithIndex.foreach { case(iq, i) => 242bf35baadSXuan Hu iq.io.wakeupFromIQ.foreach { wakeUp => 2430c7ebb58Sxiaofeibao-xjtu val wakeUpIn = iqWakeUpInMap(wakeUp.bits.exuIdx) 2440c7ebb58Sxiaofeibao-xjtu val exuIdx = wakeUp.bits.exuIdx 2450c7ebb58Sxiaofeibao-xjtu println(s"[Backend] Connect wakeup exuIdx ${exuIdx}") 2460c7ebb58Sxiaofeibao-xjtu connectSamePort(wakeUp,wakeUpIn) 2470c7ebb58Sxiaofeibao-xjtu backendParams.connectWakeup(exuIdx) 2480c7ebb58Sxiaofeibao-xjtu if (backendParams.isCopyPdest(exuIdx)) { 2490c7ebb58Sxiaofeibao-xjtu println(s"[Backend] exuIdx ${exuIdx} use pdestCopy ${backendParams.getCopyPdestIndex(exuIdx)}") 2500c7ebb58Sxiaofeibao-xjtu wakeUp.bits.pdest := wakeUpIn.bits.pdestCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2514c5a0d77Sxiaofeibao-xjtu if (wakeUpIn.bits.rfWenCopy.nonEmpty) wakeUp.bits.rfWen := wakeUpIn.bits.rfWenCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2524c5a0d77Sxiaofeibao-xjtu if (wakeUpIn.bits.fpWenCopy.nonEmpty) wakeUp.bits.fpWen := wakeUpIn.bits.fpWenCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2534c5a0d77Sxiaofeibao-xjtu if (wakeUpIn.bits.vecWenCopy.nonEmpty) wakeUp.bits.vecWen := wakeUpIn.bits.vecWenCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2544c5a0d77Sxiaofeibao-xjtu if (wakeUpIn.bits.loadDependencyCopy.nonEmpty) wakeUp.bits.loadDependency := wakeUpIn.bits.loadDependencyCopy.get(backendParams.getCopyPdestIndex(exuIdx)) 2550c7ebb58Sxiaofeibao-xjtu } 25660912d84Sxiaofeibao-xjtu if (iq.params.numIntSrc == 0) wakeUp.bits.rfWen := false.B 257*60f0c5aeSxiaofeibao if (iq.params.numFpSrc == 0) wakeUp.bits.fpWen := false.B 25860912d84Sxiaofeibao-xjtu if (iq.params.numVfSrc == 0) wakeUp.bits.vecWen := false.B 259bf35baadSXuan Hu } 260ea46c302SXuan Hu iq.io.og0Cancel := io.fromDataPath.og0Cancel 261ea46c302SXuan Hu iq.io.og1Cancel := io.fromDataPath.og1Cancel 2620f55a0d3SHaojin Tang iq.io.ldCancel := io.ldCancel 263bf35baadSXuan Hu } 264bf35baadSXuan Hu 265c0be7f33SXuan Hu private val iqWakeUpOutMap: Map[Int, ValidIO[IssueQueueIQWakeUpBundle]] = 266bf35baadSXuan Hu issueQueues.flatMap(_.io.wakeupToIQ) 267c0be7f33SXuan Hu .map(x => (x.bits.exuIdx, x)) 268bf35baadSXuan Hu .toMap 269bf35baadSXuan Hu 270bf35baadSXuan Hu // Connect bundles having the same wakeup source 271bf35baadSXuan Hu io.toSchedulers.wakeupVec.foreach { wakeUp => 272c0be7f33SXuan Hu wakeUp := iqWakeUpOutMap(wakeUp.bits.exuIdx) 273bf35baadSXuan Hu } 274bf35baadSXuan Hu 27559ef6009Sxiaofeibao-xjtu io.toDataPathAfterDelay.zipWithIndex.foreach { case (toDpDy, i) => 27659ef6009Sxiaofeibao-xjtu toDpDy <> issueQueues(i).io.deqDelay 27759ef6009Sxiaofeibao-xjtu } 278bf35baadSXuan Hu 279f99b81adSHaojin Tang // Response 280f99b81adSHaojin Tang issueQueues.zipWithIndex.foreach { case (iq, i) => 281f99b81adSHaojin Tang iq.io.og0Resp.zipWithIndex.foreach { case (og0Resp, j) => 282f99b81adSHaojin Tang og0Resp := io.fromDataPath(i)(j).og0resp 283f99b81adSHaojin Tang } 284f99b81adSHaojin Tang iq.io.og1Resp.zipWithIndex.foreach { case (og1Resp, j) => 285f99b81adSHaojin Tang og1Resp := io.fromDataPath(i)(j).og1resp 286f99b81adSHaojin Tang } 287f99b81adSHaojin Tang iq.io.finalIssueResp.foreach(_.zipWithIndex.foreach { case (finalIssueResp, j) => 288670870b3SXuan Hu if (io.loadFinalIssueResp(i).isDefinedAt(j)) { 289f99b81adSHaojin Tang finalIssueResp := io.loadFinalIssueResp(i)(j) 290670870b3SXuan Hu } else { 291670870b3SXuan Hu finalIssueResp := 0.U.asTypeOf(finalIssueResp) 292670870b3SXuan Hu } 293f99b81adSHaojin Tang }) 294e8800897SXuan Hu iq.io.memAddrIssueResp.foreach(_.zipWithIndex.foreach { case (memAddrIssueResp, j) => 295aa2bcc31SzhanglyGit if (io.memAddrIssueResp(i).isDefinedAt(j)) { 296e8800897SXuan Hu memAddrIssueResp := io.memAddrIssueResp(i)(j) 297aa2bcc31SzhanglyGit } else { 298aa2bcc31SzhanglyGit memAddrIssueResp := 0.U.asTypeOf(memAddrIssueResp) 299aa2bcc31SzhanglyGit } 300e8800897SXuan Hu }) 301c38df446SzhanglyGit if(params.isVfSchd) { 302c38df446SzhanglyGit iq.io.og2Resp.get.zipWithIndex.foreach { case (og2Resp, exuIdx) => 303c38df446SzhanglyGit og2Resp := io.fromOg2.get(i)(exuIdx) 304c38df446SzhanglyGit } 305c38df446SzhanglyGit } 306f99b81adSHaojin Tang iq.io.wbBusyTableRead := io.fromWbFuBusyTable.fuBusyTableRead(i) 307f99b81adSHaojin Tang io.wbFuBusyTable(i) := iq.io.wbBusyTableWrite 308f99b81adSHaojin Tang } 309f99b81adSHaojin Tang 310c0be7f33SXuan Hu println(s"[Scheduler] io.fromSchedulers.wakeupVec: ${io.fromSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}") 311bf35baadSXuan Hu println(s"[Scheduler] iqWakeUpInKeys: ${iqWakeUpInMap.keys}") 312bf35baadSXuan Hu 313bf35baadSXuan Hu println(s"[Scheduler] iqWakeUpOutKeys: ${iqWakeUpOutMap.keys}") 314c0be7f33SXuan Hu println(s"[Scheduler] io.toSchedulers.wakeupVec: ${io.toSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}") 315730cfbc0SXuan Hu} 316730cfbc0SXuan Hu 317730cfbc0SXuan Huclass SchedulerArithImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters) 318730cfbc0SXuan Hu extends SchedulerImpBase(wrapper) 319730cfbc0SXuan Hu with HasXSParameter 320730cfbc0SXuan Hu{ 3212e0a7dc5Sfdy// dontTouch(io.vfWbFuBusyTable) 322730cfbc0SXuan Hu println(s"[SchedulerArithImp] " + 323730cfbc0SXuan Hu s"has intBusyTable: ${intBusyTable.nonEmpty}, " + 324730cfbc0SXuan Hu s"has vfBusyTable: ${vfBusyTable.nonEmpty}") 325730cfbc0SXuan Hu 326730cfbc0SXuan Hu issueQueues.zipWithIndex.foreach { case (iq, i) => 327730cfbc0SXuan Hu iq.io.flush <> io.fromCtrlBlock.flush 328730cfbc0SXuan Hu iq.io.enq <> dispatch2Iq.io.out(i) 329f39a61a1SzhanglyGit val intWBIQ = params.schdType match { 330f39a61a1SzhanglyGit case IntScheduler() => wakeupFromIntWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1) 331*60f0c5aeSxiaofeibao case FpScheduler() => wakeupFromFpWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromFpWBPort.keys.toSeq.contains(x._2)).map(_._1) 332b8475955SzhanglyGit case VfScheduler() => wakeupFromVfWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromVfWBPort.keys.toSeq.contains(x._2)).map(_._1) 333596af5d2SHaojin Tang case _ => null 334f39a61a1SzhanglyGit } 335f39a61a1SzhanglyGit iq.io.wakeupFromWB.zip(intWBIQ).foreach{ case (sink, source) => sink := source} 336730cfbc0SXuan Hu } 337730cfbc0SXuan Hu} 338730cfbc0SXuan Hu 339f99b81adSHaojin Tang// FIXME: Vector mem instructions may not be handled properly! 340730cfbc0SXuan Huclass SchedulerMemImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters) 341730cfbc0SXuan Hu extends SchedulerImpBase(wrapper) 342730cfbc0SXuan Hu with HasXSParameter 343730cfbc0SXuan Hu{ 344730cfbc0SXuan Hu println(s"[SchedulerMemImp] " + 345730cfbc0SXuan Hu s"has intBusyTable: ${intBusyTable.nonEmpty}, " + 346730cfbc0SXuan Hu s"has vfBusyTable: ${vfBusyTable.nonEmpty}") 347730cfbc0SXuan Hu 348559c1710SHaojin Tang val memAddrIQs = issueQueues.filter(_.params.isMemAddrIQ) 349e07131b2Ssinsanction val stAddrIQs = issueQueues.filter(iq => iq.params.StaCnt > 0) // included in memAddrIQs 350e07131b2Ssinsanction val ldAddrIQs = issueQueues.filter(iq => iq.params.LduCnt > 0) 351e07131b2Ssinsanction val stDataIQs = issueQueues.filter(iq => iq.params.StdCnt > 0) 352559c1710SHaojin Tang val vecMemIQs = issueQueues.filter(_.params.isVecMemIQ) 353559c1710SHaojin Tang val (hyuIQs, hyuIQIdxs) = issueQueues.zipWithIndex.filter(_._1.params.HyuCnt > 0).unzip 354499caf4cSXuan Hu 355499caf4cSXuan Hu println(s"[SchedulerMemImp] memAddrIQs.size: ${memAddrIQs.size}, enq.size: ${memAddrIQs.map(_.io.enq.size).sum}") 356499caf4cSXuan Hu println(s"[SchedulerMemImp] stAddrIQs.size: ${stAddrIQs.size }, enq.size: ${stAddrIQs.map(_.io.enq.size).sum}") 357499caf4cSXuan Hu println(s"[SchedulerMemImp] ldAddrIQs.size: ${ldAddrIQs.size }, enq.size: ${ldAddrIQs.map(_.io.enq.size).sum}") 358499caf4cSXuan Hu println(s"[SchedulerMemImp] stDataIQs.size: ${stDataIQs.size }, enq.size: ${stDataIQs.map(_.io.enq.size).sum}") 359499caf4cSXuan Hu println(s"[SchedulerMemImp] hyuIQs.size: ${hyuIQs.size }, enq.size: ${hyuIQs.map(_.io.enq.size).sum}") 360730cfbc0SXuan Hu require(memAddrIQs.nonEmpty && stDataIQs.nonEmpty) 361730cfbc0SXuan Hu 362853cd2d8SHaojin Tang io.toMem.get.loadFastMatch := 0.U.asTypeOf(io.toMem.get.loadFastMatch) // TODO: is still needed? 363853cd2d8SHaojin Tang 364fc45ed13SXuan Hu private val loadWakeUp = issueQueues.filter(_.params.LdExuCnt > 0).map(_.asInstanceOf[IssueQueueMemAddrImp].io.memIO.get.loadWakeUp).flatten 365596af5d2SHaojin Tang require(loadWakeUp.length == io.fromMem.get.wakeup.length) 366596af5d2SHaojin Tang loadWakeUp.zip(io.fromMem.get.wakeup).foreach(x => x._1 := x._2) 367596af5d2SHaojin Tang 368730cfbc0SXuan Hu memAddrIQs.zipWithIndex.foreach { case (iq, i) => 369730cfbc0SXuan Hu iq.io.flush <> io.fromCtrlBlock.flush 370730cfbc0SXuan Hu iq.io.enq <> dispatch2Iq.io.out(i) 371*60f0c5aeSxiaofeibao iq.io.wakeupFromWB.zip( 372*60f0c5aeSxiaofeibao wakeupFromIntWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1) ++ 373*60f0c5aeSxiaofeibao wakeupFromFpWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromFpWBPort.keys.toSeq.contains(x._2)).map(_._1) ++ 374*60f0c5aeSxiaofeibao wakeupFromVfWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromVfWBPort.keys.toSeq.contains(x._2)).map(_._1) 375*60f0c5aeSxiaofeibao ).foreach{ case (sink, source) => sink := source} 376730cfbc0SXuan Hu } 377730cfbc0SXuan Hu 378ecfc6f16SXuan Hu ldAddrIQs.zipWithIndex.foreach { 379ecfc6f16SXuan Hu case (imp: IssueQueueMemAddrImp, i) => 380ecfc6f16SXuan Hu imp.io.memIO.get.feedbackIO.head := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO.head) 381c14e89f4SHaojin Tang imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr 382de784418SXuan Hu imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 3837b753bebSXuan Hu case _ => 3847b753bebSXuan Hu } 3857b753bebSXuan Hu 386ecfc6f16SXuan Hu stAddrIQs.zipWithIndex.foreach { 387ecfc6f16SXuan Hu case (imp: IssueQueueMemAddrImp, i) => 388ecfc6f16SXuan Hu imp.io.memIO.get.feedbackIO.head := io.fromMem.get.staFeedback(i) 389c14e89f4SHaojin Tang imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr 390c14e89f4SHaojin Tang imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 3917b753bebSXuan Hu case _ => 3927b753bebSXuan Hu } 393730cfbc0SXuan Hu 394559c1710SHaojin Tang hyuIQs.zip(hyuIQIdxs).foreach { 395559c1710SHaojin Tang case (imp: IssueQueueMemAddrImp, idx) => 396670870b3SXuan Hu imp.io.memIO.get.feedbackIO.head := io.fromMem.get.hyuFeedback.head 397670870b3SXuan Hu imp.io.memIO.get.feedbackIO(1) := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO(1)) 3988f1fa9b1Ssfencevma imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr 3998f1fa9b1Ssfencevma imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 400559c1710SHaojin Tang // TODO: refactor ditry code 401559c1710SHaojin Tang imp.io.deqDelay(1).ready := false.B 402559c1710SHaojin Tang io.toDataPathAfterDelay(idx)(1).valid := false.B 403559c1710SHaojin Tang io.toDataPathAfterDelay(idx)(1).bits := 0.U.asTypeOf(io.toDataPathAfterDelay(idx)(1).bits) 4048f1fa9b1Ssfencevma case _ => 4058f1fa9b1Ssfencevma } 4068f1fa9b1Ssfencevma 407e62b6911SXuan Hu private val staIdxSeq = (stAddrIQs).map(iq => iq.params.idxInSchBlk) 408e62b6911SXuan Hu private val hyaIdxSeq = (hyuIQs).map(iq => iq.params.idxInSchBlk) 409e62b6911SXuan Hu 410e62b6911SXuan Hu println(s"[SchedulerMemImp] sta iq idx in memSchdBlock: $staIdxSeq") 411e62b6911SXuan Hu println(s"[SchedulerMemImp] hya iq idx in memSchdBlock: $hyaIdxSeq") 412e62b6911SXuan Hu 413e62b6911SXuan Hu private val staEnqs = stAddrIQs.map(_.io.enq).flatten 414e62b6911SXuan Hu private val stdEnqs = stDataIQs.map(_.io.enq).flatten.take(staEnqs.size) 415e62b6911SXuan Hu private val hyaEnqs = hyuIQs.map(_.io.enq).flatten 416e62b6911SXuan Hu private val hydEnqs = stDataIQs.map(_.io.enq).flatten.drop(staEnqs.size) 417e62b6911SXuan Hu 418e62b6911SXuan Hu require(staEnqs.size == stdEnqs.size, s"number of enq ports of store address IQs(${staEnqs.size}) " + 419e62b6911SXuan Hu s"should be equal to number of enq ports of store data IQs(${stdEnqs.size})") 420e62b6911SXuan Hu 421e62b6911SXuan Hu require(hyaEnqs.size == hydEnqs.size, s"number of enq ports of hybrid address IQs(${hyaEnqs.size}) " + 422e62b6911SXuan Hu s"should be equal to number of enq ports of hybrid data IQs(${hydEnqs.size})") 4239b258a00Sxgkiri 4240438e8f4SHaojin Tang val d2IqStaOut = dispatch2Iq.io.out.zipWithIndex.filter(staIdxSeq contains _._2).unzip._1.flatten 4250438e8f4SHaojin Tang d2IqStaOut.zip(staEnqs).zip(stdEnqs).foreach{ case((dp, staIQ), stdIQ) => 426730cfbc0SXuan Hu val isAllReady = staIQ.ready && stdIQ.ready 427e62b6911SXuan Hu dp.ready := isAllReady 428e62b6911SXuan Hu staIQ.valid := dp.valid && isAllReady 4290438e8f4SHaojin Tang stdIQ.valid := dp.valid && isAllReady && FuType.FuTypeOrR(dp.bits.fuType, FuType.stu, FuType.mou) 4309b258a00Sxgkiri } 431730cfbc0SXuan Hu 4320438e8f4SHaojin Tang val d2IqHyaOut = dispatch2Iq.io.out.zipWithIndex.filter(hyaIdxSeq contains _._2).unzip._1.flatten 4330438e8f4SHaojin Tang d2IqHyaOut.zip(hyaEnqs).zip(hydEnqs).foreach{ case((dp, hyaIQ), hydIQ) => 434e62b6911SXuan Hu val isAllReady = hyaIQ.ready && hydIQ.ready 435e62b6911SXuan Hu dp.ready := isAllReady 436e62b6911SXuan Hu hyaIQ.valid := dp.valid && isAllReady 43756bceacbSHaojin Tang hydIQ.valid := dp.valid && isAllReady && FuType.FuTypeOrR(dp.bits.fuType, FuType.stu, FuType.mou) 438e62b6911SXuan Hu } 439730cfbc0SXuan Hu 440e62b6911SXuan Hu stDataIQs.zipWithIndex.foreach { case (iq, i) => 441e62b6911SXuan Hu iq.io.flush <> io.fromCtrlBlock.flush 442*60f0c5aeSxiaofeibao iq.io.wakeupFromWB.zip( 443*60f0c5aeSxiaofeibao wakeupFromIntWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq ++ 444*60f0c5aeSxiaofeibao wakeupFromFpWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromFpWBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq ++ 445*60f0c5aeSxiaofeibao wakeupFromVfWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromVfWBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq 446*60f0c5aeSxiaofeibao ).foreach{ case (sink, source) => sink := source} 447e62b6911SXuan Hu } 448e62b6911SXuan Hu 449e62b6911SXuan Hu (stdEnqs ++ hydEnqs).zip(staEnqs ++ hyaEnqs).zipWithIndex.foreach { case ((stdIQEnq, staIQEnq), i) => 450730cfbc0SXuan Hu stdIQEnq.bits := staIQEnq.bits 451730cfbc0SXuan Hu // Store data reuses store addr src(1) in dispatch2iq 452e62b6911SXuan Hu // [dispatch2iq] --src*------src*(0)--> [staIQ|hyaIQ] 453730cfbc0SXuan Hu // \ 454730cfbc0SXuan Hu // ---src*(1)--> [stdIQ] 455730cfbc0SXuan Hu // Since the src(1) of sta is easier to get, stdIQEnq.bits.src*(0) is assigned to staIQEnq.bits.src*(1) 456730cfbc0SXuan Hu // instead of dispatch2Iq.io.out(x).bits.src*(1) 45797b279b9SXuan Hu val stdIdx = 1 4582d270511Ssinsanction stdIQEnq.bits.srcState(0) := staIQEnq.bits.srcState(stdIdx) 45913551487SzhanglyGit stdIQEnq.bits.srcLoadDependency(0) := staIQEnq.bits.srcLoadDependency(1) 4602d270511Ssinsanction stdIQEnq.bits.srcType(0) := staIQEnq.bits.srcType(stdIdx) 4612d270511Ssinsanction stdIQEnq.bits.psrc(0) := staIQEnq.bits.psrc(stdIdx) 462730cfbc0SXuan Hu stdIQEnq.bits.sqIdx := staIQEnq.bits.sqIdx 463730cfbc0SXuan Hu } 464730cfbc0SXuan Hu 4652d270511Ssinsanction vecMemIQs.foreach { 4662d270511Ssinsanction case imp: IssueQueueVecMemImp => 4672d270511Ssinsanction imp.io.memIO.get.sqDeqPtr.foreach(_ := io.fromMem.get.sqDeqPtr) 4682d270511Ssinsanction imp.io.memIO.get.lqDeqPtr.foreach(_ := io.fromMem.get.lqDeqPtr) 4691f3d1b4dSXuan Hu // not used 4701f3d1b4dSXuan Hu imp.io.memIO.get.feedbackIO := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO) 4711f3d1b4dSXuan Hu // maybe not used 4721f3d1b4dSXuan Hu imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr 4731f3d1b4dSXuan Hu imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq 474*60f0c5aeSxiaofeibao imp.io.wakeupFromWB.zip( 475*60f0c5aeSxiaofeibao wakeupFromIntWBVec.zipWithIndex.filter(x => imp.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq ++ 476*60f0c5aeSxiaofeibao wakeupFromFpWBVec.zipWithIndex.filter(x => imp.params.needWakeupFromFpWBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq ++ 477*60f0c5aeSxiaofeibao wakeupFromVfWBVec.zipWithIndex.filter(x => imp.params.needWakeupFromVfWBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq 478*60f0c5aeSxiaofeibao ).foreach{ case (sink, source) => sink := source} 479f39a61a1SzhanglyGit 4802d270511Ssinsanction case _ => 4812d270511Ssinsanction } 4822d270511Ssinsanction 483730cfbc0SXuan Hu val lsqEnqCtrl = Module(new LsqEnqCtrl) 484730cfbc0SXuan Hu 485730cfbc0SXuan Hu lsqEnqCtrl.io.redirect <> io.fromCtrlBlock.flush 486730cfbc0SXuan Hu lsqEnqCtrl.io.enq <> dispatch2Iq.io.enqLsqIO.get 487730cfbc0SXuan Hu lsqEnqCtrl.io.lcommit := io.fromMem.get.lcommit 488730cfbc0SXuan Hu lsqEnqCtrl.io.scommit := io.fromMem.get.scommit 489730cfbc0SXuan Hu lsqEnqCtrl.io.lqCancelCnt := io.fromMem.get.lqCancelCnt 490730cfbc0SXuan Hu lsqEnqCtrl.io.sqCancelCnt := io.fromMem.get.sqCancelCnt 491730cfbc0SXuan Hu io.memIO.get.lsqEnqIO <> lsqEnqCtrl.io.enqLsq 492730cfbc0SXuan Hu} 493