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