xref: /XiangShan/src/main/scala/xiangshan/backend/fu/Alu.scala (revision ee8ff153da78c0e2933b0e53d29a7f40ba42ccc1)
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._
22*ee8ff153Szfwimport 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)))
2831ea8750SLinJiawei    val out = Output(UInt((XLEN+1).W))
2931ea8750SLinJiawei  })
302bd5334dSYinan Xu  io.out := 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)))
3631ea8750SLinJiawei    val out = Output(UInt((XLEN+1).W))
3731ea8750SLinJiawei  })
382bd5334dSYinan Xu  io.out := (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  })
4731ea8750SLinJiawei  io.sll := (io.sllSrc << io.shamt)(XLEN - 1, 0)
4831ea8750SLinJiawei}
4931ea8750SLinJiawei
502225d46eSJiawei Linclass RightShiftModule(implicit p: Parameters) extends XSModule {
5131ea8750SLinJiawei  val io = IO(new Bundle() {
5231ea8750SLinJiawei    val shamt = Input(UInt(6.W))
5331ea8750SLinJiawei    val srlSrc, sraSrc = Input(UInt(XLEN.W))
5467630d0bSLinJiawei    val srl_l, srl_w, sra_l, sra_w = Output(UInt(XLEN.W))
5531ea8750SLinJiawei  })
5667630d0bSLinJiawei  io.srl_l := io.srlSrc >> io.shamt
5767630d0bSLinJiawei  io.srl_w := io.srlSrc(31, 0) >> io.shamt
5867630d0bSLinJiawei  io.sra_l := (io.sraSrc.asSInt() >> io.shamt).asUInt()
59c57a9346SLinJiawei  io.sra_w := (Cat(Fill(32, io.sraSrc(31)), io.sraSrc(31, 0)).asSInt() >> io.shamt).asUInt()
6031ea8750SLinJiawei}
6131ea8750SLinJiawei
62*ee8ff153Szfwclass RotateShiftModule(implicit p: Parameters) extends XSModule {
63*ee8ff153Szfw  val io = IO(new Bundle() {
64*ee8ff153Szfw    val shamt = Input(UInt(6.W))
65*ee8ff153Szfw    val roSrc = Input(UInt(XLEN.W))
66*ee8ff153Szfw    val rol_l, rol_w, ror_l, ror_w = Output(UInt(XLEN.W))
67*ee8ff153Szfw  })
68*ee8ff153Szfw  io.rol_l := io.roSrc << io.shamt | io.roSrc >> ((~io.shamt).asUInt()+&1.U)
69*ee8ff153Szfw  io.rol_w := (io.roSrc << io.shamt | io.roSrc >> (32.U-io.shamt))(31,0)
70*ee8ff153Szfw  io.ror_l := io.roSrc>>io.shamt | io.roSrc << ((~io.shamt).asUInt()+&1.U)
71*ee8ff153Szfw  io.ror_w := (io.roSrc>>io.shamt | io.roSrc << (32.U-io.shamt))(31,0)
72*ee8ff153Szfw}
73*ee8ff153Szfw
742225d46eSJiawei Linclass MiscResultSelect(implicit p: Parameters) extends XSModule {
7531ea8750SLinJiawei  val io = IO(new Bundle() {
7631ea8750SLinJiawei    val func = Input(UInt())
77*ee8ff153Szfw    val andn, orn, xnor, and, or, xor, sltu, slt, maxMin, maxMinU, sextb, sexth, zexth, rev8, orcb = Input(UInt(XLEN.W))
7831ea8750SLinJiawei    val miscRes = Output(UInt(XLEN.W))
7931ea8750SLinJiawei  })
80*ee8ff153Szfw
81*ee8ff153Szfw  val (func, andn, orn, xnor, and, or, xor, sltu, slt, maxMin, maxMinU, sextb, sexth, zexth, rev8, orcb) =
82*ee8ff153Szfw    (io.func, io.andn, io.orn, io.xnor, io.and, io.or, io.xor, io.sltu, io.slt, io.maxMin, io.maxMinU, io.sextb, io.sexth, io.zexth, io.rev8, io.orcb)
83*ee8ff153Szfw
84*ee8ff153Szfw  val baseMisc = ParallelMux(List(
85*ee8ff153Szfw    ALUOpType.andn -> andn,
86*ee8ff153Szfw    ALUOpType.and  -> and,
87*ee8ff153Szfw    ALUOpType.orn  -> orn,
88*ee8ff153Szfw    ALUOpType.or   -> or,
89*ee8ff153Szfw    ALUOpType.xnor -> xnor,
90*ee8ff153Szfw    ALUOpType.xor  -> xor
91*ee8ff153Szfw  ).map(x => (x._1(2, 0) === io.func(2, 0), x._2)))
92*ee8ff153Szfw
93*ee8ff153Szfw  val bitMisc = ParallelMux(List(
94*ee8ff153Szfw    ALUOpType.sext_b -> sextb,
95*ee8ff153Szfw    ALUOpType.sext_h -> sexth,
96*ee8ff153Szfw    ALUOpType.zext_h -> zexth,
97*ee8ff153Szfw    ALUOpType.orc_b  -> orcb,
98*ee8ff153Szfw    ALUOpType.rev8   -> rev8
99*ee8ff153Szfw  ).map(x => (x._1(2, 0) === io.func(2, 0), x._2)))
100*ee8ff153Szfw
101*ee8ff153Szfw  val compMisc = Mux(func(2),
102*ee8ff153Szfw    Mux(func(1), maxMinU, maxMin),
103*ee8ff153Szfw    Mux(func(1), sltu, slt))
104*ee8ff153Szfw
105*ee8ff153Szfw  io.miscRes := Mux(func(4), compMisc, Mux(func(3), bitMisc, baseMisc))
10631ea8750SLinJiawei}
10731ea8750SLinJiawei
108*ee8ff153Szfwclass ShiftResultSelect(implicit p: Parameters) extends XSModule {
109*ee8ff153Szfw  val io = IO(new Bundle() {
110*ee8ff153Szfw    val func = Input(UInt())
111*ee8ff153Szfw    val sll, srl, sra, rol, ror, bclr, bset, binv, bext = Input(UInt(XLEN.W))
112*ee8ff153Szfw    val shiftRes = Output(UInt(XLEN.W))
113*ee8ff153Szfw  })
114*ee8ff153Szfw
115*ee8ff153Szfw  val (func, sll, srl, sra, rol, ror, bclr, bset, binv, bext) =
116*ee8ff153Szfw    (io.func, io.sll, io.srl, io.sra, io.rol, io.ror, io.bclr, io.bset, io.binv, io.bext)
117*ee8ff153Szfw
118*ee8ff153Szfw  val singleBitRes = ParallelMux(List(
119*ee8ff153Szfw    ALUOpType.bclr -> bclr,
120*ee8ff153Szfw    ALUOpType.binv -> binv,
121*ee8ff153Szfw    ALUOpType.bset -> bset,
122*ee8ff153Szfw    ALUOpType.bext -> bext
123*ee8ff153Szfw  ).map(x => (x._1(1, 0) === io.func(1, 0), x._2)))
124*ee8ff153Szfw
125*ee8ff153Szfw  val lrShiftRes = Mux(func(1), Mux(func(0), sra, srl), sll)
126*ee8ff153Szfw  val rotateShiftRes = Mux(func(3), ror, rol)
127*ee8ff153Szfw
128*ee8ff153Szfw  io.shiftRes := Mux(func(4), rotateShiftRes, Mux(func(2), singleBitRes, lrShiftRes))
129*ee8ff153Szfw}
130*ee8ff153Szfw
131*ee8ff153Szfw
1322225d46eSJiawei Linclass AluResSel(implicit p: Parameters) extends XSModule {
13331ea8750SLinJiawei  val io = IO(new Bundle() {
13431ea8750SLinJiawei    val func = Input(UInt())
135*ee8ff153Szfw    // val addSubRes, shiftRes, miscRes, countRes = Input(UInt(XLEN.W))
136*ee8ff153Szfw    val addSubRes, shiftRes, miscRes = Input(UInt(XLEN.W))
13731ea8750SLinJiawei    val aluRes = Output(UInt(XLEN.W))
13831ea8750SLinJiawei  })
139*ee8ff153Szfw
140*ee8ff153Szfw  val res = Mux(io.func(6),
141*ee8ff153Szfw    io.shiftRes,
142*ee8ff153Szfw    Mux(io.func(5), io.addSubRes, io.miscRes)
14331ea8750SLinJiawei  )
144*ee8ff153Szfw  val h32 = Mux(io.func(7), Fill(32, res(31)), res(63, 32))
14531ea8750SLinJiawei  io.aluRes := Cat(h32, res(31, 0))
14631ea8750SLinJiawei}
14731ea8750SLinJiawei
1482225d46eSJiawei Linclass AluDataModule(implicit p: Parameters) extends XSModule {
149e2203130SLinJiawei  val io = IO(new Bundle() {
1502bd5334dSYinan Xu    val src = Vec(2, Input(UInt(XLEN.W)))
151e2203130SLinJiawei    val func = Input(FuOpType())
152e2203130SLinJiawei    val pred_taken, isBranch = Input(Bool())
153e2203130SLinJiawei    val result = Output(UInt(XLEN.W))
154e2203130SLinJiawei    val taken, mispredict = Output(Bool())
155e2203130SLinJiawei  })
1562bd5334dSYinan Xu  val (src1, src2, func) = (io.src(0), io.src(1), io.func)
157e18c367fSLinJiawei
15831ea8750SLinJiawei  val addModule = Module(new AddModule)
1592bd5334dSYinan Xu  addModule.io.src(1) := src2
160*ee8ff153Szfw  addModule.io.src(0) := ParallelMux(List(
161*ee8ff153Szfw    "b000".U -> src1,
162*ee8ff153Szfw    "b001".U -> src1(31,0),
163*ee8ff153Szfw    "b010".U -> Cat(src1(62,0), 0.U(1.W)),
164*ee8ff153Szfw    "b011".U -> Cat(src1(30,0), 0.U(1.W)),
165*ee8ff153Szfw    "b100".U -> Cat(src1(61,0), 0.U(2.W)),
166*ee8ff153Szfw    "b101".U -> Cat(src1(29,0), 0.U(2.W)),
167*ee8ff153Szfw    "b110".U -> Cat(src1(60,0), 0.U(3.W)),
168*ee8ff153Szfw    "b111".U -> Cat(src1(28,0), 0.U(3.W)),
169*ee8ff153Szfw  ).map(x => (x._1(2, 0) === func(2,0), x._2)))
170*ee8ff153Szfw
171*ee8ff153Szfw
17231ea8750SLinJiawei  val subModule = Module(new SubModule)
1732bd5334dSYinan Xu  subModule.io.src(0) := src1
1742bd5334dSYinan Xu  subModule.io.src(1) := src2
175*ee8ff153Szfw  val add = addModule.io.out
176*ee8ff153Szfw  val sub = subModule.io.out
177e18c367fSLinJiawei
178*ee8ff153Szfw
179*ee8ff153Szfw // Misc
180*ee8ff153Szfw  val andn    = ~(src1 & src2)
181*ee8ff153Szfw  val orn     = ~(src1 | src2)
182*ee8ff153Szfw  val xnor    = ~(src1 ^ src2)
183*ee8ff153Szfw  val and     = ~andn
184*ee8ff153Szfw  val or      = ~orn
185*ee8ff153Szfw  val xor     = ~xnor
186*ee8ff153Szfw  val sltu    = !sub(XLEN)
187*ee8ff153Szfw  val slt     = xor(XLEN-1) ^ sltu
188*ee8ff153Szfw  val maxMin  = Mux(slt ^ func(0), src2, src1)
189*ee8ff153Szfw  val maxMinU = Mux(sltu^ func(0), src2, src1)
190*ee8ff153Szfw  val sextb   = SignExt(src1(7, 0), XLEN)
191*ee8ff153Szfw  val sexth   = SignExt(src1(15, 0), XLEN)
192*ee8ff153Szfw  val zexth   = ZeroExt(src1(15, 0), XLEN)
193*ee8ff153Szfw  val rev8    = Cat(src1(7,0), src1(15,8), src1(23,16), src1(31,24),
194*ee8ff153Szfw                    src1(39,32), src1(47,40), src1(55,48), src1(63,56))
195*ee8ff153Szfw  val orcb    = Cat(Reverse(src1(63,56)), Reverse(src1(55,48)), Reverse(src1(47,40)), Reverse(src1(39,32)),
196*ee8ff153Szfw                    Reverse(src1(31,24)), Reverse(src1(23,16)), Reverse(src1(15,8)), Reverse(src1(7,0)))
197*ee8ff153Szfw
198*ee8ff153Szfw  val branchOpTable = List(
199*ee8ff153Szfw    ALUOpType.getBranchType(ALUOpType.beq)  -> !xor.orR,
200*ee8ff153Szfw    ALUOpType.getBranchType(ALUOpType.blt)  -> slt,
201*ee8ff153Szfw    ALUOpType.getBranchType(ALUOpType.bltu) -> sltu
202*ee8ff153Szfw  )
203*ee8ff153Szfw  val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func)
204*ee8ff153Szfw
205*ee8ff153Szfw
206*ee8ff153Szfw  // Shift
20731ea8750SLinJiawei  val isW = ALUOpType.isWordOp(func)
2084a6ab1cdSLinJiawei  val shamt = Cat(!isW && src2(5), src2(4, 0))
2093ef996e9SLinJiawei
21031ea8750SLinJiawei  val leftShiftModule = Module(new LeftShiftModule)
211*ee8ff153Szfw  leftShiftModule.io.sllSrc := Mux(func(2), 1.U, Mux(func(0), src1(31,0), src1))
21231ea8750SLinJiawei  leftShiftModule.io.shamt := shamt
213*ee8ff153Szfw  val sll  = leftShiftModule.io.sll
214*ee8ff153Szfw  val bset = src1 | sll
215*ee8ff153Szfw  val bclr = src1 & ~sll
216*ee8ff153Szfw  val binv = src1 ^ sll
217*ee8ff153Szfw
2183ef996e9SLinJiawei
21931ea8750SLinJiawei  val rightShiftModule = Module(new RightShiftModule)
22031ea8750SLinJiawei  rightShiftModule.io.shamt := shamt
22167630d0bSLinJiawei  rightShiftModule.io.srlSrc := src1
22267630d0bSLinJiawei  rightShiftModule.io.sraSrc := src1
22367630d0bSLinJiawei  val srl = Mux(isW, rightShiftModule.io.srl_w, rightShiftModule.io.srl_l)
22467630d0bSLinJiawei  val sra = Mux(isW, rightShiftModule.io.sra_w, rightShiftModule.io.sra_l)
225*ee8ff153Szfw  val bext = srl(0)
226*ee8ff153Szfw
227*ee8ff153Szfw  val rotateShiftModule = Module(new RotateShiftModule)
228*ee8ff153Szfw  rotateShiftModule.io.shamt := Mux(isW, src2(4,0), src2(5,0))
229*ee8ff153Szfw  rotateShiftModule.io.roSrc := Mux(isW, src1(31,0), src1)
230*ee8ff153Szfw  val rol = Mux(isW, rotateShiftModule.io.rol_w, rotateShiftModule.io.rol_l)
231*ee8ff153Szfw  val ror = Mux(isW, rotateShiftModule.io.ror_w, rotateShiftModule.io.ror_l)
23231ea8750SLinJiawei
23331ea8750SLinJiawei  val miscResSel = Module(new MiscResultSelect)
234*ee8ff153Szfw  miscResSel.io.func    := func(4, 0)
235*ee8ff153Szfw  miscResSel.io.andn    := andn
236*ee8ff153Szfw  miscResSel.io.orn     := orn
237*ee8ff153Szfw  miscResSel.io.xnor    := xnor
238*ee8ff153Szfw  miscResSel.io.and     := and
239*ee8ff153Szfw  miscResSel.io.or      := or
240*ee8ff153Szfw  miscResSel.io.xor     := xor
241*ee8ff153Szfw  miscResSel.io.sltu    := sltu
242*ee8ff153Szfw  miscResSel.io.slt     := slt
243*ee8ff153Szfw  miscResSel.io.maxMin  := maxMin
244*ee8ff153Szfw  miscResSel.io.maxMinU := maxMinU
245*ee8ff153Szfw  miscResSel.io.sextb   := sextb
246*ee8ff153Szfw  miscResSel.io.sexth   := sexth
247*ee8ff153Szfw  miscResSel.io.zexth   := zexth
248*ee8ff153Szfw  miscResSel.io.rev8    := rev8
249*ee8ff153Szfw  miscResSel.io.orcb    := orcb
25031ea8750SLinJiawei  val miscRes = miscResSel.io.miscRes
25131ea8750SLinJiawei
252*ee8ff153Szfw  val addSubRes = Mux(func(3), sub, add)
253*ee8ff153Szfw
254*ee8ff153Szfw  val shiftResSel = Module(new ShiftResultSelect)
255*ee8ff153Szfw  shiftResSel.io.func := func(4,0)
256*ee8ff153Szfw  shiftResSel.io.sll  := sll
257*ee8ff153Szfw  shiftResSel.io.srl  := srl
258*ee8ff153Szfw  shiftResSel.io.sra  := sra
259*ee8ff153Szfw  shiftResSel.io.rol  := rol
260*ee8ff153Szfw  shiftResSel.io.ror  := ror
261*ee8ff153Szfw  shiftResSel.io.bclr := bclr
262*ee8ff153Szfw  shiftResSel.io.binv := binv
263*ee8ff153Szfw  shiftResSel.io.bset := bset
264*ee8ff153Szfw  shiftResSel.io.bext := bext
265*ee8ff153Szfw  val shiftRes = shiftResSel.io.shiftRes
266*ee8ff153Szfw
26731ea8750SLinJiawei  val aluResSel = Module(new AluResSel)
26831ea8750SLinJiawei  aluResSel.io.func := func
269*ee8ff153Szfw  aluResSel.io.addSubRes := addSubRes
270*ee8ff153Szfw  aluResSel.io.shiftRes := shiftRes
27131ea8750SLinJiawei  aluResSel.io.miscRes := miscRes
27231ea8750SLinJiawei  val aluRes = aluResSel.io.aluRes
273e18c367fSLinJiawei
274e2203130SLinJiawei  io.result := aluRes
275e2203130SLinJiawei  io.taken := taken
276e2203130SLinJiawei  io.mispredict := (io.pred_taken ^ taken) && io.isBranch
277e2203130SLinJiawei}
278e2203130SLinJiawei
279adb5df20SYinan Xuclass Alu(implicit p: Parameters) extends FUWithRedirect {
280e2203130SLinJiawei
281e2203130SLinJiawei  val (src1, src2, func, pc, uop) = (
282e2203130SLinJiawei    io.in.bits.src(0),
283e2203130SLinJiawei    io.in.bits.src(1),
284e2203130SLinJiawei    io.in.bits.uop.ctrl.fuOpType,
285e2203130SLinJiawei    SignExt(io.in.bits.uop.cf.pc, AddrBits),
286e2203130SLinJiawei    io.in.bits.uop
287e2203130SLinJiawei  )
288e2203130SLinJiawei
289e2203130SLinJiawei  val valid = io.in.valid
290e2203130SLinJiawei  val isBranch = ALUOpType.isBranch(func)
291e2203130SLinJiawei  val dataModule = Module(new AluDataModule)
292e2203130SLinJiawei
2932bd5334dSYinan Xu  dataModule.io.src(0) := src1
2942bd5334dSYinan Xu  dataModule.io.src(1) := src2
295e2203130SLinJiawei  dataModule.io.func := func
296e2203130SLinJiawei  dataModule.io.pred_taken := uop.cf.pred_taken
297e2203130SLinJiawei  dataModule.io.isBranch := isBranch
298e2203130SLinJiawei
299e18c367fSLinJiawei  redirectOutValid := io.out.valid && isBranch
300151e3043SLinJiawei  redirectOut := DontCare
301bfb958a3SYinan Xu  redirectOut.level := RedirectLevel.flushAfter
302e18c367fSLinJiawei  redirectOut.roqIdx := uop.roqIdx
303cde9280dSLinJiawei  redirectOut.ftqIdx := uop.cf.ftqPtr
304cde9280dSLinJiawei  redirectOut.ftqOffset := uop.cf.ftqOffset
305e2203130SLinJiawei  redirectOut.cfiUpdate.isMisPred := dataModule.io.mispredict
306e2203130SLinJiawei  redirectOut.cfiUpdate.taken := dataModule.io.taken
307cde9280dSLinJiawei  redirectOut.cfiUpdate.predTaken := uop.cf.pred_taken
308151e3043SLinJiawei
309e18c367fSLinJiawei  io.in.ready := io.out.ready
310e18c367fSLinJiawei  io.out.valid := valid
311e18c367fSLinJiawei  io.out.bits.uop <> io.in.bits.uop
312e2203130SLinJiawei  io.out.bits.data := dataModule.io.result
313e18c367fSLinJiawei}
314