1package xiangshan.frontend 2 3import chisel3._ 4import chisel3.util._ 5import utils._ 6import xiangshan._ 7import xiangshan.backend.ALUOpType 8import xiangshan.backend.JumpOpType 9 10class TableAddr(val idxBits: Int, val banks: Int) extends XSBundle { 11 def tagBits = VAddrBits - idxBits - 1 12 13 val tag = UInt(tagBits.W) 14 val idx = UInt(idxBits.W) 15 val offset = UInt(1.W) 16 17 def fromUInt(x: UInt) = x.asTypeOf(UInt(VAddrBits.W)).asTypeOf(this) 18 def getTag(x: UInt) = fromUInt(x).tag 19 def getIdx(x: UInt) = fromUInt(x).idx 20 def getBank(x: UInt) = getIdx(x)(log2Up(banks) - 1, 0) 21 def getBankIdx(x: UInt) = getIdx(x)(idxBits - 1, log2Up(banks)) 22} 23 24class PredictorResponse extends XSBundle { 25 // the valid bits indicates whether a target is hit 26 val ubtb = new Bundle { 27 val targets = Vec(PredictWidth, ValidUndirectioned(UInt(VaddrBits.W))) 28 val takens = Vec(PredictWidth, Bool()) 29 } 30 // the valid bits indicates whether a target is hit 31 val btb = new Bundle { 32 val targets = Vec(PredictWidth, ValidUndirectioned(UInt(VaddrBits.W))) 33 val takens = Vec(PredictWidth, Bool()) 34 } 35 // the valid bits indicates whether a prediction is hit 36 val tage = new Bundle { 37 val takens = Vec(PredictWidth, ValidUndirectioned(Bool())) 38 } 39} 40 41class BPUStageIO extends XSBundle { 42 val pc = Output(UInt(VAddrBits.W)) 43 val btbResp = Output(new PredictorResponse) 44 val brInfo = Output(Vec(PredictWidth, new BranchInfo)) 45} 46 47 48class BPUStage1 extends XSModule { 49 val io = IO(new Bundle() { 50 val flush = Input(Bool()) 51 val in = new Bundle { val pc = Flipped(ValidIO(UInt(VAddrBits.W))) } 52 val pred = Decoupled(new BranchPrediction) 53 val out = Decoupled(new BPUStageIO) 54 // For repair & update 55 val outOfOrderBrInfo = Flipped(ValidIO(new BranchUpdateInfo)) 56 val inOrderBrInfo = Flipped(ValidIO(new BranchUpdateInfo)) 57 }) 58 59} 60 61class BPUStage2 extends XSModule { 62 val io = IO(new Bundle() { 63 val flush = Input(Bool()) 64 val in = Flipped(Decoupled(new BPUStageIO)) 65 val pred = Decoupled(new BranchPrediction) 66 val out = Decoupled(new BPUStageIO) 67 }) 68} 69 70class BPUStage3 extends XSModule { 71 val io = IO(new Bundle() { 72 val flush = Input(Bool()) 73 val in = Flipped(Decoupled(new BPUStageIO)) 74 val pred = Decoupled(new BranchPrediction) 75 val predecode = Flipped(ValidIO(new Predecode)) 76 }) 77 78} 79 80class BaseBPU extends XSModule { 81 val io = IO(new Bundle() { 82 // from backend 83 val outOfOrderBrInfo = Flipped(ValidIO(new BranchUpdateInfo)) 84 val inOrderBrInfo = Flipped(ValidIO(new BranchUpdateInfo)) 85 // from ifu, frontend redirect 86 val flush = Input(UInt(3.W)) 87 // from if1 88 val in = new Bundle { val pc = Flipped(ValidIO(UInt(VAddrBits.W))) } 89 // to if2/if3/if4 90 val out = Vec(3, Decoupled(new BranchPrediction)) 91 // from if4 92 val predecode = Flipped(ValidIO(new Predecode)) 93 // to if4, some bpu info used for updating 94 val branchInfo = Decoupled(Vec(PredictWidth, new BranchInfo)) 95 }) 96} 97 98class FakeBPU extends BaseBPU { 99 io.out.foreach(i => { 100 i <> DontCare 101 i.redirect := false.B 102 }) 103 io.branchInfo <> DontCare 104} 105 106class BPU extends BaseBPU { 107 108 val s1 = Module(new BPUStage1) 109 val s2 = Module(new BPUStage2) 110 val s3 = Module(new BPUStage3) 111 112 s1.io.flush := io.flush(0) 113 s2.io.flush := io.flush(1) 114 s3.io.flush := io.flush(2) 115 116 s1.io.in <> io.in 117 s2.io.in <> s1.io.out 118 s3.io.in <> s2.io.out 119 120 io.out(0) <> s1.io.pred 121 io.out(1) <> s2.io.pred 122 io.out(2) <> s3.io.pred 123 124 s1.io.redirect <> io.redirect 125 s1.io.outOfOrderBrInfo <> io.outOfOrderBrInfo 126 s1.io.inOrderBrInfo <> io.inOrderBrInfo 127 s2.io.outOfOrderBrInfo <> io.outOfOrderBrInfo 128 s2.io.inOrderBrInfo <> io.inOrderBrInfo 129 130 s3.io.predecode <> io.predecode 131} 132