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 17e18c367fSLinJiaweipackage xiangshan.backend.fu 18e18c367fSLinJiawei 192225d46eSJiawei Linimport chipsalliance.rocketchip.config.Parameters 20e18c367fSLinJiaweiimport chisel3._ 21e18c367fSLinJiaweiimport chisel3.util._ 2231ea8750SLinJiaweiimport utils.{LookupTree, ParallelMux, SignExt, ZeroExt} 23e18c367fSLinJiaweiimport xiangshan._ 24e18c367fSLinJiawei 252225d46eSJiawei Linclass AddModule(implicit p: Parameters) extends XSModule { 2631ea8750SLinJiawei val io = IO(new Bundle() { 272bd5334dSYinan Xu val src = Vec(2, Input(UInt(XLEN.W))) 2831ea8750SLinJiawei val out = Output(UInt((XLEN+1).W)) 2931ea8750SLinJiawei }) 302bd5334dSYinan Xu io.out := io.src(0) +& io.src(1) 3131ea8750SLinJiawei} 3231ea8750SLinJiawei 332225d46eSJiawei Linclass SubModule(implicit p: Parameters) extends XSModule { 3431ea8750SLinJiawei val io = IO(new Bundle() { 352bd5334dSYinan Xu val src = Vec(2, Input(UInt(XLEN.W))) 3631ea8750SLinJiawei val out = Output(UInt((XLEN+1).W)) 3731ea8750SLinJiawei }) 382bd5334dSYinan Xu io.out := (io.src(0) +& (~io.src(1)).asUInt()) + 1.U 3931ea8750SLinJiawei} 4031ea8750SLinJiawei 412225d46eSJiawei Linclass LeftShiftModule(implicit p: Parameters) extends XSModule { 4231ea8750SLinJiawei val io = IO(new Bundle() { 4331ea8750SLinJiawei val shamt = Input(UInt(6.W)) 4431ea8750SLinJiawei val sllSrc = Input(UInt(XLEN.W)) 4531ea8750SLinJiawei val sll = Output(UInt(XLEN.W)) 4631ea8750SLinJiawei }) 4731ea8750SLinJiawei io.sll := (io.sllSrc << io.shamt)(XLEN - 1, 0) 4831ea8750SLinJiawei} 4931ea8750SLinJiawei 502225d46eSJiawei Linclass RightShiftModule(implicit p: Parameters) extends XSModule { 5131ea8750SLinJiawei val io = IO(new Bundle() { 5231ea8750SLinJiawei val shamt = Input(UInt(6.W)) 5331ea8750SLinJiawei val srlSrc, sraSrc = Input(UInt(XLEN.W)) 5467630d0bSLinJiawei val srl_l, srl_w, sra_l, sra_w = Output(UInt(XLEN.W)) 5531ea8750SLinJiawei }) 5667630d0bSLinJiawei io.srl_l := io.srlSrc >> io.shamt 5767630d0bSLinJiawei io.srl_w := io.srlSrc(31, 0) >> io.shamt 5867630d0bSLinJiawei io.sra_l := (io.sraSrc.asSInt() >> io.shamt).asUInt() 59c57a9346SLinJiawei io.sra_w := (Cat(Fill(32, io.sraSrc(31)), io.sraSrc(31, 0)).asSInt() >> io.shamt).asUInt() 6031ea8750SLinJiawei} 6131ea8750SLinJiawei 622225d46eSJiawei Linclass MiscResultSelect(implicit p: Parameters) extends XSModule { 6331ea8750SLinJiawei val io = IO(new Bundle() { 6431ea8750SLinJiawei val func = Input(UInt()) 6531ea8750SLinJiawei val sll, slt, sltu, xor, srl, or, and, sra = Input(UInt(XLEN.W)) 6631ea8750SLinJiawei val miscRes = Output(UInt(XLEN.W)) 6731ea8750SLinJiawei 6831ea8750SLinJiawei }) 6931ea8750SLinJiawei io.miscRes := ParallelMux(List( 7031ea8750SLinJiawei ALUOpType.and -> io.and, 7131ea8750SLinJiawei ALUOpType.or -> io.or, 7231ea8750SLinJiawei ALUOpType.xor -> io.xor, 7331ea8750SLinJiawei ALUOpType.slt -> ZeroExt(io.slt, XLEN), 7431ea8750SLinJiawei ALUOpType.sltu -> ZeroExt(io.sltu, XLEN), 7531ea8750SLinJiawei ALUOpType.srl -> io.srl, 7631ea8750SLinJiawei ALUOpType.sll -> io.sll, 7731ea8750SLinJiawei ALUOpType.sra -> io.sra 7831ea8750SLinJiawei ).map(x => (x._1 === io.func(3, 0), x._2))) 7931ea8750SLinJiawei} 8031ea8750SLinJiawei 812225d46eSJiawei Linclass AluResSel(implicit p: Parameters) extends XSModule { 8231ea8750SLinJiawei val io = IO(new Bundle() { 8331ea8750SLinJiawei val func = Input(UInt()) 8431ea8750SLinJiawei val isSub = Input(Bool()) 8531ea8750SLinJiawei val addRes, subRes, miscRes = Input(UInt(XLEN.W)) 8631ea8750SLinJiawei val aluRes = Output(UInt(XLEN.W)) 8731ea8750SLinJiawei }) 8831ea8750SLinJiawei val isAddSub = ALUOpType.isAddSub(io.func) 8931ea8750SLinJiawei val res = Mux(ALUOpType.isAddSub(io.func), 9031ea8750SLinJiawei Mux(io.isSub, io.subRes, io.addRes), 9131ea8750SLinJiawei io.miscRes 9231ea8750SLinJiawei ) 9331ea8750SLinJiawei val h32 = Mux(ALUOpType.isWordOp(io.func), Fill(32, res(31)), res(63, 32)) 9431ea8750SLinJiawei io.aluRes := Cat(h32, res(31, 0)) 9531ea8750SLinJiawei} 9631ea8750SLinJiawei 972225d46eSJiawei Linclass AluDataModule(implicit p: Parameters) extends XSModule { 98e2203130SLinJiawei val io = IO(new Bundle() { 992bd5334dSYinan Xu val src = Vec(2, Input(UInt(XLEN.W))) 100e2203130SLinJiawei val func = Input(FuOpType()) 101e2203130SLinJiawei val pred_taken, isBranch = Input(Bool()) 102e2203130SLinJiawei val result = Output(UInt(XLEN.W)) 103e2203130SLinJiawei val taken, mispredict = Output(Bool()) 104e2203130SLinJiawei }) 1052bd5334dSYinan Xu val (src1, src2, func) = (io.src(0), io.src(1), io.func) 106e18c367fSLinJiawei 107e18c367fSLinJiawei val isAdderSub = (func =/= ALUOpType.add) && (func =/= ALUOpType.addw) 10831ea8750SLinJiawei val addModule = Module(new AddModule) 1092bd5334dSYinan Xu addModule.io.src(0) := src1 1102bd5334dSYinan Xu addModule.io.src(1) := src2 11131ea8750SLinJiawei val subModule = Module(new SubModule) 1122bd5334dSYinan Xu subModule.io.src(0) := src1 1132bd5334dSYinan Xu subModule.io.src(1) := src2 11431ea8750SLinJiawei val addRes = addModule.io.out 11531ea8750SLinJiawei val subRes = subModule.io.out 116e18c367fSLinJiawei val xorRes = src1 ^ src2 1173ef996e9SLinJiawei val sltu = !subRes(XLEN) 118e18c367fSLinJiawei val slt = xorRes(XLEN-1) ^ sltu 119e18c367fSLinJiawei 12031ea8750SLinJiawei val isW = ALUOpType.isWordOp(func) 1214a6ab1cdSLinJiawei val shamt = Cat(!isW && src2(5), src2(4, 0)) 1223ef996e9SLinJiawei 12331ea8750SLinJiawei val leftShiftModule = Module(new LeftShiftModule) 12431ea8750SLinJiawei leftShiftModule.io.sllSrc := src1 12531ea8750SLinJiawei leftShiftModule.io.shamt := shamt 1263ef996e9SLinJiawei 12731ea8750SLinJiawei val rightShiftModule = Module(new RightShiftModule) 12831ea8750SLinJiawei rightShiftModule.io.shamt := shamt 12967630d0bSLinJiawei rightShiftModule.io.srlSrc := src1 13067630d0bSLinJiawei rightShiftModule.io.sraSrc := src1 1313ef996e9SLinJiawei 13231ea8750SLinJiawei val sll = leftShiftModule.io.sll 13367630d0bSLinJiawei val srl = Mux(isW, rightShiftModule.io.srl_w, rightShiftModule.io.srl_l) 13467630d0bSLinJiawei val sra = Mux(isW, rightShiftModule.io.sra_w, rightShiftModule.io.sra_l) 13531ea8750SLinJiawei 13631ea8750SLinJiawei val miscResSel = Module(new MiscResultSelect) 13731ea8750SLinJiawei miscResSel.io.func := func(3, 0) 13831ea8750SLinJiawei miscResSel.io.sll := sll 13931ea8750SLinJiawei miscResSel.io.slt := ZeroExt(slt, XLEN) 14031ea8750SLinJiawei miscResSel.io.sltu := ZeroExt(sltu, XLEN) 14131ea8750SLinJiawei miscResSel.io.xor := xorRes 14231ea8750SLinJiawei miscResSel.io.srl := srl 14331ea8750SLinJiawei miscResSel.io.or := (src1 | src2) 14431ea8750SLinJiawei miscResSel.io.and := (src1 & src2) 14531ea8750SLinJiawei miscResSel.io.sra := sra 14631ea8750SLinJiawei 14731ea8750SLinJiawei val miscRes = miscResSel.io.miscRes 14831ea8750SLinJiawei 14931ea8750SLinJiawei val aluResSel = Module(new AluResSel) 15031ea8750SLinJiawei aluResSel.io.func := func 15131ea8750SLinJiawei aluResSel.io.isSub := isAdderSub 15231ea8750SLinJiawei aluResSel.io.addRes := addRes 15331ea8750SLinJiawei aluResSel.io.subRes := subRes 15431ea8750SLinJiawei aluResSel.io.miscRes := miscRes 15531ea8750SLinJiawei val aluRes = aluResSel.io.aluRes 156e18c367fSLinJiawei 157e18c367fSLinJiawei val branchOpTable = List( 158e18c367fSLinJiawei ALUOpType.getBranchType(ALUOpType.beq) -> !xorRes.orR, 159e18c367fSLinJiawei ALUOpType.getBranchType(ALUOpType.blt) -> slt, 160e18c367fSLinJiawei ALUOpType.getBranchType(ALUOpType.bltu) -> sltu 161e18c367fSLinJiawei ) 1626060732cSLinJiawei val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func) 163e18c367fSLinJiawei 164e2203130SLinJiawei io.result := aluRes 165e2203130SLinJiawei io.taken := taken 166e2203130SLinJiawei io.mispredict := (io.pred_taken ^ taken) && io.isBranch 167e2203130SLinJiawei} 168e2203130SLinJiawei 169*adb5df20SYinan Xuclass Alu(implicit p: Parameters) extends FUWithRedirect { 170e2203130SLinJiawei 171e2203130SLinJiawei val (src1, src2, func, pc, uop) = ( 172e2203130SLinJiawei io.in.bits.src(0), 173e2203130SLinJiawei io.in.bits.src(1), 174e2203130SLinJiawei io.in.bits.uop.ctrl.fuOpType, 175e2203130SLinJiawei SignExt(io.in.bits.uop.cf.pc, AddrBits), 176e2203130SLinJiawei io.in.bits.uop 177e2203130SLinJiawei ) 178e2203130SLinJiawei 179e2203130SLinJiawei val valid = io.in.valid 180e2203130SLinJiawei val isBranch = ALUOpType.isBranch(func) 181e2203130SLinJiawei val dataModule = Module(new AluDataModule) 182e2203130SLinJiawei 1832bd5334dSYinan Xu dataModule.io.src(0) := src1 1842bd5334dSYinan Xu dataModule.io.src(1) := src2 185e2203130SLinJiawei dataModule.io.func := func 186e2203130SLinJiawei dataModule.io.pred_taken := uop.cf.pred_taken 187e2203130SLinJiawei dataModule.io.isBranch := isBranch 188e2203130SLinJiawei 189e18c367fSLinJiawei redirectOutValid := io.out.valid && isBranch 190151e3043SLinJiawei redirectOut := DontCare 191bfb958a3SYinan Xu redirectOut.level := RedirectLevel.flushAfter 192e18c367fSLinJiawei redirectOut.roqIdx := uop.roqIdx 193cde9280dSLinJiawei redirectOut.ftqIdx := uop.cf.ftqPtr 194cde9280dSLinJiawei redirectOut.ftqOffset := uop.cf.ftqOffset 195e2203130SLinJiawei redirectOut.cfiUpdate.isMisPred := dataModule.io.mispredict 196e2203130SLinJiawei redirectOut.cfiUpdate.taken := dataModule.io.taken 197cde9280dSLinJiawei redirectOut.cfiUpdate.predTaken := uop.cf.pred_taken 198151e3043SLinJiawei 199e18c367fSLinJiawei io.in.ready := io.out.ready 200e18c367fSLinJiawei io.out.valid := valid 201e18c367fSLinJiawei io.out.bits.uop <> io.in.bits.uop 202e2203130SLinJiawei io.out.bits.data := dataModule.io.result 203e18c367fSLinJiawei} 204