1package xiangshan.backend.fu 2 3import chisel3._ 4import chisel3.util._ 5import utils.{LookupTree, LookupTreeDefault, ParallelMux, SignExt, XSDebug, ZeroExt} 6import xiangshan._ 7import xiangshan.backend.ALUOpType 8 9class Alu extends FunctionUnit with HasRedirectOut { 10 11 val (src1, src2, func, pc, uop) = ( 12 io.in.bits.src(0), 13 io.in.bits.src(1), 14 io.in.bits.uop.ctrl.fuOpType, 15 SignExt(io.in.bits.uop.cf.pc, AddrBits), 16 io.in.bits.uop 17 ) 18 19 val offset = src2 20 21 val valid = io.in.valid 22 23 val isAdderSub = (func =/= ALUOpType.add) && (func =/= ALUOpType.addw) 24 val addRes = src1 +& src2 25 val subRes = (src1 +& (~src2).asUInt()) + 1.U 26 val xorRes = src1 ^ src2 27 val sltu = !subRes(XLEN) 28 val slt = xorRes(XLEN-1) ^ sltu 29 30 val shsrc1 = LookupTreeDefault(func, src1, List( 31 ALUOpType.srlw -> ZeroExt(src1(31,0), 64), 32 ALUOpType.sraw -> SignExt(src1(31,0), 64) 33 )) 34 val shamt = Mux(ALUOpType.isWordOp(func), src2(4, 0), src2(5, 0)) 35 36 val miscRes = ParallelMux(List( 37 ALUOpType.sll -> (shsrc1 << shamt)(XLEN-1, 0), 38 ALUOpType.slt -> ZeroExt(slt, XLEN), 39 ALUOpType.sltu -> ZeroExt(sltu, XLEN), 40 ALUOpType.xor -> xorRes, 41 ALUOpType.srl -> (shsrc1 >> shamt), 42 ALUOpType.or -> (src1 | src2), 43 ALUOpType.and -> (src1 & src2), 44 ALUOpType.sra -> (shsrc1.asSInt >> shamt).asUInt 45 ).map(x => (x._1 === func(3, 0), x._2))) 46 47 val res = Mux(ALUOpType.isAddSub(func), 48 Mux(isAdderSub, subRes, addRes), 49 miscRes 50 ) 51 52 val aluRes = Mux(ALUOpType.isWordOp(func), SignExt(res(31,0), 64), res) 53 54 val branchOpTable = List( 55 ALUOpType.getBranchType(ALUOpType.beq) -> !xorRes.orR, 56 ALUOpType.getBranchType(ALUOpType.blt) -> slt, 57 ALUOpType.getBranchType(ALUOpType.bltu) -> sltu 58 ) 59 60 val isBranch = ALUOpType.isBranch(func) 61 val isRVC = uop.cf.brUpdate.pd.isRVC 62 val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func) 63 val target = (pc + offset)(VAddrBits-1,0) 64 val snpc = Mux(isRVC, pc + 2.U, pc + 4.U) 65 66 redirectOutValid := io.out.valid && isBranch 67 // Only brTag, level, roqIdx are needed 68 // other infos are stored in brq 69 redirectOut := DontCare 70 redirectOut.brTag := uop.brTag 71 redirectOut.level := RedirectLevel.flushAfter 72 redirectOut.roqIdx := uop.roqIdx 73 74// redirectOut.pc := DontCare//uop.cf.pc 75// redirectOut.target := DontCare//Mux(!taken && isBranch, snpc, target) 76// redirectOut.interrupt := DontCare//DontCare 77 78 // Only taken really needed, do we need brTag ? 79 brUpdate := DontCare 80 brUpdate.taken := isBranch && taken 81 brUpdate.brTag := uop.brTag 82 83// brUpdate := uop.cf.brUpdate 84// // override brUpdate 85// brUpdate.pc := uop.cf.pc 86// brUpdate.target := Mux(!taken && isBranch, snpc, target) 87// brUpdate.brTarget := target 88// brUpdate.taken := isBranch && taken 89// brUpdate.brTag := uop.brTag 90 91 io.in.ready := io.out.ready 92 io.out.valid := valid 93 io.out.bits.uop <> io.in.bits.uop 94 io.out.bits.data := aluRes 95} 96