1package xiangshan.backend.issue 2 3import org.chipsalliance.cde.config.Parameters 4import chisel3._ 5import chisel3.util._ 6import utility.{HasCircularQueuePtrHelper, GatedValidRegNext} 7import utils.{MathUtils, OptionWrapper} 8import xiangshan._ 9import xiangshan.backend.Bundles._ 10import xiangshan.backend.fu.FuType 11import xiangshan.backend.datapath.DataSource 12import xiangshan.backend.rob.RobPtr 13import xiangshan.backend.issue.EntryBundles._ 14import xiangshan.mem.{MemWaitUpdateReq, SqPtr, LqPtr} 15 16 17class EnqEntryIO(implicit p: Parameters, params: IssueBlockParams) extends XSBundle { 18 //input 19 val commonIn = new CommonInBundle 20 val enqDelayIn1 = new EnqDelayInBundle 21 val enqDelayIn2 = new EnqDelayInBundle 22 23 //output 24 val commonOut = new CommonOutBundle 25 26 def wakeup = commonIn.wakeUpFromWB ++ commonIn.wakeUpFromIQ 27} 28 29class EnqEntry(isComp: Boolean)(implicit p: Parameters, params: IssueBlockParams) extends XSModule { 30 val io = IO(new EnqEntryIO) 31 32 val common = Wire(new CommonWireBundle) 33 val entryUpdate = Wire(new EntryBundle) 34 val entryRegNext = Wire(new EntryBundle) 35 val enqDelayValidRegNext= Wire(Bool()) 36 val hasWakeupIQ = OptionWrapper(params.hasIQWakeUp, Wire(new CommonIQWakeupBundle)) 37 38 val currentStatus = Wire(new Status()) 39 val enqDelaySrcState = Wire(Vec(params.numRegSrc, SrcState())) 40 val enqDelayDataSources = Wire(Vec(params.numRegSrc, DataSource())) 41 val enqDelaySrcWakeUpL1ExuOH = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, ExuOH()))) 42 val enqDelaySrcLoadDependency = Wire(Vec(params.numRegSrc, Vec(LoadPipelineWidth, UInt(3.W)))) 43 44 //Reg 45 val validReg = GatedValidRegNext(common.validRegNext, false.B) 46 val entryReg = RegEnable(entryRegNext, validReg || common.validRegNext) 47 val enqDelayValidReg = GatedValidRegNext(enqDelayValidRegNext, false.B) 48 49 //Wire 50 CommonWireConnect(common, hasWakeupIQ, validReg, currentStatus, io.commonIn, true) 51 52 when(io.commonIn.enq.valid) { 53 assert(common.enqReady, "Entry is not ready when enq is valid\n") 54 } 55 56 when(io.commonIn.enq.valid && common.enqReady) { 57 entryRegNext := io.commonIn.enq.bits 58 }.otherwise { 59 entryRegNext := entryUpdate 60 } 61 62 when(io.commonIn.enq.valid && common.enqReady) { 63 enqDelayValidRegNext := true.B 64 }.otherwise { 65 enqDelayValidRegNext := false.B 66 } 67 68 if (params.hasIQWakeUp) { 69 ShiftLoadDependency(hasWakeupIQ.get) 70 CommonIQWakeupConnect(common, hasWakeupIQ.get, validReg, currentStatus, io.commonIn, true) 71 } 72 73 // enq delay wakeup 74 val enqDelayOut1 = Wire(new EnqDelayOutBundle) 75 val enqDelayOut2 = Wire(new EnqDelayOutBundle) 76 EnqDelayWakeupConnect(io.enqDelayIn1, enqDelayOut1, entryReg.status, delay = 1) 77 EnqDelayWakeupConnect(io.enqDelayIn2, enqDelayOut2, entryReg.status, delay = 2) 78 79 for (i <- 0 until params.numRegSrc) { 80 if (params.inVfSchd && params.readVfRf && params.hasIQWakeUp) { 81 val enqDelay1WakeUpValid = enqDelayOut1.srcWakeUpByIQVec(i).asUInt.orR 82 val enqDelay1WakeUpOH = enqDelayOut1.srcWakeUpByIQVec(i) 83 val enqDelay2WakeUpOH = enqDelayOut2.srcWakeUpByIQVec(i) 84 val enqDelay1IsWakeupByMemIQ = enqDelay1WakeUpOH.zip(io.commonIn.wakeUpFromIQ).filter(_._2.bits.params.isMemExeUnit).map(_._1).fold(false.B)(_ || _) 85 val enqDelay2IsWakeupByMemIQ = enqDelay2WakeUpOH.zip(io.commonIn.wakeUpFromIQ).filter(_._2.bits.params.isMemExeUnit).map(_._1).fold(false.B)(_ || _) 86 87 enqDelayDataSources(i).value := Mux(enqDelayOut1.srcWakeUpByIQ(i).asBool, 88 if (params.hasWakeupFromMem) Mux(enqDelay1IsWakeupByMemIQ, DataSource.bypass2, DataSource.bypass) else DataSource.bypass, 89 Mux(enqDelayOut2.srcWakeUpByIQ(i).asBool, 90 if (params.hasWakeupFromMem) Mux(enqDelay2IsWakeupByMemIQ, DataSource.reg, DataSource.bypass2) else DataSource.bypass2, 91 entryReg.status.srcStatus(i).dataSources.value)) 92 enqDelaySrcWakeUpL1ExuOH.get(i) := Mux(enqDelay1WakeUpValid, 93 Mux1H(enqDelay1WakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W))), 94 Mux1H(enqDelay2WakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W)))) 95 } else { 96 enqDelayDataSources(i).value := Mux(enqDelayOut1.srcWakeUpByIQ(i).asBool, DataSource.bypass, entryReg.status.srcStatus(i).dataSources.value) 97 if (params.hasIQWakeUp) { 98 val wakeUpOH = enqDelayOut1.srcWakeUpByIQVec(i) 99 enqDelaySrcWakeUpL1ExuOH.get(i) := Mux1H(wakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W)).toSeq) 100 } 101 } 102 103 enqDelaySrcState(i) := entryReg.status.srcStatus(i).srcState | enqDelayOut1.srcWakeUpByWB(i) | enqDelayOut1.srcWakeUpByIQ(i) 104 if (params.hasIQWakeUp) { 105 val wakeUpValid = enqDelayOut1.srcWakeUpByIQVec(i).asUInt.orR 106 val wakeUpOH = enqDelayOut1.srcWakeUpByIQVec(i) 107 enqDelaySrcLoadDependency(i) := Mux(wakeUpValid, Mux1H(wakeUpOH, enqDelayOut1.shiftedWakeupLoadDependencyByIQVec), entryReg.status.srcStatus(i).srcLoadDependency) 108 } else { 109 enqDelaySrcLoadDependency(i) := entryReg.status.srcStatus(i).srcLoadDependency 110 } 111 } 112 113 // current status 114 currentStatus := entryReg.status 115 when (enqDelayValidReg) { 116 currentStatus.srcStatus.zipWithIndex.foreach { case (srcStatus, srcIdx) => 117 srcStatus.srcState := enqDelaySrcState(srcIdx) 118 srcStatus.dataSources := enqDelayDataSources(srcIdx) 119 srcStatus.srcLoadDependency := enqDelaySrcLoadDependency(srcIdx) 120 } 121 } 122 123 if (params.hasIQWakeUp) { 124 currentStatus.srcStatus.map(_.srcWakeUpL1ExuOH.get).zip(entryReg.status.srcStatus.map(_.srcWakeUpL1ExuOH.get)).zip(enqDelaySrcWakeUpL1ExuOH.get).foreach { 125 case ((currExuOH, regExuOH), enqDelayExuOH) => 126 currExuOH := 0.U.asTypeOf(currExuOH) 127 params.wakeUpSourceExuIdx.foreach(x => currExuOH(x) := Mux(enqDelayValidReg, enqDelayExuOH(x), regExuOH(x))) 128 } 129 } 130 131 EntryRegCommonConnect(common, hasWakeupIQ, validReg, entryUpdate, entryReg, currentStatus, io.commonIn, true) 132 133 //output 134 CommonOutConnect(io.commonOut, common, hasWakeupIQ, validReg, entryUpdate, entryReg, currentStatus, io.commonIn, true, isComp) 135} 136 137class EnqEntryVecMem(isComp: Boolean)(implicit p: Parameters, params: IssueBlockParams) extends EnqEntry(isComp) 138 with HasCircularQueuePtrHelper { 139 140 require(params.isVecMemIQ, "EnqEntryVecMem can only be instance of VecMem IQ") 141 142 EntryVecMemConnect(io.commonIn, common, validReg, entryReg, entryRegNext, entryUpdate) 143} 144 145object EnqEntry { 146 def apply(isComp: Boolean)(implicit p: Parameters, iqParams: IssueBlockParams): EnqEntry = { 147 iqParams.schdType match { 148 case IntScheduler() => new EnqEntry(isComp) 149 case MemScheduler() => 150 if (iqParams.isVecMemIQ) new EnqEntryVecMem(isComp) 151 else new EnqEntry(isComp) 152 case VfScheduler() => new EnqEntry(isComp) 153 case _ => null 154 } 155 } 156}