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