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