1*3a6ab23aSczw/*************************************************************************************** 2*3a6ab23aSczw* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3*3a6ab23aSczw* Copyright (c) 2020-2021 Peng Cheng Laboratory 4*3a6ab23aSczw* 5*3a6ab23aSczw* XiangShan is licensed under Mulan PSL v2. 6*3a6ab23aSczw* You can use this software according to the terms and conditions of the Mulan PSL v2. 7*3a6ab23aSczw* You may obtain a copy of Mulan PSL v2 at: 8*3a6ab23aSczw* http://license.coscl.org.cn/MulanPSL2 9*3a6ab23aSczw* 10*3a6ab23aSczw* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11*3a6ab23aSczw* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12*3a6ab23aSczw* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13*3a6ab23aSczw* 14*3a6ab23aSczw* See the Mulan PSL v2 for more details. 15*3a6ab23aSczw***************************************************************************************/ 16*3a6ab23aSczw 17*3a6ab23aSczwpackage xiangshan.backend.fu 18*3a6ab23aSczw 19*3a6ab23aSczwimport chipsalliance.rocketchip.config.Parameters 20*3a6ab23aSczwimport chisel3._ 21*3a6ab23aSczwimport chisel3.util._ 22*3a6ab23aSczwimport utility.LookupTree 23*3a6ab23aSczwimport xiangshan._ 24*3a6ab23aSczwimport xiangshan.backend.fu.SubModule 25*3a6ab23aSczw 26*3a6ab23aSczwclass BranchModule(implicit p: Parameters) extends XSModule { 27*3a6ab23aSczw val io = IO(new Bundle() { 28*3a6ab23aSczw val src = Vec(2, Input(UInt(XLEN.W))) 29*3a6ab23aSczw val func = Input(FuOpType()) 30*3a6ab23aSczw val pred_taken, isBranch = Input(Bool()) 31*3a6ab23aSczw val taken, mispredict = Output(Bool()) 32*3a6ab23aSczw }) 33*3a6ab23aSczw val (src1, src2, func) = (io.src(0), io.src(1), io.func) 34*3a6ab23aSczw 35*3a6ab23aSczw val subModule = Module(new SubModule) 36*3a6ab23aSczw subModule.io.src(0) := src1 37*3a6ab23aSczw subModule.io.src(1) := src2 38*3a6ab23aSczw val sub = subModule.io.sub 39*3a6ab23aSczw val sltu = !sub(XLEN) 40*3a6ab23aSczw val slt = src1(XLEN - 1) ^ src2(XLEN - 1) ^ sltu 41*3a6ab23aSczw val logicSrc2 = Mux(!func(5) && func(0), ~src2, src2) 42*3a6ab23aSczw val xor = src1 ^ logicSrc2 43*3a6ab23aSczw // branch 44*3a6ab23aSczw val branchOpTable = List( 45*3a6ab23aSczw ALUOpType.getBranchType(ALUOpType.beq) -> !xor.orR, 46*3a6ab23aSczw ALUOpType.getBranchType(ALUOpType.blt) -> slt, 47*3a6ab23aSczw ALUOpType.getBranchType(ALUOpType.bltu) -> sltu 48*3a6ab23aSczw ) 49*3a6ab23aSczw val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func) 50*3a6ab23aSczw 51*3a6ab23aSczw io.taken := taken 52*3a6ab23aSczw io.mispredict := (io.pred_taken ^ taken) && io.isBranch 53*3a6ab23aSczw} 54*3a6ab23aSczw 55*3a6ab23aSczwclass Branch(implicit p: Parameters) extends FUWithRedirect { 56*3a6ab23aSczw 57*3a6ab23aSczw val uop = io.in.bits.uop 58*3a6ab23aSczw 59*3a6ab23aSczw val isBranch = ALUOpType.isBranch(io.in.bits.uop.ctrl.fuOpType) 60*3a6ab23aSczw val dataModule = Module(new BranchModule) // 纯组合逻辑 61*3a6ab23aSczw 62*3a6ab23aSczw dataModule.io.src := io.in.bits.src.take(2) 63*3a6ab23aSczw dataModule.io.func := io.in.bits.uop.ctrl.fuOpType 64*3a6ab23aSczw dataModule.io.pred_taken := uop.cf.pred_taken 65*3a6ab23aSczw dataModule.io.isBranch := isBranch 66*3a6ab23aSczw 67*3a6ab23aSczw redirectOutValid := io.out.valid && isBranch 68*3a6ab23aSczw redirectOut := DontCare 69*3a6ab23aSczw redirectOut.level := RedirectLevel.flushAfter 70*3a6ab23aSczw redirectOut.robIdx := uop.robIdx 71*3a6ab23aSczw redirectOut.ftqIdx := uop.cf.ftqPtr 72*3a6ab23aSczw redirectOut.ftqOffset := uop.cf.ftqOffset 73*3a6ab23aSczw redirectOut.cfiUpdate.isMisPred := dataModule.io.mispredict 74*3a6ab23aSczw redirectOut.cfiUpdate.taken := dataModule.io.taken 75*3a6ab23aSczw redirectOut.cfiUpdate.predTaken := uop.cf.pred_taken 76*3a6ab23aSczw 77*3a6ab23aSczw io.in.ready := io.out.ready 78*3a6ab23aSczw io.out.valid := io.in.valid 79*3a6ab23aSczw io.out.bits.uop <> DontCare 80*3a6ab23aSczw io.out.bits.data := DontCare 81*3a6ab23aSczw}