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