/*************************************************************************************** * Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences * Copyright (c) 2020-2021 Peng Cheng Laboratory * * XiangShan is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: * http://license.coscl.org.cn/MulanPSL2 * * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * * See the Mulan PSL v2 for more details. ***************************************************************************************/ package xiangshan.backend.fu import chipsalliance.rocketchip.config.Parameters import chisel3._ import chisel3.util._ import utility.LookupTree import xiangshan._ class BranchModule(implicit p: Parameters) extends XSModule { val io = IO(new Bundle() { val src = Vec(2, Input(UInt(XLEN.W))) val func = Input(FuOpType()) val pred_taken, isBranch = Input(Bool()) val taken, mispredict = Output(Bool()) }) val (src1, src2, func) = (io.src(0), io.src(1), io.func) val subModule = Module(new SubModule) subModule.io.src(0) := src1 subModule.io.src(1) := src2 val sub = subModule.io.sub val sltu = !sub(XLEN) val slt = src1(XLEN - 1) ^ src2(XLEN - 1) ^ sltu val logicSrc2 = Mux(!func(5) && func(0), ~src2, src2) val xor = src1 ^ logicSrc2 // branch val branchOpTable = List( ALUOpType.getBranchType(ALUOpType.beq) -> !xor.orR, ALUOpType.getBranchType(ALUOpType.blt) -> slt, ALUOpType.getBranchType(ALUOpType.bltu) -> sltu ) val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func) io.taken := taken io.mispredict := (io.pred_taken ^ taken) && io.isBranch } class Branch(implicit p: Parameters) extends FUWithRedirect { val uop = io.in.bits.uop val isBranch = ALUOpType.isBranch(io.in.bits.uop.ctrl.fuOpType) val dataModule = Module(new BranchModule) // 纯组合逻辑 dataModule.io.src := io.in.bits.src.take(2) dataModule.io.func := io.in.bits.uop.ctrl.fuOpType dataModule.io.pred_taken := uop.cf.pred_taken dataModule.io.isBranch := isBranch redirectOutValid := io.out.valid && isBranch redirectOut := DontCare redirectOut.level := RedirectLevel.flushAfter redirectOut.robIdx := uop.robIdx redirectOut.ftqIdx := uop.cf.ftqPtr redirectOut.ftqOffset := uop.cf.ftqOffset redirectOut.cfiUpdate.isMisPred := dataModule.io.mispredict redirectOut.cfiUpdate.taken := dataModule.io.taken redirectOut.cfiUpdate.predTaken := uop.cf.pred_taken io.in.ready := io.out.ready io.out.valid := io.in.valid && isBranch io.out.bits.uop <> DontCare io.out.bits.data := DontCare }