Alu.scala 2.6 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 11 12 13 14 15 16 17 18 19

  val (src1, src2, offset, func, pc, uop) = (
    io.in.bits.src(0),
    io.in.bits.src(1),
    io.in.bits.uop.ctrl.imm,
    io.in.bits.uop.ctrl.fuOpType,
    SignExt(io.in.bits.uop.cf.pc, AddrBits),
    io.in.bits.uop
  )

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

  val isAdderSub = (func =/= ALUOpType.add) && (func =/= ALUOpType.addw)
L
LinJiawei 已提交
23 24
  val addRes = src1 +& src2
  val subRes = (src1 +& (~src2).asUInt()) + 1.U
L
LinJiawei 已提交
25
  val xorRes = src1 ^ src2
L
LinJiawei 已提交
26
  val sltu = !subRes(XLEN)
L
LinJiawei 已提交
27 28 29 30 31 32 33
  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 已提交
34 35 36

  val miscRes = ParallelMux(List(
    ALUOpType.sll  -> (shsrc1 << shamt)(XLEN-1, 0),
L
LinJiawei 已提交
37 38 39
    ALUOpType.slt  -> ZeroExt(slt, XLEN),
    ALUOpType.sltu -> ZeroExt(sltu, XLEN),
    ALUOpType.xor  -> xorRes,
L
LinJiawei 已提交
40 41 42 43 44 45 46 47 48 49 50
    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 已提交
51 52 53 54 55 56 57 58
  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
  )

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

  redirectOutValid := io.out.valid && isBranch
  redirectOut.pc := uop.cf.pc
  redirectOut.target := Mux(!taken && isBranch, snpc, target)
  redirectOut.brTag := uop.brTag
69 70
  redirectOut.level := RedirectLevel.flushAfter
  redirectOut.interrupt := DontCare
L
LinJiawei 已提交
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
  redirectOut.roqIdx := uop.roqIdx

  brUpdate := uop.cf.brUpdate
  // override brUpdate
  brUpdate.pc := uop.cf.pc
  brUpdate.target := Mux(!taken && isBranch, snpc, target)
  brUpdate.brTarget := target
  brUpdate.taken := isBranch && taken
  brUpdate.brTag := uop.brTag

  io.in.ready := io.out.ready
  io.out.valid := valid
  io.out.bits.uop <> io.in.bits.uop
  io.out.bits.data := aluRes
}