xref: /XiangShan/src/main/scala/xiangshan/backend/fu/Alu.scala (revision 31ea87508ae5aa44ff948d6f3c9b073a089d9998)
1e18c367fSLinJiaweipackage xiangshan.backend.fu
2e18c367fSLinJiawei
3e18c367fSLinJiaweiimport chisel3._
4e18c367fSLinJiaweiimport chisel3.util._
5*31ea8750SLinJiaweiimport utils.{LookupTree, ParallelMux, SignExt, ZeroExt}
6e18c367fSLinJiaweiimport xiangshan._
7e18c367fSLinJiaweiimport xiangshan.backend.ALUOpType
8e18c367fSLinJiawei
9*31ea8750SLinJiaweiclass AddModule extends XSModule {
10*31ea8750SLinJiawei  val io = IO(new Bundle() {
11*31ea8750SLinJiawei    val src1, src2 = Input(UInt(XLEN.W))
12*31ea8750SLinJiawei    val out = Output(UInt((XLEN+1).W))
13*31ea8750SLinJiawei  })
14*31ea8750SLinJiawei  io.out := io.src1 +& io.src2
15*31ea8750SLinJiawei}
16*31ea8750SLinJiawei
17*31ea8750SLinJiaweiclass SubModule extends XSModule {
18*31ea8750SLinJiawei  val io = IO(new Bundle() {
19*31ea8750SLinJiawei    val src1, src2 = Input(UInt(XLEN.W))
20*31ea8750SLinJiawei    val out = Output(UInt((XLEN+1).W))
21*31ea8750SLinJiawei  })
22*31ea8750SLinJiawei  io.out := (io.src1 +& (~io.src2).asUInt()) + 1.U
23*31ea8750SLinJiawei}
24*31ea8750SLinJiawei
25*31ea8750SLinJiaweiclass LeftShiftModule extends XSModule {
26*31ea8750SLinJiawei  val io = IO(new Bundle() {
27*31ea8750SLinJiawei    val shamt = Input(UInt(6.W))
28*31ea8750SLinJiawei    val sllSrc = Input(UInt(XLEN.W))
29*31ea8750SLinJiawei    val sll = Output(UInt(XLEN.W))
30*31ea8750SLinJiawei  })
31*31ea8750SLinJiawei  io.sll := (io.sllSrc << io.shamt)(XLEN - 1, 0)
32*31ea8750SLinJiawei}
33*31ea8750SLinJiawei
34*31ea8750SLinJiaweiclass RightShiftModule extends XSModule {
35*31ea8750SLinJiawei  val io = IO(new Bundle() {
36*31ea8750SLinJiawei    val shamt = Input(UInt(6.W))
37*31ea8750SLinJiawei    val srlSrc, sraSrc = Input(UInt(XLEN.W))
38*31ea8750SLinJiawei    val srl, sra = Output(UInt(XLEN.W))
39*31ea8750SLinJiawei  })
40*31ea8750SLinJiawei  io.srl := io.srlSrc >> io.shamt
41*31ea8750SLinJiawei  io.sra := (io.sraSrc.asSInt() >> io.shamt).asUInt()
42*31ea8750SLinJiawei}
43*31ea8750SLinJiawei
44*31ea8750SLinJiaweiclass ShiftModule extends XSModule {
45*31ea8750SLinJiawei  val io = IO(new Bundle() {
46*31ea8750SLinJiawei    val shamt = Input(UInt(6.W))
47*31ea8750SLinJiawei    val shsrc1 = Input(UInt(XLEN.W))
48*31ea8750SLinJiawei    val sll, srl, sra = Output(UInt(XLEN.W))
49*31ea8750SLinJiawei  })
50*31ea8750SLinJiawei  io.sll := (io.shsrc1 << io.shamt)(XLEN-1, 0)
51*31ea8750SLinJiawei  io.srl := io.shsrc1 >> io.shamt
52*31ea8750SLinJiawei  io.sra := (io.shsrc1.asSInt >> io.shamt).asUInt
53*31ea8750SLinJiawei}
54*31ea8750SLinJiawei
55*31ea8750SLinJiaweiclass MiscResultSelect extends XSModule {
56*31ea8750SLinJiawei  val io = IO(new Bundle() {
57*31ea8750SLinJiawei    val func = Input(UInt())
58*31ea8750SLinJiawei    val sll, slt, sltu, xor, srl, or, and, sra = Input(UInt(XLEN.W))
59*31ea8750SLinJiawei    val miscRes = Output(UInt(XLEN.W))
60*31ea8750SLinJiawei
61*31ea8750SLinJiawei  })
62*31ea8750SLinJiawei  io.miscRes := ParallelMux(List(
63*31ea8750SLinJiawei    ALUOpType.and  -> io.and,
64*31ea8750SLinJiawei    ALUOpType.or   -> io.or,
65*31ea8750SLinJiawei    ALUOpType.xor  -> io.xor,
66*31ea8750SLinJiawei    ALUOpType.slt  -> ZeroExt(io.slt, XLEN),
67*31ea8750SLinJiawei    ALUOpType.sltu -> ZeroExt(io.sltu, XLEN),
68*31ea8750SLinJiawei    ALUOpType.srl  -> io.srl,
69*31ea8750SLinJiawei    ALUOpType.sll  -> io.sll,
70*31ea8750SLinJiawei    ALUOpType.sra  -> io.sra
71*31ea8750SLinJiawei  ).map(x => (x._1 === io.func(3, 0), x._2)))
72*31ea8750SLinJiawei}
73*31ea8750SLinJiawei
74*31ea8750SLinJiaweiclass AluResSel extends XSModule {
75*31ea8750SLinJiawei  val io = IO(new Bundle() {
76*31ea8750SLinJiawei    val func = Input(UInt())
77*31ea8750SLinJiawei    val isSub = Input(Bool())
78*31ea8750SLinJiawei    val addRes, subRes, miscRes = Input(UInt(XLEN.W))
79*31ea8750SLinJiawei    val aluRes = Output(UInt(XLEN.W))
80*31ea8750SLinJiawei  })
81*31ea8750SLinJiawei  val isAddSub = ALUOpType.isAddSub(io.func)
82*31ea8750SLinJiawei  val res = Mux(ALUOpType.isAddSub(io.func),
83*31ea8750SLinJiawei    Mux(io.isSub, io.subRes, io.addRes),
84*31ea8750SLinJiawei    io.miscRes
85*31ea8750SLinJiawei  )
86*31ea8750SLinJiawei  val h32 = Mux(ALUOpType.isWordOp(io.func), Fill(32, res(31)), res(63, 32))
87*31ea8750SLinJiawei  io.aluRes := Cat(h32, res(31, 0))
88*31ea8750SLinJiawei}
89*31ea8750SLinJiawei
9052c3f215SLinJiaweiclass Alu extends FunctionUnit with HasRedirectOut {
91e18c367fSLinJiawei
92b0ae3ac4SLinJiawei  val (src1, src2, func, pc, uop) = (
93e18c367fSLinJiawei    io.in.bits.src(0),
94e18c367fSLinJiawei    io.in.bits.src(1),
95e18c367fSLinJiawei    io.in.bits.uop.ctrl.fuOpType,
96e18c367fSLinJiawei    SignExt(io.in.bits.uop.cf.pc, AddrBits),
97e18c367fSLinJiawei    io.in.bits.uop
98e18c367fSLinJiawei  )
99e18c367fSLinJiawei
100dfd9e0a8SLinJiawei  val valid = io.in.valid
101e18c367fSLinJiawei
102e18c367fSLinJiawei  val isAdderSub = (func =/= ALUOpType.add) && (func =/= ALUOpType.addw)
103*31ea8750SLinJiawei  val addModule = Module(new AddModule)
104*31ea8750SLinJiawei  addModule.io.src1 := src1
105*31ea8750SLinJiawei  addModule.io.src2 := src2
106*31ea8750SLinJiawei  val subModule = Module(new SubModule)
107*31ea8750SLinJiawei  subModule.io.src1 := src1
108*31ea8750SLinJiawei  subModule.io.src2 := src2
109*31ea8750SLinJiawei  val addRes = addModule.io.out
110*31ea8750SLinJiawei  val subRes = subModule.io.out
111e18c367fSLinJiawei  val xorRes = src1 ^ src2
1123ef996e9SLinJiawei  val sltu = !subRes(XLEN)
113e18c367fSLinJiawei  val slt = xorRes(XLEN-1) ^ sltu
114e18c367fSLinJiawei
115*31ea8750SLinJiawei  val isW = ALUOpType.isWordOp(func)
116*31ea8750SLinJiawei  val shamt = Cat(isW && src2(5), src2(4, 0))
1173ef996e9SLinJiawei
118*31ea8750SLinJiawei  val leftShiftModule = Module(new LeftShiftModule)
119*31ea8750SLinJiawei  leftShiftModule.io.sllSrc := src1
120*31ea8750SLinJiawei  leftShiftModule.io.shamt := shamt
1213ef996e9SLinJiawei
122*31ea8750SLinJiawei  val rightShiftModule = Module(new RightShiftModule)
123*31ea8750SLinJiawei  rightShiftModule.io.shamt := shamt
124*31ea8750SLinJiawei  rightShiftModule.io.srlSrc := Cat(
125*31ea8750SLinJiawei    Mux(isW, 0.U(32.W), src1(63, 32)),
126*31ea8750SLinJiawei    src1(31, 0)
127*31ea8750SLinJiawei  )
128*31ea8750SLinJiawei  rightShiftModule.io.sraSrc := Cat(
129*31ea8750SLinJiawei    Mux(isW, Fill(32, src1(31)), src1(63, 32)),
130*31ea8750SLinJiawei    src1(31, 0)
1313ef996e9SLinJiawei  )
1323ef996e9SLinJiawei
133*31ea8750SLinJiawei  val sll = leftShiftModule.io.sll
134*31ea8750SLinJiawei  val srl = rightShiftModule.io.srl
135*31ea8750SLinJiawei  val sra = rightShiftModule.io.sra
136*31ea8750SLinJiawei
137*31ea8750SLinJiawei  val miscResSel = Module(new MiscResultSelect)
138*31ea8750SLinJiawei  miscResSel.io.func := func(3, 0)
139*31ea8750SLinJiawei  miscResSel.io.sll := sll
140*31ea8750SLinJiawei  miscResSel.io.slt := ZeroExt(slt, XLEN)
141*31ea8750SLinJiawei  miscResSel.io.sltu := ZeroExt(sltu, XLEN)
142*31ea8750SLinJiawei  miscResSel.io.xor := xorRes
143*31ea8750SLinJiawei  miscResSel.io.srl := srl
144*31ea8750SLinJiawei  miscResSel.io.or := (src1 | src2)
145*31ea8750SLinJiawei  miscResSel.io.and := (src1 & src2)
146*31ea8750SLinJiawei  miscResSel.io.sra := sra
147*31ea8750SLinJiawei
148*31ea8750SLinJiawei  val miscRes = miscResSel.io.miscRes
149*31ea8750SLinJiawei
150*31ea8750SLinJiawei  val aluResSel = Module(new AluResSel)
151*31ea8750SLinJiawei  aluResSel.io.func := func
152*31ea8750SLinJiawei  aluResSel.io.isSub := isAdderSub
153*31ea8750SLinJiawei  aluResSel.io.addRes := addRes
154*31ea8750SLinJiawei  aluResSel.io.subRes := subRes
155*31ea8750SLinJiawei  aluResSel.io.miscRes := miscRes
156*31ea8750SLinJiawei  val aluRes = aluResSel.io.aluRes
157e18c367fSLinJiawei
158e18c367fSLinJiawei  val branchOpTable = List(
159e18c367fSLinJiawei    ALUOpType.getBranchType(ALUOpType.beq)  -> !xorRes.orR,
160e18c367fSLinJiawei    ALUOpType.getBranchType(ALUOpType.blt)  -> slt,
161e18c367fSLinJiawei    ALUOpType.getBranchType(ALUOpType.bltu) -> sltu
162e18c367fSLinJiawei  )
163e18c367fSLinJiawei
164869210c7SYinan Xu  val isBranch = ALUOpType.isBranch(func)
1656060732cSLinJiawei  val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func)
166e18c367fSLinJiawei
167e18c367fSLinJiawei  redirectOutValid := io.out.valid && isBranch
168151e3043SLinJiawei  redirectOut := DontCare
169bfb958a3SYinan Xu  redirectOut.level := RedirectLevel.flushAfter
170e18c367fSLinJiawei  redirectOut.roqIdx := uop.roqIdx
171cde9280dSLinJiawei  redirectOut.ftqIdx := uop.cf.ftqPtr
172cde9280dSLinJiawei  redirectOut.ftqOffset := uop.cf.ftqOffset
1736060732cSLinJiawei  redirectOut.cfiUpdate.isMisPred := (uop.cf.pred_taken ^ taken) && isBranch
174cde9280dSLinJiawei  redirectOut.cfiUpdate.taken := taken
175cde9280dSLinJiawei  redirectOut.cfiUpdate.predTaken := uop.cf.pred_taken
176151e3043SLinJiawei
177e18c367fSLinJiawei  io.in.ready := io.out.ready
178e18c367fSLinJiawei  io.out.valid := valid
179e18c367fSLinJiawei  io.out.bits.uop <> io.in.bits.uop
180e18c367fSLinJiawei  io.out.bits.data := aluRes
181e18c367fSLinJiawei}
182