1e18c367fSLinJiaweipackage xiangshan.backend.fu 2e18c367fSLinJiawei 32225d46eSJiawei Linimport chipsalliance.rocketchip.config.Parameters 4e18c367fSLinJiaweiimport chisel3._ 5e18c367fSLinJiaweiimport chisel3.util._ 631ea8750SLinJiaweiimport utils.{LookupTree, ParallelMux, SignExt, ZeroExt} 7e18c367fSLinJiaweiimport xiangshan._ 8e18c367fSLinJiawei 92225d46eSJiawei Linclass AddModule(implicit p: Parameters) extends XSModule { 1031ea8750SLinJiawei val io = IO(new Bundle() { 11*2bd5334dSYinan Xu val src = Vec(2, Input(UInt(XLEN.W))) 1231ea8750SLinJiawei val out = Output(UInt((XLEN+1).W)) 1331ea8750SLinJiawei }) 14*2bd5334dSYinan Xu io.out := io.src(0) +& io.src(1) 1531ea8750SLinJiawei} 1631ea8750SLinJiawei 172225d46eSJiawei Linclass SubModule(implicit p: Parameters) extends XSModule { 1831ea8750SLinJiawei val io = IO(new Bundle() { 19*2bd5334dSYinan Xu val src = Vec(2, Input(UInt(XLEN.W))) 2031ea8750SLinJiawei val out = Output(UInt((XLEN+1).W)) 2131ea8750SLinJiawei }) 22*2bd5334dSYinan Xu io.out := (io.src(0) +& (~io.src(1)).asUInt()) + 1.U 2331ea8750SLinJiawei} 2431ea8750SLinJiawei 252225d46eSJiawei Linclass LeftShiftModule(implicit p: Parameters) extends XSModule { 2631ea8750SLinJiawei val io = IO(new Bundle() { 2731ea8750SLinJiawei val shamt = Input(UInt(6.W)) 2831ea8750SLinJiawei val sllSrc = Input(UInt(XLEN.W)) 2931ea8750SLinJiawei val sll = Output(UInt(XLEN.W)) 3031ea8750SLinJiawei }) 3131ea8750SLinJiawei io.sll := (io.sllSrc << io.shamt)(XLEN - 1, 0) 3231ea8750SLinJiawei} 3331ea8750SLinJiawei 342225d46eSJiawei Linclass RightShiftModule(implicit p: Parameters) extends XSModule { 3531ea8750SLinJiawei val io = IO(new Bundle() { 3631ea8750SLinJiawei val shamt = Input(UInt(6.W)) 3731ea8750SLinJiawei val srlSrc, sraSrc = Input(UInt(XLEN.W)) 3867630d0bSLinJiawei val srl_l, srl_w, sra_l, sra_w = Output(UInt(XLEN.W)) 3931ea8750SLinJiawei }) 4067630d0bSLinJiawei io.srl_l := io.srlSrc >> io.shamt 4167630d0bSLinJiawei io.srl_w := io.srlSrc(31, 0) >> io.shamt 4267630d0bSLinJiawei io.sra_l := (io.sraSrc.asSInt() >> io.shamt).asUInt() 43c57a9346SLinJiawei io.sra_w := (Cat(Fill(32, io.sraSrc(31)), io.sraSrc(31, 0)).asSInt() >> io.shamt).asUInt() 4431ea8750SLinJiawei} 4531ea8750SLinJiawei 462225d46eSJiawei Linclass MiscResultSelect(implicit p: Parameters) extends XSModule { 4731ea8750SLinJiawei val io = IO(new Bundle() { 4831ea8750SLinJiawei val func = Input(UInt()) 4931ea8750SLinJiawei val sll, slt, sltu, xor, srl, or, and, sra = Input(UInt(XLEN.W)) 5031ea8750SLinJiawei val miscRes = Output(UInt(XLEN.W)) 5131ea8750SLinJiawei 5231ea8750SLinJiawei }) 5331ea8750SLinJiawei io.miscRes := ParallelMux(List( 5431ea8750SLinJiawei ALUOpType.and -> io.and, 5531ea8750SLinJiawei ALUOpType.or -> io.or, 5631ea8750SLinJiawei ALUOpType.xor -> io.xor, 5731ea8750SLinJiawei ALUOpType.slt -> ZeroExt(io.slt, XLEN), 5831ea8750SLinJiawei ALUOpType.sltu -> ZeroExt(io.sltu, XLEN), 5931ea8750SLinJiawei ALUOpType.srl -> io.srl, 6031ea8750SLinJiawei ALUOpType.sll -> io.sll, 6131ea8750SLinJiawei ALUOpType.sra -> io.sra 6231ea8750SLinJiawei ).map(x => (x._1 === io.func(3, 0), x._2))) 6331ea8750SLinJiawei} 6431ea8750SLinJiawei 652225d46eSJiawei Linclass AluResSel(implicit p: Parameters) extends XSModule { 6631ea8750SLinJiawei val io = IO(new Bundle() { 6731ea8750SLinJiawei val func = Input(UInt()) 6831ea8750SLinJiawei val isSub = Input(Bool()) 6931ea8750SLinJiawei val addRes, subRes, miscRes = Input(UInt(XLEN.W)) 7031ea8750SLinJiawei val aluRes = Output(UInt(XLEN.W)) 7131ea8750SLinJiawei }) 7231ea8750SLinJiawei val isAddSub = ALUOpType.isAddSub(io.func) 7331ea8750SLinJiawei val res = Mux(ALUOpType.isAddSub(io.func), 7431ea8750SLinJiawei Mux(io.isSub, io.subRes, io.addRes), 7531ea8750SLinJiawei io.miscRes 7631ea8750SLinJiawei ) 7731ea8750SLinJiawei val h32 = Mux(ALUOpType.isWordOp(io.func), Fill(32, res(31)), res(63, 32)) 7831ea8750SLinJiawei io.aluRes := Cat(h32, res(31, 0)) 7931ea8750SLinJiawei} 8031ea8750SLinJiawei 812225d46eSJiawei Linclass AluDataModule(implicit p: Parameters) extends XSModule { 82e2203130SLinJiawei val io = IO(new Bundle() { 83*2bd5334dSYinan Xu val src = Vec(2, Input(UInt(XLEN.W))) 84e2203130SLinJiawei val func = Input(FuOpType()) 85e2203130SLinJiawei val pred_taken, isBranch = Input(Bool()) 86e2203130SLinJiawei val result = Output(UInt(XLEN.W)) 87e2203130SLinJiawei val taken, mispredict = Output(Bool()) 88e2203130SLinJiawei }) 89*2bd5334dSYinan Xu val (src1, src2, func) = (io.src(0), io.src(1), io.func) 90e18c367fSLinJiawei 91e18c367fSLinJiawei val isAdderSub = (func =/= ALUOpType.add) && (func =/= ALUOpType.addw) 9231ea8750SLinJiawei val addModule = Module(new AddModule) 93*2bd5334dSYinan Xu addModule.io.src(0) := src1 94*2bd5334dSYinan Xu addModule.io.src(1) := src2 9531ea8750SLinJiawei val subModule = Module(new SubModule) 96*2bd5334dSYinan Xu subModule.io.src(0) := src1 97*2bd5334dSYinan Xu subModule.io.src(1) := src2 9831ea8750SLinJiawei val addRes = addModule.io.out 9931ea8750SLinJiawei val subRes = subModule.io.out 100e18c367fSLinJiawei val xorRes = src1 ^ src2 1013ef996e9SLinJiawei val sltu = !subRes(XLEN) 102e18c367fSLinJiawei val slt = xorRes(XLEN-1) ^ sltu 103e18c367fSLinJiawei 10431ea8750SLinJiawei val isW = ALUOpType.isWordOp(func) 1054a6ab1cdSLinJiawei val shamt = Cat(!isW && src2(5), src2(4, 0)) 1063ef996e9SLinJiawei 10731ea8750SLinJiawei val leftShiftModule = Module(new LeftShiftModule) 10831ea8750SLinJiawei leftShiftModule.io.sllSrc := src1 10931ea8750SLinJiawei leftShiftModule.io.shamt := shamt 1103ef996e9SLinJiawei 11131ea8750SLinJiawei val rightShiftModule = Module(new RightShiftModule) 11231ea8750SLinJiawei rightShiftModule.io.shamt := shamt 11367630d0bSLinJiawei rightShiftModule.io.srlSrc := src1 11467630d0bSLinJiawei rightShiftModule.io.sraSrc := src1 1153ef996e9SLinJiawei 11631ea8750SLinJiawei val sll = leftShiftModule.io.sll 11767630d0bSLinJiawei val srl = Mux(isW, rightShiftModule.io.srl_w, rightShiftModule.io.srl_l) 11867630d0bSLinJiawei val sra = Mux(isW, rightShiftModule.io.sra_w, rightShiftModule.io.sra_l) 11931ea8750SLinJiawei 12031ea8750SLinJiawei val miscResSel = Module(new MiscResultSelect) 12131ea8750SLinJiawei miscResSel.io.func := func(3, 0) 12231ea8750SLinJiawei miscResSel.io.sll := sll 12331ea8750SLinJiawei miscResSel.io.slt := ZeroExt(slt, XLEN) 12431ea8750SLinJiawei miscResSel.io.sltu := ZeroExt(sltu, XLEN) 12531ea8750SLinJiawei miscResSel.io.xor := xorRes 12631ea8750SLinJiawei miscResSel.io.srl := srl 12731ea8750SLinJiawei miscResSel.io.or := (src1 | src2) 12831ea8750SLinJiawei miscResSel.io.and := (src1 & src2) 12931ea8750SLinJiawei miscResSel.io.sra := sra 13031ea8750SLinJiawei 13131ea8750SLinJiawei val miscRes = miscResSel.io.miscRes 13231ea8750SLinJiawei 13331ea8750SLinJiawei val aluResSel = Module(new AluResSel) 13431ea8750SLinJiawei aluResSel.io.func := func 13531ea8750SLinJiawei aluResSel.io.isSub := isAdderSub 13631ea8750SLinJiawei aluResSel.io.addRes := addRes 13731ea8750SLinJiawei aluResSel.io.subRes := subRes 13831ea8750SLinJiawei aluResSel.io.miscRes := miscRes 13931ea8750SLinJiawei val aluRes = aluResSel.io.aluRes 140e18c367fSLinJiawei 141e18c367fSLinJiawei val branchOpTable = List( 142e18c367fSLinJiawei ALUOpType.getBranchType(ALUOpType.beq) -> !xorRes.orR, 143e18c367fSLinJiawei ALUOpType.getBranchType(ALUOpType.blt) -> slt, 144e18c367fSLinJiawei ALUOpType.getBranchType(ALUOpType.bltu) -> sltu 145e18c367fSLinJiawei ) 1466060732cSLinJiawei val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func) 147e18c367fSLinJiawei 148e2203130SLinJiawei io.result := aluRes 149e2203130SLinJiawei io.taken := taken 150e2203130SLinJiawei io.mispredict := (io.pred_taken ^ taken) && io.isBranch 151e2203130SLinJiawei} 152e2203130SLinJiawei 1532225d46eSJiawei Linclass Alu(implicit p: Parameters) extends FunctionUnit with HasRedirectOut { 154e2203130SLinJiawei 155e2203130SLinJiawei val (src1, src2, func, pc, uop) = ( 156e2203130SLinJiawei io.in.bits.src(0), 157e2203130SLinJiawei io.in.bits.src(1), 158e2203130SLinJiawei io.in.bits.uop.ctrl.fuOpType, 159e2203130SLinJiawei SignExt(io.in.bits.uop.cf.pc, AddrBits), 160e2203130SLinJiawei io.in.bits.uop 161e2203130SLinJiawei ) 162e2203130SLinJiawei 163e2203130SLinJiawei val valid = io.in.valid 164e2203130SLinJiawei val isBranch = ALUOpType.isBranch(func) 165e2203130SLinJiawei val dataModule = Module(new AluDataModule) 166e2203130SLinJiawei 167*2bd5334dSYinan Xu dataModule.io.src(0) := src1 168*2bd5334dSYinan Xu dataModule.io.src(1) := src2 169e2203130SLinJiawei dataModule.io.func := func 170e2203130SLinJiawei dataModule.io.pred_taken := uop.cf.pred_taken 171e2203130SLinJiawei dataModule.io.isBranch := isBranch 172e2203130SLinJiawei 173e18c367fSLinJiawei redirectOutValid := io.out.valid && isBranch 174151e3043SLinJiawei redirectOut := DontCare 175bfb958a3SYinan Xu redirectOut.level := RedirectLevel.flushAfter 176e18c367fSLinJiawei redirectOut.roqIdx := uop.roqIdx 177cde9280dSLinJiawei redirectOut.ftqIdx := uop.cf.ftqPtr 178cde9280dSLinJiawei redirectOut.ftqOffset := uop.cf.ftqOffset 179e2203130SLinJiawei redirectOut.cfiUpdate.isMisPred := dataModule.io.mispredict 180e2203130SLinJiawei redirectOut.cfiUpdate.taken := dataModule.io.taken 181cde9280dSLinJiawei redirectOut.cfiUpdate.predTaken := uop.cf.pred_taken 182151e3043SLinJiawei 183e18c367fSLinJiawei io.in.ready := io.out.ready 184e18c367fSLinJiawei io.out.valid := valid 185e18c367fSLinJiawei io.out.bits.uop <> io.in.bits.uop 186e2203130SLinJiawei io.out.bits.data := dataModule.io.result 187e18c367fSLinJiawei} 188