xref: /XiangShan/src/main/scala/xiangshan/Bundle.scala (revision c361fb1ed51d2e09c48d444590bcc6d833e49307)
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(1.W)
188  val typeTagOut = UInt(1.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  val singleStep = Bool()
222
223  def decode(inst: UInt, table: Iterable[(BitPat, List[BitPat])]) = {
224    val decoder = freechips.rocketchip.rocket.DecodeLogic(inst, XDecode.decodeDefault, table)
225    val signals =
226      Seq(srcType(0), srcType(1), srcType(2), fuType, fuOpType, rfWen, fpWen,
227        isXSTrap, noSpecExec, blockBackward, flushPipe, isRVF, selImm)
228    signals zip decoder map { case (s, d) => s := d }
229    commitType := DontCare
230    this
231  }
232}
233
234class CfCtrl(implicit p: Parameters) extends XSBundle {
235  val cf = new CtrlFlow
236  val ctrl = new CtrlSignals
237}
238
239class PerfDebugInfo(implicit p: Parameters) extends XSBundle {
240  val eliminatedMove = 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 eliminatedMove = Bool()
266  val debugInfo = new PerfDebugInfo
267  def needRfRPort(index: Int, rfType: Int, ignoreState: Boolean = true) : Bool = {
268    (index, rfType) match {
269      case (0, 0) => ctrl.srcType(0) === SrcType.reg && ctrl.lsrc(0) =/= 0.U && (srcState(0) === SrcState.rdy || ignoreState.B)
270      case (1, 0) => ctrl.srcType(1) === SrcType.reg && ctrl.lsrc(1) =/= 0.U && (srcState(1) === SrcState.rdy || ignoreState.B)
271      case (0, 1) => ctrl.srcType(0) === SrcType.fp && (srcState(0) === SrcState.rdy || ignoreState.B)
272      case (1, 1) => ctrl.srcType(1) === SrcType.fp && (srcState(1) === SrcState.rdy || ignoreState.B)
273      case (2, 1) => ctrl.srcType(2) === SrcType.fp && (srcState(2) === SrcState.rdy || ignoreState.B)
274      case _ => false.B
275    }
276  }
277  def srcIsReady: Vec[Bool] = {
278    VecInit(ctrl.srcType.zip(srcState).map{ case (t, s) => SrcType.isPcImm(t) || s === SrcState.rdy })
279  }
280  def doWriteIntRf: Bool = ctrl.rfWen && ctrl.ldest =/= 0.U
281  def doWriteFpRf: Bool = ctrl.fpWen
282}
283
284class MicroOpRbExt(implicit p: Parameters) extends XSBundle {
285  val uop = new MicroOp
286  val flag = UInt(1.W)
287}
288
289class Redirect(implicit p: Parameters) extends XSBundle {
290  val roqIdx = new RoqPtr
291  val ftqIdx = new FtqPtr
292  val ftqOffset = UInt(log2Up(PredictWidth).W)
293  val level = RedirectLevel()
294  val interrupt = Bool()
295  val cfiUpdate = new CfiUpdateInfo
296
297  val stFtqIdx = new FtqPtr // for load violation predict
298  val stFtqOffset = UInt(log2Up(PredictWidth).W)
299
300  // def isUnconditional() = RedirectLevel.isUnconditional(level)
301  def flushItself() = RedirectLevel.flushItself(level)
302  // def isException() = RedirectLevel.isException(level)
303}
304
305class Dp1ToDp2IO(implicit p: Parameters) extends XSBundle {
306  val intDqToDp2 = Vec(dpParams.IntDqDeqWidth, DecoupledIO(new MicroOp))
307  val fpDqToDp2 = Vec(dpParams.FpDqDeqWidth, DecoupledIO(new MicroOp))
308  val lsDqToDp2 = Vec(dpParams.LsDqDeqWidth, DecoupledIO(new MicroOp))
309}
310
311class ReplayPregReq(implicit p: Parameters) extends XSBundle {
312  // NOTE: set isInt and isFp both to 'false' when invalid
313  val isInt = Bool()
314  val isFp = Bool()
315  val preg = UInt(PhyRegIdxWidth.W)
316}
317
318class DebugBundle(implicit p: Parameters) extends XSBundle {
319  val isMMIO = Bool()
320  val isPerfCnt = Bool()
321  val paddr = UInt(PAddrBits.W)
322}
323
324class ExuInput(implicit p: Parameters) extends XSBundle {
325  val uop = new MicroOp
326  val src = Vec(3, UInt(XLEN.W))
327}
328
329class ExuOutput(implicit p: Parameters) extends XSBundle {
330  val uop = new MicroOp
331  val data = UInt(XLEN.W)
332  val fflags = UInt(5.W)
333  val redirectValid = Bool()
334  val redirect = new Redirect
335  val debug = new DebugBundle
336}
337
338class ExternalInterruptIO(implicit p: Parameters) extends XSBundle {
339  val mtip = Input(Bool())
340  val msip = Input(Bool())
341  val meip = Input(Bool())
342  val debug = Input(Bool())
343}
344
345class CSRSpecialIO(implicit p: Parameters) extends XSBundle {
346  val exception = Flipped(ValidIO(new MicroOp))
347  val isInterrupt = Input(Bool())
348  val memExceptionVAddr = Input(UInt(VAddrBits.W))
349  val trapTarget = Output(UInt(VAddrBits.W))
350  val externalInterrupt = new ExternalInterruptIO
351  val interrupt = Output(Bool())
352}
353
354class ExceptionInfo(implicit p: Parameters) extends XSBundle {
355  val uop = new MicroOp
356  val isInterrupt = Bool()
357}
358
359class RoqCommitInfo(implicit p: Parameters) extends XSBundle {
360  val ldest = UInt(5.W)
361  val rfWen = Bool()
362  val fpWen = Bool()
363  val wflags = Bool()
364  val commitType = CommitType()
365  val eliminatedMove = Bool()
366  val pdest = UInt(PhyRegIdxWidth.W)
367  val old_pdest = UInt(PhyRegIdxWidth.W)
368  val ftqIdx = new FtqPtr
369  val ftqOffset = UInt(log2Up(PredictWidth).W)
370
371  // these should be optimized for synthesis verilog
372  val pc = UInt(VAddrBits.W)
373}
374
375class RoqCommitIO(implicit p: Parameters) extends XSBundle {
376  val isWalk = Output(Bool())
377  val valid = Vec(CommitWidth, Output(Bool()))
378  val info = Vec(CommitWidth, Output(new RoqCommitInfo))
379
380  def hasWalkInstr = isWalk && valid.asUInt.orR
381
382  def hasCommitInstr = !isWalk && valid.asUInt.orR
383}
384
385class RSFeedback(implicit p: Parameters) extends XSBundle {
386  val rsIdx = UInt(log2Up(IssQueSize).W)
387  val hit = Bool()
388  val flushState = Bool()
389  val sourceType = RSFeedbackType()
390}
391
392class FrontendToCtrlIO(implicit p: Parameters) extends XSBundle {
393  // to backend end
394  val cfVec = Vec(DecodeWidth, DecoupledIO(new CtrlFlow))
395  val fromFtq = new FtqToCtrlIO
396  // from backend
397  val toFtq = Flipped(new CtrlToFtqIO)
398}
399
400class TlbCsrBundle(implicit p: Parameters) extends XSBundle {
401  val satp = new Bundle {
402    val mode = UInt(4.W) // TODO: may change number to parameter
403    val asid = UInt(16.W)
404    val ppn = UInt(44.W) // just use PAddrBits - 3 - vpnnLen
405  }
406  val priv = new Bundle {
407    val mxr = Bool()
408    val sum = Bool()
409    val imode = UInt(2.W)
410    val dmode = UInt(2.W)
411  }
412
413  override def toPrintable: Printable = {
414    p"Satp mode:0x${Hexadecimal(satp.mode)} asid:0x${Hexadecimal(satp.asid)} ppn:0x${Hexadecimal(satp.ppn)} " +
415      p"Priv mxr:${priv.mxr} sum:${priv.sum} imode:${priv.imode} dmode:${priv.dmode}"
416  }
417}
418
419class SfenceBundle(implicit p: Parameters) extends XSBundle {
420  val valid = Bool()
421  val bits = new Bundle {
422    val rs1 = Bool()
423    val rs2 = Bool()
424    val addr = UInt(VAddrBits.W)
425  }
426
427  override def toPrintable: Printable = {
428    p"valid:0x${Hexadecimal(valid)} rs1:${bits.rs1} rs2:${bits.rs2} addr:${Hexadecimal(bits.addr)}"
429  }
430}
431
432// Bundle for load violation predictor updating
433class MemPredUpdateReq(implicit p: Parameters) extends XSBundle  {
434  val valid = Bool()
435
436  // wait table update
437  val waddr = UInt(MemPredPCWidth.W)
438  val wdata = Bool() // true.B by default
439
440  // store set update
441  // by default, ldpc/stpc should be xor folded
442  val ldpc = UInt(MemPredPCWidth.W)
443  val stpc = UInt(MemPredPCWidth.W)
444}
445
446class CustomCSRCtrlIO(implicit p: Parameters) extends XSBundle {
447  // Prefetcher
448  val l1plus_pf_enable = Output(Bool())
449  val l2_pf_enable = Output(Bool())
450  // Labeled XiangShan
451  val dsid = Output(UInt(8.W)) // TODO: DsidWidth as parameter
452  // Load violation predictor
453  val lvpred_disable = Output(Bool())
454  val no_spec_load = Output(Bool())
455  val waittable_timeout = Output(UInt(5.W))
456  // Branch predictor
457  val bp_ctrl = Output(new BPUCtrl)
458  // Memory Block
459  val sbuffer_threshold = Output(UInt(4.W))
460  // Rename
461  val move_elim_enable = Output(Bool())
462}
463