1package xiangshan.backend.fu 2 3import chisel3._ 4import chisel3.util._ 5import utils.{LookupTree, LookupTreeDefault, SignExt, XSDebug, ZeroExt} 6import xiangshan._ 7import xiangshan.backend.ALUOpType 8 9class Alu extends FunctionUnit(FuConfig( 10 fuType = FuType.alu, 11 numIntSrc = 2, 12 numFpSrc = 0, 13 writeIntRf = true, 14 writeFpRf = false, 15 hasRedirect = true 16)) with HasRedirectOut { 17 18 val (src1, src2, offset, func, pc, uop) = ( 19 io.in.bits.src(0), 20 io.in.bits.src(1), 21 io.in.bits.uop.ctrl.imm, 22 io.in.bits.uop.ctrl.fuOpType, 23 SignExt(io.in.bits.uop.cf.pc, AddrBits), 24 io.in.bits.uop 25 ) 26 27 val redirectHit = uop.roqIdx.needFlush(io.redirectIn) 28 val valid = io.in.valid && !redirectHit 29 30 val isAdderSub = (func =/= ALUOpType.add) && (func =/= ALUOpType.addw) 31 val adderRes = (src1 +& (src2 ^ Fill(XLEN, isAdderSub))) + isAdderSub 32 val xorRes = src1 ^ src2 33 val sltu = !adderRes(XLEN) 34 val slt = xorRes(XLEN-1) ^ sltu 35 36 val shsrc1 = LookupTreeDefault(func, src1, List( 37 ALUOpType.srlw -> ZeroExt(src1(31,0), 64), 38 ALUOpType.sraw -> SignExt(src1(31,0), 64) 39 )) 40 val shamt = Mux(ALUOpType.isWordOp(func), src2(4, 0), src2(5, 0)) 41 val res = LookupTreeDefault(func(3, 0), adderRes, List( 42 ALUOpType.sll -> ((shsrc1 << shamt)(XLEN-1, 0)), 43 ALUOpType.slt -> ZeroExt(slt, XLEN), 44 ALUOpType.sltu -> ZeroExt(sltu, XLEN), 45 ALUOpType.xor -> xorRes, 46 ALUOpType.srl -> (shsrc1 >> shamt), 47 ALUOpType.or -> (src1 | src2), 48 ALUOpType.and -> (src1 & src2), 49 ALUOpType.sra -> ((shsrc1.asSInt >> shamt).asUInt) 50 )) 51 val aluRes = Mux(ALUOpType.isWordOp(func), SignExt(res(31,0), 64), res) 52 53 val branchOpTable = List( 54 ALUOpType.getBranchType(ALUOpType.beq) -> !xorRes.orR, 55 ALUOpType.getBranchType(ALUOpType.blt) -> slt, 56 ALUOpType.getBranchType(ALUOpType.bltu) -> sltu 57 ) 58 59 val isBranch = uop.cf.brUpdate.pd.isBr// ALUOpType.isBranch(func) 60 val isRVC = uop.cf.brUpdate.pd.isRVC//(io.in.bits.cf.instr(1,0) =/= "b11".U) 61 val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func) 62 val target = Mux(isBranch, pc + offset, adderRes)(VAddrBits-1,0) 63 val snpc = Mux(isRVC, pc + 2.U, pc + 4.U) 64 65 redirectOutValid := io.out.valid && isBranch 66 redirectOut.pc := uop.cf.pc 67 redirectOut.target := Mux(!taken && isBranch, snpc, target) 68 redirectOut.brTag := uop.brTag 69 redirectOut.isException := false.B 70 redirectOut.isMisPred := DontCare // check this in brq 71 redirectOut.isFlushPipe := false.B 72 redirectOut.isReplay := false.B 73 redirectOut.roqIdx := uop.roqIdx 74 75 brUpdate := uop.cf.brUpdate 76 // override brUpdate 77 brUpdate.pc := uop.cf.pc 78 brUpdate.target := Mux(!taken && isBranch, snpc, target) 79 brUpdate.brTarget := target 80 brUpdate.taken := isBranch && taken 81 brUpdate.brTag := uop.brTag 82 83 io.in.ready := io.out.ready 84 io.out.valid := valid 85 io.out.bits.uop <> io.in.bits.uop 86 io.out.bits.data := aluRes 87} 88