1e18c367fSLinJiaweipackage xiangshan.backend.fu 2e18c367fSLinJiawei 3e18c367fSLinJiaweiimport chisel3._ 4e18c367fSLinJiaweiimport chisel3.util._ 531ea8750SLinJiaweiimport utils.{LookupTree, ParallelMux, SignExt, ZeroExt} 6e18c367fSLinJiaweiimport xiangshan._ 7e18c367fSLinJiaweiimport xiangshan.backend.ALUOpType 8e18c367fSLinJiawei 931ea8750SLinJiaweiclass AddModule extends XSModule { 1031ea8750SLinJiawei val io = IO(new Bundle() { 1131ea8750SLinJiawei val src1, src2 = Input(UInt(XLEN.W)) 1231ea8750SLinJiawei val out = Output(UInt((XLEN+1).W)) 1331ea8750SLinJiawei }) 1431ea8750SLinJiawei io.out := io.src1 +& io.src2 1531ea8750SLinJiawei} 1631ea8750SLinJiawei 1731ea8750SLinJiaweiclass SubModule extends XSModule { 1831ea8750SLinJiawei val io = IO(new Bundle() { 1931ea8750SLinJiawei val src1, src2 = Input(UInt(XLEN.W)) 2031ea8750SLinJiawei val out = Output(UInt((XLEN+1).W)) 2131ea8750SLinJiawei }) 2231ea8750SLinJiawei io.out := (io.src1 +& (~io.src2).asUInt()) + 1.U 2331ea8750SLinJiawei} 2431ea8750SLinJiawei 2531ea8750SLinJiaweiclass LeftShiftModule 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 3431ea8750SLinJiaweiclass RightShiftModule extends XSModule { 3531ea8750SLinJiawei val io = IO(new Bundle() { 3631ea8750SLinJiawei val shamt = Input(UInt(6.W)) 3731ea8750SLinJiawei val srlSrc, sraSrc = Input(UInt(XLEN.W)) 3831ea8750SLinJiawei val srl, sra = Output(UInt(XLEN.W)) 3931ea8750SLinJiawei }) 4031ea8750SLinJiawei io.srl := io.srlSrc >> io.shamt 4131ea8750SLinJiawei io.sra := (io.sraSrc.asSInt() >> io.shamt).asUInt() 4231ea8750SLinJiawei} 4331ea8750SLinJiawei 4431ea8750SLinJiaweiclass MiscResultSelect extends XSModule { 4531ea8750SLinJiawei val io = IO(new Bundle() { 4631ea8750SLinJiawei val func = Input(UInt()) 4731ea8750SLinJiawei val sll, slt, sltu, xor, srl, or, and, sra = Input(UInt(XLEN.W)) 4831ea8750SLinJiawei val miscRes = Output(UInt(XLEN.W)) 4931ea8750SLinJiawei 5031ea8750SLinJiawei }) 5131ea8750SLinJiawei io.miscRes := ParallelMux(List( 5231ea8750SLinJiawei ALUOpType.and -> io.and, 5331ea8750SLinJiawei ALUOpType.or -> io.or, 5431ea8750SLinJiawei ALUOpType.xor -> io.xor, 5531ea8750SLinJiawei ALUOpType.slt -> ZeroExt(io.slt, XLEN), 5631ea8750SLinJiawei ALUOpType.sltu -> ZeroExt(io.sltu, XLEN), 5731ea8750SLinJiawei ALUOpType.srl -> io.srl, 5831ea8750SLinJiawei ALUOpType.sll -> io.sll, 5931ea8750SLinJiawei ALUOpType.sra -> io.sra 6031ea8750SLinJiawei ).map(x => (x._1 === io.func(3, 0), x._2))) 6131ea8750SLinJiawei} 6231ea8750SLinJiawei 6331ea8750SLinJiaweiclass AluResSel extends XSModule { 6431ea8750SLinJiawei val io = IO(new Bundle() { 6531ea8750SLinJiawei val func = Input(UInt()) 6631ea8750SLinJiawei val isSub = Input(Bool()) 6731ea8750SLinJiawei val addRes, subRes, miscRes = Input(UInt(XLEN.W)) 6831ea8750SLinJiawei val aluRes = Output(UInt(XLEN.W)) 6931ea8750SLinJiawei }) 7031ea8750SLinJiawei val isAddSub = ALUOpType.isAddSub(io.func) 7131ea8750SLinJiawei val res = Mux(ALUOpType.isAddSub(io.func), 7231ea8750SLinJiawei Mux(io.isSub, io.subRes, io.addRes), 7331ea8750SLinJiawei io.miscRes 7431ea8750SLinJiawei ) 7531ea8750SLinJiawei val h32 = Mux(ALUOpType.isWordOp(io.func), Fill(32, res(31)), res(63, 32)) 7631ea8750SLinJiawei io.aluRes := Cat(h32, res(31, 0)) 7731ea8750SLinJiawei} 7831ea8750SLinJiawei 79*e2203130SLinJiaweiclass AluDataModule extends XSModule { 80*e2203130SLinJiawei val io = IO(new Bundle() { 81*e2203130SLinJiawei val src1, src2 = Input(UInt(XLEN.W)) 82*e2203130SLinJiawei val func = Input(FuOpType()) 83*e2203130SLinJiawei val pred_taken, isBranch = Input(Bool()) 84*e2203130SLinJiawei val result = Output(UInt(XLEN.W)) 85*e2203130SLinJiawei val taken, mispredict = Output(Bool()) 86*e2203130SLinJiawei }) 87*e2203130SLinJiawei val (src1, src2, func) = (io.src1, io.src2, io.func) 88e18c367fSLinJiawei 89e18c367fSLinJiawei val isAdderSub = (func =/= ALUOpType.add) && (func =/= ALUOpType.addw) 9031ea8750SLinJiawei val addModule = Module(new AddModule) 9131ea8750SLinJiawei addModule.io.src1 := src1 9231ea8750SLinJiawei addModule.io.src2 := src2 9331ea8750SLinJiawei val subModule = Module(new SubModule) 9431ea8750SLinJiawei subModule.io.src1 := src1 9531ea8750SLinJiawei subModule.io.src2 := src2 9631ea8750SLinJiawei val addRes = addModule.io.out 9731ea8750SLinJiawei val subRes = subModule.io.out 98e18c367fSLinJiawei val xorRes = src1 ^ src2 993ef996e9SLinJiawei val sltu = !subRes(XLEN) 100e18c367fSLinJiawei val slt = xorRes(XLEN-1) ^ sltu 101e18c367fSLinJiawei 10231ea8750SLinJiawei val isW = ALUOpType.isWordOp(func) 1034a6ab1cdSLinJiawei val shamt = Cat(!isW && src2(5), src2(4, 0)) 1043ef996e9SLinJiawei 10531ea8750SLinJiawei val leftShiftModule = Module(new LeftShiftModule) 10631ea8750SLinJiawei leftShiftModule.io.sllSrc := src1 10731ea8750SLinJiawei leftShiftModule.io.shamt := shamt 1083ef996e9SLinJiawei 10931ea8750SLinJiawei val rightShiftModule = Module(new RightShiftModule) 11031ea8750SLinJiawei rightShiftModule.io.shamt := shamt 11131ea8750SLinJiawei rightShiftModule.io.srlSrc := Cat( 11231ea8750SLinJiawei Mux(isW, 0.U(32.W), src1(63, 32)), 11331ea8750SLinJiawei src1(31, 0) 11431ea8750SLinJiawei ) 11531ea8750SLinJiawei rightShiftModule.io.sraSrc := Cat( 11631ea8750SLinJiawei Mux(isW, Fill(32, src1(31)), src1(63, 32)), 11731ea8750SLinJiawei src1(31, 0) 1183ef996e9SLinJiawei ) 1193ef996e9SLinJiawei 12031ea8750SLinJiawei val sll = leftShiftModule.io.sll 12131ea8750SLinJiawei val srl = rightShiftModule.io.srl 12231ea8750SLinJiawei val sra = rightShiftModule.io.sra 12331ea8750SLinJiawei 12431ea8750SLinJiawei val miscResSel = Module(new MiscResultSelect) 12531ea8750SLinJiawei miscResSel.io.func := func(3, 0) 12631ea8750SLinJiawei miscResSel.io.sll := sll 12731ea8750SLinJiawei miscResSel.io.slt := ZeroExt(slt, XLEN) 12831ea8750SLinJiawei miscResSel.io.sltu := ZeroExt(sltu, XLEN) 12931ea8750SLinJiawei miscResSel.io.xor := xorRes 13031ea8750SLinJiawei miscResSel.io.srl := srl 13131ea8750SLinJiawei miscResSel.io.or := (src1 | src2) 13231ea8750SLinJiawei miscResSel.io.and := (src1 & src2) 13331ea8750SLinJiawei miscResSel.io.sra := sra 13431ea8750SLinJiawei 13531ea8750SLinJiawei val miscRes = miscResSel.io.miscRes 13631ea8750SLinJiawei 13731ea8750SLinJiawei val aluResSel = Module(new AluResSel) 13831ea8750SLinJiawei aluResSel.io.func := func 13931ea8750SLinJiawei aluResSel.io.isSub := isAdderSub 14031ea8750SLinJiawei aluResSel.io.addRes := addRes 14131ea8750SLinJiawei aluResSel.io.subRes := subRes 14231ea8750SLinJiawei aluResSel.io.miscRes := miscRes 14331ea8750SLinJiawei val aluRes = aluResSel.io.aluRes 144e18c367fSLinJiawei 145e18c367fSLinJiawei val branchOpTable = List( 146e18c367fSLinJiawei ALUOpType.getBranchType(ALUOpType.beq) -> !xorRes.orR, 147e18c367fSLinJiawei ALUOpType.getBranchType(ALUOpType.blt) -> slt, 148e18c367fSLinJiawei ALUOpType.getBranchType(ALUOpType.bltu) -> sltu 149e18c367fSLinJiawei ) 1506060732cSLinJiawei val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func) 151e18c367fSLinJiawei 152*e2203130SLinJiawei io.result := aluRes 153*e2203130SLinJiawei io.taken := taken 154*e2203130SLinJiawei io.mispredict := (io.pred_taken ^ taken) && io.isBranch 155*e2203130SLinJiawei} 156*e2203130SLinJiawei 157*e2203130SLinJiaweiclass Alu extends FunctionUnit with HasRedirectOut { 158*e2203130SLinJiawei 159*e2203130SLinJiawei val (src1, src2, func, pc, uop) = ( 160*e2203130SLinJiawei io.in.bits.src(0), 161*e2203130SLinJiawei io.in.bits.src(1), 162*e2203130SLinJiawei io.in.bits.uop.ctrl.fuOpType, 163*e2203130SLinJiawei SignExt(io.in.bits.uop.cf.pc, AddrBits), 164*e2203130SLinJiawei io.in.bits.uop 165*e2203130SLinJiawei ) 166*e2203130SLinJiawei 167*e2203130SLinJiawei val valid = io.in.valid 168*e2203130SLinJiawei val isBranch = ALUOpType.isBranch(func) 169*e2203130SLinJiawei val dataModule = Module(new AluDataModule) 170*e2203130SLinJiawei 171*e2203130SLinJiawei dataModule.io.src1 := src1 172*e2203130SLinJiawei dataModule.io.src2 := src2 173*e2203130SLinJiawei dataModule.io.func := func 174*e2203130SLinJiawei dataModule.io.pred_taken := uop.cf.pred_taken 175*e2203130SLinJiawei dataModule.io.isBranch := isBranch 176*e2203130SLinJiawei 177e18c367fSLinJiawei redirectOutValid := io.out.valid && isBranch 178151e3043SLinJiawei redirectOut := DontCare 179bfb958a3SYinan Xu redirectOut.level := RedirectLevel.flushAfter 180e18c367fSLinJiawei redirectOut.roqIdx := uop.roqIdx 181cde9280dSLinJiawei redirectOut.ftqIdx := uop.cf.ftqPtr 182cde9280dSLinJiawei redirectOut.ftqOffset := uop.cf.ftqOffset 183*e2203130SLinJiawei redirectOut.cfiUpdate.isMisPred := dataModule.io.mispredict 184*e2203130SLinJiawei redirectOut.cfiUpdate.taken := dataModule.io.taken 185cde9280dSLinJiawei redirectOut.cfiUpdate.predTaken := uop.cf.pred_taken 186151e3043SLinJiawei 187e18c367fSLinJiawei io.in.ready := io.out.ready 188e18c367fSLinJiawei io.out.valid := valid 189e18c367fSLinJiawei io.out.bits.uop <> io.in.bits.uop 190*e2203130SLinJiawei io.out.bits.data := dataModule.io.result 191e18c367fSLinJiawei} 192