xref: /XiangShan/src/main/scala/xiangshan/backend/fu/Alu.scala (revision 0a6fa50eb85d82d4dccfa45a8d0be107f61bbae4)
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._
22ee8ff153Szfwimport 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)))
2828c18878Szfw    val srcw = Input(UInt((XLEN/2).W))
2928c18878Szfw    val add = Output(UInt(XLEN.W))
3028c18878Szfw    val addw = Output(UInt((XLEN/2).W))
3131ea8750SLinJiawei  })
3228c18878Szfw  io.add := io.src(0) + io.src(1)
3328c18878Szfw  io.addw := io.srcw + io.src(1)(31,0)
3431ea8750SLinJiawei}
3531ea8750SLinJiawei
362225d46eSJiawei Linclass SubModule(implicit p: Parameters) extends XSModule {
3731ea8750SLinJiawei  val io = IO(new Bundle() {
382bd5334dSYinan Xu    val src = Vec(2, Input(UInt(XLEN.W)))
39184a1958Szfw    val sub = Output(UInt((XLEN+1).W))
4031ea8750SLinJiawei  })
41184a1958Szfw  io.sub := (io.src(0) +& (~io.src(1)).asUInt()) + 1.U
4231ea8750SLinJiawei}
4331ea8750SLinJiawei
442225d46eSJiawei Linclass LeftShiftModule(implicit p: Parameters) extends XSModule {
4531ea8750SLinJiawei  val io = IO(new Bundle() {
4631ea8750SLinJiawei    val shamt = Input(UInt(6.W))
4728c18878Szfw    val revShamt = Input(UInt(6.W))
4831ea8750SLinJiawei    val sllSrc = Input(UInt(XLEN.W))
4931ea8750SLinJiawei    val sll = Output(UInt(XLEN.W))
5028c18878Szfw    val revSll = Output(UInt(XLEN.W))
5131ea8750SLinJiawei  })
52184a1958Szfw  io.sll := io.sllSrc << io.shamt
5328c18878Szfw  io.revSll := io.sllSrc << io.revShamt
54184a1958Szfw}
55184a1958Szfw
56184a1958Szfwclass LeftShiftWordModule(implicit p: Parameters) extends XSModule {
57184a1958Szfw  val io = IO(new Bundle() {
58184a1958Szfw    val shamt = Input(UInt(5.W))
5928c18878Szfw    val revShamt = Input(UInt(5.W))
60184a1958Szfw    val sllSrc = Input(UInt((XLEN/2).W))
61184a1958Szfw    val sllw = Output(UInt((XLEN/2).W))
6228c18878Szfw    val revSllw = Output(UInt((XLEN/2).W))
63184a1958Szfw  })
64184a1958Szfw  io.sllw := io.sllSrc << io.shamt
6528c18878Szfw  io.revSllw := io.sllSrc << io.revShamt
6631ea8750SLinJiawei}
6731ea8750SLinJiawei
682225d46eSJiawei Linclass RightShiftModule(implicit p: Parameters) extends XSModule {
6931ea8750SLinJiawei  val io = IO(new Bundle() {
7031ea8750SLinJiawei    val shamt = Input(UInt(6.W))
7128c18878Szfw    val revShamt = Input(UInt(6.W))
7231ea8750SLinJiawei    val srlSrc, sraSrc = Input(UInt(XLEN.W))
73184a1958Szfw    val srl, sra = Output(UInt(XLEN.W))
7428c18878Szfw    val revSrl = Output(UInt(XLEN.W))
7531ea8750SLinJiawei  })
76184a1958Szfw  io.srl  := io.srlSrc >> io.shamt
77184a1958Szfw  io.sra  := (io.sraSrc.asSInt() >> io.shamt).asUInt()
7828c18878Szfw  io.revSrl  := io.srlSrc >> io.revShamt
7931ea8750SLinJiawei}
8031ea8750SLinJiawei
81184a1958Szfwclass RightShiftWordModule(implicit p: Parameters) extends XSModule {
82ee8ff153Szfw  val io = IO(new Bundle() {
83184a1958Szfw    val shamt = Input(UInt(5.W))
8428c18878Szfw    val revShamt = Input(UInt(5.W))
85184a1958Szfw    val srlSrc, sraSrc = Input(UInt((XLEN/2).W))
86184a1958Szfw    val srlw, sraw = Output(UInt((XLEN/2).W))
8728c18878Szfw    val revSrlw = Output(UInt((XLEN/2).W))
88ee8ff153Szfw  })
89184a1958Szfw
90184a1958Szfw  io.srlw := io.srlSrc >> io.shamt
91184a1958Szfw  io.sraw := (io.sraSrc.asSInt() >> io.shamt).asUInt()
9228c18878Szfw  io.revSrlw := io.srlSrc >> io.revShamt
93ee8ff153Szfw}
94ee8ff153Szfw
95184a1958Szfw
962225d46eSJiawei Linclass MiscResultSelect(implicit p: Parameters) extends XSModule {
9731ea8750SLinJiawei  val io = IO(new Bundle() {
9831ea8750SLinJiawei    val func = Input(UInt())
99184a1958Szfw    val andn, orn, xnor, and, or, xor, sextb, sexth, zexth, rev8, orcb = Input(UInt(XLEN.W))
10031ea8750SLinJiawei    val miscRes = Output(UInt(XLEN.W))
10131ea8750SLinJiawei  })
102ee8ff153Szfw
103184a1958Szfw  val miscRes = ParallelMux(List(
104184a1958Szfw    ALUOpType.andn -> io.andn,
105184a1958Szfw    ALUOpType.and  -> io.and,
106184a1958Szfw    ALUOpType.orn  -> io.orn,
107184a1958Szfw    ALUOpType.or   -> io.or,
108184a1958Szfw    ALUOpType.xnor -> io.xnor,
109184a1958Szfw    ALUOpType.xor  -> io.xor,
110184a1958Szfw    ALUOpType.sext_b -> io.sextb,
111184a1958Szfw    ALUOpType.sext_h -> io.sexth,
112184a1958Szfw    ALUOpType.zext_h -> io.zexth,
113184a1958Szfw    ALUOpType.orc_b  -> io.orcb,
114184a1958Szfw    ALUOpType.rev8   -> io.rev8
115184a1958Szfw  ).map(x => (x._1(3, 0) === io.func(3, 0), x._2)))
116ee8ff153Szfw
117184a1958Szfw  io.miscRes := miscRes
11831ea8750SLinJiawei}
11931ea8750SLinJiawei
120ee8ff153Szfwclass ShiftResultSelect(implicit p: Parameters) extends XSModule {
121ee8ff153Szfw  val io = IO(new Bundle() {
122ee8ff153Szfw    val func = Input(UInt())
12328c18878Szfw    val sll, srl, sra, rol, ror, bclr, bset, binv, bext = Input(UInt(XLEN.W))
124ee8ff153Szfw    val shiftRes = Output(UInt(XLEN.W))
125ee8ff153Szfw  })
126ee8ff153Szfw
127184a1958Szfw  val leftBit  = Mux(io.func(1), io.binv, Mux(io.func(0), io.bset, io.bclr))
128184a1958Szfw  val leftRes  = Mux(io.func(2), leftBit, io.sll)
129184a1958Szfw  val rightRes = Mux(io.func(2), io.sra, Mux(io.func(1), io.bext, io.srl))
130ee8ff153Szfw
13128c18878Szfw  io.shiftRes := Mux(io.func(4), Mux(io.func(3), io.ror, io.rol), Mux(io.func(3), rightRes, leftRes))
132184a1958Szfw}
133ee8ff153Szfw
134184a1958Szfwclass WordResultSelect(implicit p: Parameters) extends XSModule {
135184a1958Szfw  val io = IO(new Bundle() {
136184a1958Szfw    val func = Input(UInt())
13728c18878Szfw    val sllw, srlw, sraw, rolw, rorw, addw, subw = Input(UInt((XLEN/2).W))
138184a1958Szfw    val wordRes = Output(UInt(XLEN.W))
139184a1958Szfw  })
140ee8ff153Szfw
141184a1958Szfw  val addsubRes = Mux(io.func(6), io.subw, io.addw)
14228c18878Szfw  val shiftRes = Mux(io.func(4),
14328c18878Szfw                  Mux(io.func(3), io.rorw, io.rolw),
144184a1958Szfw                  Mux(io.func(3),
145184a1958Szfw                    Mux(io.func(2), io.sraw, io.srlw),
146184a1958Szfw                    io.sllw))
147184a1958Szfw  val wordRes = Mux(io.func(6,5) === 2.U, shiftRes, addsubRes)
148184a1958Szfw  io.wordRes := SignExt(wordRes, XLEN)
149ee8ff153Szfw}
150ee8ff153Szfw
151ee8ff153Szfw
1522225d46eSJiawei Linclass AluResSel(implicit p: Parameters) extends XSModule {
15331ea8750SLinJiawei  val io = IO(new Bundle() {
15431ea8750SLinJiawei    val func = Input(UInt())
155184a1958Szfw    val addRes, shiftRes, miscRes, compareRes, wordRes = Input(UInt(XLEN.W))
15631ea8750SLinJiawei    val aluRes = Output(UInt(XLEN.W))
15731ea8750SLinJiawei  })
158ee8ff153Szfw
159184a1958Szfw  val res = Mux(io.func(7), io.wordRes, Mux(io.func(6),
160184a1958Szfw    Mux(io.func(5), io.compareRes, io.shiftRes),
161184a1958Szfw    Mux(io.func(5), io.addRes, io.miscRes)
162184a1958Szfw  ))
163184a1958Szfw  io.aluRes := res
16431ea8750SLinJiawei}
16531ea8750SLinJiawei
1662225d46eSJiawei Linclass AluDataModule(implicit p: Parameters) extends XSModule {
167e2203130SLinJiawei  val io = IO(new Bundle() {
1682bd5334dSYinan Xu    val src = Vec(2, Input(UInt(XLEN.W)))
169e2203130SLinJiawei    val func = Input(FuOpType())
170e2203130SLinJiawei    val pred_taken, isBranch = Input(Bool())
171e2203130SLinJiawei    val result = Output(UInt(XLEN.W))
172e2203130SLinJiawei    val taken, mispredict = Output(Bool())
173e2203130SLinJiawei  })
1742bd5334dSYinan Xu  val (src1, src2, func) = (io.src(0), io.src(1), io.func)
175e18c367fSLinJiawei
176184a1958Szfw  val isW = ALUOpType.isWordOp(func)
177ee8ff153Szfw
178184a1958Szfw  val addModule = Module(new AddModule)
179184a1958Szfw  val shaddShamt = func(2,1)
180184a1958Szfw  val add  = addModule.io.add
18128c18878Szfw  val addw = addModule.io.addw
18228c18878Szfw  addModule.io.src(0) := (Cat(Fill(32, func(0)), Fill(32,1.U)) & src1) << shaddShamt
183184a1958Szfw  addModule.io.src(1) := src2
18428c18878Szfw  addModule.io.srcw := src1(31,0)
18528c18878Szfw
18628c18878Szfw
187ee8ff153Szfw
18831ea8750SLinJiawei  val subModule = Module(new SubModule)
189184a1958Szfw  val sub  = subModule.io.sub
190184a1958Szfw  val subw = subModule.io.sub
1912bd5334dSYinan Xu  subModule.io.src(0) := src1
1922bd5334dSYinan Xu  subModule.io.src(1) := src2
193e18c367fSLinJiawei
194184a1958Szfw  val shamt = src2(5, 0)
195184a1958Szfw  val revShamt = ~src2(5,0) + 1.U
196ee8ff153Szfw
197184a1958Szfw  val leftShiftModule = Module(new LeftShiftModule)
198184a1958Szfw  val sll = leftShiftModule.io.sll
19928c18878Szfw  val revSll = leftShiftModule.io.revSll
20028c18878Szfw  leftShiftModule.io.sllSrc := Cat(Fill(32, func(0)), Fill(32,1.U)) & src1
20128c18878Szfw  leftShiftModule.io.shamt := shamt
20228c18878Szfw  leftShiftModule.io.revShamt := revShamt
203184a1958Szfw
204184a1958Szfw  val leftShiftWordModule = Module(new LeftShiftWordModule)
205184a1958Szfw  val sllw = leftShiftWordModule.io.sllw
20628c18878Szfw  val revSllw = leftShiftWordModule.io.revSllw
207184a1958Szfw  leftShiftWordModule.io.sllSrc := src1
20828c18878Szfw  leftShiftWordModule.io.shamt := shamt
20928c18878Szfw  leftShiftWordModule.io.revShamt := revShamt
210184a1958Szfw
211184a1958Szfw  val rightShiftModule = Module(new RightShiftModule)
212184a1958Szfw  val srl = rightShiftModule.io.srl
21328c18878Szfw  val revSrl = rightShiftModule.io.revSrl
214184a1958Szfw  val sra = rightShiftModule.io.sra
21528c18878Szfw  rightShiftModule.io.shamt := shamt
21628c18878Szfw  rightShiftModule.io.revShamt := revShamt
217184a1958Szfw  rightShiftModule.io.srlSrc := src1
21828c18878Szfw  rightShiftModule.io.sraSrc := src1
219184a1958Szfw
220184a1958Szfw  val rightShiftWordModule = Module(new RightShiftWordModule)
221184a1958Szfw  val srlw = rightShiftWordModule.io.srlw
22228c18878Szfw  val revSrlw = rightShiftWordModule.io.revSrlw
223184a1958Szfw  val sraw = rightShiftWordModule.io.sraw
22428c18878Szfw  rightShiftWordModule.io.shamt := shamt
22528c18878Szfw  rightShiftWordModule.io.revShamt := revShamt
226184a1958Szfw  rightShiftWordModule.io.srlSrc := src1
227184a1958Szfw  rightShiftWordModule.io.sraSrc := src1
228184a1958Szfw
22928c18878Szfw  val rol = revSrl | sll
23028c18878Szfw  val ror = srl | revSll
23128c18878Szfw  val rolw = revSrlw | sllw
23228c18878Szfw  val rorw = srlw | revSllw
233184a1958Szfw
234184a1958Szfw  val bitShift = 1.U << src2(5, 0)
235184a1958Szfw  val bset = src1 | bitShift
236184a1958Szfw  val bclr = src1 & ~bitShift
237184a1958Szfw  val binv = src1 ^ bitShift
238184a1958Szfw  val bext = srl(0)
239184a1958Szfw
240*0a6fa50eSzfw  val andn    = src1 & ~src2
241*0a6fa50eSzfw  val orn     = src1 | ~src2
242*0a6fa50eSzfw  val xnor    = src1 ^ ~src2
243*0a6fa50eSzfw  val and     = src1 & src2
244*0a6fa50eSzfw  val or      = src1 | src2
245*0a6fa50eSzfw  val xor     = src1 ^ src2
246184a1958Szfw  val sgtu    = sub(XLEN)
247184a1958Szfw  val sltu    = !sgtu
248ee8ff153Szfw  val slt     = xor(XLEN-1) ^ sltu
24928c18878Szfw  // val maxMin  = Mux(slt ^ func(0), src2, src1)
25028c18878Szfw  // val maxMinU = Mux(sltu^ func(0), src2, src1)
251ee8ff153Szfw  val maxMin  = Mux(slt ^ func(0), src2, src1)
25228c18878Szfw  val maxMinU = Mux((sgtu && func(0)) || ~(sgtu && func(0)), src2, src1)
253ee8ff153Szfw  val sextb   = SignExt(src1(7, 0), XLEN)
254ee8ff153Szfw  val sexth   = SignExt(src1(15, 0), XLEN)
255ee8ff153Szfw  val zexth   = ZeroExt(src1(15, 0), XLEN)
256ee8ff153Szfw  val rev8    = Cat(src1(7,0), src1(15,8), src1(23,16), src1(31,24),
257ee8ff153Szfw                    src1(39,32), src1(47,40), src1(55,48), src1(63,56))
258ee8ff153Szfw  val orcb    = Cat(Reverse(src1(63,56)), Reverse(src1(55,48)), Reverse(src1(47,40)), Reverse(src1(39,32)),
259ee8ff153Szfw                    Reverse(src1(31,24)), Reverse(src1(23,16)), Reverse(src1(15,8)), Reverse(src1(7,0)))
260ee8ff153Szfw
261ee8ff153Szfw  val branchOpTable = List(
262ee8ff153Szfw    ALUOpType.getBranchType(ALUOpType.beq)  -> !xor.orR,
263ee8ff153Szfw    ALUOpType.getBranchType(ALUOpType.blt)  -> slt,
264ee8ff153Szfw    ALUOpType.getBranchType(ALUOpType.bltu) -> sltu
265ee8ff153Szfw  )
266ee8ff153Szfw  val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func)
267ee8ff153Szfw
268ee8ff153Szfw
269184a1958Szfw  // Result Select
2703ef996e9SLinJiawei
271184a1958Szfw  val compareRes = Mux(func(2), Mux(func(1), maxMin, maxMinU), Mux(func(1), slt, Mux(func(0), sltu, sub)))
272ee8ff153Szfw
273184a1958Szfw  val shiftResSel = Module(new ShiftResultSelect)
274184a1958Szfw  shiftResSel.io.func := func(4,0)
275184a1958Szfw  shiftResSel.io.sll  := sll
276184a1958Szfw  shiftResSel.io.srl  := srl
277184a1958Szfw  shiftResSel.io.sra  := sra
27828c18878Szfw  shiftResSel.io.rol  := rol
27928c18878Szfw  shiftResSel.io.ror  := ror
280184a1958Szfw  shiftResSel.io.bclr := bclr
281184a1958Szfw  shiftResSel.io.binv := binv
282184a1958Szfw  shiftResSel.io.bset := bset
283184a1958Szfw  shiftResSel.io.bext := bext
284184a1958Szfw  val shiftRes = shiftResSel.io.shiftRes
28531ea8750SLinJiawei
28631ea8750SLinJiawei  val miscResSel = Module(new MiscResultSelect)
287184a1958Szfw  miscResSel.io.func    := func(3, 0)
288ee8ff153Szfw  miscResSel.io.andn    := andn
289ee8ff153Szfw  miscResSel.io.orn     := orn
290ee8ff153Szfw  miscResSel.io.xnor    := xnor
291ee8ff153Szfw  miscResSel.io.and     := and
292ee8ff153Szfw  miscResSel.io.or      := or
293ee8ff153Szfw  miscResSel.io.xor     := xor
294ee8ff153Szfw  miscResSel.io.sextb   := sextb
295ee8ff153Szfw  miscResSel.io.sexth   := sexth
296ee8ff153Szfw  miscResSel.io.zexth   := zexth
297ee8ff153Szfw  miscResSel.io.rev8    := rev8
298ee8ff153Szfw  miscResSel.io.orcb    := orcb
29931ea8750SLinJiawei  val miscRes = miscResSel.io.miscRes
30031ea8750SLinJiawei
301184a1958Szfw  val wordResSel = Module(new WordResultSelect)
302184a1958Szfw  wordResSel.io.func := func
303184a1958Szfw  wordResSel.io.addw := addw
304184a1958Szfw  wordResSel.io.subw := subw
305184a1958Szfw  wordResSel.io.sllw := sllw
306184a1958Szfw  wordResSel.io.srlw := srlw
307184a1958Szfw  wordResSel.io.sraw := sraw
30828c18878Szfw  wordResSel.io.rolw := rolw
30928c18878Szfw  wordResSel.io.rorw := rorw
310184a1958Szfw  val wordRes = wordResSel.io.wordRes
311ee8ff153Szfw
31231ea8750SLinJiawei  val aluResSel = Module(new AluResSel)
31331ea8750SLinJiawei  aluResSel.io.func := func
314184a1958Szfw  aluResSel.io.addRes := add
315184a1958Szfw  aluResSel.io.compareRes := compareRes
316ee8ff153Szfw  aluResSel.io.shiftRes := shiftRes
31731ea8750SLinJiawei  aluResSel.io.miscRes := miscRes
318184a1958Szfw  aluResSel.io.wordRes := wordRes
31931ea8750SLinJiawei  val aluRes = aluResSel.io.aluRes
320e18c367fSLinJiawei
321e2203130SLinJiawei  io.result := aluRes
322e2203130SLinJiawei  io.taken := taken
323e2203130SLinJiawei  io.mispredict := (io.pred_taken ^ taken) && io.isBranch
324e2203130SLinJiawei}
325e2203130SLinJiawei
326adb5df20SYinan Xuclass Alu(implicit p: Parameters) extends FUWithRedirect {
327e2203130SLinJiawei
328e2203130SLinJiawei  val (src1, src2, func, pc, uop) = (
329e2203130SLinJiawei    io.in.bits.src(0),
330e2203130SLinJiawei    io.in.bits.src(1),
331e2203130SLinJiawei    io.in.bits.uop.ctrl.fuOpType,
332e2203130SLinJiawei    SignExt(io.in.bits.uop.cf.pc, AddrBits),
333e2203130SLinJiawei    io.in.bits.uop
334e2203130SLinJiawei  )
335e2203130SLinJiawei
336e2203130SLinJiawei  val valid = io.in.valid
337e2203130SLinJiawei  val isBranch = ALUOpType.isBranch(func)
338e2203130SLinJiawei  val dataModule = Module(new AluDataModule)
339e2203130SLinJiawei
3402bd5334dSYinan Xu  dataModule.io.src(0) := src1
3412bd5334dSYinan Xu  dataModule.io.src(1) := src2
342e2203130SLinJiawei  dataModule.io.func := func
343e2203130SLinJiawei  dataModule.io.pred_taken := uop.cf.pred_taken
344e2203130SLinJiawei  dataModule.io.isBranch := isBranch
345e2203130SLinJiawei
346e18c367fSLinJiawei  redirectOutValid := io.out.valid && isBranch
347151e3043SLinJiawei  redirectOut := DontCare
348bfb958a3SYinan Xu  redirectOut.level := RedirectLevel.flushAfter
349e18c367fSLinJiawei  redirectOut.roqIdx := uop.roqIdx
350cde9280dSLinJiawei  redirectOut.ftqIdx := uop.cf.ftqPtr
351cde9280dSLinJiawei  redirectOut.ftqOffset := uop.cf.ftqOffset
352e2203130SLinJiawei  redirectOut.cfiUpdate.isMisPred := dataModule.io.mispredict
353e2203130SLinJiawei  redirectOut.cfiUpdate.taken := dataModule.io.taken
354cde9280dSLinJiawei  redirectOut.cfiUpdate.predTaken := uop.cf.pred_taken
355151e3043SLinJiawei
356e18c367fSLinJiawei  io.in.ready := io.out.ready
357e18c367fSLinJiawei  io.out.valid := valid
358e18c367fSLinJiawei  io.out.bits.uop <> io.in.bits.uop
359e2203130SLinJiawei  io.out.bits.data := dataModule.io.result
360e18c367fSLinJiawei}
361