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