1e18c367fSLinJiaweipackage xiangshan.backend.fu 2e18c367fSLinJiawei 3e18c367fSLinJiaweiimport chisel3._ 4e18c367fSLinJiaweiimport chisel3.util._ 53ef996e9SLinJiaweiimport utils.{LookupTree, LookupTreeDefault, ParallelMux, SignExt, XSDebug, ZeroExt} 6e18c367fSLinJiaweiimport xiangshan._ 7e18c367fSLinJiaweiimport xiangshan.backend.ALUOpType 8e18c367fSLinJiawei 952c3f215SLinJiaweiclass Alu extends FunctionUnit with HasRedirectOut { 10e18c367fSLinJiawei 11b0ae3ac4SLinJiawei val (src1, src2, func, pc, uop) = ( 12e18c367fSLinJiawei io.in.bits.src(0), 13e18c367fSLinJiawei io.in.bits.src(1), 14e18c367fSLinJiawei io.in.bits.uop.ctrl.fuOpType, 15e18c367fSLinJiawei SignExt(io.in.bits.uop.cf.pc, AddrBits), 16e18c367fSLinJiawei io.in.bits.uop 17e18c367fSLinJiawei ) 18e18c367fSLinJiawei 19b0ae3ac4SLinJiawei val offset = src2 20b0ae3ac4SLinJiawei 21dfd9e0a8SLinJiawei val valid = io.in.valid 22e18c367fSLinJiawei 23e18c367fSLinJiawei val isAdderSub = (func =/= ALUOpType.add) && (func =/= ALUOpType.addw) 243ef996e9SLinJiawei val addRes = src1 +& src2 253ef996e9SLinJiawei val subRes = (src1 +& (~src2).asUInt()) + 1.U 26e18c367fSLinJiawei val xorRes = src1 ^ src2 273ef996e9SLinJiawei val sltu = !subRes(XLEN) 28e18c367fSLinJiawei val slt = xorRes(XLEN-1) ^ sltu 29e18c367fSLinJiawei 30e18c367fSLinJiawei val shsrc1 = LookupTreeDefault(func, src1, List( 31e18c367fSLinJiawei ALUOpType.srlw -> ZeroExt(src1(31,0), 64), 32e18c367fSLinJiawei ALUOpType.sraw -> SignExt(src1(31,0), 64) 33e18c367fSLinJiawei )) 34e18c367fSLinJiawei val shamt = Mux(ALUOpType.isWordOp(func), src2(4, 0), src2(5, 0)) 353ef996e9SLinJiawei 363ef996e9SLinJiawei val miscRes = ParallelMux(List( 373ef996e9SLinJiawei ALUOpType.sll -> (shsrc1 << shamt)(XLEN-1, 0), 38e18c367fSLinJiawei ALUOpType.slt -> ZeroExt(slt, XLEN), 39e18c367fSLinJiawei ALUOpType.sltu -> ZeroExt(sltu, XLEN), 40e18c367fSLinJiawei ALUOpType.xor -> xorRes, 41e18c367fSLinJiawei ALUOpType.srl -> (shsrc1 >> shamt), 42e18c367fSLinJiawei ALUOpType.or -> (src1 | src2), 43e18c367fSLinJiawei ALUOpType.and -> (src1 & src2), 443ef996e9SLinJiawei ALUOpType.sra -> (shsrc1.asSInt >> shamt).asUInt 453ef996e9SLinJiawei ).map(x => (x._1 === func(3, 0), x._2))) 463ef996e9SLinJiawei 473ef996e9SLinJiawei val res = Mux(ALUOpType.isAddSub(func), 483ef996e9SLinJiawei Mux(isAdderSub, subRes, addRes), 493ef996e9SLinJiawei miscRes 503ef996e9SLinJiawei ) 513ef996e9SLinJiawei 52e18c367fSLinJiawei val aluRes = Mux(ALUOpType.isWordOp(func), SignExt(res(31,0), 64), res) 53e18c367fSLinJiawei 54e18c367fSLinJiawei val branchOpTable = List( 55e18c367fSLinJiawei ALUOpType.getBranchType(ALUOpType.beq) -> !xorRes.orR, 56e18c367fSLinJiawei ALUOpType.getBranchType(ALUOpType.blt) -> slt, 57e18c367fSLinJiawei ALUOpType.getBranchType(ALUOpType.bltu) -> sltu 58e18c367fSLinJiawei ) 59e18c367fSLinJiawei 60869210c7SYinan Xu val isBranch = ALUOpType.isBranch(func) 613ef996e9SLinJiawei val isRVC = uop.cf.brUpdate.pd.isRVC 62e18c367fSLinJiawei val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func) 633ef996e9SLinJiawei val target = (pc + offset)(VAddrBits-1,0) 64e18c367fSLinJiawei val snpc = Mux(isRVC, pc + 2.U, pc + 4.U) 65e18c367fSLinJiawei 66e18c367fSLinJiawei redirectOutValid := io.out.valid && isBranch 67*151e3043SLinJiawei // Only brTag, level, roqIdx are needed 68*151e3043SLinJiawei // other infos are stored in brq 69*151e3043SLinJiawei redirectOut := DontCare 70e18c367fSLinJiawei redirectOut.brTag := uop.brTag 71bfb958a3SYinan Xu redirectOut.level := RedirectLevel.flushAfter 72e18c367fSLinJiawei redirectOut.roqIdx := uop.roqIdx 73e18c367fSLinJiawei 74*151e3043SLinJiawei// redirectOut.pc := DontCare//uop.cf.pc 75*151e3043SLinJiawei// redirectOut.target := DontCare//Mux(!taken && isBranch, snpc, target) 76*151e3043SLinJiawei// redirectOut.interrupt := DontCare//DontCare 77*151e3043SLinJiawei 78*151e3043SLinJiawei // Only taken really needed, do we need brTag ? 79*151e3043SLinJiawei brUpdate := DontCare 80e18c367fSLinJiawei brUpdate.taken := isBranch && taken 81e18c367fSLinJiawei brUpdate.brTag := uop.brTag 82e18c367fSLinJiawei 83*151e3043SLinJiawei// brUpdate := uop.cf.brUpdate 84*151e3043SLinJiawei// // override brUpdate 85*151e3043SLinJiawei// brUpdate.pc := uop.cf.pc 86*151e3043SLinJiawei// brUpdate.target := Mux(!taken && isBranch, snpc, target) 87*151e3043SLinJiawei// brUpdate.brTarget := target 88*151e3043SLinJiawei// brUpdate.taken := isBranch && taken 89*151e3043SLinJiawei// brUpdate.brTag := uop.brTag 90*151e3043SLinJiawei 91e18c367fSLinJiawei io.in.ready := io.out.ready 92e18c367fSLinJiawei io.out.valid := valid 93e18c367fSLinJiawei io.out.bits.uop <> io.in.bits.uop 94e18c367fSLinJiawei io.out.bits.data := aluRes 95e18c367fSLinJiawei} 96