xref: /XiangShan/src/main/scala/xiangshan/backend/fu/Alu.scala (revision bfb958a3953e2f6c64e52bd60a33e02f220e7f89)
1e18c367fSLinJiaweipackage xiangshan.backend.fu
2e18c367fSLinJiawei
3e18c367fSLinJiaweiimport chisel3._
4e18c367fSLinJiaweiimport chisel3.util._
5e18c367fSLinJiaweiimport utils.{LookupTree, LookupTreeDefault, SignExt, XSDebug, ZeroExt}
6e18c367fSLinJiaweiimport xiangshan._
7e18c367fSLinJiaweiimport xiangshan.backend.ALUOpType
8e18c367fSLinJiawei
952c3f215SLinJiaweiclass Alu extends FunctionUnit with HasRedirectOut {
10e18c367fSLinJiawei
11e18c367fSLinJiawei  val (src1, src2, offset, func, pc, uop) = (
12e18c367fSLinJiawei    io.in.bits.src(0),
13e18c367fSLinJiawei    io.in.bits.src(1),
14e18c367fSLinJiawei    io.in.bits.uop.ctrl.imm,
15e18c367fSLinJiawei    io.in.bits.uop.ctrl.fuOpType,
16e18c367fSLinJiawei    SignExt(io.in.bits.uop.cf.pc, AddrBits),
17e18c367fSLinJiawei    io.in.bits.uop
18e18c367fSLinJiawei  )
19e18c367fSLinJiawei
20e18c367fSLinJiawei  val redirectHit = uop.roqIdx.needFlush(io.redirectIn)
21e18c367fSLinJiawei  val valid = io.in.valid && !redirectHit
22e18c367fSLinJiawei
23e18c367fSLinJiawei  val isAdderSub = (func =/= ALUOpType.add) && (func =/= ALUOpType.addw)
24e18c367fSLinJiawei  val adderRes = (src1 +& (src2 ^ Fill(XLEN, isAdderSub))) + isAdderSub
25e18c367fSLinJiawei  val xorRes = src1 ^ src2
26e18c367fSLinJiawei  val sltu = !adderRes(XLEN)
27e18c367fSLinJiawei  val slt = xorRes(XLEN-1) ^ sltu
28e18c367fSLinJiawei
29e18c367fSLinJiawei  val shsrc1 = LookupTreeDefault(func, src1, List(
30e18c367fSLinJiawei    ALUOpType.srlw -> ZeroExt(src1(31,0), 64),
31e18c367fSLinJiawei    ALUOpType.sraw -> SignExt(src1(31,0), 64)
32e18c367fSLinJiawei  ))
33e18c367fSLinJiawei  val shamt = Mux(ALUOpType.isWordOp(func), src2(4, 0), src2(5, 0))
34e18c367fSLinJiawei  val res = LookupTreeDefault(func(3, 0), adderRes, List(
35e18c367fSLinJiawei    ALUOpType.sll  -> ((shsrc1  << shamt)(XLEN-1, 0)),
36e18c367fSLinJiawei    ALUOpType.slt  -> ZeroExt(slt, XLEN),
37e18c367fSLinJiawei    ALUOpType.sltu -> ZeroExt(sltu, XLEN),
38e18c367fSLinJiawei    ALUOpType.xor  -> xorRes,
39e18c367fSLinJiawei    ALUOpType.srl  -> (shsrc1  >> shamt),
40e18c367fSLinJiawei    ALUOpType.or   -> (src1  |  src2),
41e18c367fSLinJiawei    ALUOpType.and  -> (src1  &  src2),
42e18c367fSLinJiawei    ALUOpType.sra  -> ((shsrc1.asSInt >> shamt).asUInt)
43e18c367fSLinJiawei  ))
44e18c367fSLinJiawei  val aluRes = Mux(ALUOpType.isWordOp(func), SignExt(res(31,0), 64), res)
45e18c367fSLinJiawei
46e18c367fSLinJiawei  val branchOpTable = List(
47e18c367fSLinJiawei    ALUOpType.getBranchType(ALUOpType.beq)  -> !xorRes.orR,
48e18c367fSLinJiawei    ALUOpType.getBranchType(ALUOpType.blt)  -> slt,
49e18c367fSLinJiawei    ALUOpType.getBranchType(ALUOpType.bltu) -> sltu
50e18c367fSLinJiawei  )
51e18c367fSLinJiawei
52e18c367fSLinJiawei  val isBranch = uop.cf.brUpdate.pd.isBr// ALUOpType.isBranch(func)
53e18c367fSLinJiawei  val isRVC = uop.cf.brUpdate.pd.isRVC//(io.in.bits.cf.instr(1,0) =/= "b11".U)
54e18c367fSLinJiawei  val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func)
55e18c367fSLinJiawei  val target = Mux(isBranch, pc + offset, adderRes)(VAddrBits-1,0)
56e18c367fSLinJiawei  val snpc = Mux(isRVC, pc + 2.U, pc + 4.U)
57e18c367fSLinJiawei
58e18c367fSLinJiawei  redirectOutValid := io.out.valid && isBranch
59e18c367fSLinJiawei  redirectOut.pc := uop.cf.pc
60e18c367fSLinJiawei  redirectOut.target := Mux(!taken && isBranch, snpc, target)
61e18c367fSLinJiawei  redirectOut.brTag := uop.brTag
62*bfb958a3SYinan Xu  redirectOut.level := RedirectLevel.flushAfter
63*bfb958a3SYinan Xu  redirectOut.interrupt := DontCare
64e18c367fSLinJiawei  redirectOut.roqIdx := uop.roqIdx
65e18c367fSLinJiawei
66e18c367fSLinJiawei  brUpdate := uop.cf.brUpdate
67e18c367fSLinJiawei  // override brUpdate
68e18c367fSLinJiawei  brUpdate.pc := uop.cf.pc
69e18c367fSLinJiawei  brUpdate.target := Mux(!taken && isBranch, snpc, target)
70e18c367fSLinJiawei  brUpdate.brTarget := target
71e18c367fSLinJiawei  brUpdate.taken := isBranch && taken
72e18c367fSLinJiawei  brUpdate.brTag := uop.brTag
73e18c367fSLinJiawei
74e18c367fSLinJiawei  io.in.ready := io.out.ready
75e18c367fSLinJiawei  io.out.valid := valid
76e18c367fSLinJiawei  io.out.bits.uop <> io.in.bits.uop
77e18c367fSLinJiawei  io.out.bits.data := aluRes
78e18c367fSLinJiawei}
79