1e18c367fSLinJiaweipackage xiangshan.backend.fu 2e18c367fSLinJiawei 3e18c367fSLinJiaweiimport chisel3._ 4e18c367fSLinJiaweiimport chisel3.util._ 5*31ea8750SLinJiaweiimport utils.{LookupTree, ParallelMux, SignExt, ZeroExt} 6e18c367fSLinJiaweiimport xiangshan._ 7e18c367fSLinJiaweiimport xiangshan.backend.ALUOpType 8e18c367fSLinJiawei 9*31ea8750SLinJiaweiclass AddModule extends XSModule { 10*31ea8750SLinJiawei val io = IO(new Bundle() { 11*31ea8750SLinJiawei val src1, src2 = Input(UInt(XLEN.W)) 12*31ea8750SLinJiawei val out = Output(UInt((XLEN+1).W)) 13*31ea8750SLinJiawei }) 14*31ea8750SLinJiawei io.out := io.src1 +& io.src2 15*31ea8750SLinJiawei} 16*31ea8750SLinJiawei 17*31ea8750SLinJiaweiclass SubModule extends XSModule { 18*31ea8750SLinJiawei val io = IO(new Bundle() { 19*31ea8750SLinJiawei val src1, src2 = Input(UInt(XLEN.W)) 20*31ea8750SLinJiawei val out = Output(UInt((XLEN+1).W)) 21*31ea8750SLinJiawei }) 22*31ea8750SLinJiawei io.out := (io.src1 +& (~io.src2).asUInt()) + 1.U 23*31ea8750SLinJiawei} 24*31ea8750SLinJiawei 25*31ea8750SLinJiaweiclass LeftShiftModule extends XSModule { 26*31ea8750SLinJiawei val io = IO(new Bundle() { 27*31ea8750SLinJiawei val shamt = Input(UInt(6.W)) 28*31ea8750SLinJiawei val sllSrc = Input(UInt(XLEN.W)) 29*31ea8750SLinJiawei val sll = Output(UInt(XLEN.W)) 30*31ea8750SLinJiawei }) 31*31ea8750SLinJiawei io.sll := (io.sllSrc << io.shamt)(XLEN - 1, 0) 32*31ea8750SLinJiawei} 33*31ea8750SLinJiawei 34*31ea8750SLinJiaweiclass RightShiftModule extends XSModule { 35*31ea8750SLinJiawei val io = IO(new Bundle() { 36*31ea8750SLinJiawei val shamt = Input(UInt(6.W)) 37*31ea8750SLinJiawei val srlSrc, sraSrc = Input(UInt(XLEN.W)) 38*31ea8750SLinJiawei val srl, sra = Output(UInt(XLEN.W)) 39*31ea8750SLinJiawei }) 40*31ea8750SLinJiawei io.srl := io.srlSrc >> io.shamt 41*31ea8750SLinJiawei io.sra := (io.sraSrc.asSInt() >> io.shamt).asUInt() 42*31ea8750SLinJiawei} 43*31ea8750SLinJiawei 44*31ea8750SLinJiaweiclass ShiftModule extends XSModule { 45*31ea8750SLinJiawei val io = IO(new Bundle() { 46*31ea8750SLinJiawei val shamt = Input(UInt(6.W)) 47*31ea8750SLinJiawei val shsrc1 = Input(UInt(XLEN.W)) 48*31ea8750SLinJiawei val sll, srl, sra = Output(UInt(XLEN.W)) 49*31ea8750SLinJiawei }) 50*31ea8750SLinJiawei io.sll := (io.shsrc1 << io.shamt)(XLEN-1, 0) 51*31ea8750SLinJiawei io.srl := io.shsrc1 >> io.shamt 52*31ea8750SLinJiawei io.sra := (io.shsrc1.asSInt >> io.shamt).asUInt 53*31ea8750SLinJiawei} 54*31ea8750SLinJiawei 55*31ea8750SLinJiaweiclass MiscResultSelect extends XSModule { 56*31ea8750SLinJiawei val io = IO(new Bundle() { 57*31ea8750SLinJiawei val func = Input(UInt()) 58*31ea8750SLinJiawei val sll, slt, sltu, xor, srl, or, and, sra = Input(UInt(XLEN.W)) 59*31ea8750SLinJiawei val miscRes = Output(UInt(XLEN.W)) 60*31ea8750SLinJiawei 61*31ea8750SLinJiawei }) 62*31ea8750SLinJiawei io.miscRes := ParallelMux(List( 63*31ea8750SLinJiawei ALUOpType.and -> io.and, 64*31ea8750SLinJiawei ALUOpType.or -> io.or, 65*31ea8750SLinJiawei ALUOpType.xor -> io.xor, 66*31ea8750SLinJiawei ALUOpType.slt -> ZeroExt(io.slt, XLEN), 67*31ea8750SLinJiawei ALUOpType.sltu -> ZeroExt(io.sltu, XLEN), 68*31ea8750SLinJiawei ALUOpType.srl -> io.srl, 69*31ea8750SLinJiawei ALUOpType.sll -> io.sll, 70*31ea8750SLinJiawei ALUOpType.sra -> io.sra 71*31ea8750SLinJiawei ).map(x => (x._1 === io.func(3, 0), x._2))) 72*31ea8750SLinJiawei} 73*31ea8750SLinJiawei 74*31ea8750SLinJiaweiclass AluResSel extends XSModule { 75*31ea8750SLinJiawei val io = IO(new Bundle() { 76*31ea8750SLinJiawei val func = Input(UInt()) 77*31ea8750SLinJiawei val isSub = Input(Bool()) 78*31ea8750SLinJiawei val addRes, subRes, miscRes = Input(UInt(XLEN.W)) 79*31ea8750SLinJiawei val aluRes = Output(UInt(XLEN.W)) 80*31ea8750SLinJiawei }) 81*31ea8750SLinJiawei val isAddSub = ALUOpType.isAddSub(io.func) 82*31ea8750SLinJiawei val res = Mux(ALUOpType.isAddSub(io.func), 83*31ea8750SLinJiawei Mux(io.isSub, io.subRes, io.addRes), 84*31ea8750SLinJiawei io.miscRes 85*31ea8750SLinJiawei ) 86*31ea8750SLinJiawei val h32 = Mux(ALUOpType.isWordOp(io.func), Fill(32, res(31)), res(63, 32)) 87*31ea8750SLinJiawei io.aluRes := Cat(h32, res(31, 0)) 88*31ea8750SLinJiawei} 89*31ea8750SLinJiawei 9052c3f215SLinJiaweiclass Alu extends FunctionUnit with HasRedirectOut { 91e18c367fSLinJiawei 92b0ae3ac4SLinJiawei val (src1, src2, func, pc, uop) = ( 93e18c367fSLinJiawei io.in.bits.src(0), 94e18c367fSLinJiawei io.in.bits.src(1), 95e18c367fSLinJiawei io.in.bits.uop.ctrl.fuOpType, 96e18c367fSLinJiawei SignExt(io.in.bits.uop.cf.pc, AddrBits), 97e18c367fSLinJiawei io.in.bits.uop 98e18c367fSLinJiawei ) 99e18c367fSLinJiawei 100dfd9e0a8SLinJiawei val valid = io.in.valid 101e18c367fSLinJiawei 102e18c367fSLinJiawei val isAdderSub = (func =/= ALUOpType.add) && (func =/= ALUOpType.addw) 103*31ea8750SLinJiawei val addModule = Module(new AddModule) 104*31ea8750SLinJiawei addModule.io.src1 := src1 105*31ea8750SLinJiawei addModule.io.src2 := src2 106*31ea8750SLinJiawei val subModule = Module(new SubModule) 107*31ea8750SLinJiawei subModule.io.src1 := src1 108*31ea8750SLinJiawei subModule.io.src2 := src2 109*31ea8750SLinJiawei val addRes = addModule.io.out 110*31ea8750SLinJiawei val subRes = subModule.io.out 111e18c367fSLinJiawei val xorRes = src1 ^ src2 1123ef996e9SLinJiawei val sltu = !subRes(XLEN) 113e18c367fSLinJiawei val slt = xorRes(XLEN-1) ^ sltu 114e18c367fSLinJiawei 115*31ea8750SLinJiawei val isW = ALUOpType.isWordOp(func) 116*31ea8750SLinJiawei val shamt = Cat(isW && src2(5), src2(4, 0)) 1173ef996e9SLinJiawei 118*31ea8750SLinJiawei val leftShiftModule = Module(new LeftShiftModule) 119*31ea8750SLinJiawei leftShiftModule.io.sllSrc := src1 120*31ea8750SLinJiawei leftShiftModule.io.shamt := shamt 1213ef996e9SLinJiawei 122*31ea8750SLinJiawei val rightShiftModule = Module(new RightShiftModule) 123*31ea8750SLinJiawei rightShiftModule.io.shamt := shamt 124*31ea8750SLinJiawei rightShiftModule.io.srlSrc := Cat( 125*31ea8750SLinJiawei Mux(isW, 0.U(32.W), src1(63, 32)), 126*31ea8750SLinJiawei src1(31, 0) 127*31ea8750SLinJiawei ) 128*31ea8750SLinJiawei rightShiftModule.io.sraSrc := Cat( 129*31ea8750SLinJiawei Mux(isW, Fill(32, src1(31)), src1(63, 32)), 130*31ea8750SLinJiawei src1(31, 0) 1313ef996e9SLinJiawei ) 1323ef996e9SLinJiawei 133*31ea8750SLinJiawei val sll = leftShiftModule.io.sll 134*31ea8750SLinJiawei val srl = rightShiftModule.io.srl 135*31ea8750SLinJiawei val sra = rightShiftModule.io.sra 136*31ea8750SLinJiawei 137*31ea8750SLinJiawei val miscResSel = Module(new MiscResultSelect) 138*31ea8750SLinJiawei miscResSel.io.func := func(3, 0) 139*31ea8750SLinJiawei miscResSel.io.sll := sll 140*31ea8750SLinJiawei miscResSel.io.slt := ZeroExt(slt, XLEN) 141*31ea8750SLinJiawei miscResSel.io.sltu := ZeroExt(sltu, XLEN) 142*31ea8750SLinJiawei miscResSel.io.xor := xorRes 143*31ea8750SLinJiawei miscResSel.io.srl := srl 144*31ea8750SLinJiawei miscResSel.io.or := (src1 | src2) 145*31ea8750SLinJiawei miscResSel.io.and := (src1 & src2) 146*31ea8750SLinJiawei miscResSel.io.sra := sra 147*31ea8750SLinJiawei 148*31ea8750SLinJiawei val miscRes = miscResSel.io.miscRes 149*31ea8750SLinJiawei 150*31ea8750SLinJiawei val aluResSel = Module(new AluResSel) 151*31ea8750SLinJiawei aluResSel.io.func := func 152*31ea8750SLinJiawei aluResSel.io.isSub := isAdderSub 153*31ea8750SLinJiawei aluResSel.io.addRes := addRes 154*31ea8750SLinJiawei aluResSel.io.subRes := subRes 155*31ea8750SLinJiawei aluResSel.io.miscRes := miscRes 156*31ea8750SLinJiawei val aluRes = aluResSel.io.aluRes 157e18c367fSLinJiawei 158e18c367fSLinJiawei val branchOpTable = List( 159e18c367fSLinJiawei ALUOpType.getBranchType(ALUOpType.beq) -> !xorRes.orR, 160e18c367fSLinJiawei ALUOpType.getBranchType(ALUOpType.blt) -> slt, 161e18c367fSLinJiawei ALUOpType.getBranchType(ALUOpType.bltu) -> sltu 162e18c367fSLinJiawei ) 163e18c367fSLinJiawei 164869210c7SYinan Xu val isBranch = ALUOpType.isBranch(func) 1656060732cSLinJiawei val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func) 166e18c367fSLinJiawei 167e18c367fSLinJiawei redirectOutValid := io.out.valid && isBranch 168151e3043SLinJiawei redirectOut := DontCare 169bfb958a3SYinan Xu redirectOut.level := RedirectLevel.flushAfter 170e18c367fSLinJiawei redirectOut.roqIdx := uop.roqIdx 171cde9280dSLinJiawei redirectOut.ftqIdx := uop.cf.ftqPtr 172cde9280dSLinJiawei redirectOut.ftqOffset := uop.cf.ftqOffset 1736060732cSLinJiawei redirectOut.cfiUpdate.isMisPred := (uop.cf.pred_taken ^ taken) && isBranch 174cde9280dSLinJiawei redirectOut.cfiUpdate.taken := taken 175cde9280dSLinJiawei redirectOut.cfiUpdate.predTaken := uop.cf.pred_taken 176151e3043SLinJiawei 177e18c367fSLinJiawei io.in.ready := io.out.ready 178e18c367fSLinJiawei io.out.valid := valid 179e18c367fSLinJiawei io.out.bits.uop <> io.in.bits.uop 180e18c367fSLinJiawei io.out.bits.data := aluRes 181e18c367fSLinJiawei} 182