xref: /XiangShan/src/main/scala/xiangshan/backend/fu/Jump.scala (revision 6ac289b3dc20532e9deb86b6607dd341443ad6c5)
1cafb3558SLinJiaweipackage xiangshan.backend.fu
2cafb3558SLinJiawei
3cafb3558SLinJiaweiimport chisel3._
4cafb3558SLinJiaweiimport chisel3.util._
5cafb3558SLinJiaweiimport xiangshan._
6b9fd1892SLinJiaweiimport utils._
7cafb3558SLinJiaweiimport xiangshan.backend._
8b0ae3ac4SLinJiaweiimport xiangshan.backend.decode.ImmUnion
9cafb3558SLinJiaweiimport xiangshan.backend.fu.FunctionUnit._
10ccd5d342SGouLingruiimport xiangshan.backend.decode.isa._
11cafb3558SLinJiawei
12e18c367fSLinJiaweitrait HasRedirectOut { this: RawModule =>
13e18c367fSLinJiawei  val redirectOutValid = IO(Output(Bool()))
14e18c367fSLinJiawei  val redirectOut = IO(Output(new Redirect))
1543ad9482SLingrui98  val brUpdate = IO(Output(new CfiUpdateInfo))
16b2e234ebSLinJiawei}
17cafb3558SLinJiawei
1852c3f215SLinJiaweiclass Jump extends FunctionUnit with HasRedirectOut {
19cafb3558SLinJiawei
20b0ae3ac4SLinJiawei  val (src1, immMin, func, pc, uop) = (
21b2e234ebSLinJiawei    io.in.bits.src(0),
22b2e234ebSLinJiawei    io.in.bits.uop.ctrl.imm,
23b2e234ebSLinJiawei    io.in.bits.uop.ctrl.fuOpType,
24b2e234ebSLinJiawei    SignExt(io.in.bits.uop.cf.pc, AddrBits),
25b2e234ebSLinJiawei    io.in.bits.uop
26b2e234ebSLinJiawei  )
27b2e234ebSLinJiawei
28*6ac289b3SLinJiawei  val offset = SignExt(Mux(JumpOpType.jumpOpisJalr(func),
29*6ac289b3SLinJiawei    ImmUnion.I.toImm32(immMin),
30*6ac289b3SLinJiawei    ImmUnion.J.toImm32(immMin) // Note: imm of auipc also expanded here
31b0ae3ac4SLinJiawei  ), XLEN)
32b0ae3ac4SLinJiawei
333136ee6aSLinJiawei  val redirectHit = uop.roqIdx.needFlush(io.redirectIn)
34dfd9e0a8SLinJiawei  val valid = io.in.valid
35cafb3558SLinJiawei
36608ba82cSzhanglinjuan  val isRVC = uop.cf.brUpdate.pd.isRVC
37e18c367fSLinJiawei  val snpc = Mux(isRVC, pc + 2.U, pc + 4.U)
38cafb3558SLinJiawei  val target = src1 + offset // NOTE: src1 is (pc/rf(rs1)), src2 is (offset)
39cafb3558SLinJiawei
40e18c367fSLinJiawei  redirectOutValid := valid
418926ac22SLinJiawei  redirectOut := DontCare
428926ac22SLinJiawei//  redirectOut.pc := uop.cf.pc
43b2e234ebSLinJiawei  redirectOut.target := target
44b2e234ebSLinJiawei  redirectOut.brTag := uop.brTag
45bfb958a3SYinan Xu  redirectOut.level := RedirectLevel.flushAfter
468926ac22SLinJiawei//  redirectOut.interrupt := DontCare
47b2e234ebSLinJiawei  redirectOut.roqIdx := uop.roqIdx
48b2e234ebSLinJiawei
498926ac22SLinJiawei  brUpdate := DontCare //uop.cf.brUpdate
508926ac22SLinJiawei//  brUpdate.pc := uop.cf.pc
51b2e234ebSLinJiawei  brUpdate.target := target
52ae97381fSYinan Xu  brUpdate.brTarget := target
53b2e234ebSLinJiawei  brUpdate.taken := true.B
54b2e6921eSLinJiawei
55cafb3558SLinJiawei  // Output
56*6ac289b3SLinJiawei  val res = Mux(JumpOpType.jumpOpisAuipc(func), target, snpc)
57cafb3558SLinJiawei
58cafb3558SLinJiawei  io.in.ready := io.out.ready
59e18c367fSLinJiawei  io.out.valid := valid
60cafb3558SLinJiawei  io.out.bits.uop <> io.in.bits.uop
61cafb3558SLinJiawei  io.out.bits.data := res
62cafb3558SLinJiawei
63cafb3558SLinJiawei  // NOTE: the debug info is for one-cycle exec, if FMV needs multi-cycle, may needs change it
64bfb958a3SYinan Xu  XSDebug(io.in.valid, "In(%d %d) Out(%d %d) Redirect:(%d %d %d) brTag:%x\n",
6512ff7156SLinJiawei    io.in.valid,
6612ff7156SLinJiawei    io.in.ready,
6712ff7156SLinJiawei    io.out.valid,
6812ff7156SLinJiawei    io.out.ready,
69b2e234ebSLinJiawei    io.redirectIn.valid,
70bfb958a3SYinan Xu    io.redirectIn.bits.level,
7112ff7156SLinJiawei    redirectHit,
72b2e234ebSLinJiawei    io.redirectIn.bits.brTag.value
7312ff7156SLinJiawei  )
7412ff7156SLinJiawei  XSDebug(io.in.valid, "src1:%x offset:%x func:%b type:JUMP pc:%x res:%x\n", src1, offset, func, pc, res)
75cafb3558SLinJiawei}
76