1/*************************************************************************************** 2 * Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3 * Copyright (c) 2020-2021 Peng Cheng Laboratory 4 * 5 * XiangShan is licensed under Mulan PSL v2. 6 * You can use this software according to the terms and conditions of the Mulan PSL v2. 7 * You may obtain a copy of Mulan PSL v2 at: 8 * http://license.coscl.org.cn/MulanPSL2 9 * 10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13 * 14 * See the Mulan PSL v2 for more details. 15 ***************************************************************************************/ 16 17package xiangshan.mem 18 19import org.chipsalliance.cde.config.Parameters 20import chisel3._ 21import chisel3.util._ 22import utils._ 23import utility._ 24import xiangshan._ 25import xiangshan.backend.Bundles._ 26import xiangshan.backend.rob.RobPtr 27import xiangshan.backend.fu.PMPRespBundle 28import xiangshan.cache.mmu.{TlbCmd, TlbRequestIO} 29import xiangshan.cache._ 30 31class VLSBundle(isVStore: Boolean=false)(implicit p: Parameters) extends VLSUBundle { 32 val flowMask = UInt(VLENB.W) // each bit for a flow 33 val byteMask = UInt(VLENB.W) // each bit for a byte 34 val data = UInt(VLEN.W) 35 // val fof = Bool() // fof is only used for vector loads 36 val excp_eew_index = UInt(elemIdxBits.W) 37 // val exceptionVec = ExceptionVec() // uop has exceptionVec 38 val baseAddr = UInt(VAddrBits.W) 39 val stride = UInt(VLEN.W) 40 // val flow_counter = UInt(flowIdxBits.W) 41 42 // instruction decode result 43 val flowNum = UInt(flowIdxBits.W) // # of flows in a uop 44 // val flowNumLog2 = UInt(log2Up(flowIdxBits).W) // log2(flowNum), for better timing of multiplication 45 val nfields = UInt(fieldBits.W) // NFIELDS 46 val vm = Bool() // whether vector masking is enabled 47 val usWholeReg = Bool() // unit-stride, whole register load 48 val usMaskReg = Bool() // unit-stride, masked store/load 49 val eew = UInt(ewBits.W) // size of memory elements 50 val sew = UInt(ewBits.W) 51 val emul = UInt(mulBits.W) 52 val lmul = UInt(mulBits.W) 53 val vlmax = UInt(elemIdxBits.W) 54 val instType = UInt(3.W) 55 val vd_last_uop = Bool() 56 val vd_first_uop = Bool() 57 58 val indexedSrcMask = UInt(VLENB.W) 59 val indexedSplitOffset = UInt(flowIdxBits.W) 60 // Inst's uop 61 val uop = new DynInst 62 63 val fof = Bool() 64 val vdIdxInField = UInt(log2Up(maxMUL).W) 65 val uopOffset = UInt(VLEN.W) 66 val preIsSplit = Bool() // if uop need split, only not Unit-Stride or not 128bit-aligned unit stride need split 67 val mBIndex = if(isVStore) UInt(vsmBindexBits.W) else UInt(vlmBindexBits.W) 68 69 val alignedType = UInt(alignTypeBits.W) 70} 71 72object VSFQFeedbackType { 73 val tlbMiss = 0.U(3.W) 74 val mshrFull = 1.U(3.W) 75 val dataInvalid = 2.U(3.W) 76 val bankConflict = 3.U(3.W) 77 val ldVioCheckRedo = 4.U(3.W) 78 val feedbackInvalid = 7.U(3.W) 79 80 def apply() = UInt(3.W) 81} 82 83class VSFQFeedback (implicit p: Parameters) extends XSBundle { 84 // val flowPtr = new VsFlowPtr 85 val hit = Bool() 86 //val flushState = Bool() 87 val sourceType = VSFQFeedbackType() 88 //val dataInvalidSqIdx = new SqPtr 89 val paddr = UInt(PAddrBits.W) 90 val mmio = Bool() 91 val atomic = Bool() 92 val exceptionVec = ExceptionVec() 93} 94 95class VecPipelineFeedbackIO(isVStore: Boolean=false) (implicit p: Parameters) extends VLSUBundle { 96 val mBIndex = if(isVStore) UInt(vsmBindexBits.W) else UInt(vlmBindexBits.W) 97 val hit = Bool() 98 val isvec = Bool() 99 val flushState = Bool() 100 val sourceType = VSFQFeedbackType() 101 //val dataInvalidSqIdx = new SqPtr 102 //val paddr = UInt(PAddrBits.W) 103 val mmio = Bool() 104 //val atomic = Bool() 105 val exceptionVec = ExceptionVec() 106 //val vec = new OnlyVecExuOutput 107 // feedback 108 val vecFeedback = Bool() 109 110 val usSecondInv = Bool() // only for unit stride, second flow is Invalid 111 val elemIdx = UInt(elemIdxBits.W) // element index 112 val mask = UInt(VLENB.W) 113 val alignedType = UInt(alignTypeBits.W) 114 // for load 115 val reg_offset = OptionWrapper(!isVStore, UInt(vOffsetBits.W)) 116 val elemIdxInsideVd = OptionWrapper(!isVStore, UInt(elemIdxBits.W)) // element index in scope of vd 117 val vecdata = OptionWrapper(!isVStore, UInt(VLEN.W)) 118} 119 120class VecPipeBundle(isVStore: Boolean=false)(implicit p: Parameters) extends VLSUBundle { 121 val vaddr = UInt(VAddrBits.W) 122 val mask = UInt(VLENB.W) 123 val isvec = Bool() 124 val uop_unit_stride_fof = Bool() 125 val reg_offset = UInt(vOffsetBits.W) 126 val alignedType = UInt(alignTypeBits.W) 127 val vecActive = Bool() // 1: vector active element, 0: vector not active element 128 val is_first_ele = Bool() 129 val isFirstIssue = Bool() 130 131 val uop = new DynInst 132 133 val usSecondInv = Bool() // only for unit stride, second flow is Invalid 134 val mBIndex = if(isVStore) UInt(vsmBindexBits.W) else UInt(vlmBindexBits.W) 135 val elemIdx = UInt(elemIdxBits.W) 136 val elemIdxInsideVd = UInt(elemIdxBits.W) // only use in unit-stride 137} 138 139object VecFeedbacks { 140 // need to invalid lsq entry 141 val FLUSH = 0 142 // merge buffer commits one uop 143 val COMMIT = 1 144 // last uop of an inst, sq can commit 145 val LAST = 2 146 // total feedbacks 147 val allFeedbacks = 3 148} 149 150class MergeBufferReq(isVStore: Boolean=false)(implicit p: Parameters) extends VLSUBundle{ 151 val mask = UInt(VLENB.W) 152 val vaddr = UInt(VAddrBits.W) 153 val flowNum = UInt(flowIdxBits.W) 154 val uop = new DynInst 155 val data = UInt(VLEN.W) 156 val vdIdx = UInt(3.W) 157 val fof = Bool() 158 val vlmax = UInt(elemIdxBits.W) 159 // val vdOffset = UInt(vdOffset.W) 160} 161 162class MergeBufferResp(isVStore: Boolean=false)(implicit p: Parameters) extends VLSUBundle{ 163 val mBIndex = if(isVStore) UInt(vsmBindexBits.W) else UInt(vlmBindexBits.W) 164 val fail = Bool() 165} 166 167class ToMergeBufferIO(isVStore: Boolean=false)(implicit p: Parameters) extends VLSUBundle{ 168 val req = DecoupledIO(new MergeBufferReq(isVStore)) 169 val resp = Flipped(ValidIO(new MergeBufferResp(isVStore))) 170 // val issueInactive = ValidIO 171} 172 173class FromSplitIO(isVStore: Boolean=false)(implicit p: Parameters) extends VLSUBundle{ 174 val req = Flipped(DecoupledIO(new MergeBufferReq(isVStore))) 175 val resp = ValidIO(new MergeBufferResp(isVStore)) 176 // val issueInactive = Flipped(ValidIO()) 177} 178 179class FeedbackToSplitIO(implicit p: Parameters) extends VLSUBundle{ 180 val elemWriteback = Bool() 181} 182 183class FeedbackToLsqIO(implicit p: Parameters) extends VLSUBundle{ 184 val robidx = new RobPtr 185 val uopidx = UopIdx() 186 val vaddr = UInt(VAddrBits.W) 187 val feedback = Vec(VecFeedbacks.allFeedbacks, Bool()) 188 // for exception 189 val vstart = UInt(elemIdxBits.W) 190 val vl = UInt(elemIdxBits.W) 191 192 def isFlush = feedback(VecFeedbacks.FLUSH) 193 def isCommit = feedback(VecFeedbacks.COMMIT) 194 def isLast = feedback(VecFeedbacks.LAST) 195} 196 197class VSplitIO(isVStore: Boolean=false)(implicit p: Parameters) extends VLSUBundle{ 198 val redirect = Flipped(ValidIO(new Redirect)) 199 val in = Flipped(Decoupled(new MemExuInput(isVector = true))) // from iq 200 val toMergeBuffer = new ToMergeBufferIO(isVStore) //to merge buffer req mergebuffer entry 201 val out = Decoupled(new VecPipeBundle(isVStore))// to scala pipeline 202 val vstd = OptionWrapper(isVStore, Valid(new MemExuOutput(isVector = true))) 203} 204 205class VSplitPipelineIO(isVStore: Boolean=false)(implicit p: Parameters) extends VLSUBundle{ 206 val redirect = Flipped(ValidIO(new Redirect)) 207 val in = Flipped(Decoupled(new MemExuInput(isVector = true))) 208 val toMergeBuffer = new ToMergeBufferIO(isVStore) // req mergebuffer entry, inactive elem issue 209 val out = Decoupled(new VLSBundle())// to split buffer 210} 211 212class VSplitBufferIO(isVStore: Boolean=false)(implicit p: Parameters) extends VLSUBundle{ 213 val redirect = Flipped(ValidIO(new Redirect)) 214 val in = Flipped(Decoupled(new VLSBundle())) 215 val out = Decoupled(new VecPipeBundle(isVStore))//to scala pipeline 216 val vstd = OptionWrapper(isVStore, ValidIO(new MemExuOutput(isVector = true))) 217} 218 219class VMergeBufferIO(isVStore : Boolean=false)(implicit p: Parameters) extends VLSUBundle{ 220 val redirect = Flipped(ValidIO(new Redirect)) 221 val fromPipeline = if(isVStore) Vec(StorePipelineWidth, Flipped(DecoupledIO(new VecPipelineFeedbackIO(isVStore)))) else Vec(LoadPipelineWidth, Flipped(DecoupledIO(new VecPipelineFeedbackIO(isVStore)))) 222 val fromSplit = if(isVStore) Vec(VecStorePipelineWidth, new FromSplitIO) else Vec(VecLoadPipelineWidth, new FromSplitIO) // req mergebuffer entry, inactive elem issue 223 val uopWriteback = if(isVStore) Vec(VSUopWritebackWidth, DecoupledIO(new MemExuOutput(isVector = true))) else Vec(VLUopWritebackWidth, DecoupledIO(new MemExuOutput(isVector = true))) 224 val toSplit = if(isVStore) Vec(VecStorePipelineWidth, ValidIO(new FeedbackToSplitIO)) else Vec(VecLoadPipelineWidth, ValidIO(new FeedbackToSplitIO)) // for inorder inst 225 val toLsq = if(isVStore) Vec(VSUopWritebackWidth, ValidIO(new FeedbackToLsqIO)) else Vec(VLUopWritebackWidth, ValidIO(new FeedbackToLsqIO)) // for lsq deq 226 val feedback = if(isVStore) Vec(VSUopWritebackWidth, ValidIO(new RSFeedback(isVector = true))) else Vec(VLUopWritebackWidth, ValidIO(new RSFeedback(isVector = true)))//for rs replay 227} 228 229class VSegmentUnitIO(implicit p: Parameters) extends VLSUBundle{ 230 val in = Flipped(Decoupled(new MemExuInput(isVector = true))) // from iq 231 val uopwriteback = DecoupledIO(new MemExuOutput(isVector = true)) // writeback data 232 val dcache = new AtomicWordIO // read dcache port 233 val dtlb = new TlbRequestIO(2) 234 val pmpResp = Flipped(new PMPRespBundle()) 235 val flush_sbuffer = new SbufferFlushBundle 236 val feedback = ValidIO(new RSFeedback(isVector = true)) 237 val redirect = Flipped(ValidIO(new Redirect)) 238 val exceptionAddr = ValidIO(new FeedbackToLsqIO) 239}