1/*************************************************************************************** 2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3* 4* XiangShan is licensed under Mulan PSL v2. 5* You can use this software according to the terms and conditions of the Mulan PSL v2. 6* You may obtain a copy of Mulan PSL v2 at: 7* http://license.coscl.org.cn/MulanPSL2 8* 9* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12* 13* See the Mulan PSL v2 for more details. 14***************************************************************************************/ 15 16package xiangshan.backend.fu 17 18import chipsalliance.rocketchip.config.Parameters 19import chisel3._ 20import chisel3.util._ 21import xiangshan._ 22import utils._ 23import xiangshan.backend._ 24import xiangshan.backend.decode.ImmUnion 25import xiangshan.backend.decode.isa._ 26 27trait HasRedirectOut { this: XSModule => 28 val redirectOutValid = IO(Output(Bool())) 29 val redirectOut = IO(Output(new Redirect)) 30} 31 32class JumpDataModule(implicit p: Parameters) extends XSModule { 33 val io = IO(new Bundle() { 34 val src = Input(UInt(XLEN.W)) 35 val pc = Input(UInt(XLEN.W)) // sign-ext to XLEN 36 val immMin = Input(UInt(ImmUnion.maxLen.W)) 37 val func = Input(FuOpType()) 38 val isRVC = Input(Bool()) 39 val result, target = Output(UInt(XLEN.W)) 40 val isAuipc = Output(Bool()) 41 }) 42 val (src1, pc, immMin, func, isRVC) = (io.src, io.pc, io.immMin, io.func, io.isRVC) 43 44 val isJalr = JumpOpType.jumpOpisJalr(func) 45 val isAuipc = JumpOpType.jumpOpisAuipc(func) 46 val offset = SignExt(ParallelMux(Seq( 47 isJalr -> ImmUnion.I.toImm32(immMin), 48 isAuipc -> ImmUnion.U.toImm32(immMin), 49 !(isJalr || isAuipc) -> ImmUnion.J.toImm32(immMin) 50 )), XLEN) 51 52 val snpc = Mux(isRVC, pc + 2.U, pc + 4.U) 53 val target = src1 + offset // NOTE: src1 is (pc/rf(rs1)), src2 is (offset) 54 55 io.target := target 56 io.result := Mux(JumpOpType.jumpOpisAuipc(func), target, snpc) 57 io.isAuipc := isAuipc 58} 59 60class Jump(implicit p: Parameters) extends FunctionUnit with HasRedirectOut { 61 62 val (src1, jalr_target, pc, immMin, func, uop) = ( 63 io.in.bits.src(0), 64 io.in.bits.src(1)(VAddrBits - 1, 0), 65 SignExt(io.in.bits.uop.cf.pc, XLEN), 66 io.in.bits.uop.ctrl.imm, 67 io.in.bits.uop.ctrl.fuOpType, 68 io.in.bits.uop 69 ) 70 71 val redirectHit = uop.roqIdx.needFlush(io.redirectIn, io.flushIn) 72 val valid = io.in.valid 73 val isRVC = uop.cf.pd.isRVC 74 75 val jumpDataModule = Module(new JumpDataModule) 76 jumpDataModule.io.src := src1 77 jumpDataModule.io.pc := pc 78 jumpDataModule.io.immMin := immMin 79 jumpDataModule.io.func := func 80 jumpDataModule.io.isRVC := isRVC 81 82 redirectOutValid := valid && !jumpDataModule.io.isAuipc 83 redirectOut := DontCare 84 redirectOut.level := RedirectLevel.flushAfter 85 redirectOut.roqIdx := uop.roqIdx 86 redirectOut.ftqIdx := uop.cf.ftqPtr 87 redirectOut.ftqOffset := uop.cf.ftqOffset 88 redirectOut.cfiUpdate.predTaken := true.B 89 redirectOut.cfiUpdate.taken := true.B 90 redirectOut.cfiUpdate.target := jumpDataModule.io.target 91 redirectOut.cfiUpdate.isMisPred := jumpDataModule.io.target(VAddrBits - 1, 0) =/= jalr_target || !uop.cf.pred_taken 92 93 io.in.ready := io.out.ready 94 io.out.valid := valid 95 io.out.bits.uop <> io.in.bits.uop 96 io.out.bits.data := jumpDataModule.io.result 97 98 // NOTE: the debug info is for one-cycle exec, if FMV needs multi-cycle, may needs change it 99 XSDebug(io.in.valid, "In(%d %d) Out(%d %d) Redirect:(%d %d %d)\n", 100 io.in.valid, 101 io.in.ready, 102 io.out.valid, 103 io.out.ready, 104 io.redirectIn.valid, 105 io.redirectIn.bits.level, 106 redirectHit 107 ) 108} 109