xref: /XiangShan/src/main/scala/xiangshan/backend/fu/Branch.scala (revision edace9bf42d3629aa254e3670e6fee86346313e8)
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._
24
25class BranchModule(implicit p: Parameters) extends XSModule {
26  val io = IO(new Bundle() {
27    val src = Vec(2, Input(UInt(XLEN.W)))
28    val func = Input(FuOpType())
29    val pred_taken, isBranch = Input(Bool())
30    val taken, mispredict = Output(Bool())
31  })
32  val (src1, src2, func) = (io.src(0), io.src(1), io.func)
33
34  val subModule = Module(new SubModule)
35  subModule.io.src(0) := src1
36  subModule.io.src(1) := src2
37  val sub  = subModule.io.sub
38  val sltu    = !sub(XLEN)
39  val slt     = src1(XLEN - 1) ^ src2(XLEN - 1) ^ sltu
40  val logicSrc2 = Mux(!func(5) && func(0), ~src2, src2)
41  val xor     = src1 ^ logicSrc2
42  // branch
43  val branchOpTable = List(
44    ALUOpType.getBranchType(ALUOpType.beq)  -> !xor.orR,
45    ALUOpType.getBranchType(ALUOpType.blt)  -> slt,
46    ALUOpType.getBranchType(ALUOpType.bltu) -> sltu
47  )
48  val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func)
49
50  io.taken := taken
51  io.mispredict := (io.pred_taken ^ taken) && io.isBranch
52}
53
54class Branch(implicit p: Parameters) extends FUWithRedirect {
55
56  val uop = io.in.bits.uop
57
58  val isBranch = ALUOpType.isBranch(io.in.bits.uop.ctrl.fuOpType)
59  val dataModule = Module(new BranchModule) // 纯组合逻辑
60
61  dataModule.io.src := io.in.bits.src.take(2)
62  dataModule.io.func := io.in.bits.uop.ctrl.fuOpType
63  dataModule.io.pred_taken := uop.cf.pred_taken
64  dataModule.io.isBranch := isBranch
65
66  redirectOutValid := io.out.valid && isBranch
67  redirectOut := DontCare
68  redirectOut.level := RedirectLevel.flushAfter
69  redirectOut.robIdx := uop.robIdx
70  redirectOut.ftqIdx := uop.cf.ftqPtr
71  redirectOut.ftqOffset := uop.cf.ftqOffset
72  redirectOut.cfiUpdate.isMisPred := dataModule.io.mispredict
73  redirectOut.cfiUpdate.taken := dataModule.io.taken
74  redirectOut.cfiUpdate.predTaken := uop.cf.pred_taken
75
76  io.in.ready := io.out.ready
77  io.out.valid := io.in.valid && isBranch
78  io.out.bits.uop <> DontCare
79  io.out.bits.data := DontCare
80}