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