xref: /XiangShan/src/main/scala/xiangshan/backend/fu/Jump.scala (revision f606cf172d2466cd69af2f7ed9f4cde14d1fb70f)
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
28c8b0e8f1SLinJiawei  val isJalr = JumpOpType.jumpOpisJalr(func)
29c8b0e8f1SLinJiawei  val isAuipc = JumpOpType.jumpOpisAuipc(func)
30c8b0e8f1SLinJiawei  val offset = SignExt(Mux1H(Seq(
31c8b0e8f1SLinJiawei    isJalr -> ImmUnion.I.toImm32(immMin),
32c8b0e8f1SLinJiawei    isAuipc -> ImmUnion.U.toImm32(immMin),
33c8b0e8f1SLinJiawei    !(isJalr || isAuipc) -> ImmUnion.J.toImm32(immMin)
34c8b0e8f1SLinJiawei  )), XLEN)
35b0ae3ac4SLinJiawei
363136ee6aSLinJiawei  val redirectHit = uop.roqIdx.needFlush(io.redirectIn)
37dfd9e0a8SLinJiawei  val valid = io.in.valid
38cafb3558SLinJiawei
39608ba82cSzhanglinjuan  val isRVC = uop.cf.brUpdate.pd.isRVC
40e18c367fSLinJiawei  val snpc = Mux(isRVC, pc + 2.U, pc + 4.U)
41cafb3558SLinJiawei  val target = src1 + offset // NOTE: src1 is (pc/rf(rs1)), src2 is (offset)
42cafb3558SLinJiawei
43e18c367fSLinJiawei  redirectOutValid := valid
448926ac22SLinJiawei  redirectOut := DontCare
458926ac22SLinJiawei//  redirectOut.pc := uop.cf.pc
46b2e234ebSLinJiawei  redirectOut.target := target
47bfb958a3SYinan Xu  redirectOut.level := RedirectLevel.flushAfter
488926ac22SLinJiawei//  redirectOut.interrupt := DontCare
49b2e234ebSLinJiawei  redirectOut.roqIdx := uop.roqIdx
50b2e234ebSLinJiawei
518926ac22SLinJiawei  brUpdate := DontCare //uop.cf.brUpdate
528926ac22SLinJiawei//  brUpdate.pc := uop.cf.pc
53b2e234ebSLinJiawei  brUpdate.target := target
54b2e234ebSLinJiawei  brUpdate.taken := true.B
55b2e6921eSLinJiawei
56cafb3558SLinJiawei  // Output
576ac289b3SLinJiawei  val res = Mux(JumpOpType.jumpOpisAuipc(func), target, snpc)
58cafb3558SLinJiawei
59cafb3558SLinJiawei  io.in.ready := io.out.ready
60e18c367fSLinJiawei  io.out.valid := valid
61cafb3558SLinJiawei  io.out.bits.uop <> io.in.bits.uop
62cafb3558SLinJiawei  io.out.bits.data := res
63cafb3558SLinJiawei
64cafb3558SLinJiawei  // NOTE: the debug info is for one-cycle exec, if FMV needs multi-cycle, may needs change it
65*f606cf17SLinJiawei  XSDebug(io.in.valid, "In(%d %d) Out(%d %d) Redirect:(%d %d %d)\n",
6612ff7156SLinJiawei    io.in.valid,
6712ff7156SLinJiawei    io.in.ready,
6812ff7156SLinJiawei    io.out.valid,
6912ff7156SLinJiawei    io.out.ready,
70b2e234ebSLinJiawei    io.redirectIn.valid,
71bfb958a3SYinan Xu    io.redirectIn.bits.level,
72*f606cf17SLinJiawei    redirectHit
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