xref: /XiangShan/src/main/scala/xiangshan/mem/Bundles.scala (revision 4ec1f4627558e8f6ca953d0fee8586429f064bac)
1/***************************************************************************************
2* Copyright (c) 2024 Beijing Institute of Open Source Chip (BOSC)
3* Copyright (c) 2020-2024 Institute of Computing Technology, Chinese Academy of Sciences
4* Copyright (c) 2020-2021 Peng Cheng Laboratory
5*
6* XiangShan is licensed under Mulan PSL v2.
7* You can use this software according to the terms and conditions of the Mulan PSL v2.
8* You may obtain a copy of Mulan PSL v2 at:
9*          http://license.coscl.org.cn/MulanPSL2
10*
11* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
12* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
13* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
14*
15* See the Mulan PSL v2 for more details.
16***************************************************************************************/
17
18package xiangshan.mem
19
20
21import org.chipsalliance.cde.config.Parameters
22import chisel3._
23import chisel3.util._
24import utility._
25import utils._
26import xiangshan._
27import xiangshan.backend.Bundles._
28import xiangshan.backend.rob.RobPtr
29import xiangshan.backend.fu.FenceToSbuffer
30import xiangshan.backend.fu.vector.Bundles._
31import xiangshan.backend.Bundles._
32import xiangshan.mem.prefetch.PrefetchReqBundle
33import xiangshan.cache._
34import xiangshan.cache.wpu.ReplayCarry
35import xiangshan.cache.mmu._
36import math._
37
38object Bundles {
39
40  class LsPipelineBundle(implicit p: Parameters) extends XSBundle
41    with HasDCacheParameters
42    with HasVLSUParameters {
43    val uop = new DynInst
44    val vaddr = UInt(VAddrBits.W)
45    val fullva = UInt(XLEN.W)
46    val vaNeedExt = Bool()
47    val paddr = UInt(PAddrBits.W)
48    val gpaddr = UInt(XLEN.W)
49    val mask = UInt((VLEN/8).W)
50    val data = UInt((VLEN+1).W)
51    val wlineflag = Bool() // store write the whole cache line
52    val miss = Bool()
53    val tlbMiss = Bool()
54    val ptwBack = Bool()
55    val af = Bool()
56    val nc = Bool()
57    val mmio = Bool()
58    val memBackTypeMM = Bool() // 1: main memory, 0: IO
59    val atomic = Bool()
60    val hasException = Bool()
61    val isHyper = Bool()
62    val isForVSnonLeafPTE = Bool()
63    val isPrefetch = Bool()
64    val isHWPrefetch = Bool()
65    val forwardMask = Vec(VLEN/8, Bool())
66    val forwardData = Vec(VLEN/8, UInt(8.W))
67    val ldCancel = ValidUndirectioned(UInt(log2Ceil(LoadPipelineWidth).W))
68    // val func                = UInt(6.W)
69
70    // vector
71    val isvec = Bool()
72    val isLastElem = Bool()
73    val is128bit = Bool()
74    val uop_unit_stride_fof = Bool()
75    val usSecondInv = Bool()
76    val elemIdx = UInt(elemIdxBits.W)
77    val alignedType = UInt(alignTypeBits.W)
78    val mbIndex = UInt(max(vlmBindexBits, vsmBindexBits).W)
79    val reg_offset = UInt(vOffsetBits.W)
80    val elemIdxInsideVd = UInt(elemIdxBits.W)
81    val is_first_ele = Bool()
82    val vecBaseVaddr = UInt(VAddrBits.W)
83    val vecVaddrOffset = UInt(VAddrBits.W)
84    val vecTriggerMask = UInt((VLEN/8).W)
85    // 1: vector active element or scala mem operation, 0: vector not active element
86    val vecActive = Bool()
87    // val flowPtr             = new VlflowPtr() // VLFlowQueue ptr
88    // val sflowPtr            = new VsFlowPtr() // VSFlowQueue ptr
89    // val rob_idx_valid       = Vec(2,Bool())
90    // val inner_idx           = Vec(2,UInt(3.W))
91    // val rob_idx             = Vec(2,new RobPtr)
92    // val offset              = Vec(2,UInt(4.W))
93
94    // replay
95    val isLoadReplay = Bool()
96    val isFastPath = Bool()
97    val isFastReplay = Bool()
98    val replayCarry = new ReplayCarry(nWays)
99    val isFirstIssue = Bool()
100    val hasROBEntry = Bool()
101    val mshrid = UInt(log2Up(cfg.nMissEntries).W)
102    val handledByMSHR= Bool()
103    val replacementUpdated  = Bool()
104    val missDbUpdated = Bool()
105    val forward_tlDchannel = Bool()
106    val dcacheRequireReplay = Bool()
107    val delayedLoadError = Bool()
108    val lateKill = Bool()
109    val feedbacked = Bool()
110    val schedIndex = UInt(log2Up(LoadQueueReplaySize).W)
111    val tlbNoQuery = Bool()
112
113    // misalign
114    val isFrmMisAlignBuf = Bool()
115    val isMisalign = Bool()
116    val isFinalSplit = Bool()
117    val misalignWith16Byte = Bool()
118    val misalignNeedWakeUp = Bool()
119    val updateAddrValid = Bool()
120
121    def isSWPrefetch: Bool = isPrefetch && !isHWPrefetch
122  }
123
124  class LsPrefetchTrainBundle(implicit p: Parameters) extends LsPipelineBundle {
125    val meta_prefetch = UInt(L1PfSourceBits.W)
126    val meta_access = Bool()
127
128    def fromLsPipelineBundle(input: LsPipelineBundle, latch: Boolean = false, enable: Bool = true.B) = {
129      val inputReg = latch match {
130        case true   => RegEnable(input, enable)
131        case false  => input
132      }
133      connectSamePort(this, inputReg)
134      this.meta_prefetch := DontCare
135      this.meta_access := DontCare
136    }
137
138    def toPrefetchReqBundle(): PrefetchReqBundle = {
139      val res = Wire(new PrefetchReqBundle)
140      res.vaddr := this.vaddr
141      res.paddr := this.paddr
142      res.pc := this.uop.pc
143      res.miss := this.miss
144      res.pfHitStream := isFromStream(this.meta_prefetch)
145      res
146    }
147  }
148
149  class LqWriteBundle(implicit p: Parameters) extends LsPipelineBundle {
150    // load inst replay informations
151    val rep_info = new LoadToLsqReplayIO
152    val nc_with_data = Bool() // nc access with data
153    // queue entry data, except flag bits, will be updated if writeQueue is true,
154    // valid bit in LqWriteBundle will be ignored
155    val data_wen_dup = Vec(6, Bool()) // dirty reg dup
156
157    def fromLsPipelineBundle(input: LsPipelineBundle, latch: Boolean = false, enable: Bool = true.B) = {
158      val inputReg = latch match {
159        case true   => RegEnable(input, enable)
160        case false  => input
161      }
162      connectSamePort(this, inputReg)
163      this.rep_info := DontCare
164      this.nc_with_data := DontCare
165      this.data_wen_dup := DontCare
166    }
167  }
168
169  class SqWriteBundle(implicit p: Parameters) extends LsPipelineBundle {
170    val need_rep = Bool()
171  }
172
173  class LoadForwardQueryIO(implicit p: Parameters) extends XSBundle {
174    val vaddr = Output(UInt(VAddrBits.W))
175    val paddr = Output(UInt(PAddrBits.W))
176    val mask = Output(UInt((VLEN/8).W))
177    val uop = Output(new DynInst) // for replay
178    val pc = Output(UInt(VAddrBits.W)) //for debug
179    val valid = Output(Bool())
180
181    val forwardMaskFast = Input(Vec((VLEN/8), Bool())) // resp to load_s1
182    val forwardMask = Input(Vec((VLEN/8), Bool())) // resp to load_s2
183    val forwardData = Input(Vec((VLEN/8), UInt(8.W))) // resp to load_s2
184
185    // val lqIdx = Output(UInt(LoadQueueIdxWidth.W))
186    val sqIdx = Output(new SqPtr)
187
188    // dataInvalid suggests store to load forward found forward should happen,
189    // but data is not available for now. If dataInvalid, load inst should
190    // be replayed from RS. Feedback type should be RSFeedbackType.dataInvalid
191    val dataInvalid = Input(Bool()) // Addr match, but data is not valid for now
192
193    // matchInvalid suggests in store to load forward logic, paddr cam result does
194    // to equal to vaddr cam result. If matchInvalid, a microarchitectural exception
195    // should be raised to flush SQ and committed sbuffer.
196    val matchInvalid = Input(Bool()) // resp to load_s2
197
198    // addrInvalid suggests store to load forward found forward should happen,
199    // but address (SSID) is not available for now. If addrInvalid, load inst should
200    // be replayed from RS. Feedback type should be RSFeedbackType.addrInvalid
201    val addrInvalid = Input(Bool())
202  }
203
204  // LoadForwardQueryIO used in load pipeline
205  //
206  // Difference between PipeLoadForwardQueryIO and LoadForwardQueryIO:
207  // PipeIO use predecoded sqIdxMask for better forward timing
208  class PipeLoadForwardQueryIO(implicit p: Parameters) extends LoadForwardQueryIO {
209    // val sqIdx = Output(new SqPtr) // for debug, should not be used in pipeline for timing reasons
210    // sqIdxMask is calcuated in earlier stage for better timing
211    val sqIdxMask = Output(UInt(StoreQueueSize.W))
212
213    // dataInvalid: addr match, but data is not valid for now
214    val dataInvalidFast = Input(Bool()) // resp to load_s1
215    // val dataInvalid = Input(Bool()) // resp to load_s2
216    val dataInvalidSqIdx = Input(new SqPtr) // resp to load_s2, sqIdx
217    val addrInvalidSqIdx = Input(new SqPtr) // resp to load_s2, sqIdx
218  }
219
220  // Query load queue for ld-ld violation
221  //
222  // Req should be send in load_s1
223  // Resp will be generated 1 cycle later
224  //
225  // Note that query req may be !ready, as dcache is releasing a block
226  // If it happens, a replay from rs is needed.
227  class LoadNukeQueryReqBundle(implicit p: Parameters) extends XSBundle { // provide lqIdx
228    val uop = new DynInst
229    // mask: load's data mask.
230    val mask = UInt((VLEN/8).W)
231
232    // paddr: load's paddr.
233    val paddr      = UInt(PAddrBits.W)
234    // dataInvalid: load data is invalid.
235    val data_valid = Bool()
236    // nc: is NC access
237    val is_nc = Bool()
238  }
239
240  class LoadNukeQueryRespBundle(implicit p: Parameters) extends XSBundle {
241    // rep_frm_fetch: ld-ld violation check success, replay from fetch.
242    val rep_frm_fetch = Bool()
243  }
244
245  class LoadNukeQueryIO(implicit p: Parameters) extends XSBundle {
246    val req    = Decoupled(new LoadNukeQueryReqBundle)
247    val resp   = Flipped(Valid(new LoadNukeQueryRespBundle))
248    val revoke = Output(Bool())
249  }
250
251  class StoreNukeQueryBundle(implicit p: Parameters) extends XSBundle {
252    //  robIdx: Requestor's (a store instruction) rob index for match logic.
253    val robIdx = new RobPtr
254
255    //  paddr: requestor's (a store instruction) physical address for match logic.
256    val paddr  = UInt(PAddrBits.W)
257
258    //  mask: requestor's (a store instruction) data width mask for match logic.
259    val mask = UInt((VLEN/8).W)
260
261    // matchLine: if store is vector 128-bits, load unit need to compare 128-bits vaddr.
262    val matchLine = Bool()
263  }
264
265  class StoreMaBufToSqControlIO(implicit p: Parameters) extends XSBundle {
266    // from storeMisalignBuffer to storeQueue, control it's sbuffer write
267    val toStoreQueue = Output(new XSBundle {
268      // This entry is a cross page
269      val crossPageWithHit = Bool()
270      val crossPageCanDeq  = Bool()
271      // High page Paddr
272      val paddr = UInt(PAddrBits.W)
273
274      val withSameUop = Bool()
275    })
276    // from storeQueue to storeMisalignBuffer, provide detail info of this store
277    val toStoreMisalignBuffer = Input(new XSBundle {
278      val sqPtr = new SqPtr
279      val doDeq = Bool()
280
281      val uop = new DynInst()
282    })
283  }
284
285  class StoreMaBufToVecStoreMergeBufferIO(implicit p: Parameters)  extends VLSUBundle{
286    val mbIndex = Output(UInt(vsmBindexBits.W))
287    val flush   = Output(Bool())
288  }
289
290  // Store byte valid mask write bundle
291  //
292  // Store byte valid mask write to SQ takes 2 cycles
293  class StoreMaskBundle(implicit p: Parameters) extends XSBundle {
294    val sqIdx = new SqPtr
295    val mask = UInt((VLEN/8).W)
296  }
297
298  class LoadDataFromDcacheBundle(implicit p: Parameters) extends DCacheBundle {
299    // old dcache: optimize data sram read fanout
300    // val bankedDcacheData = Vec(DCacheBanks, UInt(64.W))
301    // val bank_oh = UInt(DCacheBanks.W)
302
303    // new dcache
304    val respDcacheData = UInt(VLEN.W)
305    val forwardMask = Vec(VLEN/8, Bool())
306    val forwardData = Vec(VLEN/8, UInt(8.W))
307    val uop = new DynInst // for data selection, only fwen and fuOpType are used
308    val addrOffset = UInt(4.W) // for data selection
309
310    // forward tilelink D channel
311    val forward_D = Bool()
312    val forwardData_D = Vec(VLEN/8, UInt(8.W))
313
314    // forward mshr data
315    val forward_mshr = Bool()
316    val forwardData_mshr = Vec(VLEN/8, UInt(8.W))
317
318    val forward_result_valid = Bool()
319
320    def mergeTLData(): UInt = {
321      // merge TL D or MSHR data at load s2
322      val dcache_data = respDcacheData
323      val use_D = forward_D && forward_result_valid
324      val use_mshr = forward_mshr && forward_result_valid
325      Mux(
326        use_D || use_mshr,
327        Mux(
328          use_D,
329          forwardData_D.asUInt,
330          forwardData_mshr.asUInt
331        ),
332        dcache_data
333      )
334    }
335
336    def mergeLsqFwdData(dcacheData: UInt): UInt = {
337      // merge dcache and lsq forward data at load s3
338      val rdataVec = VecInit((0 until VLEN / 8).map(j =>
339        Mux(forwardMask(j), forwardData(j), dcacheData(8*(j+1)-1, 8*j))
340      ))
341      rdataVec.asUInt
342    }
343  }
344
345  // Load writeback data from load queue (refill)
346  class LoadDataFromLQBundle(implicit p: Parameters) extends XSBundle {
347    val lqData = UInt(64.W) // load queue has merged data
348    val uop = new DynInst // for data selection, only fwen and fuOpType are used
349    val addrOffset = UInt(3.W) // for data selection
350
351    def mergedData(): UInt = {
352      lqData
353    }
354  }
355
356  // Bundle for load / store wait waking up
357  class MemWaitUpdateReqBundle(implicit p: Parameters) extends XSBundle {
358    val robIdx = Vec(backendParams.StaExuCnt, ValidIO(new RobPtr))
359    val sqIdx = Vec(backendParams.StdCnt, ValidIO(new SqPtr))
360  }
361
362  class MisalignBufferEnqIO(implicit p: Parameters) extends XSBundle {
363    val req = DecoupledIO(new LqWriteBundle)
364    val revoke = Output(Bool())
365  }
366
367}
368