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.fu.NewCSR.CsrTriggerBundle 27import xiangshan.backend.rob.RobPtr 28import xiangshan.backend.fu.PMPRespBundle 29import xiangshan.backend.fu.vector.Bundles._ 30import xiangshan.cache.mmu.{TlbCmd, TlbRequestIO} 31import xiangshan.cache._ 32 33class VLSBundle(isVStore: Boolean=false)(implicit p: Parameters) extends VLSUBundle { 34 val flowMask = UInt(VLENB.W) // each bit for a flow 35 val byteMask = UInt(VLENB.W) // each bit for a byte 36 val data = UInt(VLEN.W) 37 // val fof = Bool() // fof is only used for vector loads 38 val excp_eew_index = UInt(elemIdxBits.W) 39 // val exceptionVec = ExceptionVec() // uop has exceptionVec 40 val baseAddr = UInt(XLEN.W) 41 val stride = UInt(VLEN.W) 42 // val flow_counter = UInt(flowIdxBits.W) 43 44 // instruction decode result 45 val flowNum = UInt(flowIdxBits.W) // # of flows in a uop 46 // val flowNumLog2 = UInt(log2Up(flowIdxBits).W) // log2(flowNum), for better timing of multiplication 47 val nfields = UInt(fieldBits.W) // NFIELDS 48 val vm = Bool() // whether vector masking is enabled 49 val usWholeReg = Bool() // unit-stride, whole register load 50 val usMaskReg = Bool() // unit-stride, masked store/load 51 val eew = VEew() // size of memory elements 52 val sew = UInt(ewBits.W) 53 val emul = UInt(mulBits.W) 54 val lmul = UInt(mulBits.W) 55 val vlmax = UInt(elemIdxBits.W) 56 val instType = UInt(3.W) 57 val vd_last_uop = Bool() 58 val vd_first_uop = Bool() 59 60 // Because the back-end needs to handle exceptions, it is necessary to retain the original NF. 61 // So we choose to pass the original value in the pipeline and override it when out. 62 val rawNf = Nf() 63 val indexedSrcMask = UInt(VLENB.W) 64 val indexedSplitOffset = UInt(flowIdxBits.W) 65 // Inst's uop 66 val uop = new DynInst 67 68 val fof = Bool() 69 val vdIdxInField = UInt(log2Up(maxMUL).W) 70 val uopOffset = UInt(VLEN.W) 71 val preIsSplit = Bool() // if uop need split, only not Unit-Stride or not 128bit-aligned unit stride need split 72 val mBIndex = if(isVStore) UInt(vsmBindexBits.W) else UInt(vlmBindexBits.W) 73 74 val alignedType = UInt(alignTypeBits.W) 75 val indexVlMaxInVd = UInt(elemIdxBits.W) 76 77 val usLowBitsAddr = UInt((log2Up(maxMemByteNum)).W) 78 val usAligned128 = Bool() 79 val usMask = UInt((VLENB*2).W) // for unit-stride split 80} 81 82object VSFQFeedbackType { 83 val tlbMiss = 0.U(3.W) 84 val mshrFull = 1.U(3.W) 85 val dataInvalid = 2.U(3.W) 86 val bankConflict = 3.U(3.W) 87 val ldVioCheckRedo = 4.U(3.W) 88 val feedbackInvalid = 7.U(3.W) 89 90 def apply() = UInt(3.W) 91} 92 93class VSFQFeedback (implicit p: Parameters) extends XSBundle { 94 // val flowPtr = new VsFlowPtr 95 val hit = Bool() 96 //val flushState = Bool() 97 val sourceType = VSFQFeedbackType() 98 //val dataInvalidSqIdx = new SqPtr 99 val paddr = UInt(PAddrBits.W) 100 val mmio = Bool() 101 val atomic = Bool() 102 val exceptionVec = ExceptionVec() 103} 104 105class VecPipelineFeedbackIO(isVStore: Boolean=false) (implicit p: Parameters) extends VLSUBundle { 106 val mBIndex = if(isVStore) UInt(vsmBindexBits.W) else UInt(vlmBindexBits.W) 107 val hit = Bool() 108 val isvec = Bool() 109 val flushState = Bool() 110 val sourceType = VSFQFeedbackType() 111 val trigger = TriggerAction() 112 //val dataInvalidSqIdx = new SqPtr 113 //val paddr = UInt(PAddrBits.W) 114 val nc = Bool() 115 val mmio = Bool() 116 //val atomic = Bool() 117 val exceptionVec = ExceptionVec() 118 val vaddr = UInt(XLEN.W) 119 val vaNeedExt = Bool() 120 val gpaddr = UInt(XLEN.W) 121 val isForVSnonLeafPTE = Bool() 122 val vstart = UInt(elemIdxBits.W) 123 val vecTriggerMask = UInt((VLEN/8).W) 124 125 //val vec = new OnlyVecExuOutput 126 // feedback 127 val vecFeedback = Bool() 128 129 val usSecondInv = Bool() // only for unit stride, second flow is Invalid 130 val elemIdx = UInt(elemIdxBits.W) // element index 131 val mask = UInt(VLENB.W) 132 val alignedType = UInt(alignTypeBits.W) 133 // for load 134 val reg_offset = OptionWrapper(!isVStore, UInt(vOffsetBits.W)) 135 val elemIdxInsideVd = OptionWrapper(!isVStore, UInt(elemIdxBits.W)) // element index in scope of vd 136 val vecdata = OptionWrapper(!isVStore, UInt(VLEN.W)) 137} 138 139class VecPipeBundle(isVStore: Boolean=false)(implicit p: Parameters) extends VLSUBundle { 140 val vaddr = UInt(XLEN.W) 141 val basevaddr = UInt(VAddrBits.W) 142 val mask = UInt(VLENB.W) 143 val isvec = Bool() 144 val uop_unit_stride_fof = Bool() 145 val reg_offset = UInt(vOffsetBits.W) 146 val alignedType = UInt(alignTypeBits.W) 147 val vecActive = Bool() // 1: vector active element, 0: vector not active element 148 val is_first_ele = Bool() 149 val isFirstIssue = Bool() 150 151 val uop = new DynInst 152 153 val usSecondInv = Bool() // only for unit stride, second flow is Invalid 154 val mBIndex = if(isVStore) UInt(vsmBindexBits.W) else UInt(vlmBindexBits.W) 155 val elemIdx = UInt(elemIdxBits.W) 156 val elemIdxInsideVd = UInt(elemIdxBits.W) // only use in unit-stride 157} 158 159object VecFeedbacks { 160 // need to invalid lsq entry 161 val FLUSH = 0 162 // merge buffer commits one uop 163 val COMMIT = 1 164 // last uop of an inst, sq can commit 165 val LAST = 2 166 // total feedbacks 167 val allFeedbacks = 3 168} 169 170class MergeBufferReq(isVStore: Boolean=false)(implicit p: Parameters) extends VLSUBundle{ 171 val mask = UInt(VLENB.W) 172 val vaddr = UInt(VAddrBits.W) 173 val flowNum = UInt(flowIdxBits.W) 174 val uop = new DynInst 175 val data = UInt(VLEN.W) 176 val vdIdx = UInt(3.W) 177 val fof = Bool() 178 val vlmax = UInt(elemIdxBits.W) 179 // val vdOffset = UInt(vdOffset.W) 180} 181 182class MergeBufferResp(isVStore: Boolean=false)(implicit p: Parameters) extends VLSUBundle{ 183 val mBIndex = if(isVStore) UInt(vsmBindexBits.W) else UInt(vlmBindexBits.W) 184 val fail = Bool() 185} 186 187class ToMergeBufferIO(isVStore: Boolean=false)(implicit p: Parameters) extends VLSUBundle{ 188 val req = DecoupledIO(new MergeBufferReq(isVStore)) 189 val resp = Flipped(ValidIO(new MergeBufferResp(isVStore))) 190 // val issueInactive = ValidIO 191} 192 193class FromSplitIO(isVStore: Boolean=false)(implicit p: Parameters) extends VLSUBundle{ 194 val req = Flipped(DecoupledIO(new MergeBufferReq(isVStore))) 195 val resp = ValidIO(new MergeBufferResp(isVStore)) 196 // val issueInactive = Flipped(ValidIO()) 197} 198 199class FeedbackToSplitIO(implicit p: Parameters) extends VLSUBundle{ 200 val elemWriteback = Bool() 201} 202 203class FeedbackToLsqIO(implicit p: Parameters) extends VLSUBundle{ 204 val robidx = new RobPtr 205 val uopidx = UopIdx() 206 val vaddr = UInt(XLEN.W) 207 val vaNeedExt = Bool() 208 val gpaddr = UInt(GPAddrBits.W) 209 val isForVSnonLeafPTE = Bool() 210 val feedback = Vec(VecFeedbacks.allFeedbacks, Bool()) 211 // for exception 212 val vstart = UInt(elemIdxBits.W) 213 val vl = UInt(elemIdxBits.W) 214 val exceptionVec = ExceptionVec() 215 216 def isFlush = feedback(VecFeedbacks.FLUSH) 217 def isCommit = feedback(VecFeedbacks.COMMIT) 218 def isLast = feedback(VecFeedbacks.LAST) 219} 220 221class storeMisaignIO(implicit p: Parameters) extends Bundle{ 222 val storePipeEmpty = Input(Bool()) 223 val storeMisalignBufferEmpty = Input(Bool()) 224} 225 226class VSplitIO(isVStore: Boolean=false)(implicit p: Parameters) extends VLSUBundle{ 227 val redirect = Flipped(ValidIO(new Redirect)) 228 val in = Flipped(Decoupled(new MemExuInput(isVector = true))) // from iq 229 val toMergeBuffer = new ToMergeBufferIO(isVStore) //to merge buffer req mergebuffer entry 230 val out = Decoupled(new VecPipeBundle(isVStore))// to scala pipeline 231 val vstd = OptionWrapper(isVStore, Valid(new MemExuOutput(isVector = true))) 232 val vstdMisalign = OptionWrapper(isVStore, new storeMisaignIO) 233} 234 235class VSplitPipelineIO(isVStore: Boolean=false)(implicit p: Parameters) extends VLSUBundle{ 236 val redirect = Flipped(ValidIO(new Redirect)) 237 val in = Flipped(Decoupled(new MemExuInput(isVector = true))) 238 val toMergeBuffer = new ToMergeBufferIO(isVStore) // req mergebuffer entry, inactive elem issue 239 val out = Decoupled(new VLSBundle())// to split buffer 240} 241 242class VSplitBufferIO(isVStore: Boolean=false)(implicit p: Parameters) extends VLSUBundle{ 243 val redirect = Flipped(ValidIO(new Redirect)) 244 val in = Flipped(Decoupled(new VLSBundle())) 245 val out = Decoupled(new VecPipeBundle(isVStore))//to scala pipeline 246 val vstd = OptionWrapper(isVStore, ValidIO(new MemExuOutput(isVector = true))) 247 val vstdMisalign = OptionWrapper(isVStore, new storeMisaignIO) 248} 249 250class VMergeBufferIO(isVStore : Boolean=false)(implicit p: Parameters) extends VLSUBundle{ 251 val redirect = Flipped(ValidIO(new Redirect)) 252 val fromPipeline = if(isVStore) Vec(StorePipelineWidth, Flipped(DecoupledIO(new VecPipelineFeedbackIO(isVStore)))) else Vec(LoadPipelineWidth, Flipped(DecoupledIO(new VecPipelineFeedbackIO(isVStore)))) 253 val fromSplit = if(isVStore) Vec(VecStorePipelineWidth, new FromSplitIO) else Vec(VecLoadPipelineWidth, new FromSplitIO) // req mergebuffer entry, inactive elem issue 254 val uopWriteback = if(isVStore) Vec(VSUopWritebackWidth, DecoupledIO(new MemExuOutput(isVector = true))) else Vec(VLUopWritebackWidth, DecoupledIO(new MemExuOutput(isVector = true))) 255 val toSplit = if(isVStore) Vec(VecStorePipelineWidth, ValidIO(new FeedbackToSplitIO)) else Vec(VecLoadPipelineWidth, ValidIO(new FeedbackToSplitIO)) // for inorder inst 256 val toLsq = if(isVStore) Vec(VSUopWritebackWidth, ValidIO(new FeedbackToLsqIO)) else Vec(VLUopWritebackWidth, ValidIO(new FeedbackToLsqIO)) // for lsq deq 257 val feedback = if(isVStore) Vec(VSUopWritebackWidth, ValidIO(new RSFeedback(isVector = true))) else Vec(VLUopWritebackWidth, ValidIO(new RSFeedback(isVector = true)))//for rs replay 258 259 val fromMisalignBuffer = OptionWrapper(isVStore, Flipped(new StoreMaBufToVecStoreMergeBufferIO)) 260} 261 262class VSegmentUnitIO(implicit p: Parameters) extends VLSUBundle{ 263 val in = Flipped(Decoupled(new MemExuInput(isVector = true))) // from iq 264 val uopwriteback = DecoupledIO(new MemExuOutput(isVector = true)) // writeback data 265 val rdcache = new DCacheLoadIO // read dcache port 266 val sbuffer = Decoupled(new DCacheWordReqWithVaddrAndPfFlag) 267 val vecDifftestInfo = Decoupled(new DynInst) // to sbuffer 268 val dtlb = new TlbRequestIO(2) 269 val pmpResp = Flipped(new PMPRespBundle()) 270 val flush_sbuffer = new SbufferFlushBundle 271 val feedback = ValidIO(new RSFeedback(isVector = true)) 272 val redirect = Flipped(ValidIO(new Redirect)) 273 val exceptionInfo = ValidIO(new FeedbackToLsqIO) 274 //trigger 275 val fromCsrTrigger = Input(new CsrTriggerBundle) 276} 277 278class VfofDataBuffIO(implicit p: Parameters) extends VLSUBundle{ 279 val redirect = Flipped(ValidIO(new Redirect)) 280 val in = Vec(VecLoadPipelineWidth, Flipped(Decoupled(new MemExuInput(isVector=true)))) 281 val mergeUopWriteback = Vec(VLUopWritebackWidth, Flipped(DecoupledIO(new MemExuOutput(isVector=true)))) 282 283 val uopWriteback = DecoupledIO(new MemExuOutput(isVector = true)) 284}