xref: /XiangShan/src/main/scala/xiangshan/backend/fu/Alu.scala (revision 4aa9ed342654d307178fb17faf8226c0d6136b80)
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._
223c02ee8fSwakafaimport utility.{LookupTree, LookupTreeDefault, ParallelMux, SignExt, ZeroExt}
23e18c367fSLinJiaweiimport xiangshan._
24e18c367fSLinJiawei
25*4aa9ed34Sfdyclass VsetModule(implicit p: Parameters) extends XSModule {
26*4aa9ed34Sfdy  val io = IO(new Bundle() {
27*4aa9ed34Sfdy    val lsrc0 = Input(UInt(6.W))
28*4aa9ed34Sfdy    val ldest = Input(UInt(6.W))
29*4aa9ed34Sfdy    val src0  = Input(UInt(XLEN.W))
30*4aa9ed34Sfdy    val src1  = Input(UInt(XLEN.W))
31*4aa9ed34Sfdy    val func  = Input(FuOpType())
32*4aa9ed34Sfdy    val vconfig = Input(UInt(16.W))
33*4aa9ed34Sfdy
34*4aa9ed34Sfdy    val res   = Output(UInt(XLEN.W))
35*4aa9ed34Sfdy  })
36*4aa9ed34Sfdy  val vtype = io.src1(7, 0)
37*4aa9ed34Sfdy  val vlmul = vtype(2, 0)
38*4aa9ed34Sfdy  val vsew = vtype(5, 3)
39*4aa9ed34Sfdy
40*4aa9ed34Sfdy  val avlImm = Cat(0.U(3.W), io.src1(14, 10))
41*4aa9ed34Sfdy  val vlLast = io.vconfig(15, 8)
42*4aa9ed34Sfdy
43*4aa9ed34Sfdy  val rd = io.ldest
44*4aa9ed34Sfdy  val rs1 = io.lsrc0
45*4aa9ed34Sfdy  val vl = WireInit(0.U(XLEN.W))
46*4aa9ed34Sfdy  val vconfig = WireInit(0.U(XLEN.W))
47*4aa9ed34Sfdy
48*4aa9ed34Sfdy  // vlen =  128
49*4aa9ed34Sfdy  val vlmaxVec = (0 to 7).map(i => if(i < 4) (16 << i).U(8.W) else (16 >> (8 - i)).U(8.W))
50*4aa9ed34Sfdy  val shamt = vlmul + (~vsew).asUInt + 1.U
51*4aa9ed34Sfdy  val vlmax = ParallelMux((0 to 7).map(_.U).map(_ === shamt), vlmaxVec)
52*4aa9ed34Sfdy
53*4aa9ed34Sfdy  val isVsetivli = io.func === ALUOpType.vsetivli2 || io.func === ALUOpType.vsetivli1
54*4aa9ed34Sfdy  val vlWhenRs1Not0 = Mux(isVsetivli, Mux(avlImm > vlmax, vlmax, avlImm),
55*4aa9ed34Sfdy                                      Mux(io.src0 > vlmax, vlmax, io.src0))
56*4aa9ed34Sfdy  vl := Mux(rs1 =/= 0.U, vlWhenRs1Not0,
57*4aa9ed34Sfdy          Mux(rd === 0.U, Cat(0.U(56.W), vlLast), vlmax))
58*4aa9ed34Sfdy
59*4aa9ed34Sfdy  vconfig := Cat(0.U(48.W), vl(7, 0), vtype)
60*4aa9ed34Sfdy
61*4aa9ed34Sfdy  io.res := Mux(io.func === ALUOpType.vsetvli2 || io.func === ALUOpType.vsetvl2 || io.func === ALUOpType.vsetivli2, vl, vconfig)
62*4aa9ed34Sfdy}
63*4aa9ed34Sfdy
642225d46eSJiawei Linclass AddModule(implicit p: Parameters) extends XSModule {
6531ea8750SLinJiawei  val io = IO(new Bundle() {
662bd5334dSYinan Xu    val src = Vec(2, Input(UInt(XLEN.W)))
6728c18878Szfw    val srcw = Input(UInt((XLEN/2).W))
6828c18878Szfw    val add = Output(UInt(XLEN.W))
6928c18878Szfw    val addw = Output(UInt((XLEN/2).W))
7031ea8750SLinJiawei  })
7128c18878Szfw  io.add := io.src(0) + io.src(1)
7288825c5cSYinan Xu  // TODO: why this extra adder?
7328c18878Szfw  io.addw := io.srcw + io.src(1)(31,0)
7431ea8750SLinJiawei}
7531ea8750SLinJiawei
762225d46eSJiawei Linclass SubModule(implicit p: Parameters) extends XSModule {
7731ea8750SLinJiawei  val io = IO(new Bundle() {
782bd5334dSYinan Xu    val src = Vec(2, Input(UInt(XLEN.W)))
79184a1958Szfw    val sub = Output(UInt((XLEN+1).W))
8031ea8750SLinJiawei  })
81184a1958Szfw  io.sub := (io.src(0) +& (~io.src(1)).asUInt()) + 1.U
8231ea8750SLinJiawei}
8331ea8750SLinJiawei
842225d46eSJiawei Linclass LeftShiftModule(implicit p: Parameters) extends XSModule {
8531ea8750SLinJiawei  val io = IO(new Bundle() {
8631ea8750SLinJiawei    val shamt = Input(UInt(6.W))
8728c18878Szfw    val revShamt = Input(UInt(6.W))
8831ea8750SLinJiawei    val sllSrc = Input(UInt(XLEN.W))
8931ea8750SLinJiawei    val sll = Output(UInt(XLEN.W))
9028c18878Szfw    val revSll = Output(UInt(XLEN.W))
9131ea8750SLinJiawei  })
92184a1958Szfw  io.sll := io.sllSrc << io.shamt
9328c18878Szfw  io.revSll := io.sllSrc << io.revShamt
94184a1958Szfw}
95184a1958Szfw
96184a1958Szfwclass LeftShiftWordModule(implicit p: Parameters) extends XSModule {
97184a1958Szfw  val io = IO(new Bundle() {
98184a1958Szfw    val shamt = Input(UInt(5.W))
9928c18878Szfw    val revShamt = Input(UInt(5.W))
100184a1958Szfw    val sllSrc = Input(UInt((XLEN/2).W))
101184a1958Szfw    val sllw = Output(UInt((XLEN/2).W))
10228c18878Szfw    val revSllw = Output(UInt((XLEN/2).W))
103184a1958Szfw  })
104184a1958Szfw  io.sllw := io.sllSrc << io.shamt
10528c18878Szfw  io.revSllw := io.sllSrc << io.revShamt
10631ea8750SLinJiawei}
10731ea8750SLinJiawei
1082225d46eSJiawei Linclass RightShiftModule(implicit p: Parameters) extends XSModule {
10931ea8750SLinJiawei  val io = IO(new Bundle() {
11031ea8750SLinJiawei    val shamt = Input(UInt(6.W))
11128c18878Szfw    val revShamt = Input(UInt(6.W))
11231ea8750SLinJiawei    val srlSrc, sraSrc = Input(UInt(XLEN.W))
113184a1958Szfw    val srl, sra = Output(UInt(XLEN.W))
11428c18878Szfw    val revSrl = Output(UInt(XLEN.W))
11531ea8750SLinJiawei  })
116184a1958Szfw  io.srl  := io.srlSrc >> io.shamt
117184a1958Szfw  io.sra  := (io.sraSrc.asSInt() >> io.shamt).asUInt()
11828c18878Szfw  io.revSrl  := io.srlSrc >> io.revShamt
11931ea8750SLinJiawei}
12031ea8750SLinJiawei
121184a1958Szfwclass RightShiftWordModule(implicit p: Parameters) extends XSModule {
122ee8ff153Szfw  val io = IO(new Bundle() {
123184a1958Szfw    val shamt = Input(UInt(5.W))
12428c18878Szfw    val revShamt = Input(UInt(5.W))
125184a1958Szfw    val srlSrc, sraSrc = Input(UInt((XLEN/2).W))
126184a1958Szfw    val srlw, sraw = Output(UInt((XLEN/2).W))
12728c18878Szfw    val revSrlw = Output(UInt((XLEN/2).W))
128ee8ff153Szfw  })
129184a1958Szfw
130184a1958Szfw  io.srlw := io.srlSrc >> io.shamt
131184a1958Szfw  io.sraw := (io.sraSrc.asSInt() >> io.shamt).asUInt()
13228c18878Szfw  io.revSrlw := io.srlSrc >> io.revShamt
133ee8ff153Szfw}
134ee8ff153Szfw
135184a1958Szfw
1362225d46eSJiawei Linclass MiscResultSelect(implicit p: Parameters) extends XSModule {
13731ea8750SLinJiawei  val io = IO(new Bundle() {
138675acc68SYinan Xu    val func = Input(UInt(6.W))
139675acc68SYinan Xu    val and, or, xor, orcb, orh48, sextb, packh, sexth, packw, revb, rev8, pack = Input(UInt(XLEN.W))
14088825c5cSYinan Xu    val src = Input(UInt(XLEN.W))
14131ea8750SLinJiawei    val miscRes = Output(UInt(XLEN.W))
14231ea8750SLinJiawei  })
143ee8ff153Szfw
144675acc68SYinan Xu  val logicRes = VecInit(Seq(
145675acc68SYinan Xu    io.and,
146675acc68SYinan Xu    io.or,
147675acc68SYinan Xu    io.xor,
148675acc68SYinan Xu    io.orcb
149675acc68SYinan Xu  ))(io.func(2, 1))
150675acc68SYinan Xu  val miscRes = VecInit(Seq(io.sextb, io.packh, io.sexth, io.packw))(io.func(1, 0))
151675acc68SYinan Xu  val logicBase = Mux(io.func(3), miscRes, logicRes)
15288825c5cSYinan Xu
153675acc68SYinan Xu  val revRes = VecInit(Seq(io.revb, io.rev8, io.pack, io.orh48))(io.func(1, 0))
154675acc68SYinan Xu  val customRes = VecInit(Seq(
155675acc68SYinan Xu    Cat(0.U(31.W), io.src(31, 0), 0.U(1.W)),
156675acc68SYinan Xu    Cat(0.U(30.W), io.src(31, 0), 0.U(2.W)),
157675acc68SYinan Xu    Cat(0.U(29.W), io.src(31, 0), 0.U(3.W)),
158675acc68SYinan Xu    Cat(0.U(56.W), io.src(15, 8))))(io.func(1, 0))
159675acc68SYinan Xu  val logicAdv = Mux(io.func(3), customRes, revRes)
160ee8ff153Szfw
161675acc68SYinan Xu  val mask = Cat(Fill(15, io.func(0)), 1.U(1.W))
162675acc68SYinan Xu  val maskedLogicRes = mask & logicRes
163675acc68SYinan Xu
164675acc68SYinan Xu  io.miscRes := Mux(io.func(5), maskedLogicRes, Mux(io.func(4), logicAdv, logicBase))
16531ea8750SLinJiawei}
16631ea8750SLinJiawei
167ee8ff153Szfwclass ShiftResultSelect(implicit p: Parameters) extends XSModule {
168ee8ff153Szfw  val io = IO(new Bundle() {
169675acc68SYinan Xu    val func = Input(UInt(4.W))
17028c18878Szfw    val sll, srl, sra, rol, ror, bclr, bset, binv, bext = Input(UInt(XLEN.W))
171ee8ff153Szfw    val shiftRes = Output(UInt(XLEN.W))
172ee8ff153Szfw  })
173ee8ff153Szfw
174675acc68SYinan Xu  // val leftBit  = Mux(io.func(1), io.binv, Mux(io.func(0), io.bset, io.bclr))
175675acc68SYinan Xu  // val leftRes  = Mux(io.func(2), leftBit, io.sll)
176675acc68SYinan Xu  // val rightRes = Mux(io.func(1) && io.func(0), io.sra, Mux(io.func(1), io.bext, io.srl))
177675acc68SYinan Xu  val resultSource = VecInit(Seq(
178675acc68SYinan Xu    io.sll,
179675acc68SYinan Xu    io.sll,
180675acc68SYinan Xu    io.bclr,
181675acc68SYinan Xu    io.bset,
182675acc68SYinan Xu    io.binv,
183675acc68SYinan Xu    io.srl,
184675acc68SYinan Xu    io.bext,
185675acc68SYinan Xu    io.sra
186675acc68SYinan Xu  ))
187675acc68SYinan Xu  val simple = resultSource(io.func(2, 0))
188ee8ff153Szfw
1897b441e5eSYinan Xu  io.shiftRes := Mux(io.func(3), Mux(io.func(1), io.ror, io.rol), simple)
190184a1958Szfw}
191ee8ff153Szfw
192184a1958Szfwclass WordResultSelect(implicit p: Parameters) extends XSModule {
193184a1958Szfw  val io = IO(new Bundle() {
194184a1958Szfw    val func = Input(UInt())
19528c18878Szfw    val sllw, srlw, sraw, rolw, rorw, addw, subw = Input(UInt((XLEN/2).W))
196184a1958Szfw    val wordRes = Output(UInt(XLEN.W))
197184a1958Szfw  })
198ee8ff153Szfw
199675acc68SYinan Xu  val addsubRes = Mux(!io.func(2) && io.func(1), io.subw, io.addw)
200675acc68SYinan Xu  val shiftRes = Mux(io.func(2), Mux(io.func(0), io.rorw, io.rolw),
201675acc68SYinan Xu                  Mux(io.func(1), io.sraw, Mux(io.func(0), io.srlw, io.sllw)))
202675acc68SYinan Xu  val wordRes = Mux(io.func(3), shiftRes, addsubRes)
203184a1958Szfw  io.wordRes := SignExt(wordRes, XLEN)
204ee8ff153Szfw}
205ee8ff153Szfw
206ee8ff153Szfw
2072225d46eSJiawei Linclass AluResSel(implicit p: Parameters) extends XSModule {
20831ea8750SLinJiawei  val io = IO(new Bundle() {
209*4aa9ed34Sfdy    val func = Input(UInt(4.W))
210*4aa9ed34Sfdy    val addRes, shiftRes, miscRes, compareRes, wordRes, vsetRes = Input(UInt(XLEN.W))
21131ea8750SLinJiawei    val aluRes = Output(UInt(XLEN.W))
21231ea8750SLinJiawei  })
213ee8ff153Szfw
214*4aa9ed34Sfdy  val res = Mux(io.func(3), io.vsetRes,
215*4aa9ed34Sfdy              Mux(io.func(2, 1) === 0.U, Mux(io.func(0), io.wordRes, io.shiftRes),
216*4aa9ed34Sfdy                Mux(!io.func(2), Mux(io.func(0), io.compareRes, io.addRes), io.miscRes)))
217184a1958Szfw  io.aluRes := res
21831ea8750SLinJiawei}
21931ea8750SLinJiawei
2202225d46eSJiawei Linclass AluDataModule(implicit p: Parameters) extends XSModule {
221e2203130SLinJiawei  val io = IO(new Bundle() {
2222bd5334dSYinan Xu    val src = Vec(2, Input(UInt(XLEN.W)))
223e2203130SLinJiawei    val func = Input(FuOpType())
224e2203130SLinJiawei    val pred_taken, isBranch = Input(Bool())
225e2203130SLinJiawei    val result = Output(UInt(XLEN.W))
226e2203130SLinJiawei    val taken, mispredict = Output(Bool())
227*4aa9ed34Sfdy    val lsrc0 = Input(UInt(6.W))
228*4aa9ed34Sfdy    val ldest = Input(UInt(6.W))
229*4aa9ed34Sfdy    val vconfig = Input(UInt(16.W))
230e2203130SLinJiawei  })
2312bd5334dSYinan Xu  val (src1, src2, func) = (io.src(0), io.src(1), io.func)
232e18c367fSLinJiawei
233675acc68SYinan Xu  val shamt = src2(5, 0)
234675acc68SYinan Xu  val revShamt = ~src2(5,0) + 1.U
235675acc68SYinan Xu
236675acc68SYinan Xu  // slliuw, sll
237675acc68SYinan Xu  val leftShiftModule = Module(new LeftShiftModule)
238675acc68SYinan Xu  val sll = leftShiftModule.io.sll
239675acc68SYinan Xu  val revSll = leftShiftModule.io.revSll
240675acc68SYinan Xu  leftShiftModule.io.sllSrc := Cat(Fill(32, func(0)), Fill(32, 1.U)) & src1
241675acc68SYinan Xu  leftShiftModule.io.shamt := shamt
242675acc68SYinan Xu  leftShiftModule.io.revShamt := revShamt
243675acc68SYinan Xu
244675acc68SYinan Xu  // bclr, bset, binv
245675acc68SYinan Xu  val bitShift = 1.U << src2(5, 0)
246675acc68SYinan Xu  val bclr = src1 & ~bitShift
247675acc68SYinan Xu  val bset = src1 | bitShift
248675acc68SYinan Xu  val binv = src1 ^ bitShift
249675acc68SYinan Xu
250675acc68SYinan Xu  // srl, sra, bext
251675acc68SYinan Xu  val rightShiftModule = Module(new RightShiftModule)
252675acc68SYinan Xu  val srl = rightShiftModule.io.srl
253675acc68SYinan Xu  val revSrl = rightShiftModule.io.revSrl
254675acc68SYinan Xu  val sra = rightShiftModule.io.sra
255675acc68SYinan Xu  rightShiftModule.io.shamt := shamt
256675acc68SYinan Xu  rightShiftModule.io.revShamt := revShamt
257675acc68SYinan Xu  rightShiftModule.io.srlSrc := src1
258675acc68SYinan Xu  rightShiftModule.io.sraSrc := src1
259675acc68SYinan Xu  val bext = srl(0)
260675acc68SYinan Xu
261675acc68SYinan Xu  val rol = revSrl | sll
262675acc68SYinan Xu  val ror = srl | revSll
263675acc68SYinan Xu
264*4aa9ed34Sfdy  // vset
265*4aa9ed34Sfdy  val vsetModule = Module(new VsetModule)
266*4aa9ed34Sfdy  vsetModule.io.lsrc0 := io.lsrc0
267*4aa9ed34Sfdy  vsetModule.io.ldest := io.ldest
268*4aa9ed34Sfdy  vsetModule.io.src0 := io.src(0)
269*4aa9ed34Sfdy  vsetModule.io.src1 := io.src(1)
270*4aa9ed34Sfdy  vsetModule.io.func := io.func
271*4aa9ed34Sfdy  vsetModule.io.vconfig := io.vconfig
272*4aa9ed34Sfdy
273675acc68SYinan Xu  // addw
274184a1958Szfw  val addModule = Module(new AddModule)
275675acc68SYinan Xu  addModule.io.srcw := Mux(!func(2) && func(0), ZeroExt(src1(0), XLEN), src1(31, 0))
276675acc68SYinan Xu  val addwResultAll = VecInit(Seq(
277675acc68SYinan Xu    ZeroExt(addModule.io.addw(0), XLEN),
278675acc68SYinan Xu    ZeroExt(addModule.io.addw(7, 0), XLEN),
279675acc68SYinan Xu    ZeroExt(addModule.io.addw(15, 0), XLEN),
280675acc68SYinan Xu    SignExt(addModule.io.addw(15, 0), XLEN)
281675acc68SYinan Xu  ))
282675acc68SYinan Xu  val addw = Mux(func(2), addwResultAll(func(1, 0)), addModule.io.addw)
283675acc68SYinan Xu
284675acc68SYinan Xu  // subw
285675acc68SYinan Xu  val subModule = Module(new SubModule)
286675acc68SYinan Xu  val subw = subModule.io.sub
287675acc68SYinan Xu
288675acc68SYinan Xu  // sllw
289675acc68SYinan Xu  val leftShiftWordModule = Module(new LeftShiftWordModule)
290675acc68SYinan Xu  val sllw = leftShiftWordModule.io.sllw
291675acc68SYinan Xu  val revSllw = leftShiftWordModule.io.revSllw
292675acc68SYinan Xu  leftShiftWordModule.io.sllSrc := src1
293675acc68SYinan Xu  leftShiftWordModule.io.shamt := shamt
294675acc68SYinan Xu  leftShiftWordModule.io.revShamt := revShamt
295675acc68SYinan Xu
296675acc68SYinan Xu  val rightShiftWordModule = Module(new RightShiftWordModule)
297675acc68SYinan Xu  val srlw = rightShiftWordModule.io.srlw
298675acc68SYinan Xu  val revSrlw = rightShiftWordModule.io.revSrlw
299675acc68SYinan Xu  val sraw = rightShiftWordModule.io.sraw
300675acc68SYinan Xu  rightShiftWordModule.io.shamt := shamt
301675acc68SYinan Xu  rightShiftWordModule.io.revShamt := revShamt
302675acc68SYinan Xu  rightShiftWordModule.io.srlSrc := src1
303675acc68SYinan Xu  rightShiftWordModule.io.sraSrc := src1
304675acc68SYinan Xu
305675acc68SYinan Xu  val rolw = revSrlw | sllw
306675acc68SYinan Xu  val rorw = srlw | revSllw
307675acc68SYinan Xu
308675acc68SYinan Xu  // add
309a792bcf1SYinan Xu  val wordMaskAddSource = Cat(Fill(32, func(0)), Fill(32, 1.U)) & src1
310a792bcf1SYinan Xu  val shaddSource = VecInit(Seq(
311a792bcf1SYinan Xu    Cat(wordMaskAddSource(62, 0), 0.U(1.W)),
312a792bcf1SYinan Xu    Cat(wordMaskAddSource(61, 0), 0.U(2.W)),
313a792bcf1SYinan Xu    Cat(wordMaskAddSource(60, 0), 0.U(3.W)),
314a792bcf1SYinan Xu    Cat(wordMaskAddSource(59, 0), 0.U(4.W))
315a792bcf1SYinan Xu  ))
316a792bcf1SYinan Xu  val sraddSource = VecInit(Seq(
317a792bcf1SYinan Xu    ZeroExt(src1(63, 29), XLEN),
31888825c5cSYinan Xu    ZeroExt(src1(63, 30), XLEN),
31988825c5cSYinan Xu    ZeroExt(src1(63, 31), XLEN),
32088825c5cSYinan Xu    ZeroExt(src1(63, 32), XLEN)
32188825c5cSYinan Xu  ))
322a792bcf1SYinan Xu  // TODO: use decoder or other libraries to optimize timing
323a792bcf1SYinan Xu  // Now we assume shadd has the worst timing.
324675acc68SYinan Xu  addModule.io.src(0) := Mux(func(3), shaddSource(func(2, 1)),
325675acc68SYinan Xu    Mux(func(2), sraddSource(func(1, 0)),
326675acc68SYinan Xu    Mux(func(1), ZeroExt(src1(0), XLEN), wordMaskAddSource))
327a792bcf1SYinan Xu  )
328a792bcf1SYinan Xu  addModule.io.src(1) := src2
32988825c5cSYinan Xu  val add = addModule.io.add
330ee8ff153Szfw
331675acc68SYinan Xu  // sub
332184a1958Szfw  val sub  = subModule.io.sub
3332bd5334dSYinan Xu  subModule.io.src(0) := src1
3342bd5334dSYinan Xu  subModule.io.src(1) := src2
3357b441e5eSYinan Xu  val sltu    = !sub(XLEN)
336675acc68SYinan Xu  val slt     = src1(XLEN - 1) ^ src2(XLEN - 1) ^ sltu
337ee8ff153Szfw  val maxMin  = Mux(slt ^ func(0), src2, src1)
3387b441e5eSYinan Xu  val maxMinU = Mux(sltu ^ func(0), src2, src1)
339675acc68SYinan Xu  val compareRes = Mux(func(2), Mux(func(1), maxMin, maxMinU), Mux(func(1), slt, Mux(func(0), sltu, sub)))
340ee8ff153Szfw
341675acc68SYinan Xu  // logic
342675acc68SYinan Xu  val logicSrc2 = Mux(!func(5) && func(0), ~src2, src2)
343675acc68SYinan Xu  val and     = src1 & logicSrc2
344675acc68SYinan Xu  val or      = src1 | logicSrc2
345675acc68SYinan Xu  val xor     = src1 ^ logicSrc2
34673be64b3SJiawei Lin  val orcb    = Cat((0 until 8).map(i => Fill(8, src1(i * 8 + 7, i * 8).orR)).reverse)
347675acc68SYinan Xu  val orh48   = Cat(src1(63, 8), 0.U(8.W)) | src2
348675acc68SYinan Xu
349675acc68SYinan Xu  val sextb = SignExt(src1(7, 0), XLEN)
350675acc68SYinan Xu  val packh = Cat(src2(7,0), src1(7,0))
351675acc68SYinan Xu  val sexth = SignExt(src1(15, 0), XLEN)
352675acc68SYinan Xu  val packw = SignExt(Cat(src2(15, 0), src1(15, 0)), XLEN)
353675acc68SYinan Xu
35473be64b3SJiawei Lin  val revb = Cat((0 until 8).map(i => Reverse(src1(8 * i + 7, 8 * i))).reverse)
355675acc68SYinan Xu  val pack = Cat(src2(31, 0), src1(31, 0))
356675acc68SYinan Xu  val rev8 = Cat((0 until 8).map(i => src1(8 * i + 7, 8 * i)))
357675acc68SYinan Xu
358675acc68SYinan Xu  // branch
359ee8ff153Szfw  val branchOpTable = List(
360ee8ff153Szfw    ALUOpType.getBranchType(ALUOpType.beq)  -> !xor.orR,
361ee8ff153Szfw    ALUOpType.getBranchType(ALUOpType.blt)  -> slt,
362ee8ff153Szfw    ALUOpType.getBranchType(ALUOpType.bltu) -> sltu
363ee8ff153Szfw  )
364ee8ff153Szfw  val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func)
365ee8ff153Szfw
366184a1958Szfw  // Result Select
367184a1958Szfw  val shiftResSel = Module(new ShiftResultSelect)
368675acc68SYinan Xu  shiftResSel.io.func := func(3, 0)
369184a1958Szfw  shiftResSel.io.sll  := sll
370184a1958Szfw  shiftResSel.io.srl  := srl
371184a1958Szfw  shiftResSel.io.sra  := sra
37228c18878Szfw  shiftResSel.io.rol  := rol
37328c18878Szfw  shiftResSel.io.ror  := ror
374184a1958Szfw  shiftResSel.io.bclr := bclr
375184a1958Szfw  shiftResSel.io.binv := binv
376184a1958Szfw  shiftResSel.io.bset := bset
377184a1958Szfw  shiftResSel.io.bext := bext
378184a1958Szfw  val shiftRes = shiftResSel.io.shiftRes
37931ea8750SLinJiawei
38031ea8750SLinJiawei  val miscResSel = Module(new MiscResultSelect)
381675acc68SYinan Xu  miscResSel.io.func    := func(5, 0)
382ee8ff153Szfw  miscResSel.io.and     := and
383ee8ff153Szfw  miscResSel.io.or      := or
384ee8ff153Szfw  miscResSel.io.xor     := xor
385675acc68SYinan Xu  miscResSel.io.orcb    := orcb
38688825c5cSYinan Xu  miscResSel.io.orh48   := orh48
387ee8ff153Szfw  miscResSel.io.sextb   := sextb
388675acc68SYinan Xu  miscResSel.io.packh   := packh
389ee8ff153Szfw  miscResSel.io.sexth   := sexth
390675acc68SYinan Xu  miscResSel.io.packw   := packw
391675acc68SYinan Xu  miscResSel.io.revb    := revb
392ee8ff153Szfw  miscResSel.io.rev8    := rev8
393675acc68SYinan Xu  miscResSel.io.pack    := pack
39488825c5cSYinan Xu  miscResSel.io.src     := src1
39531ea8750SLinJiawei  val miscRes = miscResSel.io.miscRes
39631ea8750SLinJiawei
397184a1958Szfw  val wordResSel = Module(new WordResultSelect)
398184a1958Szfw  wordResSel.io.func := func
399184a1958Szfw  wordResSel.io.addw := addw
400184a1958Szfw  wordResSel.io.subw := subw
401184a1958Szfw  wordResSel.io.sllw := sllw
402184a1958Szfw  wordResSel.io.srlw := srlw
403184a1958Szfw  wordResSel.io.sraw := sraw
40428c18878Szfw  wordResSel.io.rolw := rolw
40528c18878Szfw  wordResSel.io.rorw := rorw
406184a1958Szfw  val wordRes = wordResSel.io.wordRes
407ee8ff153Szfw
40831ea8750SLinJiawei  val aluResSel = Module(new AluResSel)
409*4aa9ed34Sfdy  aluResSel.io.func := func(7, 4)
410184a1958Szfw  aluResSel.io.addRes := add
411184a1958Szfw  aluResSel.io.compareRes := compareRes
412ee8ff153Szfw  aluResSel.io.shiftRes := shiftRes
41331ea8750SLinJiawei  aluResSel.io.miscRes := miscRes
414184a1958Szfw  aluResSel.io.wordRes := wordRes
415*4aa9ed34Sfdy  aluResSel.io.vsetRes := vsetModule.io.res
41631ea8750SLinJiawei  val aluRes = aluResSel.io.aluRes
417e18c367fSLinJiawei
418e2203130SLinJiawei  io.result := aluRes
419e2203130SLinJiawei  io.taken := taken
420e2203130SLinJiawei  io.mispredict := (io.pred_taken ^ taken) && io.isBranch
421e2203130SLinJiawei}
422e2203130SLinJiawei
423adb5df20SYinan Xuclass Alu(implicit p: Parameters) extends FUWithRedirect {
424e2203130SLinJiawei
425675acc68SYinan Xu  val uop = io.in.bits.uop
426e2203130SLinJiawei
427675acc68SYinan Xu  val isBranch = ALUOpType.isBranch(io.in.bits.uop.ctrl.fuOpType)
428e2203130SLinJiawei  val dataModule = Module(new AluDataModule)
429e2203130SLinJiawei
430675acc68SYinan Xu  dataModule.io.src := io.in.bits.src.take(2)
431675acc68SYinan Xu  dataModule.io.func := io.in.bits.uop.ctrl.fuOpType
432e2203130SLinJiawei  dataModule.io.pred_taken := uop.cf.pred_taken
433e2203130SLinJiawei  dataModule.io.isBranch := isBranch
434*4aa9ed34Sfdy  dataModule.io.lsrc0 := uop.ctrl.lsrc(0)
435*4aa9ed34Sfdy  dataModule.io.ldest := uop.ctrl.ldest
436*4aa9ed34Sfdy  dataModule.io.vconfig := uop.ctrl.vconfig
437e2203130SLinJiawei
438e18c367fSLinJiawei  redirectOutValid := io.out.valid && isBranch
439151e3043SLinJiawei  redirectOut := DontCare
440bfb958a3SYinan Xu  redirectOut.level := RedirectLevel.flushAfter
4419aca92b9SYinan Xu  redirectOut.robIdx := uop.robIdx
442cde9280dSLinJiawei  redirectOut.ftqIdx := uop.cf.ftqPtr
443cde9280dSLinJiawei  redirectOut.ftqOffset := uop.cf.ftqOffset
444e2203130SLinJiawei  redirectOut.cfiUpdate.isMisPred := dataModule.io.mispredict
445e2203130SLinJiawei  redirectOut.cfiUpdate.taken := dataModule.io.taken
446cde9280dSLinJiawei  redirectOut.cfiUpdate.predTaken := uop.cf.pred_taken
447151e3043SLinJiawei
448e18c367fSLinJiawei  io.in.ready := io.out.ready
449675acc68SYinan Xu  io.out.valid := io.in.valid
450e18c367fSLinJiawei  io.out.bits.uop <> io.in.bits.uop
451e2203130SLinJiawei  io.out.bits.data := dataModule.io.result
452e18c367fSLinJiawei}
453