Alu.scala 2.5 KB
Newer Older
L
LinJiawei 已提交
1 2 3 4
package xiangshan.backend.fu

import chisel3._
import chisel3.util._
L
LinJiawei 已提交
5
import utils.{LookupTree, LookupTreeDefault, ParallelMux, SignExt, XSDebug, ZeroExt}
L
LinJiawei 已提交
6 7 8
import xiangshan._
import xiangshan.backend.ALUOpType

9
class Alu extends FunctionUnit with HasRedirectOut {
L
LinJiawei 已提交
10

L
LinJiawei 已提交
11
  val (src1, src2, func, pc, uop) = (
L
LinJiawei 已提交
12 13 14 15 16 17 18
    io.in.bits.src(0),
    io.in.bits.src(1),
    io.in.bits.uop.ctrl.fuOpType,
    SignExt(io.in.bits.uop.cf.pc, AddrBits),
    io.in.bits.uop
  )

L
LinJiawei 已提交
19 20
  val offset = src2

L
LinJiawei 已提交
21
  val valid = io.in.valid
L
LinJiawei 已提交
22 23

  val isAdderSub = (func =/= ALUOpType.add) && (func =/= ALUOpType.addw)
L
LinJiawei 已提交
24 25
  val addRes = src1 +& src2
  val subRes = (src1 +& (~src2).asUInt()) + 1.U
L
LinJiawei 已提交
26
  val xorRes = src1 ^ src2
L
LinJiawei 已提交
27
  val sltu = !subRes(XLEN)
L
LinJiawei 已提交
28 29 30 31 32 33 34
  val slt = xorRes(XLEN-1) ^ sltu

  val shsrc1 = LookupTreeDefault(func, src1, List(
    ALUOpType.srlw -> ZeroExt(src1(31,0), 64),
    ALUOpType.sraw -> SignExt(src1(31,0), 64)
  ))
  val shamt = Mux(ALUOpType.isWordOp(func), src2(4, 0), src2(5, 0))
L
LinJiawei 已提交
35 36 37

  val miscRes = ParallelMux(List(
    ALUOpType.sll  -> (shsrc1 << shamt)(XLEN-1, 0),
L
LinJiawei 已提交
38 39 40
    ALUOpType.slt  -> ZeroExt(slt, XLEN),
    ALUOpType.sltu -> ZeroExt(sltu, XLEN),
    ALUOpType.xor  -> xorRes,
L
LinJiawei 已提交
41 42 43 44 45 46 47 48 49 50 51
    ALUOpType.srl  -> (shsrc1 >> shamt),
    ALUOpType.or   -> (src1 | src2),
    ALUOpType.and  -> (src1 & src2),
    ALUOpType.sra  -> (shsrc1.asSInt >> shamt).asUInt
  ).map(x => (x._1 === func(3, 0), x._2)))

  val res = Mux(ALUOpType.isAddSub(func),
    Mux(isAdderSub, subRes, addRes),
    miscRes
  )

L
LinJiawei 已提交
52 53 54 55 56 57 58 59
  val aluRes = Mux(ALUOpType.isWordOp(func), SignExt(res(31,0), 64), res)

  val branchOpTable = List(
    ALUOpType.getBranchType(ALUOpType.beq)  -> !xorRes.orR,
    ALUOpType.getBranchType(ALUOpType.blt)  -> slt,
    ALUOpType.getBranchType(ALUOpType.bltu) -> sltu
  )

60
  val isBranch = ALUOpType.isBranch(func)
L
LinJiawei 已提交
61
  val isRVC = uop.cf.pd.isRVC
L
LinJiawei 已提交
62
  val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func)
L
LinJiawei 已提交
63
  val target = (pc + offset)(VAddrBits-1,0)
L
LinJiawei 已提交
64 65 66
  val snpc = Mux(isRVC, pc + 2.U, pc + 4.U)

  redirectOutValid := io.out.valid && isBranch
L
LinJiawei 已提交
67 68 69
  // Only brTag, level, roqIdx are needed
  // other infos are stored in brq
  redirectOut := DontCare
70
  redirectOut.level := RedirectLevel.flushAfter
L
LinJiawei 已提交
71
  redirectOut.roqIdx := uop.roqIdx
L
LinJiawei 已提交
72 73
  redirectOut.ftqIdx := uop.cf.ftqPtr
  redirectOut.ftqOffset := uop.cf.ftqOffset
L
LinJiawei 已提交
74
  redirectOut.cfiUpdate.isMisPred := (uop.cf.pred_taken ^ taken) && isBranch
L
LinJiawei 已提交
75 76
  redirectOut.cfiUpdate.taken := taken
  redirectOut.cfiUpdate.predTaken := uop.cf.pred_taken
L
LinJiawei 已提交
77

L
LinJiawei 已提交
78 79 80 81 82
  io.in.ready := io.out.ready
  io.out.valid := valid
  io.out.bits.uop <> io.in.bits.uop
  io.out.bits.data := aluRes
}