1package xiangshan.backend.issue 2 3import org.chipsalliance.cde.config.Parameters 4import chisel3._ 5import chisel3.util._ 6import utility.HasCircularQueuePtrHelper 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 OthersEntryIO(implicit p: Parameters, params: IssueBlockParams) extends XSBundle { 18 //input 19 val commonIn = new CommonInBundle 20 //output 21 val commonOut = new CommonOutBundle 22 23 def wakeup = commonIn.wakeUpFromWB ++ commonIn.wakeUpFromIQ 24} 25 26class OthersEntry(isComp: Boolean)(implicit p: Parameters, params: IssueBlockParams) extends XSModule { 27 val io = IO(new OthersEntryIO) 28 29 val validReg = RegInit(false.B) 30 val entryReg = Reg(new EntryBundle) 31 32 val common = Wire(new CommonWireBundle) 33 val entryUpdate = Wire(new EntryBundle) 34 val entryRegNext = Wire(new EntryBundle) 35 val hasWakeupIQ = OptionWrapper(params.hasIQWakeUp, Wire(new CommonIQWakeupBundle)) 36 37 //Reg 38 validReg := common.validRegNext 39 entryReg := entryRegNext 40 41 //Wire 42 CommonWireConnect(common, hasWakeupIQ, validReg, entryReg.status, io.commonIn, false) 43 44 if (params.hasIQWakeUp) { 45 ShiftLoadDependency(hasWakeupIQ.get) 46 CommonIQWakeupConnect(common, hasWakeupIQ.get, validReg, entryReg.status, io.commonIn, false) 47 } 48 49 when(io.commonIn.enq.valid) { 50 assert(common.enqReady, "Entry is not ready when enq is valid\n") 51 } 52 53 when(io.commonIn.enq.valid) { 54 entryRegNext := io.commonIn.enq.bits 55 }.otherwise { 56 entryRegNext := entryUpdate 57 } 58 59 EntryRegCommonConnect(common, hasWakeupIQ, validReg, entryUpdate, entryReg, entryReg.status, io.commonIn, false) 60 61 //output 62 CommonOutConnect(io.commonOut, common, hasWakeupIQ, validReg, entryUpdate, entryReg, entryReg.status, io.commonIn, false, isComp) 63} 64 65class OthersEntryMem(isComp: Boolean)(implicit p: Parameters, params: IssueBlockParams) extends OthersEntry(isComp) 66 with HasCircularQueuePtrHelper { 67 EntryMemConnect(io.commonIn, common, validReg, entryReg, entryRegNext, entryUpdate, false) 68} 69 70class OthersEntryVecMemAddr(isComp: Boolean)(implicit p: Parameters, params: IssueBlockParams) extends OthersEntryMem(isComp) { 71 72 require(params.isVecMemAddrIQ, "OthersEntryVecMemAddr can only be instance of VecMemAddr IQ") 73 74 val commonIn = io.commonIn 75 val enqValid = commonIn.enq.valid && commonIn.transSel 76 val fromMem = commonIn.fromMem.get 77 val memStatus = entryReg.status.mem.get 78 val memStatusNext = entryRegNext.status.mem.get 79 val shouldBlock = Mux(commonIn.enq.valid && commonIn.transSel, commonIn.enq.bits.status.blocked, entryReg.status.blocked) 80 // load cannot be issued before older store, unless meet some condition 81 val blockedByOlderStore = isAfter(memStatusNext.sqIdx, fromMem.stIssuePtr) 82 83 val vecMemStatus = entryReg.status.vecMem.get 84 val vecMemStatusNext = entryRegNext.status.vecMem.get 85 val vecMemStatusUpdate = entryUpdate.status.vecMem.get 86 87 val fromLsq = io.commonIn.fromLsq.get 88 89 when(enqValid) { 90 vecMemStatusNext := io.commonIn.enq.bits.status.vecMem.get 91 }.otherwise { 92 vecMemStatusNext := vecMemStatus 93 } 94 95 val isLsqHead = { 96 entryRegNext.status.vecMem.get.lqIdx <= fromLsq.lqDeqPtr && 97 entryRegNext.status.vecMem.get.sqIdx <= fromLsq.sqDeqPtr 98 } 99 dontTouch(isLsqHead) 100 101 entryRegNext.status.blocked := !isLsqHead 102} 103 104class OthersEntryVecMemData(isComp: Boolean)(implicit p: Parameters, params: IssueBlockParams) extends OthersEntry(isComp) 105 with HasCircularQueuePtrHelper { 106 107 require(params.isVecStDataIQ, "OthersEntryVecMemData can only be instance of VecMemData IQ") 108 109 val commonIn = io.commonIn 110 val enqValid = commonIn.enq.valid && commonIn.transSel 111 val vecMemStatus = entryReg.status.vecMem.get 112 val vecMemStatusNext = entryRegNext.status.vecMem.get 113 val fromLsq = io.commonIn.fromLsq.get 114 115 when(enqValid) { 116 vecMemStatusNext.sqIdx := commonIn.enq.bits.status.vecMem.get.sqIdx 117 vecMemStatusNext.lqIdx := commonIn.enq.bits.status.vecMem.get.lqIdx 118 vecMemStatusNext.uopIdx := commonIn.enq.bits.status.vecMem.get.uopIdx 119 }.otherwise { 120 vecMemStatusNext := vecMemStatus 121 } 122 123 val isLsqHead = entryRegNext.status.vecMem.get.sqIdx.value === fromLsq.sqDeqPtr.value 124 125 entryRegNext.status.blocked := !isLsqHead 126} 127 128object OthersEntry { 129 def apply(isComp: Boolean)(implicit p: Parameters, iqParams: IssueBlockParams): OthersEntry = { 130 iqParams.schdType match { 131 case IntScheduler() => new OthersEntry(isComp) 132 case MemScheduler() => 133 if (iqParams.isLdAddrIQ || iqParams.isStAddrIQ || iqParams.isHyAddrIQ) new OthersEntryMem(isComp) 134 else if (iqParams.isVecMemAddrIQ) new OthersEntryVecMemAddr(isComp) 135 else if (iqParams.isVecStDataIQ) new OthersEntryVecMemData(isComp) 136 else new OthersEntry(isComp) 137 case VfScheduler() => new OthersEntry(isComp) 138 case _ => null 139 } 140 } 141}