xref: /XiangShan/src/main/scala/xiangshan/backend/fu/Branch.scala (revision 3a6ab23a860d5e58a0dd361d2b2c685dbd41de6b)
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}