xref: /XiangShan/src/main/scala/xiangshan/backend/fu/Alu.scala (revision 184a195889c871432da1d39e2885d0af812be3fe)
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)))
28*184a1958Szfw    val add = Output(UInt((XLEN+1).W))
2931ea8750SLinJiawei  })
30*184a1958Szfw  io.add := 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)))
36*184a1958Szfw    val sub = Output(UInt((XLEN+1).W))
3731ea8750SLinJiawei  })
38*184a1958Szfw  io.sub := (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  })
47*184a1958Szfw  io.sll := io.sllSrc << io.shamt
48*184a1958Szfw}
49*184a1958Szfw
50*184a1958Szfwclass LeftShiftWordModule(implicit p: Parameters) extends XSModule {
51*184a1958Szfw  val io = IO(new Bundle() {
52*184a1958Szfw    val shamt = Input(UInt(5.W))
53*184a1958Szfw    val sllSrc = Input(UInt((XLEN/2).W))
54*184a1958Szfw    val sllw = Output(UInt((XLEN/2).W))
55*184a1958Szfw  })
56*184a1958Szfw  io.sllw := io.sllSrc << io.shamt
5731ea8750SLinJiawei}
5831ea8750SLinJiawei
592225d46eSJiawei Linclass RightShiftModule(implicit p: Parameters) extends XSModule {
6031ea8750SLinJiawei  val io = IO(new Bundle() {
6131ea8750SLinJiawei    val shamt = Input(UInt(6.W))
6231ea8750SLinJiawei    val srlSrc, sraSrc = Input(UInt(XLEN.W))
63*184a1958Szfw    val srl, sra = Output(UInt(XLEN.W))
6431ea8750SLinJiawei  })
65*184a1958Szfw  io.srl  := io.srlSrc >> io.shamt
66*184a1958Szfw  io.sra  := (io.sraSrc.asSInt() >> io.shamt).asUInt()
6731ea8750SLinJiawei}
6831ea8750SLinJiawei
69*184a1958Szfwclass RightShiftWordModule(implicit p: Parameters) extends XSModule {
70ee8ff153Szfw  val io = IO(new Bundle() {
71*184a1958Szfw    val shamt = Input(UInt(5.W))
72*184a1958Szfw    val srlSrc, sraSrc = Input(UInt((XLEN/2).W))
73*184a1958Szfw    val srlw, sraw = Output(UInt((XLEN/2).W))
74ee8ff153Szfw  })
75*184a1958Szfw
76*184a1958Szfw  io.srlw := io.srlSrc >> io.shamt
77*184a1958Szfw  io.sraw := (io.sraSrc.asSInt() >> io.shamt).asUInt()
78ee8ff153Szfw}
79ee8ff153Szfw
80*184a1958Szfw
812225d46eSJiawei Linclass MiscResultSelect(implicit p: Parameters) extends XSModule {
8231ea8750SLinJiawei  val io = IO(new Bundle() {
8331ea8750SLinJiawei    val func = Input(UInt())
84*184a1958Szfw    val andn, orn, xnor, and, or, xor, sextb, sexth, zexth, rev8, orcb = Input(UInt(XLEN.W))
8531ea8750SLinJiawei    val miscRes = Output(UInt(XLEN.W))
8631ea8750SLinJiawei  })
87ee8ff153Szfw
88*184a1958Szfw  val miscRes = ParallelMux(List(
89*184a1958Szfw    ALUOpType.andn -> io.andn,
90*184a1958Szfw    ALUOpType.and  -> io.and,
91*184a1958Szfw    ALUOpType.orn  -> io.orn,
92*184a1958Szfw    ALUOpType.or   -> io.or,
93*184a1958Szfw    ALUOpType.xnor -> io.xnor,
94*184a1958Szfw    ALUOpType.xor  -> io.xor,
95*184a1958Szfw    ALUOpType.sext_b -> io.sextb,
96*184a1958Szfw    ALUOpType.sext_h -> io.sexth,
97*184a1958Szfw    ALUOpType.zext_h -> io.zexth,
98*184a1958Szfw    ALUOpType.orc_b  -> io.orcb,
99*184a1958Szfw    ALUOpType.rev8   -> io.rev8
100*184a1958Szfw  ).map(x => (x._1(3, 0) === io.func(3, 0), x._2)))
101ee8ff153Szfw
102*184a1958Szfw  io.miscRes := miscRes
10331ea8750SLinJiawei}
10431ea8750SLinJiawei
105ee8ff153Szfwclass ShiftResultSelect(implicit p: Parameters) extends XSModule {
106ee8ff153Szfw  val io = IO(new Bundle() {
107ee8ff153Szfw    val func = Input(UInt())
108*184a1958Szfw    val sll, srl, sra, rot, bclr, bset, binv, bext = Input(UInt(XLEN.W))
109ee8ff153Szfw    val shiftRes = Output(UInt(XLEN.W))
110ee8ff153Szfw  })
111ee8ff153Szfw
112*184a1958Szfw  val leftBit  = Mux(io.func(1), io.binv, Mux(io.func(0), io.bset, io.bclr))
113*184a1958Szfw  val leftRes  = Mux(io.func(2), leftBit, io.sll)
114*184a1958Szfw  val rightRes = Mux(io.func(2), io.sra, Mux(io.func(1), io.bext, io.srl))
115ee8ff153Szfw
116*184a1958Szfw  io.shiftRes := Mux(io.func(4), io.rot, Mux(io.func(3), rightRes, leftRes))
117*184a1958Szfw}
118ee8ff153Szfw
119*184a1958Szfwclass WordResultSelect(implicit p: Parameters) extends XSModule {
120*184a1958Szfw  val io = IO(new Bundle() {
121*184a1958Szfw    val func = Input(UInt())
122*184a1958Szfw    val sllw, srlw, sraw, rotw, addw, subw = Input(UInt((XLEN/2).W))
123*184a1958Szfw    val wordRes = Output(UInt(XLEN.W))
124*184a1958Szfw  })
125ee8ff153Szfw
126*184a1958Szfw  val addsubRes = Mux(io.func(6), io.subw, io.addw)
127*184a1958Szfw  val shiftRes = Mux(io.func(4), io.rotw,
128*184a1958Szfw                  Mux(io.func(3),
129*184a1958Szfw                    Mux(io.func(2), io.sraw, io.srlw),
130*184a1958Szfw                    io.sllw))
131*184a1958Szfw  val wordRes = Mux(io.func(6,5) === 2.U, shiftRes, addsubRes)
132*184a1958Szfw  io.wordRes := SignExt(wordRes, XLEN)
133ee8ff153Szfw}
134ee8ff153Szfw
135ee8ff153Szfw
1362225d46eSJiawei Linclass AluResSel(implicit p: Parameters) extends XSModule {
13731ea8750SLinJiawei  val io = IO(new Bundle() {
13831ea8750SLinJiawei    val func = Input(UInt())
139*184a1958Szfw    val addRes, shiftRes, miscRes, compareRes, wordRes = Input(UInt(XLEN.W))
14031ea8750SLinJiawei    val aluRes = Output(UInt(XLEN.W))
14131ea8750SLinJiawei  })
142ee8ff153Szfw
143*184a1958Szfw  val res = Mux(io.func(7), io.wordRes, Mux(io.func(6),
144*184a1958Szfw    Mux(io.func(5), io.compareRes, io.shiftRes),
145*184a1958Szfw    Mux(io.func(5), io.addRes, io.miscRes)
146*184a1958Szfw  ))
147*184a1958Szfw  io.aluRes := res
14831ea8750SLinJiawei}
14931ea8750SLinJiawei
1502225d46eSJiawei Linclass AluDataModule(implicit p: Parameters) extends XSModule {
151e2203130SLinJiawei  val io = IO(new Bundle() {
1522bd5334dSYinan Xu    val src = Vec(2, Input(UInt(XLEN.W)))
153e2203130SLinJiawei    val func = Input(FuOpType())
154e2203130SLinJiawei    val pred_taken, isBranch = Input(Bool())
155e2203130SLinJiawei    val result = Output(UInt(XLEN.W))
156e2203130SLinJiawei    val taken, mispredict = Output(Bool())
157e2203130SLinJiawei  })
1582bd5334dSYinan Xu  val (src1, src2, func) = (io.src(0), io.src(1), io.func)
159e18c367fSLinJiawei
160*184a1958Szfw  val isW = ALUOpType.isWordOp(func)
161ee8ff153Szfw
162*184a1958Szfw  val addModule = Module(new AddModule)
163*184a1958Szfw  val shaddShamt = func(2,1)
164*184a1958Szfw  val add  = addModule.io.add
165*184a1958Szfw  val addw = addModule.io.add
166*184a1958Szfw  addModule.io.src(0) := Mux(func(0),src1(31,0), src1) << shaddShamt
167*184a1958Szfw  addModule.io.src(1) := src2
168ee8ff153Szfw
16931ea8750SLinJiawei  val subModule = Module(new SubModule)
170*184a1958Szfw  val sub  = subModule.io.sub
171*184a1958Szfw  val subw = subModule.io.sub
1722bd5334dSYinan Xu  subModule.io.src(0) := src1
1732bd5334dSYinan Xu  subModule.io.src(1) := src2
174e18c367fSLinJiawei
175*184a1958Szfw  val shamt = src2(5, 0)
176*184a1958Szfw  val revShamt = ~src2(5,0) + 1.U
177ee8ff153Szfw
178*184a1958Szfw  val leftShiftModule = Module(new LeftShiftModule)
179*184a1958Szfw  val sll = leftShiftModule.io.sll
180*184a1958Szfw  leftShiftModule.io.sllSrc := Mux(func(0), src1(31,0), src1)
181*184a1958Szfw  leftShiftModule.io.shamt := Mux(func(3), revShamt, shamt)
182*184a1958Szfw
183*184a1958Szfw  val leftShiftWordModule = Module(new LeftShiftWordModule)
184*184a1958Szfw  val sllw = leftShiftWordModule.io.sllw
185*184a1958Szfw  leftShiftWordModule.io.sllSrc := src1
186*184a1958Szfw  leftShiftWordModule.io.shamt := Mux(func(3), revShamt, shamt)
187*184a1958Szfw
188*184a1958Szfw  val rightShiftModule = Module(new RightShiftModule)
189*184a1958Szfw  val srl = rightShiftModule.io.srl
190*184a1958Szfw  val sra = rightShiftModule.io.sra
191*184a1958Szfw  rightShiftModule.io.shamt := Mux(func(3), shamt, revShamt)
192*184a1958Szfw  rightShiftModule.io.srlSrc := src1
193*184a1958Szfw  rightShiftModule.io.sraSrc := src1   // 这里可以优化成 不过Mux的src1
194*184a1958Szfw
195*184a1958Szfw  val rightShiftWordModule = Module(new RightShiftWordModule)
196*184a1958Szfw  val srlw = rightShiftWordModule.io.srlw
197*184a1958Szfw  val sraw = rightShiftWordModule.io.sraw
198*184a1958Szfw  rightShiftWordModule.io.shamt := Mux(func(3), shamt, revShamt)
199*184a1958Szfw  rightShiftWordModule.io.srlSrc := src1
200*184a1958Szfw  rightShiftWordModule.io.sraSrc := src1
201*184a1958Szfw
202*184a1958Szfw  val rot = srl | sll
203*184a1958Szfw  val rotw = srlw | sllw
204*184a1958Szfw
205*184a1958Szfw  val bitShift = 1.U << src2(5, 0)
206*184a1958Szfw  val bset = src1 | bitShift
207*184a1958Szfw  val bclr = src1 & ~bitShift
208*184a1958Szfw  val binv = src1 ^ bitShift
209*184a1958Szfw  val bext = srl(0)
210*184a1958Szfw
211ee8ff153Szfw  val andn    = ~(src1 & src2)
212ee8ff153Szfw  val orn     = ~(src1 | src2)
213ee8ff153Szfw  val xnor    = ~(src1 ^ src2)
214ee8ff153Szfw  val and     = ~andn
215ee8ff153Szfw  val or      = ~orn
216ee8ff153Szfw  val xor     = ~xnor
217*184a1958Szfw  val sgtu    = sub(XLEN)
218*184a1958Szfw  val sltu    = !sgtu
219ee8ff153Szfw  val slt     = xor(XLEN-1) ^ sltu
220ee8ff153Szfw  val maxMin  = Mux(slt ^ func(0), src2, src1)
221ee8ff153Szfw  val maxMinU = Mux(sltu^ func(0), src2, src1)
222ee8ff153Szfw  val sextb   = SignExt(src1(7, 0), XLEN)
223ee8ff153Szfw  val sexth   = SignExt(src1(15, 0), XLEN)
224ee8ff153Szfw  val zexth   = ZeroExt(src1(15, 0), XLEN)
225ee8ff153Szfw  val rev8    = Cat(src1(7,0), src1(15,8), src1(23,16), src1(31,24),
226ee8ff153Szfw                    src1(39,32), src1(47,40), src1(55,48), src1(63,56))
227ee8ff153Szfw  val orcb    = Cat(Reverse(src1(63,56)), Reverse(src1(55,48)), Reverse(src1(47,40)), Reverse(src1(39,32)),
228ee8ff153Szfw                    Reverse(src1(31,24)), Reverse(src1(23,16)), Reverse(src1(15,8)), Reverse(src1(7,0)))
229ee8ff153Szfw
230ee8ff153Szfw  val branchOpTable = List(
231ee8ff153Szfw    ALUOpType.getBranchType(ALUOpType.beq)  -> !xor.orR,
232ee8ff153Szfw    ALUOpType.getBranchType(ALUOpType.blt)  -> slt,
233ee8ff153Szfw    ALUOpType.getBranchType(ALUOpType.bltu) -> sltu
234ee8ff153Szfw  )
235ee8ff153Szfw  val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func)
236ee8ff153Szfw
237ee8ff153Szfw
238*184a1958Szfw  // Result Select
2393ef996e9SLinJiawei
240*184a1958Szfw  val compareRes = Mux(func(2), Mux(func(1), maxMin, maxMinU), Mux(func(1), slt, Mux(func(0), sltu, sub)))
241ee8ff153Szfw
242*184a1958Szfw  val shiftResSel = Module(new ShiftResultSelect)
243*184a1958Szfw  shiftResSel.io.func := func(4,0)
244*184a1958Szfw  shiftResSel.io.sll  := sll
245*184a1958Szfw  shiftResSel.io.srl  := srl
246*184a1958Szfw  shiftResSel.io.sra  := sra
247*184a1958Szfw  shiftResSel.io.rot  := rot
248*184a1958Szfw  shiftResSel.io.bclr := bclr
249*184a1958Szfw  shiftResSel.io.binv := binv
250*184a1958Szfw  shiftResSel.io.bset := bset
251*184a1958Szfw  shiftResSel.io.bext := bext
252*184a1958Szfw  val shiftRes = shiftResSel.io.shiftRes
25331ea8750SLinJiawei
25431ea8750SLinJiawei  val miscResSel = Module(new MiscResultSelect)
255*184a1958Szfw  miscResSel.io.func    := func(3, 0)
256ee8ff153Szfw  miscResSel.io.andn    := andn
257ee8ff153Szfw  miscResSel.io.orn     := orn
258ee8ff153Szfw  miscResSel.io.xnor    := xnor
259ee8ff153Szfw  miscResSel.io.and     := and
260ee8ff153Szfw  miscResSel.io.or      := or
261ee8ff153Szfw  miscResSel.io.xor     := xor
262ee8ff153Szfw  miscResSel.io.sextb   := sextb
263ee8ff153Szfw  miscResSel.io.sexth   := sexth
264ee8ff153Szfw  miscResSel.io.zexth   := zexth
265ee8ff153Szfw  miscResSel.io.rev8    := rev8
266ee8ff153Szfw  miscResSel.io.orcb    := orcb
26731ea8750SLinJiawei  val miscRes = miscResSel.io.miscRes
26831ea8750SLinJiawei
269*184a1958Szfw  val wordResSel = Module(new WordResultSelect)
270*184a1958Szfw  wordResSel.io.func := func
271*184a1958Szfw  wordResSel.io.addw := addw
272*184a1958Szfw  wordResSel.io.subw := subw
273*184a1958Szfw  wordResSel.io.sllw := sllw
274*184a1958Szfw  wordResSel.io.srlw := srlw
275*184a1958Szfw  wordResSel.io.sraw := sraw
276*184a1958Szfw  wordResSel.io.rotw := rotw
277*184a1958Szfw  val wordRes = wordResSel.io.wordRes
278ee8ff153Szfw
27931ea8750SLinJiawei  val aluResSel = Module(new AluResSel)
28031ea8750SLinJiawei  aluResSel.io.func := func
281*184a1958Szfw  aluResSel.io.addRes := add
282*184a1958Szfw  aluResSel.io.compareRes := compareRes
283ee8ff153Szfw  aluResSel.io.shiftRes := shiftRes
28431ea8750SLinJiawei  aluResSel.io.miscRes := miscRes
285*184a1958Szfw  aluResSel.io.wordRes := wordRes
28631ea8750SLinJiawei  val aluRes = aluResSel.io.aluRes
287e18c367fSLinJiawei
288e2203130SLinJiawei  io.result := aluRes
289e2203130SLinJiawei  io.taken := taken
290e2203130SLinJiawei  io.mispredict := (io.pred_taken ^ taken) && io.isBranch
291e2203130SLinJiawei}
292e2203130SLinJiawei
293adb5df20SYinan Xuclass Alu(implicit p: Parameters) extends FUWithRedirect {
294e2203130SLinJiawei
295e2203130SLinJiawei  val (src1, src2, func, pc, uop) = (
296e2203130SLinJiawei    io.in.bits.src(0),
297e2203130SLinJiawei    io.in.bits.src(1),
298e2203130SLinJiawei    io.in.bits.uop.ctrl.fuOpType,
299e2203130SLinJiawei    SignExt(io.in.bits.uop.cf.pc, AddrBits),
300e2203130SLinJiawei    io.in.bits.uop
301e2203130SLinJiawei  )
302e2203130SLinJiawei
303e2203130SLinJiawei  val valid = io.in.valid
304e2203130SLinJiawei  val isBranch = ALUOpType.isBranch(func)
305e2203130SLinJiawei  val dataModule = Module(new AluDataModule)
306e2203130SLinJiawei
3072bd5334dSYinan Xu  dataModule.io.src(0) := src1
3082bd5334dSYinan Xu  dataModule.io.src(1) := src2
309e2203130SLinJiawei  dataModule.io.func := func
310e2203130SLinJiawei  dataModule.io.pred_taken := uop.cf.pred_taken
311e2203130SLinJiawei  dataModule.io.isBranch := isBranch
312e2203130SLinJiawei
313e18c367fSLinJiawei  redirectOutValid := io.out.valid && isBranch
314151e3043SLinJiawei  redirectOut := DontCare
315bfb958a3SYinan Xu  redirectOut.level := RedirectLevel.flushAfter
316e18c367fSLinJiawei  redirectOut.roqIdx := uop.roqIdx
317cde9280dSLinJiawei  redirectOut.ftqIdx := uop.cf.ftqPtr
318cde9280dSLinJiawei  redirectOut.ftqOffset := uop.cf.ftqOffset
319e2203130SLinJiawei  redirectOut.cfiUpdate.isMisPred := dataModule.io.mispredict
320e2203130SLinJiawei  redirectOut.cfiUpdate.taken := dataModule.io.taken
321cde9280dSLinJiawei  redirectOut.cfiUpdate.predTaken := uop.cf.pred_taken
322151e3043SLinJiawei
323e18c367fSLinJiawei  io.in.ready := io.out.ready
324e18c367fSLinJiawei  io.out.valid := valid
325e18c367fSLinJiawei  io.out.bits.uop <> io.in.bits.uop
326e2203130SLinJiawei  io.out.bits.data := dataModule.io.result
327e18c367fSLinJiawei}
328