xref: /XiangShan/src/main/scala/xiangshan/mem/vector/VecBundle.scala (revision c41f725a91c55e75c95c55b4bb0d2649f43e4c83)
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