xref: /XiangShan/src/main/scala/xiangshan/backend/fu/Alu.scala (revision adb5df205ceac5d65d54830db3b061f71eb5180a)
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._
2231ea8750SLinJiaweiimport utils.{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
622225d46eSJiawei Linclass MiscResultSelect(implicit p: Parameters) extends XSModule {
6331ea8750SLinJiawei  val io = IO(new Bundle() {
6431ea8750SLinJiawei    val func = Input(UInt())
6531ea8750SLinJiawei    val sll, slt, sltu, xor, srl, or, and, sra = Input(UInt(XLEN.W))
6631ea8750SLinJiawei    val miscRes = Output(UInt(XLEN.W))
6731ea8750SLinJiawei
6831ea8750SLinJiawei  })
6931ea8750SLinJiawei  io.miscRes := ParallelMux(List(
7031ea8750SLinJiawei    ALUOpType.and  -> io.and,
7131ea8750SLinJiawei    ALUOpType.or   -> io.or,
7231ea8750SLinJiawei    ALUOpType.xor  -> io.xor,
7331ea8750SLinJiawei    ALUOpType.slt  -> ZeroExt(io.slt, XLEN),
7431ea8750SLinJiawei    ALUOpType.sltu -> ZeroExt(io.sltu, XLEN),
7531ea8750SLinJiawei    ALUOpType.srl  -> io.srl,
7631ea8750SLinJiawei    ALUOpType.sll  -> io.sll,
7731ea8750SLinJiawei    ALUOpType.sra  -> io.sra
7831ea8750SLinJiawei  ).map(x => (x._1 === io.func(3, 0), x._2)))
7931ea8750SLinJiawei}
8031ea8750SLinJiawei
812225d46eSJiawei Linclass AluResSel(implicit p: Parameters) extends XSModule {
8231ea8750SLinJiawei  val io = IO(new Bundle() {
8331ea8750SLinJiawei    val func = Input(UInt())
8431ea8750SLinJiawei    val isSub = Input(Bool())
8531ea8750SLinJiawei    val addRes, subRes, miscRes = Input(UInt(XLEN.W))
8631ea8750SLinJiawei    val aluRes = Output(UInt(XLEN.W))
8731ea8750SLinJiawei  })
8831ea8750SLinJiawei  val isAddSub = ALUOpType.isAddSub(io.func)
8931ea8750SLinJiawei  val res = Mux(ALUOpType.isAddSub(io.func),
9031ea8750SLinJiawei    Mux(io.isSub, io.subRes, io.addRes),
9131ea8750SLinJiawei    io.miscRes
9231ea8750SLinJiawei  )
9331ea8750SLinJiawei  val h32 = Mux(ALUOpType.isWordOp(io.func), Fill(32, res(31)), res(63, 32))
9431ea8750SLinJiawei  io.aluRes := Cat(h32, res(31, 0))
9531ea8750SLinJiawei}
9631ea8750SLinJiawei
972225d46eSJiawei Linclass AluDataModule(implicit p: Parameters) extends XSModule {
98e2203130SLinJiawei  val io = IO(new Bundle() {
992bd5334dSYinan Xu    val src = Vec(2, Input(UInt(XLEN.W)))
100e2203130SLinJiawei    val func = Input(FuOpType())
101e2203130SLinJiawei    val pred_taken, isBranch = Input(Bool())
102e2203130SLinJiawei    val result = Output(UInt(XLEN.W))
103e2203130SLinJiawei    val taken, mispredict = Output(Bool())
104e2203130SLinJiawei  })
1052bd5334dSYinan Xu  val (src1, src2, func) = (io.src(0), io.src(1), io.func)
106e18c367fSLinJiawei
107e18c367fSLinJiawei  val isAdderSub = (func =/= ALUOpType.add) && (func =/= ALUOpType.addw)
10831ea8750SLinJiawei  val addModule = Module(new AddModule)
1092bd5334dSYinan Xu  addModule.io.src(0) := src1
1102bd5334dSYinan Xu  addModule.io.src(1) := src2
11131ea8750SLinJiawei  val subModule = Module(new SubModule)
1122bd5334dSYinan Xu  subModule.io.src(0) := src1
1132bd5334dSYinan Xu  subModule.io.src(1) := src2
11431ea8750SLinJiawei  val addRes = addModule.io.out
11531ea8750SLinJiawei  val subRes = subModule.io.out
116e18c367fSLinJiawei  val xorRes = src1 ^ src2
1173ef996e9SLinJiawei  val sltu = !subRes(XLEN)
118e18c367fSLinJiawei  val slt = xorRes(XLEN-1) ^ sltu
119e18c367fSLinJiawei
12031ea8750SLinJiawei  val isW = ALUOpType.isWordOp(func)
1214a6ab1cdSLinJiawei  val shamt = Cat(!isW && src2(5), src2(4, 0))
1223ef996e9SLinJiawei
12331ea8750SLinJiawei  val leftShiftModule = Module(new LeftShiftModule)
12431ea8750SLinJiawei  leftShiftModule.io.sllSrc := src1
12531ea8750SLinJiawei  leftShiftModule.io.shamt := shamt
1263ef996e9SLinJiawei
12731ea8750SLinJiawei  val rightShiftModule = Module(new RightShiftModule)
12831ea8750SLinJiawei  rightShiftModule.io.shamt := shamt
12967630d0bSLinJiawei  rightShiftModule.io.srlSrc := src1
13067630d0bSLinJiawei  rightShiftModule.io.sraSrc := src1
1313ef996e9SLinJiawei
13231ea8750SLinJiawei  val sll = leftShiftModule.io.sll
13367630d0bSLinJiawei  val srl = Mux(isW, rightShiftModule.io.srl_w, rightShiftModule.io.srl_l)
13467630d0bSLinJiawei  val sra = Mux(isW, rightShiftModule.io.sra_w, rightShiftModule.io.sra_l)
13531ea8750SLinJiawei
13631ea8750SLinJiawei  val miscResSel = Module(new MiscResultSelect)
13731ea8750SLinJiawei  miscResSel.io.func := func(3, 0)
13831ea8750SLinJiawei  miscResSel.io.sll := sll
13931ea8750SLinJiawei  miscResSel.io.slt := ZeroExt(slt, XLEN)
14031ea8750SLinJiawei  miscResSel.io.sltu := ZeroExt(sltu, XLEN)
14131ea8750SLinJiawei  miscResSel.io.xor := xorRes
14231ea8750SLinJiawei  miscResSel.io.srl := srl
14331ea8750SLinJiawei  miscResSel.io.or := (src1 | src2)
14431ea8750SLinJiawei  miscResSel.io.and := (src1 & src2)
14531ea8750SLinJiawei  miscResSel.io.sra := sra
14631ea8750SLinJiawei
14731ea8750SLinJiawei  val miscRes = miscResSel.io.miscRes
14831ea8750SLinJiawei
14931ea8750SLinJiawei  val aluResSel = Module(new AluResSel)
15031ea8750SLinJiawei  aluResSel.io.func := func
15131ea8750SLinJiawei  aluResSel.io.isSub := isAdderSub
15231ea8750SLinJiawei  aluResSel.io.addRes := addRes
15331ea8750SLinJiawei  aluResSel.io.subRes := subRes
15431ea8750SLinJiawei  aluResSel.io.miscRes := miscRes
15531ea8750SLinJiawei  val aluRes = aluResSel.io.aluRes
156e18c367fSLinJiawei
157e18c367fSLinJiawei  val branchOpTable = List(
158e18c367fSLinJiawei    ALUOpType.getBranchType(ALUOpType.beq)  -> !xorRes.orR,
159e18c367fSLinJiawei    ALUOpType.getBranchType(ALUOpType.blt)  -> slt,
160e18c367fSLinJiawei    ALUOpType.getBranchType(ALUOpType.bltu) -> sltu
161e18c367fSLinJiawei  )
1626060732cSLinJiawei  val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func)
163e18c367fSLinJiawei
164e2203130SLinJiawei  io.result := aluRes
165e2203130SLinJiawei  io.taken := taken
166e2203130SLinJiawei  io.mispredict := (io.pred_taken ^ taken) && io.isBranch
167e2203130SLinJiawei}
168e2203130SLinJiawei
169*adb5df20SYinan Xuclass Alu(implicit p: Parameters) extends FUWithRedirect {
170e2203130SLinJiawei
171e2203130SLinJiawei  val (src1, src2, func, pc, uop) = (
172e2203130SLinJiawei    io.in.bits.src(0),
173e2203130SLinJiawei    io.in.bits.src(1),
174e2203130SLinJiawei    io.in.bits.uop.ctrl.fuOpType,
175e2203130SLinJiawei    SignExt(io.in.bits.uop.cf.pc, AddrBits),
176e2203130SLinJiawei    io.in.bits.uop
177e2203130SLinJiawei  )
178e2203130SLinJiawei
179e2203130SLinJiawei  val valid = io.in.valid
180e2203130SLinJiawei  val isBranch = ALUOpType.isBranch(func)
181e2203130SLinJiawei  val dataModule = Module(new AluDataModule)
182e2203130SLinJiawei
1832bd5334dSYinan Xu  dataModule.io.src(0) := src1
1842bd5334dSYinan Xu  dataModule.io.src(1) := src2
185e2203130SLinJiawei  dataModule.io.func := func
186e2203130SLinJiawei  dataModule.io.pred_taken := uop.cf.pred_taken
187e2203130SLinJiawei  dataModule.io.isBranch := isBranch
188e2203130SLinJiawei
189e18c367fSLinJiawei  redirectOutValid := io.out.valid && isBranch
190151e3043SLinJiawei  redirectOut := DontCare
191bfb958a3SYinan Xu  redirectOut.level := RedirectLevel.flushAfter
192e18c367fSLinJiawei  redirectOut.roqIdx := uop.roqIdx
193cde9280dSLinJiawei  redirectOut.ftqIdx := uop.cf.ftqPtr
194cde9280dSLinJiawei  redirectOut.ftqOffset := uop.cf.ftqOffset
195e2203130SLinJiawei  redirectOut.cfiUpdate.isMisPred := dataModule.io.mispredict
196e2203130SLinJiawei  redirectOut.cfiUpdate.taken := dataModule.io.taken
197cde9280dSLinJiawei  redirectOut.cfiUpdate.predTaken := uop.cf.pred_taken
198151e3043SLinJiawei
199e18c367fSLinJiawei  io.in.ready := io.out.ready
200e18c367fSLinJiawei  io.out.valid := valid
201e18c367fSLinJiawei  io.out.bits.uop <> io.in.bits.uop
202e2203130SLinJiawei  io.out.bits.data := dataModule.io.result
203e18c367fSLinJiawei}
204