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 org.chipsalliance.cde.config.Parameters 20import chisel3._ 21import chisel3.util._ 22import utility.{LookupTree, LookupTreeDefault, ParallelMux, SignExt, ZeroExt} 23import xiangshan._ 24import utils._ 25 26class AddModule(implicit p: Parameters) extends XSModule { 27 val io = IO(new Bundle() { 28 val src = Vec(2, Input(UInt(XLEN.W))) 29 val srcw = Input(UInt((XLEN/2).W)) 30 val add = Output(UInt(XLEN.W)) 31 val addw = Output(UInt((XLEN/2).W)) 32 }) 33 io.add := io.src(0) + io.src(1) 34 // TODO: why this extra adder? 35 io.addw := io.srcw + io.src(1)(31,0) 36} 37 38class SubModule(implicit p: Parameters) extends XSModule { 39 val io = IO(new Bundle() { 40 val src = Vec(2, Input(UInt(XLEN.W))) 41 val sub = Output(UInt((XLEN+1).W)) 42 }) 43 io.sub := (io.src(0) +& (~io.src(1)).asUInt) + 1.U 44} 45 46class LeftShiftModule(implicit p: Parameters) extends XSModule { 47 val io = IO(new Bundle() { 48 val shamt = Input(UInt(6.W)) 49 val revShamt = Input(UInt(6.W)) 50 val sllSrc = Input(UInt(XLEN.W)) 51 val sll = Output(UInt(XLEN.W)) 52 val revSll = Output(UInt(XLEN.W)) 53 }) 54 io.sll := io.sllSrc << io.shamt 55 io.revSll := io.sllSrc << io.revShamt 56} 57 58class LeftShiftWordModule(implicit p: Parameters) extends XSModule { 59 val io = IO(new Bundle() { 60 val shamt = Input(UInt(5.W)) 61 val revShamt = Input(UInt(5.W)) 62 val sllSrc = Input(UInt((XLEN/2).W)) 63 val sllw = Output(UInt((XLEN/2).W)) 64 val revSllw = Output(UInt((XLEN/2).W)) 65 }) 66 io.sllw := io.sllSrc << io.shamt 67 io.revSllw := io.sllSrc << io.revShamt 68} 69 70class RightShiftModule(implicit p: Parameters) extends XSModule { 71 val io = IO(new Bundle() { 72 val shamt = Input(UInt(6.W)) 73 val revShamt = Input(UInt(6.W)) 74 val srlSrc, sraSrc = Input(UInt(XLEN.W)) 75 val srl, sra = Output(UInt(XLEN.W)) 76 val revSrl = Output(UInt(XLEN.W)) 77 }) 78 io.srl := io.srlSrc >> io.shamt 79 io.sra := (io.sraSrc.asSInt >> io.shamt).asUInt 80 io.revSrl := io.srlSrc >> io.revShamt 81} 82 83class RightShiftWordModule(implicit p: Parameters) extends XSModule { 84 val io = IO(new Bundle() { 85 val shamt = Input(UInt(5.W)) 86 val revShamt = Input(UInt(5.W)) 87 val srlSrc, sraSrc = Input(UInt((XLEN/2).W)) 88 val srlw, sraw = Output(UInt((XLEN/2).W)) 89 val revSrlw = Output(UInt((XLEN/2).W)) 90 }) 91 92 io.srlw := io.srlSrc >> io.shamt 93 io.sraw := (io.sraSrc.asSInt >> io.shamt).asUInt 94 io.revSrlw := io.srlSrc >> io.revShamt 95} 96 97 98class MiscResultSelect(implicit p: Parameters) extends XSModule { 99 val io = IO(new Bundle() { 100 val func = Input(UInt(6.W)) 101 val and, or, xor, orcb, orh48, sextb, packh, sexth, packw, revb, rev8, pack = Input(UInt(XLEN.W)) 102 val src = Input(UInt(XLEN.W)) 103 val miscRes = Output(UInt(XLEN.W)) 104 }) 105 106 val logicRes = VecInit(Seq( 107 io.and, 108 io.or, 109 io.xor, 110 io.orcb 111 ))(io.func(2, 1)) 112 val miscRes = VecInit(Seq(io.sextb, io.packh, io.sexth, io.packw))(io.func(1, 0)) 113 val logicBase = Mux(io.func(3), miscRes, logicRes) 114 115 val revRes = VecInit(Seq(io.revb, io.rev8, io.pack, io.orh48))(io.func(1, 0)) 116 val customRes = VecInit(Seq( 117 Cat(0.U(31.W), io.src(31, 0), 0.U(1.W)), 118 Cat(0.U(30.W), io.src(31, 0), 0.U(2.W)), 119 Cat(0.U(29.W), io.src(31, 0), 0.U(3.W)), 120 Cat(0.U(56.W), io.src(15, 8))))(io.func(1, 0)) 121 val logicAdv = Mux(io.func(3), customRes, revRes) 122 123 val mask = Cat(Fill(15, io.func(0)), 1.U(1.W)) 124 val maskedLogicRes = mask & logicRes 125 126 io.miscRes := Mux(io.func(5), maskedLogicRes, Mux(io.func(4), logicAdv, logicBase)) 127} 128 129class ConditionalZeroModule(implicit p: Parameters) extends XSModule { 130 val io = IO(new Bundle() { 131 val condition = Input(UInt(XLEN.W)) 132 val value = Input(UInt(XLEN.W)) 133 val isNez = Input(Bool()) 134 val condRes = Output(UInt(XLEN.W)) 135 }) 136 137 val condition_zero = io.condition === 0.U 138 val use_zero = !io.isNez && condition_zero || 139 io.isNez && !condition_zero 140 141 io.condRes := Mux(use_zero, 0.U, io.value) 142} 143 144class ShiftResultSelect(implicit p: Parameters) extends XSModule { 145 val io = IO(new Bundle() { 146 val func = Input(UInt(4.W)) 147 val sll, srl, sra, rol, ror, bclr, bset, binv, bext = Input(UInt(XLEN.W)) 148 val shiftRes = Output(UInt(XLEN.W)) 149 }) 150 151 // val leftBit = Mux(io.func(1), io.binv, Mux(io.func(0), io.bset, io.bclr)) 152 // val leftRes = Mux(io.func(2), leftBit, io.sll) 153 // val rightRes = Mux(io.func(1) && io.func(0), io.sra, Mux(io.func(1), io.bext, io.srl)) 154 val resultSource = VecInit(Seq( 155 io.sll, 156 io.sll, 157 io.bclr, 158 io.bset, 159 io.binv, 160 io.srl, 161 io.bext, 162 io.sra 163 )) 164 val simple = resultSource(io.func(2, 0)) 165 166 io.shiftRes := Mux(io.func(3), Mux(io.func(1), io.ror, io.rol), simple) 167} 168 169class WordResultSelect(implicit p: Parameters) extends XSModule { 170 val io = IO(new Bundle() { 171 val func = Input(UInt()) 172 val sllw, srlw, sraw, rolw, rorw, addw, subw = Input(UInt((XLEN/2).W)) 173 val wordRes = Output(UInt(XLEN.W)) 174 }) 175 176 val addsubRes = Mux(!io.func(2) && io.func(1) && !io.func(0), io.subw, io.addw) 177 val shiftRes = Mux(io.func(2), Mux(io.func(0), io.rorw, io.rolw), 178 Mux(io.func(1), io.sraw, Mux(io.func(0), io.srlw, io.sllw))) 179 val wordRes = Mux(io.func(3), shiftRes, addsubRes) 180 io.wordRes := SignExt(wordRes, XLEN) 181} 182 183 184class AluResSel(implicit p: Parameters) extends XSModule { 185 val io = IO(new Bundle() { 186 val func = Input(UInt(3.W)) 187 val addRes, shiftRes, miscRes, compareRes, wordRes, condRes = Input(UInt(XLEN.W)) 188 val aluRes = Output(UInt(XLEN.W)) 189 }) 190 191 val res = Mux(io.func(2, 1) === 0.U, Mux(io.func(0), io.wordRes, io.shiftRes), 192 Mux(!io.func(2), Mux(io.func(0), io.compareRes, io.addRes), 193 Mux(io.func(1, 0) === 3.U, io.condRes, io.miscRes))) 194 io.aluRes := res 195} 196 197class AluDataModule(implicit p: Parameters) extends XSModule { 198 val io = IO(new Bundle() { 199 val src = Vec(2, Input(UInt(XLEN.W))) 200 val func = Input(FuOpType()) 201 val result = Output(UInt(XLEN.W)) 202 }) 203 val (src1, src2, func) = (io.src(0), io.src(1), io.func) 204 205 val shamt = src2(5, 0) 206 val revShamt = ~src2(5,0) + 1.U 207 208 // slliuw, sll 209 val leftShiftModule = Module(new LeftShiftModule) 210 val sll = leftShiftModule.io.sll 211 val revSll = leftShiftModule.io.revSll 212 leftShiftModule.io.sllSrc := Cat(Fill(32, func(0)), Fill(32, 1.U)) & src1 213 leftShiftModule.io.shamt := shamt 214 leftShiftModule.io.revShamt := revShamt 215 216 // bclr, bset, binv 217 val bitShift = 1.U << src2(5, 0) 218 val bclr = src1 & ~bitShift 219 val bset = src1 | bitShift 220 val binv = src1 ^ bitShift 221 222 // srl, sra, bext 223 val rightShiftModule = Module(new RightShiftModule) 224 val srl = rightShiftModule.io.srl 225 val revSrl = rightShiftModule.io.revSrl 226 val sra = rightShiftModule.io.sra 227 rightShiftModule.io.shamt := shamt 228 rightShiftModule.io.revShamt := revShamt 229 rightShiftModule.io.srlSrc := src1 230 rightShiftModule.io.sraSrc := src1 231 val bext = srl(0) 232 233 val rol = revSrl | sll 234 val ror = srl | revSll 235 236 // addw 237 val addModule = Module(new AddModule) 238 addModule.io.srcw := Mux(!func(2) && func(0), Mux(func(1), SignExt(src2(11, 0), XLEN), ZeroExt(src1(0), XLEN)), src1(31, 0)) 239 val addwResultAll = VecInit(Seq( 240 ZeroExt(addModule.io.addw(0), XLEN), 241 ZeroExt(addModule.io.addw(7, 0), XLEN), 242 ZeroExt(addModule.io.addw(15, 0), XLEN), 243 SignExt(addModule.io.addw(15, 0), XLEN) 244 )) 245 val addw = Mux(func(2), addwResultAll(func(1, 0)), addModule.io.addw) 246 247 // subw 248 val subModule = Module(new SubModule) 249 val subw = subModule.io.sub 250 251 // sllw 252 val leftShiftWordModule = Module(new LeftShiftWordModule) 253 val sllw = leftShiftWordModule.io.sllw 254 val revSllw = leftShiftWordModule.io.revSllw 255 leftShiftWordModule.io.sllSrc := src1 256 leftShiftWordModule.io.shamt := shamt 257 leftShiftWordModule.io.revShamt := revShamt 258 259 val rightShiftWordModule = Module(new RightShiftWordModule) 260 val srlw = rightShiftWordModule.io.srlw 261 val revSrlw = rightShiftWordModule.io.revSrlw 262 val sraw = rightShiftWordModule.io.sraw 263 rightShiftWordModule.io.shamt := shamt 264 rightShiftWordModule.io.revShamt := revShamt 265 rightShiftWordModule.io.srlSrc := src1 266 rightShiftWordModule.io.sraSrc := src1 267 268 val rolw = revSrlw | sllw 269 val rorw = srlw | revSllw 270 271 // add 272 val wordMaskAddSource = Cat(Fill(32, func(0)), Fill(32, 1.U)) & src1 273 val shaddSource = VecInit(Seq( 274 Cat(wordMaskAddSource(62, 0), 0.U(1.W)), 275 Cat(wordMaskAddSource(61, 0), 0.U(2.W)), 276 Cat(wordMaskAddSource(60, 0), 0.U(3.W)), 277 Cat(wordMaskAddSource(59, 0), 0.U(4.W)) 278 )) 279 val sraddSource = VecInit(Seq( 280 ZeroExt(src1(63, 29), XLEN), 281 ZeroExt(src1(63, 30), XLEN), 282 ZeroExt(src1(63, 31), XLEN), 283 ZeroExt(src1(63, 32), XLEN) 284 )) 285 // TODO: use decoder or other libraries to optimize timing 286 // Now we assume shadd has the worst timing. 287 addModule.io.src(0) := Mux(func(3), shaddSource(func(2, 1)), 288 Mux(func(2), sraddSource(func(1, 0)), 289 Mux(func(1), Mux(func(0), SignExt(src2(11, 0), XLEN), ZeroExt(src1(0), XLEN)), wordMaskAddSource)) 290 ) 291 addModule.io.src(1) := Mux(func(3, 0) === "b0011".U, Cat(src2(63, 12), 0.U(12.W)), src2) 292 val add = addModule.io.add 293 294 // sub 295 val sub = subModule.io.sub 296 subModule.io.src(0) := src1 297 subModule.io.src(1) := src2 298 val sltu = !sub(XLEN) 299 val slt = src1(XLEN - 1) ^ src2(XLEN - 1) ^ sltu 300 val maxMin = Mux(slt ^ func(0), src2, src1) 301 val maxMinU = Mux(sltu ^ func(0), src2, src1) 302 val compareRes = Mux(func(2), Mux(func(1), maxMin, maxMinU), Mux(func(1), slt, Mux(func(0), sltu, sub))) 303 304 // logic 305 val logicSrc2 = Mux(!func(5) && func(0), ~src2, src2) 306 val and = src1 & logicSrc2 307 val or = src1 | logicSrc2 308 val xor = src1 ^ logicSrc2 309 val orcb = Cat((0 until 8).map(i => Fill(8, src1(i * 8 + 7, i * 8).orR)).reverse) 310 val orh48 = Cat(src1(63, 8), 0.U(8.W)) | src2 311 312 val sextb = SignExt(src1(7, 0), XLEN) 313 val packh = Cat(src2(7,0), src1(7,0)) 314 val sexth = SignExt(src1(15, 0), XLEN) 315 val packw = SignExt(Cat(src2(15, 0), src1(15, 0)), XLEN) 316 317 val revb = Cat((0 until 8).map(i => Reverse(src1(8 * i + 7, 8 * i))).reverse) 318 val pack = Cat(src2(31, 0), src1(31, 0)) 319 val rev8 = Cat((0 until 8).map(i => src1(8 * i + 7, 8 * i))) 320 321 322 // Result Select 323 val shiftResSel = Module(new ShiftResultSelect) 324 shiftResSel.io.func := func(3, 0) 325 shiftResSel.io.sll := sll 326 shiftResSel.io.srl := srl 327 shiftResSel.io.sra := sra 328 shiftResSel.io.rol := rol 329 shiftResSel.io.ror := ror 330 shiftResSel.io.bclr := bclr 331 shiftResSel.io.binv := binv 332 shiftResSel.io.bset := bset 333 shiftResSel.io.bext := bext 334 val shiftRes = shiftResSel.io.shiftRes 335 336 val miscResSel = Module(new MiscResultSelect) 337 miscResSel.io.func := func(5, 0) 338 miscResSel.io.and := and 339 miscResSel.io.or := or 340 miscResSel.io.xor := xor 341 miscResSel.io.orcb := orcb 342 miscResSel.io.orh48 := orh48 343 miscResSel.io.sextb := sextb 344 miscResSel.io.packh := packh 345 miscResSel.io.sexth := sexth 346 miscResSel.io.packw := packw 347 miscResSel.io.revb := revb 348 miscResSel.io.rev8 := rev8 349 miscResSel.io.pack := pack 350 miscResSel.io.src := src1 351 val miscRes = miscResSel.io.miscRes 352 353 val condModule = Module(new ConditionalZeroModule) 354 condModule.io.value := src1 355 condModule.io.condition := src2 356 condModule.io.isNez := func(1) 357 val condRes = condModule.io.condRes 358 359 360 val wordResSel = Module(new WordResultSelect) 361 wordResSel.io.func := func 362 wordResSel.io.addw := addw 363 wordResSel.io.subw := subw 364 wordResSel.io.sllw := sllw 365 wordResSel.io.srlw := srlw 366 wordResSel.io.sraw := sraw 367 wordResSel.io.rolw := rolw 368 wordResSel.io.rorw := rorw 369 val wordRes = wordResSel.io.wordRes 370 371 val aluResSel = Module(new AluResSel) 372 aluResSel.io.func := func(6, 4) 373 aluResSel.io.addRes := add 374 aluResSel.io.compareRes := compareRes 375 aluResSel.io.shiftRes := shiftRes 376 aluResSel.io.miscRes := miscRes 377 aluResSel.io.wordRes := wordRes 378 aluResSel.io.condRes := condRes 379 val aluRes = aluResSel.io.aluRes 380 381 io.result := aluRes 382 383 XSDebug(func === ALUOpType.lui32add, p"[alu] func lui32: src1=${Hexadecimal(src1)} src2=${Hexadecimal(src2)} alures=${Hexadecimal(aluRes)}\n") 384 XSDebug(func === ALUOpType.lui32add, p"[alu] func lui32: add_src1=${Hexadecimal(addModule.io.src(0))} add_src2=${Hexadecimal(addModule.io.src(1))} addres=${Hexadecimal(add)}\n") 385 386 XSDebug(func === ALUOpType.lui32addw, p"[alu] func lui32w: src1=${Hexadecimal(src1)} src2=${Hexadecimal(src2)} alures=${Hexadecimal(aluRes)}\n") 387 XSDebug(func === ALUOpType.lui32addw, p"[alu] func lui32w: add_src1=${Hexadecimal(addModule.io.srcw)} add_src2=${Hexadecimal(addModule.io.src(1)(31,0))} addres=${Hexadecimal(addw)}\n") 388} 389