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._ 22ee8ff153Szfwimport 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))) 28*184a1958Szfw val add = Output(UInt((XLEN+1).W)) 2931ea8750SLinJiawei }) 30*184a1958Szfw io.add := 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))) 36*184a1958Szfw val sub = Output(UInt((XLEN+1).W)) 3731ea8750SLinJiawei }) 38*184a1958Szfw io.sub := (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 }) 47*184a1958Szfw io.sll := io.sllSrc << io.shamt 48*184a1958Szfw} 49*184a1958Szfw 50*184a1958Szfwclass LeftShiftWordModule(implicit p: Parameters) extends XSModule { 51*184a1958Szfw val io = IO(new Bundle() { 52*184a1958Szfw val shamt = Input(UInt(5.W)) 53*184a1958Szfw val sllSrc = Input(UInt((XLEN/2).W)) 54*184a1958Szfw val sllw = Output(UInt((XLEN/2).W)) 55*184a1958Szfw }) 56*184a1958Szfw io.sllw := io.sllSrc << io.shamt 5731ea8750SLinJiawei} 5831ea8750SLinJiawei 592225d46eSJiawei Linclass RightShiftModule(implicit p: Parameters) extends XSModule { 6031ea8750SLinJiawei val io = IO(new Bundle() { 6131ea8750SLinJiawei val shamt = Input(UInt(6.W)) 6231ea8750SLinJiawei val srlSrc, sraSrc = Input(UInt(XLEN.W)) 63*184a1958Szfw val srl, sra = Output(UInt(XLEN.W)) 6431ea8750SLinJiawei }) 65*184a1958Szfw io.srl := io.srlSrc >> io.shamt 66*184a1958Szfw io.sra := (io.sraSrc.asSInt() >> io.shamt).asUInt() 6731ea8750SLinJiawei} 6831ea8750SLinJiawei 69*184a1958Szfwclass RightShiftWordModule(implicit p: Parameters) extends XSModule { 70ee8ff153Szfw val io = IO(new Bundle() { 71*184a1958Szfw val shamt = Input(UInt(5.W)) 72*184a1958Szfw val srlSrc, sraSrc = Input(UInt((XLEN/2).W)) 73*184a1958Szfw val srlw, sraw = Output(UInt((XLEN/2).W)) 74ee8ff153Szfw }) 75*184a1958Szfw 76*184a1958Szfw io.srlw := io.srlSrc >> io.shamt 77*184a1958Szfw io.sraw := (io.sraSrc.asSInt() >> io.shamt).asUInt() 78ee8ff153Szfw} 79ee8ff153Szfw 80*184a1958Szfw 812225d46eSJiawei Linclass MiscResultSelect(implicit p: Parameters) extends XSModule { 8231ea8750SLinJiawei val io = IO(new Bundle() { 8331ea8750SLinJiawei val func = Input(UInt()) 84*184a1958Szfw val andn, orn, xnor, and, or, xor, sextb, sexth, zexth, rev8, orcb = Input(UInt(XLEN.W)) 8531ea8750SLinJiawei val miscRes = Output(UInt(XLEN.W)) 8631ea8750SLinJiawei }) 87ee8ff153Szfw 88*184a1958Szfw val miscRes = ParallelMux(List( 89*184a1958Szfw ALUOpType.andn -> io.andn, 90*184a1958Szfw ALUOpType.and -> io.and, 91*184a1958Szfw ALUOpType.orn -> io.orn, 92*184a1958Szfw ALUOpType.or -> io.or, 93*184a1958Szfw ALUOpType.xnor -> io.xnor, 94*184a1958Szfw ALUOpType.xor -> io.xor, 95*184a1958Szfw ALUOpType.sext_b -> io.sextb, 96*184a1958Szfw ALUOpType.sext_h -> io.sexth, 97*184a1958Szfw ALUOpType.zext_h -> io.zexth, 98*184a1958Szfw ALUOpType.orc_b -> io.orcb, 99*184a1958Szfw ALUOpType.rev8 -> io.rev8 100*184a1958Szfw ).map(x => (x._1(3, 0) === io.func(3, 0), x._2))) 101ee8ff153Szfw 102*184a1958Szfw io.miscRes := miscRes 10331ea8750SLinJiawei} 10431ea8750SLinJiawei 105ee8ff153Szfwclass ShiftResultSelect(implicit p: Parameters) extends XSModule { 106ee8ff153Szfw val io = IO(new Bundle() { 107ee8ff153Szfw val func = Input(UInt()) 108*184a1958Szfw val sll, srl, sra, rot, bclr, bset, binv, bext = Input(UInt(XLEN.W)) 109ee8ff153Szfw val shiftRes = Output(UInt(XLEN.W)) 110ee8ff153Szfw }) 111ee8ff153Szfw 112*184a1958Szfw val leftBit = Mux(io.func(1), io.binv, Mux(io.func(0), io.bset, io.bclr)) 113*184a1958Szfw val leftRes = Mux(io.func(2), leftBit, io.sll) 114*184a1958Szfw val rightRes = Mux(io.func(2), io.sra, Mux(io.func(1), io.bext, io.srl)) 115ee8ff153Szfw 116*184a1958Szfw io.shiftRes := Mux(io.func(4), io.rot, Mux(io.func(3), rightRes, leftRes)) 117*184a1958Szfw} 118ee8ff153Szfw 119*184a1958Szfwclass WordResultSelect(implicit p: Parameters) extends XSModule { 120*184a1958Szfw val io = IO(new Bundle() { 121*184a1958Szfw val func = Input(UInt()) 122*184a1958Szfw val sllw, srlw, sraw, rotw, addw, subw = Input(UInt((XLEN/2).W)) 123*184a1958Szfw val wordRes = Output(UInt(XLEN.W)) 124*184a1958Szfw }) 125ee8ff153Szfw 126*184a1958Szfw val addsubRes = Mux(io.func(6), io.subw, io.addw) 127*184a1958Szfw val shiftRes = Mux(io.func(4), io.rotw, 128*184a1958Szfw Mux(io.func(3), 129*184a1958Szfw Mux(io.func(2), io.sraw, io.srlw), 130*184a1958Szfw io.sllw)) 131*184a1958Szfw val wordRes = Mux(io.func(6,5) === 2.U, shiftRes, addsubRes) 132*184a1958Szfw io.wordRes := SignExt(wordRes, XLEN) 133ee8ff153Szfw} 134ee8ff153Szfw 135ee8ff153Szfw 1362225d46eSJiawei Linclass AluResSel(implicit p: Parameters) extends XSModule { 13731ea8750SLinJiawei val io = IO(new Bundle() { 13831ea8750SLinJiawei val func = Input(UInt()) 139*184a1958Szfw val addRes, shiftRes, miscRes, compareRes, wordRes = Input(UInt(XLEN.W)) 14031ea8750SLinJiawei val aluRes = Output(UInt(XLEN.W)) 14131ea8750SLinJiawei }) 142ee8ff153Szfw 143*184a1958Szfw val res = Mux(io.func(7), io.wordRes, Mux(io.func(6), 144*184a1958Szfw Mux(io.func(5), io.compareRes, io.shiftRes), 145*184a1958Szfw Mux(io.func(5), io.addRes, io.miscRes) 146*184a1958Szfw )) 147*184a1958Szfw io.aluRes := res 14831ea8750SLinJiawei} 14931ea8750SLinJiawei 1502225d46eSJiawei Linclass AluDataModule(implicit p: Parameters) extends XSModule { 151e2203130SLinJiawei val io = IO(new Bundle() { 1522bd5334dSYinan Xu val src = Vec(2, Input(UInt(XLEN.W))) 153e2203130SLinJiawei val func = Input(FuOpType()) 154e2203130SLinJiawei val pred_taken, isBranch = Input(Bool()) 155e2203130SLinJiawei val result = Output(UInt(XLEN.W)) 156e2203130SLinJiawei val taken, mispredict = Output(Bool()) 157e2203130SLinJiawei }) 1582bd5334dSYinan Xu val (src1, src2, func) = (io.src(0), io.src(1), io.func) 159e18c367fSLinJiawei 160*184a1958Szfw val isW = ALUOpType.isWordOp(func) 161ee8ff153Szfw 162*184a1958Szfw val addModule = Module(new AddModule) 163*184a1958Szfw val shaddShamt = func(2,1) 164*184a1958Szfw val add = addModule.io.add 165*184a1958Szfw val addw = addModule.io.add 166*184a1958Szfw addModule.io.src(0) := Mux(func(0),src1(31,0), src1) << shaddShamt 167*184a1958Szfw addModule.io.src(1) := src2 168ee8ff153Szfw 16931ea8750SLinJiawei val subModule = Module(new SubModule) 170*184a1958Szfw val sub = subModule.io.sub 171*184a1958Szfw val subw = subModule.io.sub 1722bd5334dSYinan Xu subModule.io.src(0) := src1 1732bd5334dSYinan Xu subModule.io.src(1) := src2 174e18c367fSLinJiawei 175*184a1958Szfw val shamt = src2(5, 0) 176*184a1958Szfw val revShamt = ~src2(5,0) + 1.U 177ee8ff153Szfw 178*184a1958Szfw val leftShiftModule = Module(new LeftShiftModule) 179*184a1958Szfw val sll = leftShiftModule.io.sll 180*184a1958Szfw leftShiftModule.io.sllSrc := Mux(func(0), src1(31,0), src1) 181*184a1958Szfw leftShiftModule.io.shamt := Mux(func(3), revShamt, shamt) 182*184a1958Szfw 183*184a1958Szfw val leftShiftWordModule = Module(new LeftShiftWordModule) 184*184a1958Szfw val sllw = leftShiftWordModule.io.sllw 185*184a1958Szfw leftShiftWordModule.io.sllSrc := src1 186*184a1958Szfw leftShiftWordModule.io.shamt := Mux(func(3), revShamt, shamt) 187*184a1958Szfw 188*184a1958Szfw val rightShiftModule = Module(new RightShiftModule) 189*184a1958Szfw val srl = rightShiftModule.io.srl 190*184a1958Szfw val sra = rightShiftModule.io.sra 191*184a1958Szfw rightShiftModule.io.shamt := Mux(func(3), shamt, revShamt) 192*184a1958Szfw rightShiftModule.io.srlSrc := src1 193*184a1958Szfw rightShiftModule.io.sraSrc := src1 // 这里可以优化成 不过Mux的src1 194*184a1958Szfw 195*184a1958Szfw val rightShiftWordModule = Module(new RightShiftWordModule) 196*184a1958Szfw val srlw = rightShiftWordModule.io.srlw 197*184a1958Szfw val sraw = rightShiftWordModule.io.sraw 198*184a1958Szfw rightShiftWordModule.io.shamt := Mux(func(3), shamt, revShamt) 199*184a1958Szfw rightShiftWordModule.io.srlSrc := src1 200*184a1958Szfw rightShiftWordModule.io.sraSrc := src1 201*184a1958Szfw 202*184a1958Szfw val rot = srl | sll 203*184a1958Szfw val rotw = srlw | sllw 204*184a1958Szfw 205*184a1958Szfw val bitShift = 1.U << src2(5, 0) 206*184a1958Szfw val bset = src1 | bitShift 207*184a1958Szfw val bclr = src1 & ~bitShift 208*184a1958Szfw val binv = src1 ^ bitShift 209*184a1958Szfw val bext = srl(0) 210*184a1958Szfw 211ee8ff153Szfw val andn = ~(src1 & src2) 212ee8ff153Szfw val orn = ~(src1 | src2) 213ee8ff153Szfw val xnor = ~(src1 ^ src2) 214ee8ff153Szfw val and = ~andn 215ee8ff153Szfw val or = ~orn 216ee8ff153Szfw val xor = ~xnor 217*184a1958Szfw val sgtu = sub(XLEN) 218*184a1958Szfw val sltu = !sgtu 219ee8ff153Szfw val slt = xor(XLEN-1) ^ sltu 220ee8ff153Szfw val maxMin = Mux(slt ^ func(0), src2, src1) 221ee8ff153Szfw val maxMinU = Mux(sltu^ func(0), src2, src1) 222ee8ff153Szfw val sextb = SignExt(src1(7, 0), XLEN) 223ee8ff153Szfw val sexth = SignExt(src1(15, 0), XLEN) 224ee8ff153Szfw val zexth = ZeroExt(src1(15, 0), XLEN) 225ee8ff153Szfw val rev8 = Cat(src1(7,0), src1(15,8), src1(23,16), src1(31,24), 226ee8ff153Szfw src1(39,32), src1(47,40), src1(55,48), src1(63,56)) 227ee8ff153Szfw val orcb = Cat(Reverse(src1(63,56)), Reverse(src1(55,48)), Reverse(src1(47,40)), Reverse(src1(39,32)), 228ee8ff153Szfw Reverse(src1(31,24)), Reverse(src1(23,16)), Reverse(src1(15,8)), Reverse(src1(7,0))) 229ee8ff153Szfw 230ee8ff153Szfw val branchOpTable = List( 231ee8ff153Szfw ALUOpType.getBranchType(ALUOpType.beq) -> !xor.orR, 232ee8ff153Szfw ALUOpType.getBranchType(ALUOpType.blt) -> slt, 233ee8ff153Szfw ALUOpType.getBranchType(ALUOpType.bltu) -> sltu 234ee8ff153Szfw ) 235ee8ff153Szfw val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func) 236ee8ff153Szfw 237ee8ff153Szfw 238*184a1958Szfw // Result Select 2393ef996e9SLinJiawei 240*184a1958Szfw val compareRes = Mux(func(2), Mux(func(1), maxMin, maxMinU), Mux(func(1), slt, Mux(func(0), sltu, sub))) 241ee8ff153Szfw 242*184a1958Szfw val shiftResSel = Module(new ShiftResultSelect) 243*184a1958Szfw shiftResSel.io.func := func(4,0) 244*184a1958Szfw shiftResSel.io.sll := sll 245*184a1958Szfw shiftResSel.io.srl := srl 246*184a1958Szfw shiftResSel.io.sra := sra 247*184a1958Szfw shiftResSel.io.rot := rot 248*184a1958Szfw shiftResSel.io.bclr := bclr 249*184a1958Szfw shiftResSel.io.binv := binv 250*184a1958Szfw shiftResSel.io.bset := bset 251*184a1958Szfw shiftResSel.io.bext := bext 252*184a1958Szfw val shiftRes = shiftResSel.io.shiftRes 25331ea8750SLinJiawei 25431ea8750SLinJiawei val miscResSel = Module(new MiscResultSelect) 255*184a1958Szfw miscResSel.io.func := func(3, 0) 256ee8ff153Szfw miscResSel.io.andn := andn 257ee8ff153Szfw miscResSel.io.orn := orn 258ee8ff153Szfw miscResSel.io.xnor := xnor 259ee8ff153Szfw miscResSel.io.and := and 260ee8ff153Szfw miscResSel.io.or := or 261ee8ff153Szfw miscResSel.io.xor := xor 262ee8ff153Szfw miscResSel.io.sextb := sextb 263ee8ff153Szfw miscResSel.io.sexth := sexth 264ee8ff153Szfw miscResSel.io.zexth := zexth 265ee8ff153Szfw miscResSel.io.rev8 := rev8 266ee8ff153Szfw miscResSel.io.orcb := orcb 26731ea8750SLinJiawei val miscRes = miscResSel.io.miscRes 26831ea8750SLinJiawei 269*184a1958Szfw val wordResSel = Module(new WordResultSelect) 270*184a1958Szfw wordResSel.io.func := func 271*184a1958Szfw wordResSel.io.addw := addw 272*184a1958Szfw wordResSel.io.subw := subw 273*184a1958Szfw wordResSel.io.sllw := sllw 274*184a1958Szfw wordResSel.io.srlw := srlw 275*184a1958Szfw wordResSel.io.sraw := sraw 276*184a1958Szfw wordResSel.io.rotw := rotw 277*184a1958Szfw val wordRes = wordResSel.io.wordRes 278ee8ff153Szfw 27931ea8750SLinJiawei val aluResSel = Module(new AluResSel) 28031ea8750SLinJiawei aluResSel.io.func := func 281*184a1958Szfw aluResSel.io.addRes := add 282*184a1958Szfw aluResSel.io.compareRes := compareRes 283ee8ff153Szfw aluResSel.io.shiftRes := shiftRes 28431ea8750SLinJiawei aluResSel.io.miscRes := miscRes 285*184a1958Szfw aluResSel.io.wordRes := wordRes 28631ea8750SLinJiawei val aluRes = aluResSel.io.aluRes 287e18c367fSLinJiawei 288e2203130SLinJiawei io.result := aluRes 289e2203130SLinJiawei io.taken := taken 290e2203130SLinJiawei io.mispredict := (io.pred_taken ^ taken) && io.isBranch 291e2203130SLinJiawei} 292e2203130SLinJiawei 293adb5df20SYinan Xuclass Alu(implicit p: Parameters) extends FUWithRedirect { 294e2203130SLinJiawei 295e2203130SLinJiawei val (src1, src2, func, pc, uop) = ( 296e2203130SLinJiawei io.in.bits.src(0), 297e2203130SLinJiawei io.in.bits.src(1), 298e2203130SLinJiawei io.in.bits.uop.ctrl.fuOpType, 299e2203130SLinJiawei SignExt(io.in.bits.uop.cf.pc, AddrBits), 300e2203130SLinJiawei io.in.bits.uop 301e2203130SLinJiawei ) 302e2203130SLinJiawei 303e2203130SLinJiawei val valid = io.in.valid 304e2203130SLinJiawei val isBranch = ALUOpType.isBranch(func) 305e2203130SLinJiawei val dataModule = Module(new AluDataModule) 306e2203130SLinJiawei 3072bd5334dSYinan Xu dataModule.io.src(0) := src1 3082bd5334dSYinan Xu dataModule.io.src(1) := src2 309e2203130SLinJiawei dataModule.io.func := func 310e2203130SLinJiawei dataModule.io.pred_taken := uop.cf.pred_taken 311e2203130SLinJiawei dataModule.io.isBranch := isBranch 312e2203130SLinJiawei 313e18c367fSLinJiawei redirectOutValid := io.out.valid && isBranch 314151e3043SLinJiawei redirectOut := DontCare 315bfb958a3SYinan Xu redirectOut.level := RedirectLevel.flushAfter 316e18c367fSLinJiawei redirectOut.roqIdx := uop.roqIdx 317cde9280dSLinJiawei redirectOut.ftqIdx := uop.cf.ftqPtr 318cde9280dSLinJiawei redirectOut.ftqOffset := uop.cf.ftqOffset 319e2203130SLinJiawei redirectOut.cfiUpdate.isMisPred := dataModule.io.mispredict 320e2203130SLinJiawei redirectOut.cfiUpdate.taken := dataModule.io.taken 321cde9280dSLinJiawei redirectOut.cfiUpdate.predTaken := uop.cf.pred_taken 322151e3043SLinJiawei 323e18c367fSLinJiawei io.in.ready := io.out.ready 324e18c367fSLinJiawei io.out.valid := valid 325e18c367fSLinJiawei io.out.bits.uop <> io.in.bits.uop 326e2203130SLinJiawei io.out.bits.data := dataModule.io.result 327e18c367fSLinJiawei} 328