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