1/*************************************************************************************** 2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3* Copyright (c) 2020-2021 Peng Cheng Laboratory 4* 5* XiangShan is licensed under Mulan PSL v2. 6* You can use this software according to the terms and conditions of the Mulan PSL v2. 7* You may obtain a copy of Mulan PSL v2 at: 8* http://license.coscl.org.cn/MulanPSL2 9* 10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13* 14* See the Mulan PSL v2 for more details. 15***************************************************************************************/ 16 17package xiangshan.backend.fu 18 19import chipsalliance.rocketchip.config.Parameters 20import chisel3._ 21import chisel3.util._ 22import utils.{LookupTreeDefault, LookupTree, ParallelMux, SignExt, ZeroExt} 23import xiangshan._ 24 25class AddModule(implicit p: Parameters) extends XSModule { 26 val io = IO(new Bundle() { 27 val src = Vec(2, Input(UInt(XLEN.W))) 28 val add = Output(UInt((XLEN+1).W)) 29 }) 30 io.add := io.src(0) +& io.src(1) 31} 32 33class SubModule(implicit p: Parameters) extends XSModule { 34 val io = IO(new Bundle() { 35 val src = Vec(2, Input(UInt(XLEN.W))) 36 val sub = Output(UInt((XLEN+1).W)) 37 }) 38 io.sub := (io.src(0) +& (~io.src(1)).asUInt()) + 1.U 39} 40 41class LeftShiftModule(implicit p: Parameters) extends XSModule { 42 val io = IO(new Bundle() { 43 val shamt = Input(UInt(6.W)) 44 val sllSrc = Input(UInt(XLEN.W)) 45 val sll = Output(UInt(XLEN.W)) 46 }) 47 io.sll := io.sllSrc << io.shamt 48} 49 50class LeftShiftWordModule(implicit p: Parameters) extends XSModule { 51 val io = IO(new Bundle() { 52 val shamt = Input(UInt(5.W)) 53 val sllSrc = Input(UInt((XLEN/2).W)) 54 val sllw = Output(UInt((XLEN/2).W)) 55 }) 56 io.sllw := io.sllSrc << io.shamt 57} 58 59class RightShiftModule(implicit p: Parameters) extends XSModule { 60 val io = IO(new Bundle() { 61 val shamt = Input(UInt(6.W)) 62 val srlSrc, sraSrc = Input(UInt(XLEN.W)) 63 val srl, sra = Output(UInt(XLEN.W)) 64 }) 65 io.srl := io.srlSrc >> io.shamt 66 io.sra := (io.sraSrc.asSInt() >> io.shamt).asUInt() 67} 68 69class RightShiftWordModule(implicit p: Parameters) extends XSModule { 70 val io = IO(new Bundle() { 71 val shamt = Input(UInt(5.W)) 72 val srlSrc, sraSrc = Input(UInt((XLEN/2).W)) 73 val srlw, sraw = Output(UInt((XLEN/2).W)) 74 }) 75 76 io.srlw := io.srlSrc >> io.shamt 77 io.sraw := (io.sraSrc.asSInt() >> io.shamt).asUInt() 78} 79 80 81class MiscResultSelect(implicit p: Parameters) extends XSModule { 82 val io = IO(new Bundle() { 83 val func = Input(UInt()) 84 val andn, orn, xnor, and, or, xor, sextb, sexth, zexth, rev8, orcb = Input(UInt(XLEN.W)) 85 val miscRes = Output(UInt(XLEN.W)) 86 }) 87 88 val miscRes = ParallelMux(List( 89 ALUOpType.andn -> io.andn, 90 ALUOpType.and -> io.and, 91 ALUOpType.orn -> io.orn, 92 ALUOpType.or -> io.or, 93 ALUOpType.xnor -> io.xnor, 94 ALUOpType.xor -> io.xor, 95 ALUOpType.sext_b -> io.sextb, 96 ALUOpType.sext_h -> io.sexth, 97 ALUOpType.zext_h -> io.zexth, 98 ALUOpType.orc_b -> io.orcb, 99 ALUOpType.rev8 -> io.rev8 100 ).map(x => (x._1(3, 0) === io.func(3, 0), x._2))) 101 102 io.miscRes := miscRes 103} 104 105class ShiftResultSelect(implicit p: Parameters) extends XSModule { 106 val io = IO(new Bundle() { 107 val func = Input(UInt()) 108 val sll, srl, sra, rot, bclr, bset, binv, bext = Input(UInt(XLEN.W)) 109 val shiftRes = Output(UInt(XLEN.W)) 110 }) 111 112 val leftBit = Mux(io.func(1), io.binv, Mux(io.func(0), io.bset, io.bclr)) 113 val leftRes = Mux(io.func(2), leftBit, io.sll) 114 val rightRes = Mux(io.func(2), io.sra, Mux(io.func(1), io.bext, io.srl)) 115 116 io.shiftRes := Mux(io.func(4), io.rot, Mux(io.func(3), rightRes, leftRes)) 117} 118 119class WordResultSelect(implicit p: Parameters) extends XSModule { 120 val io = IO(new Bundle() { 121 val func = Input(UInt()) 122 val sllw, srlw, sraw, rotw, addw, subw = Input(UInt((XLEN/2).W)) 123 val wordRes = Output(UInt(XLEN.W)) 124 }) 125 126 val addsubRes = Mux(io.func(6), io.subw, io.addw) 127 val shiftRes = Mux(io.func(4), io.rotw, 128 Mux(io.func(3), 129 Mux(io.func(2), io.sraw, io.srlw), 130 io.sllw)) 131 val wordRes = Mux(io.func(6,5) === 2.U, shiftRes, addsubRes) 132 io.wordRes := SignExt(wordRes, XLEN) 133} 134 135 136class AluResSel(implicit p: Parameters) extends XSModule { 137 val io = IO(new Bundle() { 138 val func = Input(UInt()) 139 val addRes, shiftRes, miscRes, compareRes, wordRes = Input(UInt(XLEN.W)) 140 val aluRes = Output(UInt(XLEN.W)) 141 }) 142 143 val res = Mux(io.func(7), io.wordRes, Mux(io.func(6), 144 Mux(io.func(5), io.compareRes, io.shiftRes), 145 Mux(io.func(5), io.addRes, io.miscRes) 146 )) 147 io.aluRes := res 148} 149 150class AluDataModule(implicit p: Parameters) extends XSModule { 151 val io = IO(new Bundle() { 152 val src = Vec(2, Input(UInt(XLEN.W))) 153 val func = Input(FuOpType()) 154 val pred_taken, isBranch = Input(Bool()) 155 val result = Output(UInt(XLEN.W)) 156 val taken, mispredict = Output(Bool()) 157 }) 158 val (src1, src2, func) = (io.src(0), io.src(1), io.func) 159 160 val isW = ALUOpType.isWordOp(func) 161 162 val addModule = Module(new AddModule) 163 val shaddShamt = func(2,1) 164 val add = addModule.io.add 165 val addw = addModule.io.add 166 addModule.io.src(0) := Mux(func(0),src1(31,0), src1) << shaddShamt 167 addModule.io.src(1) := src2 168 169 val subModule = Module(new SubModule) 170 val sub = subModule.io.sub 171 val subw = subModule.io.sub 172 subModule.io.src(0) := src1 173 subModule.io.src(1) := src2 174 175 val shamt = src2(5, 0) 176 val revShamt = ~src2(5,0) + 1.U 177 178 val leftShiftModule = Module(new LeftShiftModule) 179 val sll = leftShiftModule.io.sll 180 leftShiftModule.io.sllSrc := Mux(func(0), src1(31,0), src1) 181 leftShiftModule.io.shamt := Mux(func(3), revShamt, shamt) 182 183 val leftShiftWordModule = Module(new LeftShiftWordModule) 184 val sllw = leftShiftWordModule.io.sllw 185 leftShiftWordModule.io.sllSrc := src1 186 leftShiftWordModule.io.shamt := Mux(func(3), revShamt, shamt) 187 188 val rightShiftModule = Module(new RightShiftModule) 189 val srl = rightShiftModule.io.srl 190 val sra = rightShiftModule.io.sra 191 rightShiftModule.io.shamt := Mux(func(3), shamt, revShamt) 192 rightShiftModule.io.srlSrc := src1 193 rightShiftModule.io.sraSrc := src1 // 这里可以优化成 不过Mux的src1 194 195 val rightShiftWordModule = Module(new RightShiftWordModule) 196 val srlw = rightShiftWordModule.io.srlw 197 val sraw = rightShiftWordModule.io.sraw 198 rightShiftWordModule.io.shamt := Mux(func(3), shamt, revShamt) 199 rightShiftWordModule.io.srlSrc := src1 200 rightShiftWordModule.io.sraSrc := src1 201 202 val rot = srl | sll 203 val rotw = srlw | sllw 204 205 val bitShift = 1.U << src2(5, 0) 206 val bset = src1 | bitShift 207 val bclr = src1 & ~bitShift 208 val binv = src1 ^ bitShift 209 val bext = srl(0) 210 211 val andn = ~(src1 & src2) 212 val orn = ~(src1 | src2) 213 val xnor = ~(src1 ^ src2) 214 val and = ~andn 215 val or = ~orn 216 val xor = ~xnor 217 val sgtu = sub(XLEN) 218 val sltu = !sgtu 219 val slt = xor(XLEN-1) ^ sltu 220 val maxMin = Mux(slt ^ func(0), src2, src1) 221 val maxMinU = Mux(sltu^ func(0), src2, src1) 222 val sextb = SignExt(src1(7, 0), XLEN) 223 val sexth = SignExt(src1(15, 0), XLEN) 224 val zexth = ZeroExt(src1(15, 0), XLEN) 225 val rev8 = Cat(src1(7,0), src1(15,8), src1(23,16), src1(31,24), 226 src1(39,32), src1(47,40), src1(55,48), src1(63,56)) 227 val orcb = Cat(Reverse(src1(63,56)), Reverse(src1(55,48)), Reverse(src1(47,40)), Reverse(src1(39,32)), 228 Reverse(src1(31,24)), Reverse(src1(23,16)), Reverse(src1(15,8)), Reverse(src1(7,0))) 229 230 val branchOpTable = List( 231 ALUOpType.getBranchType(ALUOpType.beq) -> !xor.orR, 232 ALUOpType.getBranchType(ALUOpType.blt) -> slt, 233 ALUOpType.getBranchType(ALUOpType.bltu) -> sltu 234 ) 235 val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func) 236 237 238 // Result Select 239 240 val compareRes = Mux(func(2), Mux(func(1), maxMin, maxMinU), Mux(func(1), slt, Mux(func(0), sltu, sub))) 241 242 val shiftResSel = Module(new ShiftResultSelect) 243 shiftResSel.io.func := func(4,0) 244 shiftResSel.io.sll := sll 245 shiftResSel.io.srl := srl 246 shiftResSel.io.sra := sra 247 shiftResSel.io.rot := rot 248 shiftResSel.io.bclr := bclr 249 shiftResSel.io.binv := binv 250 shiftResSel.io.bset := bset 251 shiftResSel.io.bext := bext 252 val shiftRes = shiftResSel.io.shiftRes 253 254 val miscResSel = Module(new MiscResultSelect) 255 miscResSel.io.func := func(3, 0) 256 miscResSel.io.andn := andn 257 miscResSel.io.orn := orn 258 miscResSel.io.xnor := xnor 259 miscResSel.io.and := and 260 miscResSel.io.or := or 261 miscResSel.io.xor := xor 262 miscResSel.io.sextb := sextb 263 miscResSel.io.sexth := sexth 264 miscResSel.io.zexth := zexth 265 miscResSel.io.rev8 := rev8 266 miscResSel.io.orcb := orcb 267 val miscRes = miscResSel.io.miscRes 268 269 val wordResSel = Module(new WordResultSelect) 270 wordResSel.io.func := func 271 wordResSel.io.addw := addw 272 wordResSel.io.subw := subw 273 wordResSel.io.sllw := sllw 274 wordResSel.io.srlw := srlw 275 wordResSel.io.sraw := sraw 276 wordResSel.io.rotw := rotw 277 val wordRes = wordResSel.io.wordRes 278 279 val aluResSel = Module(new AluResSel) 280 aluResSel.io.func := func 281 aluResSel.io.addRes := add 282 aluResSel.io.compareRes := compareRes 283 aluResSel.io.shiftRes := shiftRes 284 aluResSel.io.miscRes := miscRes 285 aluResSel.io.wordRes := wordRes 286 val aluRes = aluResSel.io.aluRes 287 288 io.result := aluRes 289 io.taken := taken 290 io.mispredict := (io.pred_taken ^ taken) && io.isBranch 291} 292 293class Alu(implicit p: Parameters) extends FUWithRedirect { 294 295 val (src1, src2, func, pc, uop) = ( 296 io.in.bits.src(0), 297 io.in.bits.src(1), 298 io.in.bits.uop.ctrl.fuOpType, 299 SignExt(io.in.bits.uop.cf.pc, AddrBits), 300 io.in.bits.uop 301 ) 302 303 val valid = io.in.valid 304 val isBranch = ALUOpType.isBranch(func) 305 val dataModule = Module(new AluDataModule) 306 307 dataModule.io.src(0) := src1 308 dataModule.io.src(1) := src2 309 dataModule.io.func := func 310 dataModule.io.pred_taken := uop.cf.pred_taken 311 dataModule.io.isBranch := isBranch 312 313 redirectOutValid := io.out.valid && isBranch 314 redirectOut := DontCare 315 redirectOut.level := RedirectLevel.flushAfter 316 redirectOut.roqIdx := uop.roqIdx 317 redirectOut.ftqIdx := uop.cf.ftqPtr 318 redirectOut.ftqOffset := uop.cf.ftqOffset 319 redirectOut.cfiUpdate.isMisPred := dataModule.io.mispredict 320 redirectOut.cfiUpdate.taken := dataModule.io.taken 321 redirectOut.cfiUpdate.predTaken := uop.cf.pred_taken 322 323 io.in.ready := io.out.ready 324 io.out.valid := valid 325 io.out.bits.uop <> io.in.bits.uop 326 io.out.bits.data := dataModule.io.result 327} 328