xref: /XiangShan/src/main/scala/xiangshan/backend/fu/Jump.scala (revision 3b739f49c5a26805be859c7231717ecc38aade30)
1c6d43980SLemover/***************************************************************************************
2c6d43980SLemover* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3f320e0f0SYinan Xu* Copyright (c) 2020-2021 Peng Cheng Laboratory
4c6d43980SLemover*
5c6d43980SLemover* XiangShan is licensed under Mulan PSL v2.
6c6d43980SLemover* You can use this software according to the terms and conditions of the Mulan PSL v2.
7c6d43980SLemover* You may obtain a copy of Mulan PSL v2 at:
8c6d43980SLemover*          http://license.coscl.org.cn/MulanPSL2
9c6d43980SLemover*
10c6d43980SLemover* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11c6d43980SLemover* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12c6d43980SLemover* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13c6d43980SLemover*
14c6d43980SLemover* See the Mulan PSL v2 for more details.
15c6d43980SLemover***************************************************************************************/
16c6d43980SLemover
17cafb3558SLinJiaweipackage xiangshan.backend.fu
18cafb3558SLinJiawei
192225d46eSJiawei Linimport chipsalliance.rocketchip.config.Parameters
20cafb3558SLinJiaweiimport chisel3._
21cafb3558SLinJiaweiimport chisel3.util._
223c02ee8fSwakafaimport utility._
23*3b739f49SXuan Huimport utils._
24*3b739f49SXuan Huimport xiangshan._
25cafb3558SLinJiaweiimport xiangshan.backend._
26b0ae3ac4SLinJiaweiimport xiangshan.backend.decode.ImmUnion
27ccd5d342SGouLingruiimport xiangshan.backend.decode.isa._
28cafb3558SLinJiawei
292225d46eSJiawei Lintrait HasRedirectOut { this: XSModule =>
30e18c367fSLinJiawei  val redirectOutValid = IO(Output(Bool()))
31e18c367fSLinJiawei  val redirectOut = IO(Output(new Redirect))
32b2e234ebSLinJiawei}
33cafb3558SLinJiawei
342225d46eSJiawei Linclass JumpDataModule(implicit p: Parameters) extends XSModule {
35e2203130SLinJiawei  val io = IO(new Bundle() {
362bd5334dSYinan Xu    val src = Input(UInt(XLEN.W))
379ca85825SLinJiawei    val pc = Input(UInt(XLEN.W)) // sign-ext to XLEN
38e2203130SLinJiawei    val immMin = Input(UInt(ImmUnion.maxLen.W))
39e2203130SLinJiawei    val func = Input(FuOpType())
40e2203130SLinJiawei    val isRVC = Input(Bool())
41e2203130SLinJiawei    val result, target = Output(UInt(XLEN.W))
42e2203130SLinJiawei    val isAuipc = Output(Bool())
43e2203130SLinJiawei  })
442bd5334dSYinan Xu  val (src1, pc, immMin, func, isRVC) = (io.src, io.pc, io.immMin, io.func, io.isRVC)
45e2203130SLinJiawei
46e2203130SLinJiawei  val isJalr = JumpOpType.jumpOpisJalr(func)
47e2203130SLinJiawei  val isAuipc = JumpOpType.jumpOpisAuipc(func)
48e2203130SLinJiawei  val offset = SignExt(ParallelMux(Seq(
49e2203130SLinJiawei    isJalr -> ImmUnion.I.toImm32(immMin),
50e2203130SLinJiawei    isAuipc -> ImmUnion.U.toImm32(immMin),
51e2203130SLinJiawei    !(isJalr || isAuipc) -> ImmUnion.J.toImm32(immMin)
52e2203130SLinJiawei  )), XLEN)
53e2203130SLinJiawei
54e2203130SLinJiawei  val snpc = Mux(isRVC, pc + 2.U, pc + 4.U)
55e2203130SLinJiawei  val target = src1 + offset // NOTE: src1 is (pc/rf(rs1)), src2 is (offset)
56e2203130SLinJiawei
571a389dfdSYinan Xu  // RISC-V spec for JALR:
581a389dfdSYinan Xu  // The target address is obtained by adding the sign-extended 12-bit I-immediate to the register rs1,
591a389dfdSYinan Xu  // then setting the least-significant bit of the result to zero.
601a389dfdSYinan Xu  io.target := Cat(target(XLEN - 1, 1), false.B)
61e2203130SLinJiawei  io.result := Mux(JumpOpType.jumpOpisAuipc(func), target, snpc)
62e2203130SLinJiawei  io.isAuipc := isAuipc
63e2203130SLinJiawei}
64e2203130SLinJiawei
65*3b739f49SXuan Hu//class Jump(implicit p: Parameters) extends FUWithRedirect {
66*3b739f49SXuan Hu//
67*3b739f49SXuan Hu//  val (src1, jalr_target, pc, immMin, func, uop) = (
68*3b739f49SXuan Hu//    io.in.bits.src(0),
69*3b739f49SXuan Hu//    io.in.bits.src(1)(VAddrBits - 1, 0),
70*3b739f49SXuan Hu//    SignExt(io.in.bits.uop.cf.pc, XLEN),
71*3b739f49SXuan Hu//    io.in.bits.uop.ctrl.imm,
72*3b739f49SXuan Hu//    io.in.bits.uop.ctrl.fuOpType,
73*3b739f49SXuan Hu//    io.in.bits.uop
74*3b739f49SXuan Hu//  )
75*3b739f49SXuan Hu//
76*3b739f49SXuan Hu//  val redirectHit = uop.robIdx.needFlush(io.redirectIn)
77*3b739f49SXuan Hu//  val valid = io.in.valid
78*3b739f49SXuan Hu//  val isRVC = uop.cf.pd.isRVC
79*3b739f49SXuan Hu//
80*3b739f49SXuan Hu//  val jumpDataModule = Module(new JumpDataModule)
81*3b739f49SXuan Hu//  jumpDataModule.io.src := src1
82*3b739f49SXuan Hu//  jumpDataModule.io.pc := pc
83*3b739f49SXuan Hu//  jumpDataModule.io.immMin := immMin
84*3b739f49SXuan Hu//  jumpDataModule.io.func := func
85*3b739f49SXuan Hu//  jumpDataModule.io.isRVC := isRVC
86*3b739f49SXuan Hu//
87*3b739f49SXuan Hu//  redirectOutValid := valid && !jumpDataModule.io.isAuipc
88*3b739f49SXuan Hu//  redirectOut := DontCare
89*3b739f49SXuan Hu//  redirectOut.level := RedirectLevel.flushAfter
90*3b739f49SXuan Hu//  redirectOut.robIdx := uop.robIdx
91*3b739f49SXuan Hu//  redirectOut.ftqIdx := uop.cf.ftqPtr
92*3b739f49SXuan Hu//  redirectOut.ftqOffset := uop.cf.ftqOffset
93*3b739f49SXuan Hu//  redirectOut.cfiUpdate.predTaken := true.B
94*3b739f49SXuan Hu//  redirectOut.cfiUpdate.taken := true.B
95*3b739f49SXuan Hu//  redirectOut.cfiUpdate.target := jumpDataModule.io.target
96*3b739f49SXuan Hu//  redirectOut.cfiUpdate.isMisPred := jumpDataModule.io.target(VAddrBits - 1, 0) =/= jalr_target || !uop.cf.pred_taken
97*3b739f49SXuan Hu//  redirectOut.debug_runahead_checkpoint_id := uop.debugInfo.runahead_checkpoint_id
98*3b739f49SXuan Hu//
99*3b739f49SXuan Hu//  io.in.ready := io.out.ready
100*3b739f49SXuan Hu//  io.out.valid := valid
101*3b739f49SXuan Hu//  io.out.bits.uop <> io.in.bits.uop
102*3b739f49SXuan Hu//  io.out.bits.data := jumpDataModule.io.result
103*3b739f49SXuan Hu//
104*3b739f49SXuan Hu//  // NOTE: the debug info is for one-cycle exec, if FMV needs multi-cycle, may needs change it
105*3b739f49SXuan Hu//  XSDebug(io.in.valid, "In(%d %d) Out(%d %d) Redirect:(%d %d %d)\n",
106*3b739f49SXuan Hu//    io.in.valid,
107*3b739f49SXuan Hu//    io.in.ready,
108*3b739f49SXuan Hu//    io.out.valid,
109*3b739f49SXuan Hu//    io.out.ready,
110*3b739f49SXuan Hu//    io.redirectIn.valid,
111*3b739f49SXuan Hu//    io.redirectIn.bits.level,
112*3b739f49SXuan Hu//    redirectHit
113*3b739f49SXuan Hu//  )
114*3b739f49SXuan Hu//}
115