xref: /XiangShan/src/main/scala/xiangshan/backend/fu/Jump.scala (revision b0ae3ac4e5cdf55b27f5ffddd32e68a0733d3982)
1cafb3558SLinJiaweipackage xiangshan.backend.fu
2cafb3558SLinJiawei
3cafb3558SLinJiaweiimport chisel3._
4cafb3558SLinJiaweiimport chisel3.util._
5cafb3558SLinJiaweiimport xiangshan._
6b9fd1892SLinJiaweiimport utils._
7cafb3558SLinJiaweiimport xiangshan.backend._
8*b0ae3ac4SLinJiaweiimport 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
20*b0ae3ac4SLinJiawei  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*b0ae3ac4SLinJiawei  val offset = SignExt(Mux(JumpOpType.jumpOpIsJal(func),
29*b0ae3ac4SLinJiawei    ImmUnion.J.toImm32(immMin),
30*b0ae3ac4SLinJiawei    ImmUnion.I.toImm32(immMin)
31*b0ae3ac4SLinJiawei  ), XLEN)
32*b0ae3ac4SLinJiawei
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
41b2e234ebSLinJiawei  redirectOut.pc := uop.cf.pc
42b2e234ebSLinJiawei  redirectOut.target := target
43b2e234ebSLinJiawei  redirectOut.brTag := uop.brTag
44bfb958a3SYinan Xu  redirectOut.level := RedirectLevel.flushAfter
45bfb958a3SYinan Xu  redirectOut.interrupt := DontCare
46b2e234ebSLinJiawei  redirectOut.roqIdx := uop.roqIdx
47b2e234ebSLinJiawei
48b2e234ebSLinJiawei  brUpdate := uop.cf.brUpdate
49b2e234ebSLinJiawei  brUpdate.pc := uop.cf.pc
50b2e234ebSLinJiawei  brUpdate.target := target
51ae97381fSYinan Xu  brUpdate.brTarget := target
52b2e234ebSLinJiawei  brUpdate.taken := true.B
53b2e6921eSLinJiawei
54cafb3558SLinJiawei  // Output
55e18c367fSLinJiawei  val res = snpc
56cafb3558SLinJiawei
57cafb3558SLinJiawei  io.in.ready := io.out.ready
58e18c367fSLinJiawei  io.out.valid := valid
59cafb3558SLinJiawei  io.out.bits.uop <> io.in.bits.uop
60cafb3558SLinJiawei  io.out.bits.data := res
61cafb3558SLinJiawei
62cafb3558SLinJiawei  // NOTE: the debug info is for one-cycle exec, if FMV needs multi-cycle, may needs change it
63bfb958a3SYinan Xu  XSDebug(io.in.valid, "In(%d %d) Out(%d %d) Redirect:(%d %d %d) brTag:%x\n",
6412ff7156SLinJiawei    io.in.valid,
6512ff7156SLinJiawei    io.in.ready,
6612ff7156SLinJiawei    io.out.valid,
6712ff7156SLinJiawei    io.out.ready,
68b2e234ebSLinJiawei    io.redirectIn.valid,
69bfb958a3SYinan Xu    io.redirectIn.bits.level,
7012ff7156SLinJiawei    redirectHit,
71b2e234ebSLinJiawei    io.redirectIn.bits.brTag.value
7212ff7156SLinJiawei  )
7312ff7156SLinJiawei  XSDebug(io.in.valid, "src1:%x offset:%x func:%b type:JUMP pc:%x res:%x\n", src1, offset, func, pc, res)
74cafb3558SLinJiawei}
75