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