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 srcw = Input(UInt((XLEN/2).W)) 29 val add = Output(UInt(XLEN.W)) 30 val addw = Output(UInt((XLEN/2).W)) 31 }) 32 io.add := io.src(0) + io.src(1) 33 io.addw := io.srcw + io.src(1)(31,0) 34} 35 36class SubModule(implicit p: Parameters) extends XSModule { 37 val io = IO(new Bundle() { 38 val src = Vec(2, Input(UInt(XLEN.W))) 39 val sub = Output(UInt((XLEN+1).W)) 40 }) 41 io.sub := (io.src(0) +& (~io.src(1)).asUInt()) + 1.U 42} 43 44class LeftShiftModule(implicit p: Parameters) extends XSModule { 45 val io = IO(new Bundle() { 46 val shamt = Input(UInt(6.W)) 47 val revShamt = Input(UInt(6.W)) 48 val sllSrc = Input(UInt(XLEN.W)) 49 val sll = Output(UInt(XLEN.W)) 50 val revSll = Output(UInt(XLEN.W)) 51 }) 52 io.sll := io.sllSrc << io.shamt 53 io.revSll := io.sllSrc << io.revShamt 54} 55 56class LeftShiftWordModule(implicit p: Parameters) extends XSModule { 57 val io = IO(new Bundle() { 58 val shamt = Input(UInt(5.W)) 59 val revShamt = Input(UInt(5.W)) 60 val sllSrc = Input(UInt((XLEN/2).W)) 61 val sllw = Output(UInt((XLEN/2).W)) 62 val revSllw = Output(UInt((XLEN/2).W)) 63 }) 64 io.sllw := io.sllSrc << io.shamt 65 io.revSllw := io.sllSrc << io.revShamt 66} 67 68class RightShiftModule(implicit p: Parameters) extends XSModule { 69 val io = IO(new Bundle() { 70 val shamt = Input(UInt(6.W)) 71 val revShamt = Input(UInt(6.W)) 72 val srlSrc, sraSrc = Input(UInt(XLEN.W)) 73 val srl, sra = Output(UInt(XLEN.W)) 74 val revSrl = Output(UInt(XLEN.W)) 75 }) 76 io.srl := io.srlSrc >> io.shamt 77 io.sra := (io.sraSrc.asSInt() >> io.shamt).asUInt() 78 io.revSrl := io.srlSrc >> io.revShamt 79} 80 81class RightShiftWordModule(implicit p: Parameters) extends XSModule { 82 val io = IO(new Bundle() { 83 val shamt = Input(UInt(5.W)) 84 val revShamt = Input(UInt(5.W)) 85 val srlSrc, sraSrc = Input(UInt((XLEN/2).W)) 86 val srlw, sraw = Output(UInt((XLEN/2).W)) 87 val revSrlw = Output(UInt((XLEN/2).W)) 88 }) 89 90 io.srlw := io.srlSrc >> io.shamt 91 io.sraw := (io.sraSrc.asSInt() >> io.shamt).asUInt() 92 io.revSrlw := io.srlSrc >> io.revShamt 93} 94 95 96class MiscResultSelect(implicit p: Parameters) extends XSModule { 97 val io = IO(new Bundle() { 98 val func = Input(UInt()) 99 val andn, orn, xnor, and, or, xor, sextb, sexth, zexth, rev8, orcb = Input(UInt(XLEN.W)) 100 val miscRes = Output(UInt(XLEN.W)) 101 }) 102 103 val miscRes = ParallelMux(List( 104 ALUOpType.andn -> io.andn, 105 ALUOpType.and -> io.and, 106 ALUOpType.orn -> io.orn, 107 ALUOpType.or -> io.or, 108 ALUOpType.xnor -> io.xnor, 109 ALUOpType.xor -> io.xor, 110 ALUOpType.sext_b -> io.sextb, 111 ALUOpType.sext_h -> io.sexth, 112 ALUOpType.zext_h -> io.zexth, 113 ALUOpType.orc_b -> io.orcb, 114 ALUOpType.rev8 -> io.rev8 115 ).map(x => (x._1(3, 0) === io.func(3, 0), x._2))) 116 117 io.miscRes := miscRes 118} 119 120class ShiftResultSelect(implicit p: Parameters) extends XSModule { 121 val io = IO(new Bundle() { 122 val func = Input(UInt()) 123 val sll, srl, sra, rol, ror, bclr, bset, binv, bext = Input(UInt(XLEN.W)) 124 val shiftRes = Output(UInt(XLEN.W)) 125 }) 126 127 val leftBit = Mux(io.func(1), io.binv, Mux(io.func(0), io.bset, io.bclr)) 128 val leftRes = Mux(io.func(2), leftBit, io.sll) 129 val rightRes = Mux(io.func(2), io.sra, Mux(io.func(1), io.bext, io.srl)) 130 131 io.shiftRes := Mux(io.func(4), Mux(io.func(3), io.ror, io.rol), Mux(io.func(3), rightRes, leftRes)) 132} 133 134class WordResultSelect(implicit p: Parameters) extends XSModule { 135 val io = IO(new Bundle() { 136 val func = Input(UInt()) 137 val sllw, srlw, sraw, rolw, rorw, addw, subw = Input(UInt((XLEN/2).W)) 138 val wordRes = Output(UInt(XLEN.W)) 139 }) 140 141 val addsubRes = Mux(io.func(6), io.subw, io.addw) 142 val shiftRes = Mux(io.func(4), 143 Mux(io.func(3), io.rorw, io.rolw), 144 Mux(io.func(3), 145 Mux(io.func(2), io.sraw, io.srlw), 146 io.sllw)) 147 val wordRes = Mux(io.func(6,5) === 2.U, shiftRes, addsubRes) 148 io.wordRes := SignExt(wordRes, XLEN) 149} 150 151 152class AluResSel(implicit p: Parameters) extends XSModule { 153 val io = IO(new Bundle() { 154 val func = Input(UInt()) 155 val addRes, shiftRes, miscRes, compareRes, wordRes = Input(UInt(XLEN.W)) 156 val aluRes = Output(UInt(XLEN.W)) 157 }) 158 159 val res = Mux(io.func(7), io.wordRes, Mux(io.func(6), 160 Mux(io.func(5), io.compareRes, io.shiftRes), 161 Mux(io.func(5), io.addRes, io.miscRes) 162 )) 163 io.aluRes := res 164} 165 166class AluDataModule(implicit p: Parameters) extends XSModule { 167 val io = IO(new Bundle() { 168 val src = Vec(2, Input(UInt(XLEN.W))) 169 val func = Input(FuOpType()) 170 val pred_taken, isBranch = Input(Bool()) 171 val result = Output(UInt(XLEN.W)) 172 val taken, mispredict = Output(Bool()) 173 }) 174 val (src1, src2, func) = (io.src(0), io.src(1), io.func) 175 176 val isW = ALUOpType.isWordOp(func) 177 178 val addModule = Module(new AddModule) 179 val shaddShamt = func(2,1) 180 val add = addModule.io.add 181 val addw = addModule.io.addw 182 addModule.io.src(0) := (Cat(Fill(32, func(0)), Fill(32,1.U)) & src1) << shaddShamt 183 addModule.io.src(1) := src2 184 addModule.io.srcw := src1(31,0) 185 186 187 188 val subModule = Module(new SubModule) 189 val sub = subModule.io.sub 190 val subw = subModule.io.sub 191 subModule.io.src(0) := src1 192 subModule.io.src(1) := src2 193 194 val shamt = src2(5, 0) 195 val revShamt = ~src2(5,0) + 1.U 196 197 val leftShiftModule = Module(new LeftShiftModule) 198 val sll = leftShiftModule.io.sll 199 val revSll = leftShiftModule.io.revSll 200 leftShiftModule.io.sllSrc := Cat(Fill(32, func(0)), Fill(32,1.U)) & src1 201 leftShiftModule.io.shamt := shamt 202 leftShiftModule.io.revShamt := revShamt 203 204 val leftShiftWordModule = Module(new LeftShiftWordModule) 205 val sllw = leftShiftWordModule.io.sllw 206 val revSllw = leftShiftWordModule.io.revSllw 207 leftShiftWordModule.io.sllSrc := src1 208 leftShiftWordModule.io.shamt := shamt 209 leftShiftWordModule.io.revShamt := revShamt 210 211 val rightShiftModule = Module(new RightShiftModule) 212 val srl = rightShiftModule.io.srl 213 val revSrl = rightShiftModule.io.revSrl 214 val sra = rightShiftModule.io.sra 215 rightShiftModule.io.shamt := shamt 216 rightShiftModule.io.revShamt := revShamt 217 rightShiftModule.io.srlSrc := src1 218 rightShiftModule.io.sraSrc := src1 219 220 val rightShiftWordModule = Module(new RightShiftWordModule) 221 val srlw = rightShiftWordModule.io.srlw 222 val revSrlw = rightShiftWordModule.io.revSrlw 223 val sraw = rightShiftWordModule.io.sraw 224 rightShiftWordModule.io.shamt := shamt 225 rightShiftWordModule.io.revShamt := revShamt 226 rightShiftWordModule.io.srlSrc := src1 227 rightShiftWordModule.io.sraSrc := src1 228 229 val rol = revSrl | sll 230 val ror = srl | revSll 231 val rolw = revSrlw | sllw 232 val rorw = srlw | revSllw 233 234 val bitShift = 1.U << src2(5, 0) 235 val bset = src1 | bitShift 236 val bclr = src1 & ~bitShift 237 val binv = src1 ^ bitShift 238 val bext = srl(0) 239 240 val andn = ~(src1 & src2) 241 val orn = ~(src1 | src2) 242 val xnor = ~(src1 ^ src2) 243 val and = ~andn 244 val or = ~orn 245 val xor = ~xnor 246 val sgtu = sub(XLEN) 247 val sltu = !sgtu 248 val slt = xor(XLEN-1) ^ sltu 249 // val maxMin = Mux(slt ^ func(0), src2, src1) 250 // val maxMinU = Mux(sltu^ func(0), src2, src1) 251 val maxMin = Mux(slt ^ func(0), src2, src1) 252 val maxMinU = Mux((sgtu && func(0)) || ~(sgtu && func(0)), src2, src1) 253 val sextb = SignExt(src1(7, 0), XLEN) 254 val sexth = SignExt(src1(15, 0), XLEN) 255 val zexth = ZeroExt(src1(15, 0), XLEN) 256 val rev8 = Cat(src1(7,0), src1(15,8), src1(23,16), src1(31,24), 257 src1(39,32), src1(47,40), src1(55,48), src1(63,56)) 258 val orcb = Cat(Reverse(src1(63,56)), Reverse(src1(55,48)), Reverse(src1(47,40)), Reverse(src1(39,32)), 259 Reverse(src1(31,24)), Reverse(src1(23,16)), Reverse(src1(15,8)), Reverse(src1(7,0))) 260 261 val branchOpTable = List( 262 ALUOpType.getBranchType(ALUOpType.beq) -> !xor.orR, 263 ALUOpType.getBranchType(ALUOpType.blt) -> slt, 264 ALUOpType.getBranchType(ALUOpType.bltu) -> sltu 265 ) 266 val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func) 267 268 269 // Result Select 270 271 val compareRes = Mux(func(2), Mux(func(1), maxMin, maxMinU), Mux(func(1), slt, Mux(func(0), sltu, sub))) 272 273 val shiftResSel = Module(new ShiftResultSelect) 274 shiftResSel.io.func := func(4,0) 275 shiftResSel.io.sll := sll 276 shiftResSel.io.srl := srl 277 shiftResSel.io.sra := sra 278 shiftResSel.io.rol := rol 279 shiftResSel.io.ror := ror 280 shiftResSel.io.bclr := bclr 281 shiftResSel.io.binv := binv 282 shiftResSel.io.bset := bset 283 shiftResSel.io.bext := bext 284 val shiftRes = shiftResSel.io.shiftRes 285 286 val miscResSel = Module(new MiscResultSelect) 287 miscResSel.io.func := func(3, 0) 288 miscResSel.io.andn := andn 289 miscResSel.io.orn := orn 290 miscResSel.io.xnor := xnor 291 miscResSel.io.and := and 292 miscResSel.io.or := or 293 miscResSel.io.xor := xor 294 miscResSel.io.sextb := sextb 295 miscResSel.io.sexth := sexth 296 miscResSel.io.zexth := zexth 297 miscResSel.io.rev8 := rev8 298 miscResSel.io.orcb := orcb 299 val miscRes = miscResSel.io.miscRes 300 301 val wordResSel = Module(new WordResultSelect) 302 wordResSel.io.func := func 303 wordResSel.io.addw := addw 304 wordResSel.io.subw := subw 305 wordResSel.io.sllw := sllw 306 wordResSel.io.srlw := srlw 307 wordResSel.io.sraw := sraw 308 wordResSel.io.rolw := rolw 309 wordResSel.io.rorw := rorw 310 val wordRes = wordResSel.io.wordRes 311 312 val aluResSel = Module(new AluResSel) 313 aluResSel.io.func := func 314 aluResSel.io.addRes := add 315 aluResSel.io.compareRes := compareRes 316 aluResSel.io.shiftRes := shiftRes 317 aluResSel.io.miscRes := miscRes 318 aluResSel.io.wordRes := wordRes 319 val aluRes = aluResSel.io.aluRes 320 321 io.result := aluRes 322 io.taken := taken 323 io.mispredict := (io.pred_taken ^ taken) && io.isBranch 324} 325 326class Alu(implicit p: Parameters) extends FUWithRedirect { 327 328 val (src1, src2, func, pc, uop) = ( 329 io.in.bits.src(0), 330 io.in.bits.src(1), 331 io.in.bits.uop.ctrl.fuOpType, 332 SignExt(io.in.bits.uop.cf.pc, AddrBits), 333 io.in.bits.uop 334 ) 335 336 val valid = io.in.valid 337 val isBranch = ALUOpType.isBranch(func) 338 val dataModule = Module(new AluDataModule) 339 340 dataModule.io.src(0) := src1 341 dataModule.io.src(1) := src2 342 dataModule.io.func := func 343 dataModule.io.pred_taken := uop.cf.pred_taken 344 dataModule.io.isBranch := isBranch 345 346 redirectOutValid := io.out.valid && isBranch 347 redirectOut := DontCare 348 redirectOut.level := RedirectLevel.flushAfter 349 redirectOut.roqIdx := uop.roqIdx 350 redirectOut.ftqIdx := uop.cf.ftqPtr 351 redirectOut.ftqOffset := uop.cf.ftqOffset 352 redirectOut.cfiUpdate.isMisPred := dataModule.io.mispredict 353 redirectOut.cfiUpdate.taken := dataModule.io.taken 354 redirectOut.cfiUpdate.predTaken := uop.cf.pred_taken 355 356 io.in.ready := io.out.ready 357 io.out.valid := valid 358 io.out.bits.uop <> io.in.bits.uop 359 io.out.bits.data := dataModule.io.result 360} 361