1package xiangshan.frontend 2 3import chisel3._ 4import chisel3.util._ 5import xiangshan._ 6import xiangshan.backend.ALUOpType 7import utils._ 8 9class RAS extends BasePredictor 10 with RASParameter 11{ 12 class RASResp extends Resp 13 { 14 val target =ValiIO(UInt(VAddrBits.W)) 15 } 16 17 class RASBranchInfo extends Meta 18 { 19 val rasSp = UInt(log2Up(RasSize).W) 20 val rasTopCtr = UInt(8.W) 21 } 22 23 class RASIO extends DefaultBasePredictorIO 24 { 25 val is_ret = Input(Bool()) 26 val callIdx = Flipped(ValidIO(UInt(log2Ceil(PredictWidth).W))) 27 val isRVC = Input(Bool()) 28 val redirect = Flipped(ValidIO(new Redirect))) 29 val out = ValidIO(new RASResp) 30 val branchInfo = ValidIO(new RASBranchInfo) 31 } 32 33 def rasEntry() = new Bundle { 34 val retAddr = UInt(VAddrBits.W) 35 val ctr = UInt(8.W) // layer of nested call functions 36 } 37 val ras = RegInit(VecInit(RasSize, 0.U.asTypeOf(rasEntry()))) 38 val sp = RegInit(0.U(log2Up(RasSize).W)) 39 val ras_top_entry = ras(sp) 40 val ras_top_addr = ras_top_entry.retAddr 41 42 val is_empty = sp === 0.U 43 val is_full = sp === (RasSize - 1).U 44 // save ras checkpoint info 45 io.out.bits.rasSp := sp 46 io.out.bits.rasTopCtr := rasTop.ctr 47 48 // update RAS 49 // speculative update RAS 50 when (!is_full && io.callIdx.valid) { 51 //push 52 io.out.bits.target := ras_top_addr 53 val rasWrite = WireInit(0.U.asTypeOf(rasEntry())) 54 val allocNewEntry = rasWrite.retAddr =/= rasTopAddr 55 rasWrite.ctr := Mux(allocNewEntry, 1.U, rasTop.ctr + 1.U) 56 rasWrite.retAddr := io.pc.bits + (io.callIdx.bits << 2.U) + 4.U 57 ras(sp) := in.target 58 when(allocNewEntry){sp := sp + 1.U } 59 }.elsewhen ((!is_empty && io.retIdx.valid) { 60 //pop 61 when (ras_top_entry.ctr === 1.U) { 62 sp := Mux(sp.value === 0.U, 0.U, sp - 1.U) 63 }.otherwise { 64 ras_top_entry.ctr := ras_top_entry.ctr - 1.U 65 } 66 } 67 // TODO: back-up stack for ras 68 // use checkpoint to recover RAS 69 val recoverSp = io.redirect.rasSp 70 val recoverCtr = io.redirect.rasTopCtr 71 when (io.redirect.valid && io.redirect.isMisPred) { 72 sp := recoverSp 73 ras(recoverSp) := Cat(recoverCtr, ras(recoverSp).retAddr).asTypeOf(rasEntry()) 74 } 75 76}