1package xiangshan.backend.fu 2 3import chisel3._ 4import chisel3.util._ 5import utils.{LookupTree, ParallelMux, SignExt, ZeroExt} 6import xiangshan._ 7import xiangshan.backend.ALUOpType 8 9class AddModule extends XSModule { 10 val io = IO(new Bundle() { 11 val src1, src2 = Input(UInt(XLEN.W)) 12 val out = Output(UInt((XLEN+1).W)) 13 }) 14 io.out := io.src1 +& io.src2 15} 16 17class SubModule extends XSModule { 18 val io = IO(new Bundle() { 19 val src1, src2 = Input(UInt(XLEN.W)) 20 val out = Output(UInt((XLEN+1).W)) 21 }) 22 io.out := (io.src1 +& (~io.src2).asUInt()) + 1.U 23} 24 25class LeftShiftModule extends XSModule { 26 val io = IO(new Bundle() { 27 val shamt = Input(UInt(6.W)) 28 val sllSrc = Input(UInt(XLEN.W)) 29 val sll = Output(UInt(XLEN.W)) 30 }) 31 io.sll := (io.sllSrc << io.shamt)(XLEN - 1, 0) 32} 33 34class RightShiftModule extends XSModule { 35 val io = IO(new Bundle() { 36 val shamt = Input(UInt(6.W)) 37 val srlSrc, sraSrc = Input(UInt(XLEN.W)) 38 val srl, sra = Output(UInt(XLEN.W)) 39 }) 40 io.srl := io.srlSrc >> io.shamt 41 io.sra := (io.sraSrc.asSInt() >> io.shamt).asUInt() 42} 43 44class ShiftModule extends XSModule { 45 val io = IO(new Bundle() { 46 val shamt = Input(UInt(6.W)) 47 val shsrc1 = Input(UInt(XLEN.W)) 48 val sll, srl, sra = Output(UInt(XLEN.W)) 49 }) 50 io.sll := (io.shsrc1 << io.shamt)(XLEN-1, 0) 51 io.srl := io.shsrc1 >> io.shamt 52 io.sra := (io.shsrc1.asSInt >> io.shamt).asUInt 53} 54 55class MiscResultSelect extends XSModule { 56 val io = IO(new Bundle() { 57 val func = Input(UInt()) 58 val sll, slt, sltu, xor, srl, or, and, sra = Input(UInt(XLEN.W)) 59 val miscRes = Output(UInt(XLEN.W)) 60 61 }) 62 io.miscRes := ParallelMux(List( 63 ALUOpType.and -> io.and, 64 ALUOpType.or -> io.or, 65 ALUOpType.xor -> io.xor, 66 ALUOpType.slt -> ZeroExt(io.slt, XLEN), 67 ALUOpType.sltu -> ZeroExt(io.sltu, XLEN), 68 ALUOpType.srl -> io.srl, 69 ALUOpType.sll -> io.sll, 70 ALUOpType.sra -> io.sra 71 ).map(x => (x._1 === io.func(3, 0), x._2))) 72} 73 74class AluResSel extends XSModule { 75 val io = IO(new Bundle() { 76 val func = Input(UInt()) 77 val isSub = Input(Bool()) 78 val addRes, subRes, miscRes = Input(UInt(XLEN.W)) 79 val aluRes = Output(UInt(XLEN.W)) 80 }) 81 val isAddSub = ALUOpType.isAddSub(io.func) 82 val res = Mux(ALUOpType.isAddSub(io.func), 83 Mux(io.isSub, io.subRes, io.addRes), 84 io.miscRes 85 ) 86 val h32 = Mux(ALUOpType.isWordOp(io.func), Fill(32, res(31)), res(63, 32)) 87 io.aluRes := Cat(h32, res(31, 0)) 88} 89 90class Alu extends FunctionUnit with HasRedirectOut { 91 92 val (src1, src2, func, pc, uop) = ( 93 io.in.bits.src(0), 94 io.in.bits.src(1), 95 io.in.bits.uop.ctrl.fuOpType, 96 SignExt(io.in.bits.uop.cf.pc, AddrBits), 97 io.in.bits.uop 98 ) 99 100 val valid = io.in.valid 101 102 val isAdderSub = (func =/= ALUOpType.add) && (func =/= ALUOpType.addw) 103 val addModule = Module(new AddModule) 104 addModule.io.src1 := src1 105 addModule.io.src2 := src2 106 val subModule = Module(new SubModule) 107 subModule.io.src1 := src1 108 subModule.io.src2 := src2 109 val addRes = addModule.io.out 110 val subRes = subModule.io.out 111 val xorRes = src1 ^ src2 112 val sltu = !subRes(XLEN) 113 val slt = xorRes(XLEN-1) ^ sltu 114 115 val isW = ALUOpType.isWordOp(func) 116 val shamt = Cat(!isW && src2(5), src2(4, 0)) 117 118 val leftShiftModule = Module(new LeftShiftModule) 119 leftShiftModule.io.sllSrc := src1 120 leftShiftModule.io.shamt := shamt 121 122 val rightShiftModule = Module(new RightShiftModule) 123 rightShiftModule.io.shamt := shamt 124 rightShiftModule.io.srlSrc := Cat( 125 Mux(isW, 0.U(32.W), src1(63, 32)), 126 src1(31, 0) 127 ) 128 rightShiftModule.io.sraSrc := Cat( 129 Mux(isW, Fill(32, src1(31)), src1(63, 32)), 130 src1(31, 0) 131 ) 132 133 val sll = leftShiftModule.io.sll 134 val srl = rightShiftModule.io.srl 135 val sra = rightShiftModule.io.sra 136 137 val miscResSel = Module(new MiscResultSelect) 138 miscResSel.io.func := func(3, 0) 139 miscResSel.io.sll := sll 140 miscResSel.io.slt := ZeroExt(slt, XLEN) 141 miscResSel.io.sltu := ZeroExt(sltu, XLEN) 142 miscResSel.io.xor := xorRes 143 miscResSel.io.srl := srl 144 miscResSel.io.or := (src1 | src2) 145 miscResSel.io.and := (src1 & src2) 146 miscResSel.io.sra := sra 147 148 val miscRes = miscResSel.io.miscRes 149 150 val aluResSel = Module(new AluResSel) 151 aluResSel.io.func := func 152 aluResSel.io.isSub := isAdderSub 153 aluResSel.io.addRes := addRes 154 aluResSel.io.subRes := subRes 155 aluResSel.io.miscRes := miscRes 156 val aluRes = aluResSel.io.aluRes 157 158 val branchOpTable = List( 159 ALUOpType.getBranchType(ALUOpType.beq) -> !xorRes.orR, 160 ALUOpType.getBranchType(ALUOpType.blt) -> slt, 161 ALUOpType.getBranchType(ALUOpType.bltu) -> sltu 162 ) 163 164 val isBranch = ALUOpType.isBranch(func) 165 val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func) 166 167 redirectOutValid := io.out.valid && isBranch 168 redirectOut := DontCare 169 redirectOut.level := RedirectLevel.flushAfter 170 redirectOut.roqIdx := uop.roqIdx 171 redirectOut.ftqIdx := uop.cf.ftqPtr 172 redirectOut.ftqOffset := uop.cf.ftqOffset 173 redirectOut.cfiUpdate.isMisPred := (uop.cf.pred_taken ^ taken) && isBranch 174 redirectOut.cfiUpdate.taken := taken 175 redirectOut.cfiUpdate.predTaken := uop.cf.pred_taken 176 177 io.in.ready := io.out.ready 178 io.out.valid := valid 179 io.out.bits.uop <> io.in.bits.uop 180 io.out.bits.data := aluRes 181} 182