1*09c6f1ddSLingrui98/*************************************************************************************** 2*09c6f1ddSLingrui98* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3*09c6f1ddSLingrui98* Copyright (c) 2020-2021 Peng Cheng Laboratory 4*09c6f1ddSLingrui98* 5*09c6f1ddSLingrui98* XiangShan is licensed under Mulan PSL v2. 6*09c6f1ddSLingrui98* You can use this software according to the terms and conditions of the Mulan PSL v2. 7*09c6f1ddSLingrui98* You may obtain a copy of Mulan PSL v2 at: 8*09c6f1ddSLingrui98* http://license.coscl.org.cn/MulanPSL2 9*09c6f1ddSLingrui98* 10*09c6f1ddSLingrui98* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11*09c6f1ddSLingrui98* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12*09c6f1ddSLingrui98* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13*09c6f1ddSLingrui98* 14*09c6f1ddSLingrui98* See the Mulan PSL v2 for more details. 15*09c6f1ddSLingrui98***************************************************************************************/ 16*09c6f1ddSLingrui98 17*09c6f1ddSLingrui98package xiangshan.frontend 18*09c6f1ddSLingrui98 19*09c6f1ddSLingrui98import chipsalliance.rocketchip.config.Parameters 20*09c6f1ddSLingrui98import chisel3._ 21*09c6f1ddSLingrui98import chisel3.util._ 22*09c6f1ddSLingrui98import xiangshan._ 23*09c6f1ddSLingrui98import utils._ 24*09c6f1ddSLingrui98import chisel3.experimental.chiselName 25*09c6f1ddSLingrui98 26*09c6f1ddSLingrui98import scala.math.min 27*09c6f1ddSLingrui98 28*09c6f1ddSLingrui98trait HasSCParameter extends TageParams { 29*09c6f1ddSLingrui98 val BankSCHistLens = BankTableInfos.map(info => 0 :: info.map{ case (_,h,_) => h}.toList) 30*09c6f1ddSLingrui98 val BankSCNTables = List(6, 6) 31*09c6f1ddSLingrui98 val SCCtrBits = 6 32*09c6f1ddSLingrui98 val SCNRows = 1024 33*09c6f1ddSLingrui98 val BankSCTableInfos = (BankSCNTables zip BankSCHistLens).map { 34*09c6f1ddSLingrui98 case (ntable, histlens) => 35*09c6f1ddSLingrui98 Seq.fill(ntable)((SCNRows, SCCtrBits)) zip histlens map {case ((n, cb), h) => (n, cb, h)} 36*09c6f1ddSLingrui98 } 37*09c6f1ddSLingrui98} 38*09c6f1ddSLingrui98 39*09c6f1ddSLingrui98class SCReq(implicit p: Parameters) extends TageReq 40*09c6f1ddSLingrui98 41*09c6f1ddSLingrui98abstract class SCBundle(implicit p: Parameters) extends TageBundle with HasSCParameter {} 42*09c6f1ddSLingrui98abstract class SCModule(implicit p: Parameters) extends TageModule with HasSCParameter {} 43*09c6f1ddSLingrui98 44*09c6f1ddSLingrui98 45*09c6f1ddSLingrui98class SCMeta(val useSC: Boolean, val ntables: Int)(implicit p: Parameters) extends XSBundle with HasSCParameter { 46*09c6f1ddSLingrui98 val tageTaken = if (useSC) Bool() else UInt(0.W) 47*09c6f1ddSLingrui98 val scUsed = if (useSC) Bool() else UInt(0.W) 48*09c6f1ddSLingrui98 val scPred = if (useSC) Bool() else UInt(0.W) 49*09c6f1ddSLingrui98 // Suppose ctrbits of all tables are identical 50*09c6f1ddSLingrui98 val ctrs = if (useSC) Vec(ntables, SInt(SCCtrBits.W)) else Vec(ntables, SInt(0.W)) 51*09c6f1ddSLingrui98} 52*09c6f1ddSLingrui98 53*09c6f1ddSLingrui98 54*09c6f1ddSLingrui98class SCResp(val ctrBits: Int = 6)(implicit p: Parameters) extends SCBundle { 55*09c6f1ddSLingrui98 val ctr = Vec(2, SInt(ctrBits.W)) 56*09c6f1ddSLingrui98} 57*09c6f1ddSLingrui98 58*09c6f1ddSLingrui98class SCUpdate(val ctrBits: Int = 6)(implicit p: Parameters) extends SCBundle { 59*09c6f1ddSLingrui98 val pc = UInt(VAddrBits.W) 60*09c6f1ddSLingrui98 val hist = UInt(HistoryLength.W) 61*09c6f1ddSLingrui98 val mask = Bool() 62*09c6f1ddSLingrui98 val oldCtr = SInt(ctrBits.W) 63*09c6f1ddSLingrui98 val tagePred = Bool() 64*09c6f1ddSLingrui98 val taken = Bool() 65*09c6f1ddSLingrui98} 66*09c6f1ddSLingrui98 67*09c6f1ddSLingrui98class SCTableIO(val ctrBits: Int = 6)(implicit p: Parameters) extends SCBundle { 68*09c6f1ddSLingrui98 val req = Input(Valid(new SCReq)) 69*09c6f1ddSLingrui98 val resp = Output(new SCResp(ctrBits)) 70*09c6f1ddSLingrui98 val update = Input(new SCUpdate(ctrBits)) 71*09c6f1ddSLingrui98} 72*09c6f1ddSLingrui98 73*09c6f1ddSLingrui98@chiselName 74*09c6f1ddSLingrui98class SCTable(val nRows: Int, val ctrBits: Int, val histLen: Int)(implicit p: Parameters) 75*09c6f1ddSLingrui98 extends SCModule with HasFoldedHistory { 76*09c6f1ddSLingrui98 val io = IO(new SCTableIO(ctrBits)) 77*09c6f1ddSLingrui98 78*09c6f1ddSLingrui98 // val table = Module(new SRAMTemplate(SInt(ctrBits.W), set=nRows, way=2*TageBanks, shouldReset=true, holdRead=true, singlePort=false)) 79*09c6f1ddSLingrui98 val table = Module(new SRAMTemplate(SInt(ctrBits.W), set=nRows, way=2, shouldReset=true, holdRead=true, singlePort=false)) 80*09c6f1ddSLingrui98 81*09c6f1ddSLingrui98 val phistLen = PathHistoryLength 82*09c6f1ddSLingrui98 def getIdx(hist: UInt, pc: UInt) = { 83*09c6f1ddSLingrui98 (compute_folded_ghist(hist, log2Ceil(nRows)) ^ (pc >> instOffsetBits))(log2Ceil(nRows)-1,0) 84*09c6f1ddSLingrui98 } 85*09c6f1ddSLingrui98 86*09c6f1ddSLingrui98 def ctrUpdate(ctr: SInt, cond: Bool): SInt = signedSatUpdate(ctr, ctrBits, cond) 87*09c6f1ddSLingrui98 88*09c6f1ddSLingrui98 val s0_idx = getIdx(io.req.bits.hist, io.req.bits.pc) 89*09c6f1ddSLingrui98 val s1_idx = RegEnable(s0_idx, enable=io.req.valid) 90*09c6f1ddSLingrui98 91*09c6f1ddSLingrui98 table.io.r.req.valid := io.req.valid 92*09c6f1ddSLingrui98 table.io.r.req.bits.setIdx := s0_idx 93*09c6f1ddSLingrui98 94*09c6f1ddSLingrui98 io.resp.ctr := table.io.r.resp.data 95*09c6f1ddSLingrui98 96*09c6f1ddSLingrui98 val update_wdata = Wire(SInt(ctrBits.W)) 97*09c6f1ddSLingrui98 val updateWayMask = 98*09c6f1ddSLingrui98 VecInit((0 to 1).map(io.update.mask && _.U === io.update.tagePred.asUInt)).asUInt 99*09c6f1ddSLingrui98 100*09c6f1ddSLingrui98 val update_idx = getIdx(io.update.hist, io.update.pc) 101*09c6f1ddSLingrui98 102*09c6f1ddSLingrui98 table.io.w.apply( 103*09c6f1ddSLingrui98 valid = io.update.mask, 104*09c6f1ddSLingrui98 data = VecInit(Seq.fill(2)(update_wdata)), 105*09c6f1ddSLingrui98 setIdx = update_idx, 106*09c6f1ddSLingrui98 waymask = updateWayMask 107*09c6f1ddSLingrui98 ) 108*09c6f1ddSLingrui98 109*09c6f1ddSLingrui98 val wrBypassEntries = 4 110*09c6f1ddSLingrui98 111*09c6f1ddSLingrui98 class SCWrBypass extends XSModule { 112*09c6f1ddSLingrui98 val io = IO(new Bundle { 113*09c6f1ddSLingrui98 val wen = Input(Bool()) 114*09c6f1ddSLingrui98 val update_idx = Input(UInt(log2Ceil(nRows).W)) 115*09c6f1ddSLingrui98 val update_ctrs = Flipped(ValidIO(SInt(ctrBits.W))) 116*09c6f1ddSLingrui98 val update_ctrPos = Input(UInt(log2Ceil(2).W)) 117*09c6f1ddSLingrui98 val update_altPos = Input(UInt(log2Ceil(2).W)) 118*09c6f1ddSLingrui98 119*09c6f1ddSLingrui98 val hit = Output(Bool()) 120*09c6f1ddSLingrui98 val ctrs = Vec(2, ValidIO(SInt(ctrBits.W))) 121*09c6f1ddSLingrui98 }) 122*09c6f1ddSLingrui98 123*09c6f1ddSLingrui98 val idxes = RegInit(0.U.asTypeOf(Vec(wrBypassEntries, UInt(log2Ceil(nRows).W)))) 124*09c6f1ddSLingrui98 val ctrs = RegInit(0.U.asTypeOf(Vec(wrBypassEntries, Vec(2, SInt(ctrBits.W))))) 125*09c6f1ddSLingrui98 val ctr_valids = RegInit(0.U.asTypeOf(Vec(wrBypassEntries, Vec(2, Bool())))) 126*09c6f1ddSLingrui98 val enq_idx = RegInit(0.U(log2Ceil(wrBypassEntries).W)) 127*09c6f1ddSLingrui98 128*09c6f1ddSLingrui98 val hits = VecInit((0 until wrBypassEntries).map { i => idxes(i) === io.update_idx }) 129*09c6f1ddSLingrui98 130*09c6f1ddSLingrui98 val hit = hits.reduce(_||_) 131*09c6f1ddSLingrui98 val hit_idx = ParallelPriorityEncoder(hits) 132*09c6f1ddSLingrui98 133*09c6f1ddSLingrui98 io.hit := hit 134*09c6f1ddSLingrui98 135*09c6f1ddSLingrui98 for (i <- 0 until 2) { 136*09c6f1ddSLingrui98 io.ctrs(i).valid := ctr_valids(hit_idx)(i) 137*09c6f1ddSLingrui98 io.ctrs(i).bits := ctrs(hit_idx)(i) 138*09c6f1ddSLingrui98 } 139*09c6f1ddSLingrui98 140*09c6f1ddSLingrui98 when (io.wen) { 141*09c6f1ddSLingrui98 when (hit) { 142*09c6f1ddSLingrui98 ctrs(hit_idx)(io.update_ctrPos) := io.update_ctrs.bits 143*09c6f1ddSLingrui98 ctr_valids(hit_idx)(io.update_ctrPos) := io.update_ctrs.valid 144*09c6f1ddSLingrui98 }.otherwise { 145*09c6f1ddSLingrui98 ctr_valids(enq_idx)(io.update_altPos) := false.B 146*09c6f1ddSLingrui98 ctr_valids(enq_idx)(io.update_ctrPos) := io.update_ctrs.valid 147*09c6f1ddSLingrui98 ctrs(enq_idx)(io.update_ctrPos) := io.update_ctrs.bits 148*09c6f1ddSLingrui98 } 149*09c6f1ddSLingrui98 } 150*09c6f1ddSLingrui98 151*09c6f1ddSLingrui98 when(io.wen && !hit) { 152*09c6f1ddSLingrui98 idxes(enq_idx) := io.update_idx 153*09c6f1ddSLingrui98 enq_idx := (enq_idx + 1.U)(log2Ceil(wrBypassEntries)-1, 0) 154*09c6f1ddSLingrui98 } 155*09c6f1ddSLingrui98 } 156*09c6f1ddSLingrui98 157*09c6f1ddSLingrui98 val wrbypass = Module(new SCWrBypass) 158*09c6f1ddSLingrui98 159*09c6f1ddSLingrui98 val ctrPos = io.update.tagePred 160*09c6f1ddSLingrui98 val altPos = !io.update.tagePred 161*09c6f1ddSLingrui98 val bypass_ctr = wrbypass.io.ctrs(ctrPos) 162*09c6f1ddSLingrui98 val hit_and_valid = wrbypass.io.hit && bypass_ctr.valid 163*09c6f1ddSLingrui98 val oldCtr = Mux(hit_and_valid, bypass_ctr.bits, io.update.oldCtr) 164*09c6f1ddSLingrui98 update_wdata := ctrUpdate(oldCtr, io.update.taken) 165*09c6f1ddSLingrui98 166*09c6f1ddSLingrui98 wrbypass.io.wen := io.update.mask 167*09c6f1ddSLingrui98 wrbypass.io.update_ctrs.valid := io.update.mask 168*09c6f1ddSLingrui98 wrbypass.io.update_ctrs.bits := update_wdata 169*09c6f1ddSLingrui98 wrbypass.io.update_idx := update_idx 170*09c6f1ddSLingrui98 wrbypass.io.update_ctrPos := ctrPos 171*09c6f1ddSLingrui98 wrbypass.io.update_altPos := altPos 172*09c6f1ddSLingrui98 173*09c6f1ddSLingrui98 if (BPUDebug && debug) { 174*09c6f1ddSLingrui98 val u = io.update 175*09c6f1ddSLingrui98 XSDebug(io.req.valid, 176*09c6f1ddSLingrui98 p"scTableReq: pc=0x${Hexadecimal(io.req.bits.pc)}, " + 177*09c6f1ddSLingrui98 p"s0_idx=${s0_idx}, hist=${Hexadecimal(io.req.bits.hist)}\n") 178*09c6f1ddSLingrui98 XSDebug(RegNext(io.req.valid), 179*09c6f1ddSLingrui98 p"scTableResp: s1_idx=${s1_idx}," + 180*09c6f1ddSLingrui98 p"ctr:${io.resp.ctr}\n") 181*09c6f1ddSLingrui98 XSDebug(io.update.mask, 182*09c6f1ddSLingrui98 p"update Table: pc:${Hexadecimal(u.pc)}, hist:${Hexadecimal(u.hist)}, " + 183*09c6f1ddSLingrui98 p"tageTaken:${u.tagePred}, taken:${u.taken}, oldCtr:${u.oldCtr}\n") 184*09c6f1ddSLingrui98 val ctrPos = io.update.tagePred 185*09c6f1ddSLingrui98 val hitCtr = wrbypass.io.ctrs(ctrPos).bits 186*09c6f1ddSLingrui98 XSDebug(wrbypass.io.hit && wrbypass.io.ctrs(ctrPos).valid && io.update.mask, 187*09c6f1ddSLingrui98 p"wrbypass hit idx:$update_idx, ctr:$hitCtr, " + 188*09c6f1ddSLingrui98 p"taken:${io.update.taken} newCtr:${update_wdata}\n") 189*09c6f1ddSLingrui98 } 190*09c6f1ddSLingrui98 191*09c6f1ddSLingrui98} 192*09c6f1ddSLingrui98 193*09c6f1ddSLingrui98class SCThreshold(val ctrBits: Int = 6)(implicit p: Parameters) extends SCBundle { 194*09c6f1ddSLingrui98 val ctr = UInt(ctrBits.W) 195*09c6f1ddSLingrui98 def satPos(ctr: UInt = this.ctr) = ctr === ((1.U << ctrBits) - 1.U) 196*09c6f1ddSLingrui98 def satNeg(ctr: UInt = this.ctr) = ctr === 0.U 197*09c6f1ddSLingrui98 def neutralVal = (1.U << (ctrBits - 1)) 198*09c6f1ddSLingrui98 val thres = UInt(8.W) 199*09c6f1ddSLingrui98 def initVal = 6.U 200*09c6f1ddSLingrui98 def minThres = 6.U 201*09c6f1ddSLingrui98 def maxThres = 31.U 202*09c6f1ddSLingrui98 def update(cause: Bool): SCThreshold = { 203*09c6f1ddSLingrui98 val res = Wire(new SCThreshold(this.ctrBits)) 204*09c6f1ddSLingrui98 val newCtr = satUpdate(this.ctr, this.ctrBits, cause) 205*09c6f1ddSLingrui98 val newThres = Mux(res.satPos(newCtr) && this.thres <= maxThres, this.thres + 2.U, 206*09c6f1ddSLingrui98 Mux(res.satNeg(newCtr) && this.thres >= minThres, this.thres - 2.U, 207*09c6f1ddSLingrui98 this.thres)) 208*09c6f1ddSLingrui98 res.thres := newThres 209*09c6f1ddSLingrui98 res.ctr := Mux(res.satPos(newCtr) || res.satNeg(newCtr), res.neutralVal, newCtr) 210*09c6f1ddSLingrui98 // XSDebug(true.B, p"scThres Update: cause${cause} newCtr ${newCtr} newThres ${newThres}\n") 211*09c6f1ddSLingrui98 res 212*09c6f1ddSLingrui98 } 213*09c6f1ddSLingrui98} 214*09c6f1ddSLingrui98 215*09c6f1ddSLingrui98object SCThreshold { 216*09c6f1ddSLingrui98 def apply(bits: Int)(implicit p: Parameters) = { 217*09c6f1ddSLingrui98 val t = Wire(new SCThreshold(ctrBits=bits)) 218*09c6f1ddSLingrui98 t.ctr := t.neutralVal 219*09c6f1ddSLingrui98 t.thres := t.initVal 220*09c6f1ddSLingrui98 t 221*09c6f1ddSLingrui98 } 222*09c6f1ddSLingrui98} 223*09c6f1ddSLingrui98 224*09c6f1ddSLingrui98 225*09c6f1ddSLingrui98trait HasSC extends HasSCParameter { this: Tage => 226*09c6f1ddSLingrui98 227*09c6f1ddSLingrui98 val bank_scTables = BankSCTableInfos.zipWithIndex.map { 228*09c6f1ddSLingrui98 case (info, b) => 229*09c6f1ddSLingrui98 val tables = info.map { 230*09c6f1ddSLingrui98 case (nRows, ctrBits, histLen) => { 231*09c6f1ddSLingrui98 val t = Module(new SCTable(nRows/TageBanks, ctrBits, histLen)) 232*09c6f1ddSLingrui98 val req = t.io.req 233*09c6f1ddSLingrui98 req.valid := io.s0_fire 234*09c6f1ddSLingrui98 req.bits.pc := s0_pc 235*09c6f1ddSLingrui98 req.bits.hist := io.in.bits.ghist << b 236*09c6f1ddSLingrui98 req.bits.phist := DontCare 237*09c6f1ddSLingrui98 if (!EnableSC) {t.io.update := DontCare} 238*09c6f1ddSLingrui98 t 239*09c6f1ddSLingrui98 } 240*09c6f1ddSLingrui98 } 241*09c6f1ddSLingrui98 tables 242*09c6f1ddSLingrui98 } 243*09c6f1ddSLingrui98 244*09c6f1ddSLingrui98 val scThresholds = List.fill(TageBanks)(RegInit(SCThreshold(5))) 245*09c6f1ddSLingrui98 val useThresholds = VecInit(scThresholds map (_.thres)) 246*09c6f1ddSLingrui98 val updateThresholds = VecInit(useThresholds map (t => (t << 3) +& 21.U)) 247*09c6f1ddSLingrui98 248*09c6f1ddSLingrui98 val s1_scResps = MixedVecInit(bank_scTables.map(b => VecInit(b.map(t => t.io.resp)))) 249*09c6f1ddSLingrui98 250*09c6f1ddSLingrui98 val scUpdateMask = WireInit(0.U.asTypeOf(MixedVec(BankSCNTables.map(Vec(_, Bool()))))) 251*09c6f1ddSLingrui98 val scUpdateTagePreds = Wire(Vec(TageBanks, Bool())) 252*09c6f1ddSLingrui98 val scUpdateTakens = Wire(Vec(TageBanks, Bool())) 253*09c6f1ddSLingrui98 val scUpdateOldCtrs = Wire(MixedVec(BankSCNTables.map(Vec(_, SInt(SCCtrBits.W))))) 254*09c6f1ddSLingrui98 scUpdateTagePreds := DontCare 255*09c6f1ddSLingrui98 scUpdateTakens := DontCare 256*09c6f1ddSLingrui98 scUpdateOldCtrs := DontCare 257*09c6f1ddSLingrui98 258*09c6f1ddSLingrui98 val updateSCMetas = VecInit(updateMetas.map(_.scMeta)) 259*09c6f1ddSLingrui98 260*09c6f1ddSLingrui98 val s2_sc_used, s2_conf, s2_unconf, s2_agree, s2_disagree = 261*09c6f1ddSLingrui98 0.U.asTypeOf(Vec(TageBanks, Bool())) 262*09c6f1ddSLingrui98 val update_sc_used, update_conf, update_unconf, update_agree, update_disagree = 263*09c6f1ddSLingrui98 0.U.asTypeOf(Vec(TageBanks, Bool())) 264*09c6f1ddSLingrui98 val update_on_mispred, update_on_unconf, sc_misp_tage_corr, sc_corr_tage_misp = 265*09c6f1ddSLingrui98 0.U.asTypeOf(Vec(TageBanks, Bool())) 266*09c6f1ddSLingrui98 267*09c6f1ddSLingrui98 // for sc ctrs 268*09c6f1ddSLingrui98 def getCentered(ctr: SInt): SInt = (ctr << 1).asSInt + 1.S 269*09c6f1ddSLingrui98 // for tage ctrs 270*09c6f1ddSLingrui98 def getPvdrCentered(ctr: UInt): SInt = ((((ctr.zext -& 4.S) << 1).asSInt + 1.S) << 3).asSInt 271*09c6f1ddSLingrui98 272*09c6f1ddSLingrui98 for (w <- 0 until TageBanks) { 273*09c6f1ddSLingrui98 val scMeta = resp_meta(w).scMeta 274*09c6f1ddSLingrui98 scMeta := DontCare 275*09c6f1ddSLingrui98 // do summation in s2 276*09c6f1ddSLingrui98 val s1_scTableSums = VecInit( 277*09c6f1ddSLingrui98 (0 to 1) map { i => 278*09c6f1ddSLingrui98 ParallelSingedExpandingAdd(s1_scResps(w) map (r => getCentered(r.ctr(i)))) // TODO: rewrite with wallace tree 279*09c6f1ddSLingrui98 } 280*09c6f1ddSLingrui98 ) 281*09c6f1ddSLingrui98 282*09c6f1ddSLingrui98 val providerCtr = s1_providerCtrs(w) 283*09c6f1ddSLingrui98 val s1_pvdrCtrCentered = getPvdrCentered(providerCtr) 284*09c6f1ddSLingrui98 val s1_totalSums = VecInit(s1_scTableSums.map(_ +& s1_pvdrCtrCentered)) 285*09c6f1ddSLingrui98 val s1_sumAbs = VecInit(s1_totalSums.map(_.abs.asUInt)) 286*09c6f1ddSLingrui98 val s1_sumBelowThresholds = VecInit(s1_sumAbs map (_ <= useThresholds(w))) 287*09c6f1ddSLingrui98 val s1_scPreds = VecInit(s1_totalSums.map (_ >= 0.S)) 288*09c6f1ddSLingrui98 289*09c6f1ddSLingrui98 val s2_sumBelowThresholds = RegEnable(s1_sumBelowThresholds, io.s1_fire) 290*09c6f1ddSLingrui98 val s2_scPreds = RegEnable(s1_scPreds, io.s1_fire) 291*09c6f1ddSLingrui98 val s2_sumAbs = RegEnable(s1_sumAbs, io.s1_fire) 292*09c6f1ddSLingrui98 293*09c6f1ddSLingrui98 val s2_scCtrs = RegEnable(VecInit(s1_scResps(w).map(r => r.ctr(s1_tageTakens(w).asUInt))), io.s1_fire) 294*09c6f1ddSLingrui98 val s2_chooseBit = s2_tageTakens(w) 295*09c6f1ddSLingrui98 scMeta.tageTaken := s2_tageTakens(w) 296*09c6f1ddSLingrui98 scMeta.scUsed := s2_provideds(w) 297*09c6f1ddSLingrui98 scMeta.scPred := s2_scPreds(s2_chooseBit) 298*09c6f1ddSLingrui98 scMeta.ctrs := s2_scCtrs 299*09c6f1ddSLingrui98 300*09c6f1ddSLingrui98 when (s2_provideds(w)) { 301*09c6f1ddSLingrui98 s2_sc_used(w) := true.B 302*09c6f1ddSLingrui98 s2_unconf(w) := s2_sumBelowThresholds(s2_chooseBit) 303*09c6f1ddSLingrui98 s2_conf(w) := !s2_sumBelowThresholds(s2_chooseBit) 304*09c6f1ddSLingrui98 // Use prediction from Statistical Corrector 305*09c6f1ddSLingrui98 XSDebug(p"---------tage_bank_${w} provided so that sc used---------\n") 306*09c6f1ddSLingrui98 XSDebug(p"scCtrs:$s2_scCtrs, prdrCtr:${s2_providerCtrs(w)}, sumAbs:$s2_sumAbs, tageTaken:${s2_chooseBit}\n") 307*09c6f1ddSLingrui98 when (!s2_sumBelowThresholds(s2_chooseBit)) { 308*09c6f1ddSLingrui98 val pred = s2_scPreds(s2_chooseBit) 309*09c6f1ddSLingrui98 val debug_pc = Cat(debug_pc_s2, w.U, 0.U(instOffsetBits.W)) 310*09c6f1ddSLingrui98 s2_agree(w) := s2_tageTakens(w) === pred 311*09c6f1ddSLingrui98 s2_disagree(w) := s2_tageTakens(w) =/= pred 312*09c6f1ddSLingrui98 // fit to always-taken condition 313*09c6f1ddSLingrui98 io.out.resp.s2.preds.taken_mask(w) := pred 314*09c6f1ddSLingrui98 XSDebug(p"pc(${Hexadecimal(debug_pc)}) SC(${w.U}) overriden pred to ${pred}\n") 315*09c6f1ddSLingrui98 } 316*09c6f1ddSLingrui98 } 317*09c6f1ddSLingrui98 318*09c6f1ddSLingrui98 val updateSCMeta = updateSCMetas(w) 319*09c6f1ddSLingrui98 val updateTageMeta = updateMetas(w) 320*09c6f1ddSLingrui98 when (updateValids(w) && updateSCMeta.scUsed.asBool) { 321*09c6f1ddSLingrui98 val scPred = updateSCMeta.scPred 322*09c6f1ddSLingrui98 val tagePred = updateSCMeta.tageTaken 323*09c6f1ddSLingrui98 val taken = update.preds.taken_mask(w) 324*09c6f1ddSLingrui98 val scOldCtrs = updateSCMeta.ctrs 325*09c6f1ddSLingrui98 val pvdrCtr = updateTageMeta.providerCtr 326*09c6f1ddSLingrui98 val sum = ParallelSingedExpandingAdd(scOldCtrs.map(getCentered)) +& getPvdrCentered(pvdrCtr) 327*09c6f1ddSLingrui98 val sumAbs = sum.abs.asUInt 328*09c6f1ddSLingrui98 scUpdateTagePreds(w) := tagePred 329*09c6f1ddSLingrui98 scUpdateTakens(w) := taken 330*09c6f1ddSLingrui98 (scUpdateOldCtrs(w) zip scOldCtrs).foreach{case (t, c) => t := c} 331*09c6f1ddSLingrui98 332*09c6f1ddSLingrui98 update_sc_used(w) := true.B 333*09c6f1ddSLingrui98 update_unconf(w) := sumAbs < useThresholds(w) 334*09c6f1ddSLingrui98 update_conf(w) := sumAbs >= useThresholds(w) 335*09c6f1ddSLingrui98 update_agree(w) := scPred === tagePred 336*09c6f1ddSLingrui98 update_disagree(w) := scPred =/= tagePred 337*09c6f1ddSLingrui98 sc_corr_tage_misp(w) := scPred === taken && tagePred =/= taken && update_conf(w) 338*09c6f1ddSLingrui98 sc_misp_tage_corr(w) := scPred =/= taken && tagePred === taken && update_conf(w) 339*09c6f1ddSLingrui98 340*09c6f1ddSLingrui98 val thres = useThresholds(w) 341*09c6f1ddSLingrui98 when (scPred =/= tagePred && sumAbs >= thres - 4.U && sumAbs <= thres - 2.U) { 342*09c6f1ddSLingrui98 val newThres = scThresholds(w).update(scPred =/= taken) 343*09c6f1ddSLingrui98 scThresholds(w) := newThres 344*09c6f1ddSLingrui98 XSDebug(p"scThres $w update: old ${useThresholds(w)} --> new ${newThres.thres}\n") 345*09c6f1ddSLingrui98 } 346*09c6f1ddSLingrui98 347*09c6f1ddSLingrui98 val updateThres = updateThresholds(w) 348*09c6f1ddSLingrui98 when (scPred =/= taken || sumAbs < updateThres) { 349*09c6f1ddSLingrui98 scUpdateMask(w).foreach(_ := true.B) 350*09c6f1ddSLingrui98 XSDebug(sum < 0.S, 351*09c6f1ddSLingrui98 p"scUpdate: bank(${w}), scPred(${scPred}), tagePred(${tagePred}), " + 352*09c6f1ddSLingrui98 p"scSum(-$sumAbs), mispred: sc(${scPred =/= taken}), tage(${updateMisPreds(w)})\n" 353*09c6f1ddSLingrui98 ) 354*09c6f1ddSLingrui98 XSDebug(sum >= 0.S, 355*09c6f1ddSLingrui98 p"scUpdate: bank(${w}), scPred(${scPred}), tagePred(${tagePred}), " + 356*09c6f1ddSLingrui98 p"scSum(+$sumAbs), mispred: sc(${scPred =/= taken}), tage(${updateMisPreds(w)})\n" 357*09c6f1ddSLingrui98 ) 358*09c6f1ddSLingrui98 XSDebug(p"bank(${w}), update: sc: ${updateSCMeta}\n") 359*09c6f1ddSLingrui98 update_on_mispred(w) := scPred =/= taken 360*09c6f1ddSLingrui98 update_on_unconf(w) := scPred === taken 361*09c6f1ddSLingrui98 } 362*09c6f1ddSLingrui98 } 363*09c6f1ddSLingrui98 } 364*09c6f1ddSLingrui98 365*09c6f1ddSLingrui98 366*09c6f1ddSLingrui98 for (b <- 0 until TageBanks) { 367*09c6f1ddSLingrui98 for (i <- 0 until BankSCNTables(b)) { 368*09c6f1ddSLingrui98 bank_scTables(b)(i).io.update.mask := RegNext(scUpdateMask(b)(i)) 369*09c6f1ddSLingrui98 bank_scTables(b)(i).io.update.tagePred := RegNext(scUpdateTagePreds(b)) 370*09c6f1ddSLingrui98 bank_scTables(b)(i).io.update.taken := RegNext(scUpdateTakens(b)) 371*09c6f1ddSLingrui98 bank_scTables(b)(i).io.update.oldCtr := RegNext(scUpdateOldCtrs(b)(i)) 372*09c6f1ddSLingrui98 bank_scTables(b)(i).io.update.pc := RegNext(update.pc) 373*09c6f1ddSLingrui98 bank_scTables(b)(i).io.update.hist := RegNext(updateHist.predHist << b) 374*09c6f1ddSLingrui98 } 375*09c6f1ddSLingrui98 } 376*09c6f1ddSLingrui98 377*09c6f1ddSLingrui98 tage_perf("sc_conf", PopCount(s2_conf), PopCount(update_conf)) 378*09c6f1ddSLingrui98 tage_perf("sc_unconf", PopCount(s2_unconf), PopCount(update_unconf)) 379*09c6f1ddSLingrui98 tage_perf("sc_agree", PopCount(s2_agree), PopCount(update_agree)) 380*09c6f1ddSLingrui98 tage_perf("sc_disagree", PopCount(s2_disagree), PopCount(update_disagree)) 381*09c6f1ddSLingrui98 tage_perf("sc_used", PopCount(s2_sc_used), PopCount(update_sc_used)) 382*09c6f1ddSLingrui98 XSPerfAccumulate("sc_update_on_mispred", PopCount(update_on_mispred)) 383*09c6f1ddSLingrui98 XSPerfAccumulate("sc_update_on_unconf", PopCount(update_on_unconf)) 384*09c6f1ddSLingrui98 XSPerfAccumulate("sc_mispred_but_tage_correct", PopCount(sc_misp_tage_corr)) 385*09c6f1ddSLingrui98 XSPerfAccumulate("sc_correct_and_tage_wrong", PopCount(sc_corr_tage_misp)) 386*09c6f1ddSLingrui98} 387