1c6d43980SLemover/*************************************************************************************** 2c6d43980SLemover* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3f320e0f0SYinan Xu* Copyright (c) 2020-2021 Peng Cheng Laboratory 4c6d43980SLemover* 5c6d43980SLemover* XiangShan is licensed under Mulan PSL v2. 6c6d43980SLemover* You can use this software according to the terms and conditions of the Mulan PSL v2. 7c6d43980SLemover* You may obtain a copy of Mulan PSL v2 at: 8c6d43980SLemover* http://license.coscl.org.cn/MulanPSL2 9c6d43980SLemover* 10c6d43980SLemover* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11c6d43980SLemover* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12c6d43980SLemover* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13c6d43980SLemover* 14c6d43980SLemover* See the Mulan PSL v2 for more details. 15c6d43980SLemover***************************************************************************************/ 16c6d43980SLemover 17e18c367fSLinJiaweipackage xiangshan.backend.fu 18e18c367fSLinJiawei 192225d46eSJiawei Linimport chipsalliance.rocketchip.config.Parameters 20e18c367fSLinJiaweiimport chisel3._ 21e18c367fSLinJiaweiimport chisel3.util._ 22*ee8ff153Szfwimport utils.{LookupTreeDefault, LookupTree, ParallelMux, SignExt, ZeroExt} 23e18c367fSLinJiaweiimport xiangshan._ 24e18c367fSLinJiawei 252225d46eSJiawei Linclass AddModule(implicit p: Parameters) extends XSModule { 2631ea8750SLinJiawei val io = IO(new Bundle() { 272bd5334dSYinan Xu val src = Vec(2, Input(UInt(XLEN.W))) 2831ea8750SLinJiawei val out = Output(UInt((XLEN+1).W)) 2931ea8750SLinJiawei }) 302bd5334dSYinan Xu io.out := io.src(0) +& io.src(1) 3131ea8750SLinJiawei} 3231ea8750SLinJiawei 332225d46eSJiawei Linclass SubModule(implicit p: Parameters) extends XSModule { 3431ea8750SLinJiawei val io = IO(new Bundle() { 352bd5334dSYinan Xu val src = Vec(2, Input(UInt(XLEN.W))) 3631ea8750SLinJiawei val out = Output(UInt((XLEN+1).W)) 3731ea8750SLinJiawei }) 382bd5334dSYinan Xu io.out := (io.src(0) +& (~io.src(1)).asUInt()) + 1.U 3931ea8750SLinJiawei} 4031ea8750SLinJiawei 412225d46eSJiawei Linclass LeftShiftModule(implicit p: Parameters) extends XSModule { 4231ea8750SLinJiawei val io = IO(new Bundle() { 4331ea8750SLinJiawei val shamt = Input(UInt(6.W)) 4431ea8750SLinJiawei val sllSrc = Input(UInt(XLEN.W)) 4531ea8750SLinJiawei val sll = Output(UInt(XLEN.W)) 4631ea8750SLinJiawei }) 4731ea8750SLinJiawei io.sll := (io.sllSrc << io.shamt)(XLEN - 1, 0) 4831ea8750SLinJiawei} 4931ea8750SLinJiawei 502225d46eSJiawei Linclass RightShiftModule(implicit p: Parameters) extends XSModule { 5131ea8750SLinJiawei val io = IO(new Bundle() { 5231ea8750SLinJiawei val shamt = Input(UInt(6.W)) 5331ea8750SLinJiawei val srlSrc, sraSrc = Input(UInt(XLEN.W)) 5467630d0bSLinJiawei val srl_l, srl_w, sra_l, sra_w = Output(UInt(XLEN.W)) 5531ea8750SLinJiawei }) 5667630d0bSLinJiawei io.srl_l := io.srlSrc >> io.shamt 5767630d0bSLinJiawei io.srl_w := io.srlSrc(31, 0) >> io.shamt 5867630d0bSLinJiawei io.sra_l := (io.sraSrc.asSInt() >> io.shamt).asUInt() 59c57a9346SLinJiawei io.sra_w := (Cat(Fill(32, io.sraSrc(31)), io.sraSrc(31, 0)).asSInt() >> io.shamt).asUInt() 6031ea8750SLinJiawei} 6131ea8750SLinJiawei 62*ee8ff153Szfwclass RotateShiftModule(implicit p: Parameters) extends XSModule { 63*ee8ff153Szfw val io = IO(new Bundle() { 64*ee8ff153Szfw val shamt = Input(UInt(6.W)) 65*ee8ff153Szfw val roSrc = Input(UInt(XLEN.W)) 66*ee8ff153Szfw val rol_l, rol_w, ror_l, ror_w = Output(UInt(XLEN.W)) 67*ee8ff153Szfw }) 68*ee8ff153Szfw io.rol_l := io.roSrc << io.shamt | io.roSrc >> ((~io.shamt).asUInt()+&1.U) 69*ee8ff153Szfw io.rol_w := (io.roSrc << io.shamt | io.roSrc >> (32.U-io.shamt))(31,0) 70*ee8ff153Szfw io.ror_l := io.roSrc>>io.shamt | io.roSrc << ((~io.shamt).asUInt()+&1.U) 71*ee8ff153Szfw io.ror_w := (io.roSrc>>io.shamt | io.roSrc << (32.U-io.shamt))(31,0) 72*ee8ff153Szfw} 73*ee8ff153Szfw 742225d46eSJiawei Linclass MiscResultSelect(implicit p: Parameters) extends XSModule { 7531ea8750SLinJiawei val io = IO(new Bundle() { 7631ea8750SLinJiawei val func = Input(UInt()) 77*ee8ff153Szfw val andn, orn, xnor, and, or, xor, sltu, slt, maxMin, maxMinU, sextb, sexth, zexth, rev8, orcb = Input(UInt(XLEN.W)) 7831ea8750SLinJiawei val miscRes = Output(UInt(XLEN.W)) 7931ea8750SLinJiawei }) 80*ee8ff153Szfw 81*ee8ff153Szfw val (func, andn, orn, xnor, and, or, xor, sltu, slt, maxMin, maxMinU, sextb, sexth, zexth, rev8, orcb) = 82*ee8ff153Szfw (io.func, io.andn, io.orn, io.xnor, io.and, io.or, io.xor, io.sltu, io.slt, io.maxMin, io.maxMinU, io.sextb, io.sexth, io.zexth, io.rev8, io.orcb) 83*ee8ff153Szfw 84*ee8ff153Szfw val baseMisc = ParallelMux(List( 85*ee8ff153Szfw ALUOpType.andn -> andn, 86*ee8ff153Szfw ALUOpType.and -> and, 87*ee8ff153Szfw ALUOpType.orn -> orn, 88*ee8ff153Szfw ALUOpType.or -> or, 89*ee8ff153Szfw ALUOpType.xnor -> xnor, 90*ee8ff153Szfw ALUOpType.xor -> xor 91*ee8ff153Szfw ).map(x => (x._1(2, 0) === io.func(2, 0), x._2))) 92*ee8ff153Szfw 93*ee8ff153Szfw val bitMisc = ParallelMux(List( 94*ee8ff153Szfw ALUOpType.sext_b -> sextb, 95*ee8ff153Szfw ALUOpType.sext_h -> sexth, 96*ee8ff153Szfw ALUOpType.zext_h -> zexth, 97*ee8ff153Szfw ALUOpType.orc_b -> orcb, 98*ee8ff153Szfw ALUOpType.rev8 -> rev8 99*ee8ff153Szfw ).map(x => (x._1(2, 0) === io.func(2, 0), x._2))) 100*ee8ff153Szfw 101*ee8ff153Szfw val compMisc = Mux(func(2), 102*ee8ff153Szfw Mux(func(1), maxMinU, maxMin), 103*ee8ff153Szfw Mux(func(1), sltu, slt)) 104*ee8ff153Szfw 105*ee8ff153Szfw io.miscRes := Mux(func(4), compMisc, Mux(func(3), bitMisc, baseMisc)) 10631ea8750SLinJiawei} 10731ea8750SLinJiawei 108*ee8ff153Szfwclass ShiftResultSelect(implicit p: Parameters) extends XSModule { 109*ee8ff153Szfw val io = IO(new Bundle() { 110*ee8ff153Szfw val func = Input(UInt()) 111*ee8ff153Szfw val sll, srl, sra, rol, ror, bclr, bset, binv, bext = Input(UInt(XLEN.W)) 112*ee8ff153Szfw val shiftRes = Output(UInt(XLEN.W)) 113*ee8ff153Szfw }) 114*ee8ff153Szfw 115*ee8ff153Szfw val (func, sll, srl, sra, rol, ror, bclr, bset, binv, bext) = 116*ee8ff153Szfw (io.func, io.sll, io.srl, io.sra, io.rol, io.ror, io.bclr, io.bset, io.binv, io.bext) 117*ee8ff153Szfw 118*ee8ff153Szfw val singleBitRes = ParallelMux(List( 119*ee8ff153Szfw ALUOpType.bclr -> bclr, 120*ee8ff153Szfw ALUOpType.binv -> binv, 121*ee8ff153Szfw ALUOpType.bset -> bset, 122*ee8ff153Szfw ALUOpType.bext -> bext 123*ee8ff153Szfw ).map(x => (x._1(1, 0) === io.func(1, 0), x._2))) 124*ee8ff153Szfw 125*ee8ff153Szfw val lrShiftRes = Mux(func(1), Mux(func(0), sra, srl), sll) 126*ee8ff153Szfw val rotateShiftRes = Mux(func(3), ror, rol) 127*ee8ff153Szfw 128*ee8ff153Szfw io.shiftRes := Mux(func(4), rotateShiftRes, Mux(func(2), singleBitRes, lrShiftRes)) 129*ee8ff153Szfw} 130*ee8ff153Szfw 131*ee8ff153Szfw 1322225d46eSJiawei Linclass AluResSel(implicit p: Parameters) extends XSModule { 13331ea8750SLinJiawei val io = IO(new Bundle() { 13431ea8750SLinJiawei val func = Input(UInt()) 135*ee8ff153Szfw // val addSubRes, shiftRes, miscRes, countRes = Input(UInt(XLEN.W)) 136*ee8ff153Szfw val addSubRes, shiftRes, miscRes = Input(UInt(XLEN.W)) 13731ea8750SLinJiawei val aluRes = Output(UInt(XLEN.W)) 13831ea8750SLinJiawei }) 139*ee8ff153Szfw 140*ee8ff153Szfw val res = Mux(io.func(6), 141*ee8ff153Szfw io.shiftRes, 142*ee8ff153Szfw Mux(io.func(5), io.addSubRes, io.miscRes) 14331ea8750SLinJiawei ) 144*ee8ff153Szfw val h32 = Mux(io.func(7), Fill(32, res(31)), res(63, 32)) 14531ea8750SLinJiawei io.aluRes := Cat(h32, res(31, 0)) 14631ea8750SLinJiawei} 14731ea8750SLinJiawei 1482225d46eSJiawei Linclass AluDataModule(implicit p: Parameters) extends XSModule { 149e2203130SLinJiawei val io = IO(new Bundle() { 1502bd5334dSYinan Xu val src = Vec(2, Input(UInt(XLEN.W))) 151e2203130SLinJiawei val func = Input(FuOpType()) 152e2203130SLinJiawei val pred_taken, isBranch = Input(Bool()) 153e2203130SLinJiawei val result = Output(UInt(XLEN.W)) 154e2203130SLinJiawei val taken, mispredict = Output(Bool()) 155e2203130SLinJiawei }) 1562bd5334dSYinan Xu val (src1, src2, func) = (io.src(0), io.src(1), io.func) 157e18c367fSLinJiawei 15831ea8750SLinJiawei val addModule = Module(new AddModule) 1592bd5334dSYinan Xu addModule.io.src(1) := src2 160*ee8ff153Szfw addModule.io.src(0) := ParallelMux(List( 161*ee8ff153Szfw "b000".U -> src1, 162*ee8ff153Szfw "b001".U -> src1(31,0), 163*ee8ff153Szfw "b010".U -> Cat(src1(62,0), 0.U(1.W)), 164*ee8ff153Szfw "b011".U -> Cat(src1(30,0), 0.U(1.W)), 165*ee8ff153Szfw "b100".U -> Cat(src1(61,0), 0.U(2.W)), 166*ee8ff153Szfw "b101".U -> Cat(src1(29,0), 0.U(2.W)), 167*ee8ff153Szfw "b110".U -> Cat(src1(60,0), 0.U(3.W)), 168*ee8ff153Szfw "b111".U -> Cat(src1(28,0), 0.U(3.W)), 169*ee8ff153Szfw ).map(x => (x._1(2, 0) === func(2,0), x._2))) 170*ee8ff153Szfw 171*ee8ff153Szfw 17231ea8750SLinJiawei val subModule = Module(new SubModule) 1732bd5334dSYinan Xu subModule.io.src(0) := src1 1742bd5334dSYinan Xu subModule.io.src(1) := src2 175*ee8ff153Szfw val add = addModule.io.out 176*ee8ff153Szfw val sub = subModule.io.out 177e18c367fSLinJiawei 178*ee8ff153Szfw 179*ee8ff153Szfw // Misc 180*ee8ff153Szfw val andn = ~(src1 & src2) 181*ee8ff153Szfw val orn = ~(src1 | src2) 182*ee8ff153Szfw val xnor = ~(src1 ^ src2) 183*ee8ff153Szfw val and = ~andn 184*ee8ff153Szfw val or = ~orn 185*ee8ff153Szfw val xor = ~xnor 186*ee8ff153Szfw val sltu = !sub(XLEN) 187*ee8ff153Szfw val slt = xor(XLEN-1) ^ sltu 188*ee8ff153Szfw val maxMin = Mux(slt ^ func(0), src2, src1) 189*ee8ff153Szfw val maxMinU = Mux(sltu^ func(0), src2, src1) 190*ee8ff153Szfw val sextb = SignExt(src1(7, 0), XLEN) 191*ee8ff153Szfw val sexth = SignExt(src1(15, 0), XLEN) 192*ee8ff153Szfw val zexth = ZeroExt(src1(15, 0), XLEN) 193*ee8ff153Szfw val rev8 = Cat(src1(7,0), src1(15,8), src1(23,16), src1(31,24), 194*ee8ff153Szfw src1(39,32), src1(47,40), src1(55,48), src1(63,56)) 195*ee8ff153Szfw val orcb = Cat(Reverse(src1(63,56)), Reverse(src1(55,48)), Reverse(src1(47,40)), Reverse(src1(39,32)), 196*ee8ff153Szfw Reverse(src1(31,24)), Reverse(src1(23,16)), Reverse(src1(15,8)), Reverse(src1(7,0))) 197*ee8ff153Szfw 198*ee8ff153Szfw val branchOpTable = List( 199*ee8ff153Szfw ALUOpType.getBranchType(ALUOpType.beq) -> !xor.orR, 200*ee8ff153Szfw ALUOpType.getBranchType(ALUOpType.blt) -> slt, 201*ee8ff153Szfw ALUOpType.getBranchType(ALUOpType.bltu) -> sltu 202*ee8ff153Szfw ) 203*ee8ff153Szfw val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func) 204*ee8ff153Szfw 205*ee8ff153Szfw 206*ee8ff153Szfw // Shift 20731ea8750SLinJiawei val isW = ALUOpType.isWordOp(func) 2084a6ab1cdSLinJiawei val shamt = Cat(!isW && src2(5), src2(4, 0)) 2093ef996e9SLinJiawei 21031ea8750SLinJiawei val leftShiftModule = Module(new LeftShiftModule) 211*ee8ff153Szfw leftShiftModule.io.sllSrc := Mux(func(2), 1.U, Mux(func(0), src1(31,0), src1)) 21231ea8750SLinJiawei leftShiftModule.io.shamt := shamt 213*ee8ff153Szfw val sll = leftShiftModule.io.sll 214*ee8ff153Szfw val bset = src1 | sll 215*ee8ff153Szfw val bclr = src1 & ~sll 216*ee8ff153Szfw val binv = src1 ^ sll 217*ee8ff153Szfw 2183ef996e9SLinJiawei 21931ea8750SLinJiawei val rightShiftModule = Module(new RightShiftModule) 22031ea8750SLinJiawei rightShiftModule.io.shamt := shamt 22167630d0bSLinJiawei rightShiftModule.io.srlSrc := src1 22267630d0bSLinJiawei rightShiftModule.io.sraSrc := src1 22367630d0bSLinJiawei val srl = Mux(isW, rightShiftModule.io.srl_w, rightShiftModule.io.srl_l) 22467630d0bSLinJiawei val sra = Mux(isW, rightShiftModule.io.sra_w, rightShiftModule.io.sra_l) 225*ee8ff153Szfw val bext = srl(0) 226*ee8ff153Szfw 227*ee8ff153Szfw val rotateShiftModule = Module(new RotateShiftModule) 228*ee8ff153Szfw rotateShiftModule.io.shamt := Mux(isW, src2(4,0), src2(5,0)) 229*ee8ff153Szfw rotateShiftModule.io.roSrc := Mux(isW, src1(31,0), src1) 230*ee8ff153Szfw val rol = Mux(isW, rotateShiftModule.io.rol_w, rotateShiftModule.io.rol_l) 231*ee8ff153Szfw val ror = Mux(isW, rotateShiftModule.io.ror_w, rotateShiftModule.io.ror_l) 23231ea8750SLinJiawei 23331ea8750SLinJiawei val miscResSel = Module(new MiscResultSelect) 234*ee8ff153Szfw miscResSel.io.func := func(4, 0) 235*ee8ff153Szfw miscResSel.io.andn := andn 236*ee8ff153Szfw miscResSel.io.orn := orn 237*ee8ff153Szfw miscResSel.io.xnor := xnor 238*ee8ff153Szfw miscResSel.io.and := and 239*ee8ff153Szfw miscResSel.io.or := or 240*ee8ff153Szfw miscResSel.io.xor := xor 241*ee8ff153Szfw miscResSel.io.sltu := sltu 242*ee8ff153Szfw miscResSel.io.slt := slt 243*ee8ff153Szfw miscResSel.io.maxMin := maxMin 244*ee8ff153Szfw miscResSel.io.maxMinU := maxMinU 245*ee8ff153Szfw miscResSel.io.sextb := sextb 246*ee8ff153Szfw miscResSel.io.sexth := sexth 247*ee8ff153Szfw miscResSel.io.zexth := zexth 248*ee8ff153Szfw miscResSel.io.rev8 := rev8 249*ee8ff153Szfw miscResSel.io.orcb := orcb 25031ea8750SLinJiawei val miscRes = miscResSel.io.miscRes 25131ea8750SLinJiawei 252*ee8ff153Szfw val addSubRes = Mux(func(3), sub, add) 253*ee8ff153Szfw 254*ee8ff153Szfw val shiftResSel = Module(new ShiftResultSelect) 255*ee8ff153Szfw shiftResSel.io.func := func(4,0) 256*ee8ff153Szfw shiftResSel.io.sll := sll 257*ee8ff153Szfw shiftResSel.io.srl := srl 258*ee8ff153Szfw shiftResSel.io.sra := sra 259*ee8ff153Szfw shiftResSel.io.rol := rol 260*ee8ff153Szfw shiftResSel.io.ror := ror 261*ee8ff153Szfw shiftResSel.io.bclr := bclr 262*ee8ff153Szfw shiftResSel.io.binv := binv 263*ee8ff153Szfw shiftResSel.io.bset := bset 264*ee8ff153Szfw shiftResSel.io.bext := bext 265*ee8ff153Szfw val shiftRes = shiftResSel.io.shiftRes 266*ee8ff153Szfw 26731ea8750SLinJiawei val aluResSel = Module(new AluResSel) 26831ea8750SLinJiawei aluResSel.io.func := func 269*ee8ff153Szfw aluResSel.io.addSubRes := addSubRes 270*ee8ff153Szfw aluResSel.io.shiftRes := shiftRes 27131ea8750SLinJiawei aluResSel.io.miscRes := miscRes 27231ea8750SLinJiawei val aluRes = aluResSel.io.aluRes 273e18c367fSLinJiawei 274e2203130SLinJiawei io.result := aluRes 275e2203130SLinJiawei io.taken := taken 276e2203130SLinJiawei io.mispredict := (io.pred_taken ^ taken) && io.isBranch 277e2203130SLinJiawei} 278e2203130SLinJiawei 279adb5df20SYinan Xuclass Alu(implicit p: Parameters) extends FUWithRedirect { 280e2203130SLinJiawei 281e2203130SLinJiawei val (src1, src2, func, pc, uop) = ( 282e2203130SLinJiawei io.in.bits.src(0), 283e2203130SLinJiawei io.in.bits.src(1), 284e2203130SLinJiawei io.in.bits.uop.ctrl.fuOpType, 285e2203130SLinJiawei SignExt(io.in.bits.uop.cf.pc, AddrBits), 286e2203130SLinJiawei io.in.bits.uop 287e2203130SLinJiawei ) 288e2203130SLinJiawei 289e2203130SLinJiawei val valid = io.in.valid 290e2203130SLinJiawei val isBranch = ALUOpType.isBranch(func) 291e2203130SLinJiawei val dataModule = Module(new AluDataModule) 292e2203130SLinJiawei 2932bd5334dSYinan Xu dataModule.io.src(0) := src1 2942bd5334dSYinan Xu dataModule.io.src(1) := src2 295e2203130SLinJiawei dataModule.io.func := func 296e2203130SLinJiawei dataModule.io.pred_taken := uop.cf.pred_taken 297e2203130SLinJiawei dataModule.io.isBranch := isBranch 298e2203130SLinJiawei 299e18c367fSLinJiawei redirectOutValid := io.out.valid && isBranch 300151e3043SLinJiawei redirectOut := DontCare 301bfb958a3SYinan Xu redirectOut.level := RedirectLevel.flushAfter 302e18c367fSLinJiawei redirectOut.roqIdx := uop.roqIdx 303cde9280dSLinJiawei redirectOut.ftqIdx := uop.cf.ftqPtr 304cde9280dSLinJiawei redirectOut.ftqOffset := uop.cf.ftqOffset 305e2203130SLinJiawei redirectOut.cfiUpdate.isMisPred := dataModule.io.mispredict 306e2203130SLinJiawei redirectOut.cfiUpdate.taken := dataModule.io.taken 307cde9280dSLinJiawei redirectOut.cfiUpdate.predTaken := uop.cf.pred_taken 308151e3043SLinJiawei 309e18c367fSLinJiawei io.in.ready := io.out.ready 310e18c367fSLinJiawei io.out.valid := valid 311e18c367fSLinJiawei io.out.bits.uop <> io.in.bits.uop 312e2203130SLinJiawei io.out.bits.data := dataModule.io.result 313e18c367fSLinJiawei} 314