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