xref: /XiangShan/src/main/scala/xiangshan/backend/fu/Alu.scala (revision 2bd5334d599214aada6adb3b2be60148f5ec76cd)
1e18c367fSLinJiaweipackage xiangshan.backend.fu
2e18c367fSLinJiawei
32225d46eSJiawei Linimport chipsalliance.rocketchip.config.Parameters
4e18c367fSLinJiaweiimport chisel3._
5e18c367fSLinJiaweiimport chisel3.util._
631ea8750SLinJiaweiimport utils.{LookupTree, ParallelMux, SignExt, ZeroExt}
7e18c367fSLinJiaweiimport xiangshan._
8e18c367fSLinJiawei
92225d46eSJiawei Linclass AddModule(implicit p: Parameters) extends XSModule {
1031ea8750SLinJiawei  val io = IO(new Bundle() {
11*2bd5334dSYinan Xu    val src = Vec(2, Input(UInt(XLEN.W)))
1231ea8750SLinJiawei    val out = Output(UInt((XLEN+1).W))
1331ea8750SLinJiawei  })
14*2bd5334dSYinan Xu  io.out := io.src(0) +& io.src(1)
1531ea8750SLinJiawei}
1631ea8750SLinJiawei
172225d46eSJiawei Linclass SubModule(implicit p: Parameters) extends XSModule {
1831ea8750SLinJiawei  val io = IO(new Bundle() {
19*2bd5334dSYinan Xu    val src = Vec(2, Input(UInt(XLEN.W)))
2031ea8750SLinJiawei    val out = Output(UInt((XLEN+1).W))
2131ea8750SLinJiawei  })
22*2bd5334dSYinan Xu  io.out := (io.src(0) +& (~io.src(1)).asUInt()) + 1.U
2331ea8750SLinJiawei}
2431ea8750SLinJiawei
252225d46eSJiawei Linclass LeftShiftModule(implicit p: Parameters) extends XSModule {
2631ea8750SLinJiawei  val io = IO(new Bundle() {
2731ea8750SLinJiawei    val shamt = Input(UInt(6.W))
2831ea8750SLinJiawei    val sllSrc = Input(UInt(XLEN.W))
2931ea8750SLinJiawei    val sll = Output(UInt(XLEN.W))
3031ea8750SLinJiawei  })
3131ea8750SLinJiawei  io.sll := (io.sllSrc << io.shamt)(XLEN - 1, 0)
3231ea8750SLinJiawei}
3331ea8750SLinJiawei
342225d46eSJiawei Linclass RightShiftModule(implicit p: Parameters) extends XSModule {
3531ea8750SLinJiawei  val io = IO(new Bundle() {
3631ea8750SLinJiawei    val shamt = Input(UInt(6.W))
3731ea8750SLinJiawei    val srlSrc, sraSrc = Input(UInt(XLEN.W))
3867630d0bSLinJiawei    val srl_l, srl_w, sra_l, sra_w = Output(UInt(XLEN.W))
3931ea8750SLinJiawei  })
4067630d0bSLinJiawei  io.srl_l := io.srlSrc >> io.shamt
4167630d0bSLinJiawei  io.srl_w := io.srlSrc(31, 0) >> io.shamt
4267630d0bSLinJiawei  io.sra_l := (io.sraSrc.asSInt() >> io.shamt).asUInt()
43c57a9346SLinJiawei  io.sra_w := (Cat(Fill(32, io.sraSrc(31)), io.sraSrc(31, 0)).asSInt() >> io.shamt).asUInt()
4431ea8750SLinJiawei}
4531ea8750SLinJiawei
462225d46eSJiawei Linclass MiscResultSelect(implicit p: Parameters) extends XSModule {
4731ea8750SLinJiawei  val io = IO(new Bundle() {
4831ea8750SLinJiawei    val func = Input(UInt())
4931ea8750SLinJiawei    val sll, slt, sltu, xor, srl, or, and, sra = Input(UInt(XLEN.W))
5031ea8750SLinJiawei    val miscRes = Output(UInt(XLEN.W))
5131ea8750SLinJiawei
5231ea8750SLinJiawei  })
5331ea8750SLinJiawei  io.miscRes := ParallelMux(List(
5431ea8750SLinJiawei    ALUOpType.and  -> io.and,
5531ea8750SLinJiawei    ALUOpType.or   -> io.or,
5631ea8750SLinJiawei    ALUOpType.xor  -> io.xor,
5731ea8750SLinJiawei    ALUOpType.slt  -> ZeroExt(io.slt, XLEN),
5831ea8750SLinJiawei    ALUOpType.sltu -> ZeroExt(io.sltu, XLEN),
5931ea8750SLinJiawei    ALUOpType.srl  -> io.srl,
6031ea8750SLinJiawei    ALUOpType.sll  -> io.sll,
6131ea8750SLinJiawei    ALUOpType.sra  -> io.sra
6231ea8750SLinJiawei  ).map(x => (x._1 === io.func(3, 0), x._2)))
6331ea8750SLinJiawei}
6431ea8750SLinJiawei
652225d46eSJiawei Linclass AluResSel(implicit p: Parameters) extends XSModule {
6631ea8750SLinJiawei  val io = IO(new Bundle() {
6731ea8750SLinJiawei    val func = Input(UInt())
6831ea8750SLinJiawei    val isSub = Input(Bool())
6931ea8750SLinJiawei    val addRes, subRes, miscRes = Input(UInt(XLEN.W))
7031ea8750SLinJiawei    val aluRes = Output(UInt(XLEN.W))
7131ea8750SLinJiawei  })
7231ea8750SLinJiawei  val isAddSub = ALUOpType.isAddSub(io.func)
7331ea8750SLinJiawei  val res = Mux(ALUOpType.isAddSub(io.func),
7431ea8750SLinJiawei    Mux(io.isSub, io.subRes, io.addRes),
7531ea8750SLinJiawei    io.miscRes
7631ea8750SLinJiawei  )
7731ea8750SLinJiawei  val h32 = Mux(ALUOpType.isWordOp(io.func), Fill(32, res(31)), res(63, 32))
7831ea8750SLinJiawei  io.aluRes := Cat(h32, res(31, 0))
7931ea8750SLinJiawei}
8031ea8750SLinJiawei
812225d46eSJiawei Linclass AluDataModule(implicit p: Parameters) extends XSModule {
82e2203130SLinJiawei  val io = IO(new Bundle() {
83*2bd5334dSYinan Xu    val src = Vec(2, Input(UInt(XLEN.W)))
84e2203130SLinJiawei    val func = Input(FuOpType())
85e2203130SLinJiawei    val pred_taken, isBranch = Input(Bool())
86e2203130SLinJiawei    val result = Output(UInt(XLEN.W))
87e2203130SLinJiawei    val taken, mispredict = Output(Bool())
88e2203130SLinJiawei  })
89*2bd5334dSYinan Xu  val (src1, src2, func) = (io.src(0), io.src(1), io.func)
90e18c367fSLinJiawei
91e18c367fSLinJiawei  val isAdderSub = (func =/= ALUOpType.add) && (func =/= ALUOpType.addw)
9231ea8750SLinJiawei  val addModule = Module(new AddModule)
93*2bd5334dSYinan Xu  addModule.io.src(0) := src1
94*2bd5334dSYinan Xu  addModule.io.src(1) := src2
9531ea8750SLinJiawei  val subModule = Module(new SubModule)
96*2bd5334dSYinan Xu  subModule.io.src(0) := src1
97*2bd5334dSYinan Xu  subModule.io.src(1) := src2
9831ea8750SLinJiawei  val addRes = addModule.io.out
9931ea8750SLinJiawei  val subRes = subModule.io.out
100e18c367fSLinJiawei  val xorRes = src1 ^ src2
1013ef996e9SLinJiawei  val sltu = !subRes(XLEN)
102e18c367fSLinJiawei  val slt = xorRes(XLEN-1) ^ sltu
103e18c367fSLinJiawei
10431ea8750SLinJiawei  val isW = ALUOpType.isWordOp(func)
1054a6ab1cdSLinJiawei  val shamt = Cat(!isW && src2(5), src2(4, 0))
1063ef996e9SLinJiawei
10731ea8750SLinJiawei  val leftShiftModule = Module(new LeftShiftModule)
10831ea8750SLinJiawei  leftShiftModule.io.sllSrc := src1
10931ea8750SLinJiawei  leftShiftModule.io.shamt := shamt
1103ef996e9SLinJiawei
11131ea8750SLinJiawei  val rightShiftModule = Module(new RightShiftModule)
11231ea8750SLinJiawei  rightShiftModule.io.shamt := shamt
11367630d0bSLinJiawei  rightShiftModule.io.srlSrc := src1
11467630d0bSLinJiawei  rightShiftModule.io.sraSrc := src1
1153ef996e9SLinJiawei
11631ea8750SLinJiawei  val sll = leftShiftModule.io.sll
11767630d0bSLinJiawei  val srl = Mux(isW, rightShiftModule.io.srl_w, rightShiftModule.io.srl_l)
11867630d0bSLinJiawei  val sra = Mux(isW, rightShiftModule.io.sra_w, rightShiftModule.io.sra_l)
11931ea8750SLinJiawei
12031ea8750SLinJiawei  val miscResSel = Module(new MiscResultSelect)
12131ea8750SLinJiawei  miscResSel.io.func := func(3, 0)
12231ea8750SLinJiawei  miscResSel.io.sll := sll
12331ea8750SLinJiawei  miscResSel.io.slt := ZeroExt(slt, XLEN)
12431ea8750SLinJiawei  miscResSel.io.sltu := ZeroExt(sltu, XLEN)
12531ea8750SLinJiawei  miscResSel.io.xor := xorRes
12631ea8750SLinJiawei  miscResSel.io.srl := srl
12731ea8750SLinJiawei  miscResSel.io.or := (src1 | src2)
12831ea8750SLinJiawei  miscResSel.io.and := (src1 & src2)
12931ea8750SLinJiawei  miscResSel.io.sra := sra
13031ea8750SLinJiawei
13131ea8750SLinJiawei  val miscRes = miscResSel.io.miscRes
13231ea8750SLinJiawei
13331ea8750SLinJiawei  val aluResSel = Module(new AluResSel)
13431ea8750SLinJiawei  aluResSel.io.func := func
13531ea8750SLinJiawei  aluResSel.io.isSub := isAdderSub
13631ea8750SLinJiawei  aluResSel.io.addRes := addRes
13731ea8750SLinJiawei  aluResSel.io.subRes := subRes
13831ea8750SLinJiawei  aluResSel.io.miscRes := miscRes
13931ea8750SLinJiawei  val aluRes = aluResSel.io.aluRes
140e18c367fSLinJiawei
141e18c367fSLinJiawei  val branchOpTable = List(
142e18c367fSLinJiawei    ALUOpType.getBranchType(ALUOpType.beq)  -> !xorRes.orR,
143e18c367fSLinJiawei    ALUOpType.getBranchType(ALUOpType.blt)  -> slt,
144e18c367fSLinJiawei    ALUOpType.getBranchType(ALUOpType.bltu) -> sltu
145e18c367fSLinJiawei  )
1466060732cSLinJiawei  val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func)
147e18c367fSLinJiawei
148e2203130SLinJiawei  io.result := aluRes
149e2203130SLinJiawei  io.taken := taken
150e2203130SLinJiawei  io.mispredict := (io.pred_taken ^ taken) && io.isBranch
151e2203130SLinJiawei}
152e2203130SLinJiawei
1532225d46eSJiawei Linclass Alu(implicit p: Parameters) extends FunctionUnit with HasRedirectOut {
154e2203130SLinJiawei
155e2203130SLinJiawei  val (src1, src2, func, pc, uop) = (
156e2203130SLinJiawei    io.in.bits.src(0),
157e2203130SLinJiawei    io.in.bits.src(1),
158e2203130SLinJiawei    io.in.bits.uop.ctrl.fuOpType,
159e2203130SLinJiawei    SignExt(io.in.bits.uop.cf.pc, AddrBits),
160e2203130SLinJiawei    io.in.bits.uop
161e2203130SLinJiawei  )
162e2203130SLinJiawei
163e2203130SLinJiawei  val valid = io.in.valid
164e2203130SLinJiawei  val isBranch = ALUOpType.isBranch(func)
165e2203130SLinJiawei  val dataModule = Module(new AluDataModule)
166e2203130SLinJiawei
167*2bd5334dSYinan Xu  dataModule.io.src(0) := src1
168*2bd5334dSYinan Xu  dataModule.io.src(1) := src2
169e2203130SLinJiawei  dataModule.io.func := func
170e2203130SLinJiawei  dataModule.io.pred_taken := uop.cf.pred_taken
171e2203130SLinJiawei  dataModule.io.isBranch := isBranch
172e2203130SLinJiawei
173e18c367fSLinJiawei  redirectOutValid := io.out.valid && isBranch
174151e3043SLinJiawei  redirectOut := DontCare
175bfb958a3SYinan Xu  redirectOut.level := RedirectLevel.flushAfter
176e18c367fSLinJiawei  redirectOut.roqIdx := uop.roqIdx
177cde9280dSLinJiawei  redirectOut.ftqIdx := uop.cf.ftqPtr
178cde9280dSLinJiawei  redirectOut.ftqOffset := uop.cf.ftqOffset
179e2203130SLinJiawei  redirectOut.cfiUpdate.isMisPred := dataModule.io.mispredict
180e2203130SLinJiawei  redirectOut.cfiUpdate.taken := dataModule.io.taken
181cde9280dSLinJiawei  redirectOut.cfiUpdate.predTaken := uop.cf.pred_taken
182151e3043SLinJiawei
183e18c367fSLinJiawei  io.in.ready := io.out.ready
184e18c367fSLinJiawei  io.out.valid := valid
185e18c367fSLinJiawei  io.out.bits.uop <> io.in.bits.uop
186e2203130SLinJiawei  io.out.bits.data := dataModule.io.result
187e18c367fSLinJiawei}
188