xref: /XiangShan/src/main/scala/xiangshan/Bundle.scala (revision d57bda64dd69dbc246bd52257ef7392f220149aa)
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
18
19import chisel3._
20import chisel3.util._
21import xiangshan.backend.roq.RoqPtr
22import xiangshan.backend.CtrlToFtqIO
23import xiangshan.backend.decode.{ImmUnion, XDecode}
24import xiangshan.mem.{LqPtr, SqPtr}
25import xiangshan.frontend.PreDecodeInfo
26// import xiangshan.frontend.HasTageParameter
27// import xiangshan.frontend.HasSCParameter
28import xiangshan.frontend.HasBPUParameter
29import xiangshan.frontend.GlobalHistory
30import xiangshan.frontend.RASEntry
31import xiangshan.frontend.BPUCtrl
32import xiangshan.frontend.FtqPtr
33import xiangshan.frontend.FtqRead
34import xiangshan.frontend.FtqToCtrlIO
35import utils._
36
37import scala.math.max
38import Chisel.experimental.chiselName
39import chipsalliance.rocketchip.config.Parameters
40
41// Fetch FetchWidth x 32-bit insts from Icache
42class FetchPacket(implicit p: Parameters) extends XSBundle {
43  val instrs = Vec(PredictWidth, UInt(32.W))
44  val mask = UInt(PredictWidth.W)
45  val pdmask = UInt(PredictWidth.W)
46  // val pc = UInt(VAddrBits.W)
47  val pc = Vec(PredictWidth, UInt(VAddrBits.W))
48  val foldpc = Vec(PredictWidth, UInt(MemPredPCWidth.W))
49  val pd = Vec(PredictWidth, new PreDecodeInfo)
50  val ipf = Bool()
51  val acf = Bool()
52  val crossPageIPFFix = Bool()
53  val pred_taken = UInt(PredictWidth.W)
54  val ftqPtr = new FtqPtr
55}
56
57class ValidUndirectioned[T <: Data](gen: T) extends Bundle {
58  val valid = Bool()
59  val bits = gen.cloneType.asInstanceOf[T]
60
61  override def cloneType = new ValidUndirectioned(gen).asInstanceOf[this.type]
62}
63
64object ValidUndirectioned {
65  def apply[T <: Data](gen: T) = {
66    new ValidUndirectioned[T](gen)
67  }
68}
69
70object RSFeedbackType {
71  val tlbMiss = 0.U(2.W)
72  val mshrFull = 1.U(2.W)
73  val dataInvalid = 2.U(2.W)
74
75  def apply() = UInt(2.W)
76}
77
78// class SCMeta(val useSC: Boolean)(implicit p: Parameters) extends XSBundle with HasSCParameter {
79//   val tageTaken = if (useSC) Bool() else UInt(0.W)
80//   val scUsed = if (useSC) Bool() else UInt(0.W)
81//   val scPred = if (useSC) Bool() else UInt(0.W)
82//   // Suppose ctrbits of all tables are identical
83//   val ctrs = if (useSC) Vec(SCNTables, SInt(SCCtrBits.W)) else Vec(SCNTables, SInt(0.W))
84// }
85
86// class TageMeta(implicit p: Parameters) extends XSBundle with HasTageParameter {
87//   val provider = ValidUndirectioned(UInt(log2Ceil(TageNTables).W))
88//   val altDiffers = Bool()
89//   val providerU = UInt(2.W)
90//   val providerCtr = UInt(3.W)
91//   val allocate = ValidUndirectioned(UInt(log2Ceil(TageNTables).W))
92//   val taken = Bool()
93//   val scMeta = new SCMeta(EnableSC)
94// }
95
96class PredictorAnswer(implicit p: Parameters) extends XSBundle {
97  val hit    = if (!env.FPGAPlatform) Bool() else UInt(0.W)
98  val taken  = if (!env.FPGAPlatform) Bool() else UInt(0.W)
99  val target = if (!env.FPGAPlatform) UInt(VAddrBits.W) else UInt(0.W)
100}
101
102// class BpuMeta(implicit p: Parameters) extends XSBundle with HasBPUParameter {
103//   val btbWriteWay = UInt(log2Up(BtbWays).W)
104//   val btbHit = Bool()
105//   val bimCtr = UInt(2.W)
106//   // val tageMeta = new TageMeta
107//   // for global history
108
109//   val debug_ubtb_cycle = if (EnableBPUTimeRecord) UInt(64.W) else UInt(0.W)
110//   val debug_btb_cycle = if (EnableBPUTimeRecord) UInt(64.W) else UInt(0.W)
111//   val debug_tage_cycle = if (EnableBPUTimeRecord) UInt(64.W) else UInt(0.W)
112
113//   val predictor = if (BPUDebug) UInt(log2Up(4).W) else UInt(0.W) // Mark which component this prediction comes from {ubtb, btb, tage, loopPredictor}
114
115//   val ubtbHit = if (BPUDebug) UInt(1.W) else UInt(0.W)
116
117//   val ubtbAns = new PredictorAnswer
118//   val btbAns = new PredictorAnswer
119//   val tageAns = new PredictorAnswer
120//   val rasAns = new PredictorAnswer
121//   val loopAns = new PredictorAnswer
122
123//   // def apply(histPtr: UInt, tageMeta: TageMeta, rasSp: UInt, rasTopCtr: UInt) = {
124//   //   this.histPtr := histPtr
125//   //   this.tageMeta := tageMeta
126//   //   this.rasSp := rasSp
127//   //   this.rasTopCtr := rasTopCtr
128//   //   this.asUInt
129//   // }
130//   def size = 0.U.asTypeOf(this).getWidth
131
132//   def fromUInt(x: UInt) = x.asTypeOf(this)
133// }
134
135class CfiUpdateInfo(implicit p: Parameters) extends XSBundle with HasBPUParameter {
136  // from backend
137  val pc = UInt(VAddrBits.W)
138  // frontend -> backend -> frontend
139  val pd = new PreDecodeInfo
140  val rasSp = UInt(log2Up(RasSize).W)
141  val rasEntry = new RASEntry
142  val hist = new GlobalHistory
143  val phist = UInt(PathHistoryLength.W)
144  val predHist = new GlobalHistory
145  val specCnt = Vec(numBr, UInt(10.W))
146  val phNewBit = Bool()
147  // need pipeline update
148  val br_hit = Bool()
149  val predTaken = Bool()
150  val target = UInt(VAddrBits.W)
151  val taken = Bool()
152  val isMisPred = Bool()
153  val shift = UInt((log2Ceil(numBr)+1).W)
154  val addIntoHist = Bool()
155}
156
157// Dequeue DecodeWidth insts from Ibuffer
158class CtrlFlow(implicit p: Parameters) extends XSBundle {
159  val instr = UInt(32.W)
160  val pc = UInt(VAddrBits.W)
161  val foldpc = UInt(MemPredPCWidth.W)
162  val exceptionVec = ExceptionVec()
163  val intrVec = Vec(12, Bool())
164  val pd = new PreDecodeInfo
165  val pred_taken = Bool()
166  val crossPageIPFFix = Bool()
167  val storeSetHit = Bool() // inst has been allocated an store set
168  val loadWaitBit = Bool() // load inst should not be executed until all former store addr calcuated
169  val ssid = UInt(SSIDWidth.W)
170  val ftqPtr = new FtqPtr
171  val ftqOffset = UInt(log2Up(PredictWidth).W)
172}
173
174class FPUCtrlSignals(implicit p: Parameters) extends XSBundle {
175  val isAddSub = Bool() // swap23
176  val typeTagIn = UInt(2.W)
177  val typeTagOut = UInt(2.W)
178  val fromInt = Bool()
179  val wflags = Bool()
180  val fpWen = Bool()
181  val fmaCmd = UInt(2.W)
182  val div = Bool()
183  val sqrt = Bool()
184  val fcvt = Bool()
185  val typ = UInt(2.W)
186  val fmt = UInt(2.W)
187  val ren3 = Bool() //TODO: remove SrcType.fp
188  val rm = UInt(3.W)
189}
190
191// Decode DecodeWidth insts at Decode Stage
192class CtrlSignals(implicit p: Parameters) extends XSBundle {
193  val srcType = Vec(3, SrcType())
194  val lsrc = Vec(3, UInt(5.W))
195  val ldest = UInt(5.W)
196  val fuType = FuType()
197  val fuOpType = FuOpType()
198  val rfWen = Bool()
199  val fpWen = Bool()
200  val isXSTrap = Bool()
201  val noSpecExec = Bool() // wait forward
202  val blockBackward = Bool() // block backward
203  val flushPipe = Bool() // This inst will flush all the pipe when commit, like exception but can commit
204  val isRVF = Bool()
205  val selImm = SelImm()
206  val imm = UInt(ImmUnion.maxLen.W)
207  val commitType = CommitType()
208  val fpu = new FPUCtrlSignals
209  val isMove = Bool()
210
211  def decode(inst: UInt, table: Iterable[(BitPat, List[BitPat])]) = {
212    val decoder = freechips.rocketchip.rocket.DecodeLogic(inst, XDecode.decodeDefault, table)
213    val signals =
214      Seq(srcType(0), srcType(1), srcType(2), fuType, fuOpType, rfWen, fpWen,
215        isXSTrap, noSpecExec, blockBackward, flushPipe, isRVF, selImm)
216    signals zip decoder map { case (s, d) => s := d }
217    commitType := DontCare
218    this
219  }
220}
221
222class CfCtrl(implicit p: Parameters) extends XSBundle {
223  val cf = new CtrlFlow
224  val ctrl = new CtrlSignals
225}
226
227class PerfDebugInfo(implicit p: Parameters) extends XSBundle {
228  val src1MoveElim = Bool()
229  val src2MoveElim = Bool()
230  // val fetchTime = UInt(64.W)
231  val renameTime = UInt(64.W)
232  val dispatchTime = UInt(64.W)
233  val issueTime = UInt(64.W)
234  val writebackTime = UInt(64.W)
235  // val commitTime = UInt(64.W)
236}
237
238// Separate LSQ
239class LSIdx(implicit p: Parameters) extends XSBundle {
240  val lqIdx = new LqPtr
241  val sqIdx = new SqPtr
242}
243
244// CfCtrl -> MicroOp at Rename Stage
245class MicroOp(implicit p: Parameters) extends CfCtrl {
246  val srcState = Vec(3, SrcState())
247  val psrc = Vec(3, UInt(PhyRegIdxWidth.W))
248  val pdest = UInt(PhyRegIdxWidth.W)
249  val old_pdest = UInt(PhyRegIdxWidth.W)
250  val roqIdx = new RoqPtr
251  val lqIdx = new LqPtr
252  val sqIdx = new SqPtr
253  val diffTestDebugLrScValid = Bool()
254  val debugInfo = new PerfDebugInfo
255  def needRfRPort(index: Int, rfType: Int, ignoreState: Boolean = true) : Bool = {
256    (index, rfType) match {
257      case (0, 0) => ctrl.srcType(0) === SrcType.reg && ctrl.lsrc(0) =/= 0.U && (srcState(0) === SrcState.rdy || ignoreState.B)
258      case (1, 0) => ctrl.srcType(1) === SrcType.reg && ctrl.lsrc(1) =/= 0.U && (srcState(1) === SrcState.rdy || ignoreState.B)
259      case (0, 1) => ctrl.srcType(0) === SrcType.fp && (srcState(0) === SrcState.rdy || ignoreState.B)
260      case (1, 1) => ctrl.srcType(1) === SrcType.fp && (srcState(1) === SrcState.rdy || ignoreState.B)
261      case (2, 1) => ctrl.srcType(2) === SrcType.fp && (srcState(2) === SrcState.rdy || ignoreState.B)
262      case _ => false.B
263    }
264  }
265  def srcIsReady: Vec[Bool] = {
266    VecInit(ctrl.srcType.zip(srcState).map{ case (t, s) => SrcType.isPcImm(t) || s === SrcState.rdy })
267  }
268  def doWriteIntRf: Bool = ctrl.rfWen && ctrl.ldest =/= 0.U
269  def doWriteFpRf: Bool = ctrl.fpWen
270}
271
272class MicroOpRbExt(implicit p: Parameters) extends XSBundle {
273  val uop = new MicroOp
274  val flag = UInt(1.W)
275}
276
277class Redirect(implicit p: Parameters) extends XSBundle {
278  val roqIdx = new RoqPtr
279  val ftqIdx = new FtqPtr
280  val ftqOffset = UInt(log2Up(PredictWidth).W)
281  val level = RedirectLevel()
282  val interrupt = Bool()
283  val cfiUpdate = new CfiUpdateInfo
284
285  val stFtqIdx = new FtqPtr // for load violation predict
286  val stFtqOffset = UInt(log2Up(PredictWidth).W)
287
288  // def isUnconditional() = RedirectLevel.isUnconditional(level)
289  def flushItself() = RedirectLevel.flushItself(level)
290  // def isException() = RedirectLevel.isException(level)
291}
292
293class Dp1ToDp2IO(implicit p: Parameters) extends XSBundle {
294  val intDqToDp2 = Vec(dpParams.IntDqDeqWidth, DecoupledIO(new MicroOp))
295  val fpDqToDp2 = Vec(dpParams.FpDqDeqWidth, DecoupledIO(new MicroOp))
296  val lsDqToDp2 = Vec(dpParams.LsDqDeqWidth, DecoupledIO(new MicroOp))
297}
298
299class ReplayPregReq(implicit p: Parameters) extends XSBundle {
300  // NOTE: set isInt and isFp both to 'false' when invalid
301  val isInt = Bool()
302  val isFp = Bool()
303  val preg = UInt(PhyRegIdxWidth.W)
304}
305
306class DebugBundle(implicit p: Parameters) extends XSBundle {
307  val isMMIO = Bool()
308  val isPerfCnt = Bool()
309  val paddr = UInt(PAddrBits.W)
310}
311
312class ExuInput(implicit p: Parameters) extends XSBundle {
313  val uop = new MicroOp
314  val src = Vec(3, UInt((XLEN + 1).W))
315}
316
317class ExuOutput(implicit p: Parameters) extends XSBundle {
318  val uop = new MicroOp
319  val data = UInt((XLEN + 1).W)
320  val fflags = UInt(5.W)
321  val redirectValid = Bool()
322  val redirect = new Redirect
323  val debug = new DebugBundle
324}
325
326class ExternalInterruptIO(implicit p: Parameters) extends XSBundle {
327  val mtip = Input(Bool())
328  val msip = Input(Bool())
329  val meip = Input(Bool())
330}
331
332class CSRSpecialIO(implicit p: Parameters) extends XSBundle {
333  val exception = Flipped(ValidIO(new MicroOp))
334  val isInterrupt = Input(Bool())
335  val memExceptionVAddr = Input(UInt(VAddrBits.W))
336  val trapTarget = Output(UInt(VAddrBits.W))
337  val externalInterrupt = new ExternalInterruptIO
338  val interrupt = Output(Bool())
339}
340
341class ExceptionInfo(implicit p: Parameters) extends XSBundle {
342  val uop = new MicroOp
343  val isInterrupt = Bool()
344}
345
346class RoqCommitInfo(implicit p: Parameters) extends XSBundle {
347  val ldest = UInt(5.W)
348  val rfWen = Bool()
349  val fpWen = Bool()
350  val wflags = Bool()
351  val commitType = CommitType()
352  val pdest = UInt(PhyRegIdxWidth.W)
353  val old_pdest = UInt(PhyRegIdxWidth.W)
354  val ftqIdx = new FtqPtr
355  val ftqOffset = UInt(log2Up(PredictWidth).W)
356
357  // these should be optimized for synthesis verilog
358  val pc = UInt(VAddrBits.W)
359}
360
361class RoqCommitIO(implicit p: Parameters) extends XSBundle {
362  val isWalk = Output(Bool())
363  val valid = Vec(CommitWidth, Output(Bool()))
364  val info = Vec(CommitWidth, Output(new RoqCommitInfo))
365
366  def hasWalkInstr = isWalk && valid.asUInt.orR
367
368  def hasCommitInstr = !isWalk && valid.asUInt.orR
369}
370
371class RSFeedback(implicit p: Parameters) extends XSBundle {
372  val rsIdx = UInt(log2Up(IssQueSize).W)
373  val hit = Bool()
374  val flushState = Bool()
375  val sourceType = RSFeedbackType()
376}
377
378class FrontendToCtrlIO(implicit p: Parameters) extends XSBundle {
379  // to backend end
380  val cfVec = Vec(DecodeWidth, DecoupledIO(new CtrlFlow))
381  val fromFtq = new FtqToCtrlIO
382  // from backend
383  val toFtq = Flipped(new CtrlToFtqIO)
384}
385
386class TlbCsrBundle(implicit p: Parameters) extends XSBundle {
387  val satp = new Bundle {
388    val mode = UInt(4.W) // TODO: may change number to parameter
389    val asid = UInt(16.W)
390    val ppn = UInt(44.W) // just use PAddrBits - 3 - vpnnLen
391  }
392  val priv = new Bundle {
393    val mxr = Bool()
394    val sum = Bool()
395    val imode = UInt(2.W)
396    val dmode = UInt(2.W)
397  }
398
399  override def toPrintable: Printable = {
400    p"Satp mode:0x${Hexadecimal(satp.mode)} asid:0x${Hexadecimal(satp.asid)} ppn:0x${Hexadecimal(satp.ppn)} " +
401      p"Priv mxr:${priv.mxr} sum:${priv.sum} imode:${priv.imode} dmode:${priv.dmode}"
402  }
403}
404
405class SfenceBundle(implicit p: Parameters) extends XSBundle {
406  val valid = Bool()
407  val bits = new Bundle {
408    val rs1 = Bool()
409    val rs2 = Bool()
410    val addr = UInt(VAddrBits.W)
411  }
412
413  override def toPrintable: Printable = {
414    p"valid:0x${Hexadecimal(valid)} rs1:${bits.rs1} rs2:${bits.rs2} addr:${Hexadecimal(bits.addr)}"
415  }
416}
417
418// Bundle for load violation predictor updating
419class MemPredUpdateReq(implicit p: Parameters) extends XSBundle  {
420  val valid = Bool()
421
422  // wait table update
423  val waddr = UInt(MemPredPCWidth.W)
424  val wdata = Bool() // true.B by default
425
426  // store set update
427  // by default, ldpc/stpc should be xor folded
428  val ldpc = UInt(MemPredPCWidth.W)
429  val stpc = UInt(MemPredPCWidth.W)
430}
431
432class CustomCSRCtrlIO(implicit p: Parameters) extends XSBundle {
433  // Prefetcher
434  val l1plus_pf_enable = Output(Bool())
435  val l2_pf_enable = Output(Bool())
436  // Labeled XiangShan
437  val dsid = Output(UInt(8.W)) // TODO: DsidWidth as parameter
438  // Load violation predictor
439  val lvpred_disable = Output(Bool())
440  val no_spec_load = Output(Bool())
441  val waittable_timeout = Output(UInt(5.W))
442  // Branch predictor
443  val bp_ctrl = Output(new BPUCtrl)
444  // Memory Block
445  val sbuffer_threshold = Output(UInt(4.W))
446  // Rename
447  val move_elim_enable = Output(Bool())
448}
449