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 val enqReady = Output(Bool()) 23 24 def wakeup = commonIn.wakeUpFromWB ++ commonIn.wakeUpFromIQ 25} 26 27class OthersEntry(implicit p: Parameters, params: IssueBlockParams) extends XSModule { 28 val io = IO(new OthersEntryIO) 29 30 val validReg = RegInit(false.B) 31 val entryReg = Reg(new EntryBundle) 32 33 val common = Wire(new CommonWireBundle) 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, 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 && io.commonIn.transSel) { 50 entryRegNext := io.commonIn.enq.bits 51 }.otherwise { 52 EntryRegCommonConnect(common, hasWakeupIQ, validReg, entryRegNext, entryReg, entryReg.status, io.commonIn, false) 53 } 54 55 //output 56 CommonOutConnect(io.commonOut, common, hasWakeupIQ, validReg, entryReg, entryReg.status, io.commonIn, false) 57 io.enqReady := common.enqReady 58} 59 60class OthersEntryMem()(implicit p: Parameters, params: IssueBlockParams) extends OthersEntry 61 with HasCircularQueuePtrHelper { 62 EntryMemConnect(io.commonIn, common, validReg, entryReg, entryRegNext, false) 63} 64 65class OthersEntryVecMemAddr()(implicit p: Parameters, params: IssueBlockParams) extends OthersEntryMem { 66 67 require(params.isVecMemAddrIQ, "OthersEntryVecMemAddr can only be instance of VecMemAddr IQ") 68 69 val commonIn = io.commonIn 70 val enqValid = commonIn.enq.valid && commonIn.transSel 71 val fromMem = commonIn.fromMem.get 72 val memStatus = entryReg.status.mem.get 73 val memStatusNext = entryRegNext.status.mem.get 74 val shouldBlock = Mux(commonIn.enq.valid && commonIn.transSel, commonIn.enq.bits.status.blocked, entryReg.status.blocked) 75 // load cannot be issued before older store, unless meet some condition 76 val blockedByOlderStore = isAfter(memStatusNext.sqIdx, fromMem.stIssuePtr) 77 78 val vecMemStatus = entryReg.status.vecMem.get 79 val vecMemStatusNext = entryRegNext.status.vecMem.get 80 val fromLsq = io.commonIn.fromLsq.get 81 82 when(enqValid) { 83 vecMemStatusNext := io.commonIn.enq.bits.status.vecMem.get 84 }.otherwise { 85 vecMemStatusNext := vecMemStatus 86 } 87 88 val isLsqHead = { 89 entryRegNext.status.vecMem.get.lqIdx <= fromLsq.lqDeqPtr && 90 entryRegNext.status.vecMem.get.sqIdx <= fromLsq.sqDeqPtr 91 } 92 dontTouch(isLsqHead) 93 94 entryRegNext.status.blocked := !isLsqHead 95} 96 97class OthersEntryVecMemData()(implicit p: Parameters, params: IssueBlockParams) extends OthersEntry 98 with HasCircularQueuePtrHelper { 99 100 require(params.isVecStDataIQ, "OthersEntryVecMemData can only be instance of VecMemData IQ") 101 102 val commonIn = io.commonIn 103 val enqValid = commonIn.enq.valid && commonIn.transSel 104 val vecMemStatus = entryReg.status.vecMem.get 105 val vecMemStatusNext = entryRegNext.status.vecMem.get 106 val fromLsq = io.commonIn.fromLsq.get 107 108 when(enqValid) { 109 vecMemStatusNext.sqIdx := commonIn.enq.bits.status.vecMem.get.sqIdx 110 vecMemStatusNext.lqIdx := commonIn.enq.bits.status.vecMem.get.lqIdx 111 vecMemStatusNext.uopIdx := commonIn.enq.bits.status.vecMem.get.uopIdx 112 }.otherwise { 113 vecMemStatusNext := vecMemStatus 114 } 115 116 val isLsqHead = entryRegNext.status.vecMem.get.sqIdx.value === fromLsq.sqDeqPtr.value 117 118 entryRegNext.status.blocked := !isLsqHead 119} 120 121object OthersEntry { 122 def apply(implicit p: Parameters, iqParams: IssueBlockParams): OthersEntry = { 123 iqParams.schdType match { 124 case IntScheduler() => new OthersEntry() 125 case MemScheduler() => 126 if (iqParams.isLdAddrIQ || iqParams.isStAddrIQ || iqParams.isHyAddrIQ) new OthersEntryMem() 127 else if (iqParams.isVecMemAddrIQ) new OthersEntryVecMemAddr() 128 else if (iqParams.isVecStDataIQ) new OthersEntryVecMemData() 129 else new OthersEntry() 130 case VfScheduler() => new OthersEntry() 131 case _ => null 132 } 133 } 134}