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))) 2828c18878Szfw val srcw = Input(UInt((XLEN/2).W)) 2928c18878Szfw val add = Output(UInt(XLEN.W)) 3028c18878Szfw val addw = Output(UInt((XLEN/2).W)) 3131ea8750SLinJiawei }) 3228c18878Szfw io.add := io.src(0) + io.src(1) 3328c18878Szfw io.addw := io.srcw + io.src(1)(31,0) 3431ea8750SLinJiawei} 3531ea8750SLinJiawei 362225d46eSJiawei Linclass SubModule(implicit p: Parameters) extends XSModule { 3731ea8750SLinJiawei val io = IO(new Bundle() { 382bd5334dSYinan Xu val src = Vec(2, Input(UInt(XLEN.W))) 39184a1958Szfw val sub = Output(UInt((XLEN+1).W)) 4031ea8750SLinJiawei }) 41184a1958Szfw io.sub := (io.src(0) +& (~io.src(1)).asUInt()) + 1.U 4231ea8750SLinJiawei} 4331ea8750SLinJiawei 442225d46eSJiawei Linclass LeftShiftModule(implicit p: Parameters) extends XSModule { 4531ea8750SLinJiawei val io = IO(new Bundle() { 4631ea8750SLinJiawei val shamt = Input(UInt(6.W)) 4728c18878Szfw val revShamt = Input(UInt(6.W)) 4831ea8750SLinJiawei val sllSrc = Input(UInt(XLEN.W)) 4931ea8750SLinJiawei val sll = Output(UInt(XLEN.W)) 5028c18878Szfw val revSll = Output(UInt(XLEN.W)) 5131ea8750SLinJiawei }) 52184a1958Szfw io.sll := io.sllSrc << io.shamt 5328c18878Szfw io.revSll := io.sllSrc << io.revShamt 54184a1958Szfw} 55184a1958Szfw 56184a1958Szfwclass LeftShiftWordModule(implicit p: Parameters) extends XSModule { 57184a1958Szfw val io = IO(new Bundle() { 58184a1958Szfw val shamt = Input(UInt(5.W)) 5928c18878Szfw val revShamt = Input(UInt(5.W)) 60184a1958Szfw val sllSrc = Input(UInt((XLEN/2).W)) 61184a1958Szfw val sllw = Output(UInt((XLEN/2).W)) 6228c18878Szfw val revSllw = Output(UInt((XLEN/2).W)) 63184a1958Szfw }) 64184a1958Szfw io.sllw := io.sllSrc << io.shamt 6528c18878Szfw io.revSllw := io.sllSrc << io.revShamt 6631ea8750SLinJiawei} 6731ea8750SLinJiawei 682225d46eSJiawei Linclass RightShiftModule(implicit p: Parameters) extends XSModule { 6931ea8750SLinJiawei val io = IO(new Bundle() { 7031ea8750SLinJiawei val shamt = Input(UInt(6.W)) 7128c18878Szfw val revShamt = Input(UInt(6.W)) 7231ea8750SLinJiawei val srlSrc, sraSrc = Input(UInt(XLEN.W)) 73184a1958Szfw val srl, sra = Output(UInt(XLEN.W)) 7428c18878Szfw val revSrl = Output(UInt(XLEN.W)) 7531ea8750SLinJiawei }) 76184a1958Szfw io.srl := io.srlSrc >> io.shamt 77184a1958Szfw io.sra := (io.sraSrc.asSInt() >> io.shamt).asUInt() 7828c18878Szfw io.revSrl := io.srlSrc >> io.revShamt 7931ea8750SLinJiawei} 8031ea8750SLinJiawei 81184a1958Szfwclass RightShiftWordModule(implicit p: Parameters) extends XSModule { 82ee8ff153Szfw val io = IO(new Bundle() { 83184a1958Szfw val shamt = Input(UInt(5.W)) 8428c18878Szfw val revShamt = Input(UInt(5.W)) 85184a1958Szfw val srlSrc, sraSrc = Input(UInt((XLEN/2).W)) 86184a1958Szfw val srlw, sraw = Output(UInt((XLEN/2).W)) 8728c18878Szfw val revSrlw = Output(UInt((XLEN/2).W)) 88ee8ff153Szfw }) 89184a1958Szfw 90184a1958Szfw io.srlw := io.srlSrc >> io.shamt 91184a1958Szfw io.sraw := (io.sraSrc.asSInt() >> io.shamt).asUInt() 9228c18878Szfw io.revSrlw := io.srlSrc >> io.revShamt 93ee8ff153Szfw} 94ee8ff153Szfw 95184a1958Szfw 962225d46eSJiawei Linclass MiscResultSelect(implicit p: Parameters) extends XSModule { 9731ea8750SLinJiawei val io = IO(new Bundle() { 9831ea8750SLinJiawei val func = Input(UInt()) 99184a1958Szfw val andn, orn, xnor, and, or, xor, sextb, sexth, zexth, rev8, orcb = Input(UInt(XLEN.W)) 10031ea8750SLinJiawei val miscRes = Output(UInt(XLEN.W)) 10131ea8750SLinJiawei }) 102ee8ff153Szfw 103184a1958Szfw val miscRes = ParallelMux(List( 104184a1958Szfw ALUOpType.andn -> io.andn, 105184a1958Szfw ALUOpType.and -> io.and, 106184a1958Szfw ALUOpType.orn -> io.orn, 107184a1958Szfw ALUOpType.or -> io.or, 108184a1958Szfw ALUOpType.xnor -> io.xnor, 109184a1958Szfw ALUOpType.xor -> io.xor, 110184a1958Szfw ALUOpType.sext_b -> io.sextb, 111184a1958Szfw ALUOpType.sext_h -> io.sexth, 112184a1958Szfw ALUOpType.zext_h -> io.zexth, 113184a1958Szfw ALUOpType.orc_b -> io.orcb, 114184a1958Szfw ALUOpType.rev8 -> io.rev8 115184a1958Szfw ).map(x => (x._1(3, 0) === io.func(3, 0), x._2))) 116ee8ff153Szfw 117184a1958Szfw io.miscRes := miscRes 11831ea8750SLinJiawei} 11931ea8750SLinJiawei 120ee8ff153Szfwclass ShiftResultSelect(implicit p: Parameters) extends XSModule { 121ee8ff153Szfw val io = IO(new Bundle() { 122ee8ff153Szfw val func = Input(UInt()) 12328c18878Szfw val sll, srl, sra, rol, ror, bclr, bset, binv, bext = Input(UInt(XLEN.W)) 124ee8ff153Szfw val shiftRes = Output(UInt(XLEN.W)) 125ee8ff153Szfw }) 126ee8ff153Szfw 127184a1958Szfw val leftBit = Mux(io.func(1), io.binv, Mux(io.func(0), io.bset, io.bclr)) 128184a1958Szfw val leftRes = Mux(io.func(2), leftBit, io.sll) 129184a1958Szfw val rightRes = Mux(io.func(2), io.sra, Mux(io.func(1), io.bext, io.srl)) 130ee8ff153Szfw 13128c18878Szfw io.shiftRes := Mux(io.func(4), Mux(io.func(3), io.ror, io.rol), Mux(io.func(3), rightRes, leftRes)) 132184a1958Szfw} 133ee8ff153Szfw 134184a1958Szfwclass WordResultSelect(implicit p: Parameters) extends XSModule { 135184a1958Szfw val io = IO(new Bundle() { 136184a1958Szfw val func = Input(UInt()) 13728c18878Szfw val sllw, srlw, sraw, rolw, rorw, addw, subw = Input(UInt((XLEN/2).W)) 138184a1958Szfw val wordRes = Output(UInt(XLEN.W)) 139184a1958Szfw }) 140ee8ff153Szfw 141184a1958Szfw val addsubRes = Mux(io.func(6), io.subw, io.addw) 14228c18878Szfw val shiftRes = Mux(io.func(4), 14328c18878Szfw Mux(io.func(3), io.rorw, io.rolw), 144184a1958Szfw Mux(io.func(3), 145184a1958Szfw Mux(io.func(2), io.sraw, io.srlw), 146184a1958Szfw io.sllw)) 147184a1958Szfw val wordRes = Mux(io.func(6,5) === 2.U, shiftRes, addsubRes) 148184a1958Szfw io.wordRes := SignExt(wordRes, XLEN) 149ee8ff153Szfw} 150ee8ff153Szfw 151ee8ff153Szfw 1522225d46eSJiawei Linclass AluResSel(implicit p: Parameters) extends XSModule { 15331ea8750SLinJiawei val io = IO(new Bundle() { 15431ea8750SLinJiawei val func = Input(UInt()) 155184a1958Szfw val addRes, shiftRes, miscRes, compareRes, wordRes = Input(UInt(XLEN.W)) 15631ea8750SLinJiawei val aluRes = Output(UInt(XLEN.W)) 15731ea8750SLinJiawei }) 158ee8ff153Szfw 159184a1958Szfw val res = Mux(io.func(7), io.wordRes, Mux(io.func(6), 160184a1958Szfw Mux(io.func(5), io.compareRes, io.shiftRes), 161184a1958Szfw Mux(io.func(5), io.addRes, io.miscRes) 162184a1958Szfw )) 163184a1958Szfw io.aluRes := res 16431ea8750SLinJiawei} 16531ea8750SLinJiawei 1662225d46eSJiawei Linclass AluDataModule(implicit p: Parameters) extends XSModule { 167e2203130SLinJiawei val io = IO(new Bundle() { 1682bd5334dSYinan Xu val src = Vec(2, Input(UInt(XLEN.W))) 169e2203130SLinJiawei val func = Input(FuOpType()) 170e2203130SLinJiawei val pred_taken, isBranch = Input(Bool()) 171e2203130SLinJiawei val result = Output(UInt(XLEN.W)) 172e2203130SLinJiawei val taken, mispredict = Output(Bool()) 173e2203130SLinJiawei }) 1742bd5334dSYinan Xu val (src1, src2, func) = (io.src(0), io.src(1), io.func) 175e18c367fSLinJiawei 176184a1958Szfw val isW = ALUOpType.isWordOp(func) 177ee8ff153Szfw 178184a1958Szfw val addModule = Module(new AddModule) 179184a1958Szfw val shaddShamt = func(2,1) 180184a1958Szfw val add = addModule.io.add 18128c18878Szfw val addw = addModule.io.addw 18228c18878Szfw addModule.io.src(0) := (Cat(Fill(32, func(0)), Fill(32,1.U)) & src1) << shaddShamt 183184a1958Szfw addModule.io.src(1) := src2 18428c18878Szfw addModule.io.srcw := src1(31,0) 18528c18878Szfw 18628c18878Szfw 187ee8ff153Szfw 18831ea8750SLinJiawei val subModule = Module(new SubModule) 189184a1958Szfw val sub = subModule.io.sub 190184a1958Szfw val subw = subModule.io.sub 1912bd5334dSYinan Xu subModule.io.src(0) := src1 1922bd5334dSYinan Xu subModule.io.src(1) := src2 193e18c367fSLinJiawei 194184a1958Szfw val shamt = src2(5, 0) 195184a1958Szfw val revShamt = ~src2(5,0) + 1.U 196ee8ff153Szfw 197184a1958Szfw val leftShiftModule = Module(new LeftShiftModule) 198184a1958Szfw val sll = leftShiftModule.io.sll 19928c18878Szfw val revSll = leftShiftModule.io.revSll 20028c18878Szfw leftShiftModule.io.sllSrc := Cat(Fill(32, func(0)), Fill(32,1.U)) & src1 20128c18878Szfw leftShiftModule.io.shamt := shamt 20228c18878Szfw leftShiftModule.io.revShamt := revShamt 203184a1958Szfw 204184a1958Szfw val leftShiftWordModule = Module(new LeftShiftWordModule) 205184a1958Szfw val sllw = leftShiftWordModule.io.sllw 20628c18878Szfw val revSllw = leftShiftWordModule.io.revSllw 207184a1958Szfw leftShiftWordModule.io.sllSrc := src1 20828c18878Szfw leftShiftWordModule.io.shamt := shamt 20928c18878Szfw leftShiftWordModule.io.revShamt := revShamt 210184a1958Szfw 211184a1958Szfw val rightShiftModule = Module(new RightShiftModule) 212184a1958Szfw val srl = rightShiftModule.io.srl 21328c18878Szfw val revSrl = rightShiftModule.io.revSrl 214184a1958Szfw val sra = rightShiftModule.io.sra 21528c18878Szfw rightShiftModule.io.shamt := shamt 21628c18878Szfw rightShiftModule.io.revShamt := revShamt 217184a1958Szfw rightShiftModule.io.srlSrc := src1 21828c18878Szfw rightShiftModule.io.sraSrc := src1 219184a1958Szfw 220184a1958Szfw val rightShiftWordModule = Module(new RightShiftWordModule) 221184a1958Szfw val srlw = rightShiftWordModule.io.srlw 22228c18878Szfw val revSrlw = rightShiftWordModule.io.revSrlw 223184a1958Szfw val sraw = rightShiftWordModule.io.sraw 22428c18878Szfw rightShiftWordModule.io.shamt := shamt 22528c18878Szfw rightShiftWordModule.io.revShamt := revShamt 226184a1958Szfw rightShiftWordModule.io.srlSrc := src1 227184a1958Szfw rightShiftWordModule.io.sraSrc := src1 228184a1958Szfw 22928c18878Szfw val rol = revSrl | sll 23028c18878Szfw val ror = srl | revSll 23128c18878Szfw val rolw = revSrlw | sllw 23228c18878Szfw val rorw = srlw | revSllw 233184a1958Szfw 234184a1958Szfw val bitShift = 1.U << src2(5, 0) 235184a1958Szfw val bset = src1 | bitShift 236184a1958Szfw val bclr = src1 & ~bitShift 237184a1958Szfw val binv = src1 ^ bitShift 238184a1958Szfw val bext = srl(0) 239184a1958Szfw 240*0a6fa50eSzfw val andn = src1 & ~src2 241*0a6fa50eSzfw val orn = src1 | ~src2 242*0a6fa50eSzfw val xnor = src1 ^ ~src2 243*0a6fa50eSzfw val and = src1 & src2 244*0a6fa50eSzfw val or = src1 | src2 245*0a6fa50eSzfw val xor = src1 ^ src2 246184a1958Szfw val sgtu = sub(XLEN) 247184a1958Szfw val sltu = !sgtu 248ee8ff153Szfw val slt = xor(XLEN-1) ^ sltu 24928c18878Szfw // val maxMin = Mux(slt ^ func(0), src2, src1) 25028c18878Szfw // val maxMinU = Mux(sltu^ func(0), src2, src1) 251ee8ff153Szfw val maxMin = Mux(slt ^ func(0), src2, src1) 25228c18878Szfw val maxMinU = Mux((sgtu && func(0)) || ~(sgtu && func(0)), src2, src1) 253ee8ff153Szfw val sextb = SignExt(src1(7, 0), XLEN) 254ee8ff153Szfw val sexth = SignExt(src1(15, 0), XLEN) 255ee8ff153Szfw val zexth = ZeroExt(src1(15, 0), XLEN) 256ee8ff153Szfw val rev8 = Cat(src1(7,0), src1(15,8), src1(23,16), src1(31,24), 257ee8ff153Szfw src1(39,32), src1(47,40), src1(55,48), src1(63,56)) 258ee8ff153Szfw val orcb = Cat(Reverse(src1(63,56)), Reverse(src1(55,48)), Reverse(src1(47,40)), Reverse(src1(39,32)), 259ee8ff153Szfw Reverse(src1(31,24)), Reverse(src1(23,16)), Reverse(src1(15,8)), Reverse(src1(7,0))) 260ee8ff153Szfw 261ee8ff153Szfw val branchOpTable = List( 262ee8ff153Szfw ALUOpType.getBranchType(ALUOpType.beq) -> !xor.orR, 263ee8ff153Szfw ALUOpType.getBranchType(ALUOpType.blt) -> slt, 264ee8ff153Szfw ALUOpType.getBranchType(ALUOpType.bltu) -> sltu 265ee8ff153Szfw ) 266ee8ff153Szfw val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func) 267ee8ff153Szfw 268ee8ff153Szfw 269184a1958Szfw // Result Select 2703ef996e9SLinJiawei 271184a1958Szfw val compareRes = Mux(func(2), Mux(func(1), maxMin, maxMinU), Mux(func(1), slt, Mux(func(0), sltu, sub))) 272ee8ff153Szfw 273184a1958Szfw val shiftResSel = Module(new ShiftResultSelect) 274184a1958Szfw shiftResSel.io.func := func(4,0) 275184a1958Szfw shiftResSel.io.sll := sll 276184a1958Szfw shiftResSel.io.srl := srl 277184a1958Szfw shiftResSel.io.sra := sra 27828c18878Szfw shiftResSel.io.rol := rol 27928c18878Szfw shiftResSel.io.ror := ror 280184a1958Szfw shiftResSel.io.bclr := bclr 281184a1958Szfw shiftResSel.io.binv := binv 282184a1958Szfw shiftResSel.io.bset := bset 283184a1958Szfw shiftResSel.io.bext := bext 284184a1958Szfw val shiftRes = shiftResSel.io.shiftRes 28531ea8750SLinJiawei 28631ea8750SLinJiawei val miscResSel = Module(new MiscResultSelect) 287184a1958Szfw miscResSel.io.func := func(3, 0) 288ee8ff153Szfw miscResSel.io.andn := andn 289ee8ff153Szfw miscResSel.io.orn := orn 290ee8ff153Szfw miscResSel.io.xnor := xnor 291ee8ff153Szfw miscResSel.io.and := and 292ee8ff153Szfw miscResSel.io.or := or 293ee8ff153Szfw miscResSel.io.xor := xor 294ee8ff153Szfw miscResSel.io.sextb := sextb 295ee8ff153Szfw miscResSel.io.sexth := sexth 296ee8ff153Szfw miscResSel.io.zexth := zexth 297ee8ff153Szfw miscResSel.io.rev8 := rev8 298ee8ff153Szfw miscResSel.io.orcb := orcb 29931ea8750SLinJiawei val miscRes = miscResSel.io.miscRes 30031ea8750SLinJiawei 301184a1958Szfw val wordResSel = Module(new WordResultSelect) 302184a1958Szfw wordResSel.io.func := func 303184a1958Szfw wordResSel.io.addw := addw 304184a1958Szfw wordResSel.io.subw := subw 305184a1958Szfw wordResSel.io.sllw := sllw 306184a1958Szfw wordResSel.io.srlw := srlw 307184a1958Szfw wordResSel.io.sraw := sraw 30828c18878Szfw wordResSel.io.rolw := rolw 30928c18878Szfw wordResSel.io.rorw := rorw 310184a1958Szfw val wordRes = wordResSel.io.wordRes 311ee8ff153Szfw 31231ea8750SLinJiawei val aluResSel = Module(new AluResSel) 31331ea8750SLinJiawei aluResSel.io.func := func 314184a1958Szfw aluResSel.io.addRes := add 315184a1958Szfw aluResSel.io.compareRes := compareRes 316ee8ff153Szfw aluResSel.io.shiftRes := shiftRes 31731ea8750SLinJiawei aluResSel.io.miscRes := miscRes 318184a1958Szfw aluResSel.io.wordRes := wordRes 31931ea8750SLinJiawei val aluRes = aluResSel.io.aluRes 320e18c367fSLinJiawei 321e2203130SLinJiawei io.result := aluRes 322e2203130SLinJiawei io.taken := taken 323e2203130SLinJiawei io.mispredict := (io.pred_taken ^ taken) && io.isBranch 324e2203130SLinJiawei} 325e2203130SLinJiawei 326adb5df20SYinan Xuclass Alu(implicit p: Parameters) extends FUWithRedirect { 327e2203130SLinJiawei 328e2203130SLinJiawei val (src1, src2, func, pc, uop) = ( 329e2203130SLinJiawei io.in.bits.src(0), 330e2203130SLinJiawei io.in.bits.src(1), 331e2203130SLinJiawei io.in.bits.uop.ctrl.fuOpType, 332e2203130SLinJiawei SignExt(io.in.bits.uop.cf.pc, AddrBits), 333e2203130SLinJiawei io.in.bits.uop 334e2203130SLinJiawei ) 335e2203130SLinJiawei 336e2203130SLinJiawei val valid = io.in.valid 337e2203130SLinJiawei val isBranch = ALUOpType.isBranch(func) 338e2203130SLinJiawei val dataModule = Module(new AluDataModule) 339e2203130SLinJiawei 3402bd5334dSYinan Xu dataModule.io.src(0) := src1 3412bd5334dSYinan Xu dataModule.io.src(1) := src2 342e2203130SLinJiawei dataModule.io.func := func 343e2203130SLinJiawei dataModule.io.pred_taken := uop.cf.pred_taken 344e2203130SLinJiawei dataModule.io.isBranch := isBranch 345e2203130SLinJiawei 346e18c367fSLinJiawei redirectOutValid := io.out.valid && isBranch 347151e3043SLinJiawei redirectOut := DontCare 348bfb958a3SYinan Xu redirectOut.level := RedirectLevel.flushAfter 349e18c367fSLinJiawei redirectOut.roqIdx := uop.roqIdx 350cde9280dSLinJiawei redirectOut.ftqIdx := uop.cf.ftqPtr 351cde9280dSLinJiawei redirectOut.ftqOffset := uop.cf.ftqOffset 352e2203130SLinJiawei redirectOut.cfiUpdate.isMisPred := dataModule.io.mispredict 353e2203130SLinJiawei redirectOut.cfiUpdate.taken := dataModule.io.taken 354cde9280dSLinJiawei redirectOut.cfiUpdate.predTaken := uop.cf.pred_taken 355151e3043SLinJiawei 356e18c367fSLinJiawei io.in.ready := io.out.ready 357e18c367fSLinJiawei io.out.valid := valid 358e18c367fSLinJiawei io.out.bits.uop <> io.in.bits.uop 359e2203130SLinJiawei io.out.bits.data := dataModule.io.result 360e18c367fSLinJiawei} 361