1package xiangshan.frontend 2 3import chisel3._ 4import chisel3.util._ 5import xiangshan._ 6import xiangshan.backend.ALUOpType 7import utils._ 8 9class RAS extends BasePredictor 10{ 11 class RASResp extends Resp 12 { 13 val target =UInt(VAddrBits.W) 14 } 15 16 class RASBranchInfo extends Meta 17 { 18 val rasSp = UInt(log2Up(RasSize).W) 19 val rasTopCtr = UInt(8.W) 20 } 21 22 class RASIO extends DefaultBasePredictorIO 23 { 24 val is_ret = Input(Bool()) 25 val callIdx = Flipped(ValidIO(UInt(log2Ceil(PredictWidth).W))) 26 val isRVC = Input(Bool()) 27 val redirect = Flipped(ValidIO(new Redirect)) 28 val recover = Flipped(ValidIO(new BranchUpdateInfo)) 29 val out = ValidIO(new RASResp) 30 val branchInfo = Output(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 override val io = IO(new RASIO) 38 39 val ras = RegInit(0.U)asTypeOf(Vec(RasSize,rasEntry)) 40 val sp = RegInit(0.U(log2Up(RasSize).W)) 41 val ras_top_entry = ras(sp) 42 val ras_top_addr = ras_top_entry.retAddr 43 44 val is_empty = sp === 0.U 45 val is_full = sp === (RasSize - 1).U 46 // save ras checkpoint info 47 io.branchInfo.rasSp := sp 48 io.branchInfo.rasTopCtr := ras_top_entry.ctr 49 50 io.out.valid := !is_empty && io.is_ret 51 52 // update RAS 53 // speculative update RAS 54 io.out.bits.target := 0.U 55 when (!is_full && io.callIdx.valid) { 56 //push 57 //XDebug("d") 58 val new_addr:= io.pc.bits + (io.callIdx.bits << 2.U) + 4.U 59 val rasWrite = WireInit(0.U.asTypeOf(rasEntry())) 60 val allocNewEntry = new_addr =/= ras_top_addr 61 rasWrite.ctr := Mux(allocNewEntry, 1.U, ras_top_entry.ctr + 1.U) 62 rasWrite.retAddr := Mux(allocNewEntry, new_addr, ras_top_addr) 63 ras(sp) := rasWrite 64 when(allocNewEntry){sp := sp + 1.U } 65 }.elsewhen (!is_empty && io.is_ret) { 66 //pop 67 io.out.bits.target := ras_top_addr 68 when (ras_top_entry.ctr === 1.U) { 69 sp := Mux(sp === 0.U, 0.U, sp - 1.U) 70 }.otherwise { 71 ras_top_entry.ctr := ras_top_entry.ctr - 1.U 72 } 73 } 74 // TODO: back-up stack for ras 75 // use checkpoint to recover RAS 76 val recoverSp = io.recover.bits.brInfo.rasSp 77 val recoverCtr = io.recover.bits.brInfo.rasTopCtr 78 when (io.redirect.valid && io.redirect.bits.isMisPred) { 79 sp := recoverSp 80 ras(recoverSp).ctr := recoverCtr 81 } 82 83}