Alu.scala 5.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, ParallelMux, SignExt, ZeroExt}
L
LinJiawei 已提交
6 7 8
import xiangshan._
import xiangshan.backend.ALUOpType

L
LinJiawei 已提交
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
class AddModule extends XSModule {
  val io = IO(new Bundle() {
    val src1, src2 = Input(UInt(XLEN.W))
    val out = Output(UInt((XLEN+1).W))
  })
  io.out := io.src1 +& io.src2
}

class SubModule extends XSModule {
  val io = IO(new Bundle() {
    val src1, src2 = Input(UInt(XLEN.W))
    val out = Output(UInt((XLEN+1).W))
  })
  io.out := (io.src1 +& (~io.src2).asUInt()) + 1.U
}

class LeftShiftModule extends XSModule {
  val io = IO(new Bundle() {
    val shamt = Input(UInt(6.W))
    val sllSrc = Input(UInt(XLEN.W))
    val sll = Output(UInt(XLEN.W))
  })
  io.sll := (io.sllSrc << io.shamt)(XLEN - 1, 0)
}

class RightShiftModule extends XSModule {
  val io = IO(new Bundle() {
    val shamt = Input(UInt(6.W))
    val srlSrc, sraSrc = Input(UInt(XLEN.W))
L
LinJiawei 已提交
38
    val srl_l, srl_w, sra_l, sra_w = Output(UInt(XLEN.W))
L
LinJiawei 已提交
39
  })
L
LinJiawei 已提交
40 41 42
  io.srl_l := io.srlSrc >> io.shamt
  io.srl_w := io.srlSrc(31, 0) >> io.shamt
  io.sra_l := (io.sraSrc.asSInt() >> io.shamt).asUInt()
43
  io.sra_w := (Cat(Fill(32, io.sraSrc(31)), io.sraSrc(31, 0)).asSInt() >> io.shamt).asUInt()
L
LinJiawei 已提交
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
}

class MiscResultSelect extends XSModule {
  val io = IO(new Bundle() {
    val func = Input(UInt())
    val sll, slt, sltu, xor, srl, or, and, sra = Input(UInt(XLEN.W))
    val miscRes = Output(UInt(XLEN.W))

  })
  io.miscRes := ParallelMux(List(
    ALUOpType.and  -> io.and,
    ALUOpType.or   -> io.or,
    ALUOpType.xor  -> io.xor,
    ALUOpType.slt  -> ZeroExt(io.slt, XLEN),
    ALUOpType.sltu -> ZeroExt(io.sltu, XLEN),
    ALUOpType.srl  -> io.srl,
    ALUOpType.sll  -> io.sll,
    ALUOpType.sra  -> io.sra
  ).map(x => (x._1 === io.func(3, 0), x._2)))
}

class AluResSel extends XSModule {
  val io = IO(new Bundle() {
    val func = Input(UInt())
    val isSub = Input(Bool())
    val addRes, subRes, miscRes = Input(UInt(XLEN.W))
    val aluRes = Output(UInt(XLEN.W))
  })
  val isAddSub = ALUOpType.isAddSub(io.func)
  val res = Mux(ALUOpType.isAddSub(io.func),
    Mux(io.isSub, io.subRes, io.addRes),
    io.miscRes
  )
  val h32 = Mux(ALUOpType.isWordOp(io.func), Fill(32, res(31)), res(63, 32))
  io.aluRes := Cat(h32, res(31, 0))
}

81 82 83 84 85 86 87 88 89
class AluDataModule extends XSModule {
  val io = IO(new Bundle() {
    val src1, src2 = Input(UInt(XLEN.W))
    val func = Input(FuOpType())
    val pred_taken, isBranch = Input(Bool())
    val result = Output(UInt(XLEN.W))
    val taken, mispredict = Output(Bool())
  })
  val (src1, src2, func) = (io.src1, io.src2, io.func)
L
LinJiawei 已提交
90 91

  val isAdderSub = (func =/= ALUOpType.add) && (func =/= ALUOpType.addw)
L
LinJiawei 已提交
92 93 94 95 96 97 98 99
  val addModule = Module(new AddModule)
  addModule.io.src1 := src1
  addModule.io.src2 := src2
  val subModule = Module(new SubModule)
  subModule.io.src1 := src1
  subModule.io.src2 := src2
  val addRes = addModule.io.out
  val subRes = subModule.io.out
L
LinJiawei 已提交
100
  val xorRes = src1 ^ src2
L
LinJiawei 已提交
101
  val sltu = !subRes(XLEN)
L
LinJiawei 已提交
102 103
  val slt = xorRes(XLEN-1) ^ sltu

L
LinJiawei 已提交
104
  val isW = ALUOpType.isWordOp(func)
105
  val shamt = Cat(!isW && src2(5), src2(4, 0))
L
LinJiawei 已提交
106 107 108 109 110 111 112

  val leftShiftModule = Module(new LeftShiftModule)
  leftShiftModule.io.sllSrc := src1
  leftShiftModule.io.shamt := shamt

  val rightShiftModule = Module(new RightShiftModule)
  rightShiftModule.io.shamt := shamt
L
LinJiawei 已提交
113 114
  rightShiftModule.io.srlSrc := src1
  rightShiftModule.io.sraSrc := src1
L
LinJiawei 已提交
115

L
LinJiawei 已提交
116
  val sll = leftShiftModule.io.sll
L
LinJiawei 已提交
117 118
  val srl = Mux(isW, rightShiftModule.io.srl_w, rightShiftModule.io.srl_l)
  val sra = Mux(isW, rightShiftModule.io.sra_w, rightShiftModule.io.sra_l)
L
LinJiawei 已提交
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139

  val miscResSel = Module(new MiscResultSelect)
  miscResSel.io.func := func(3, 0)
  miscResSel.io.sll := sll
  miscResSel.io.slt := ZeroExt(slt, XLEN)
  miscResSel.io.sltu := ZeroExt(sltu, XLEN)
  miscResSel.io.xor := xorRes
  miscResSel.io.srl := srl
  miscResSel.io.or := (src1 | src2)
  miscResSel.io.and := (src1 & src2)
  miscResSel.io.sra := sra

  val miscRes = miscResSel.io.miscRes

  val aluResSel = Module(new AluResSel)
  aluResSel.io.func := func
  aluResSel.io.isSub := isAdderSub
  aluResSel.io.addRes := addRes
  aluResSel.io.subRes := subRes
  aluResSel.io.miscRes := miscRes
  val aluRes = aluResSel.io.aluRes
L
LinJiawei 已提交
140 141 142 143 144 145

  val branchOpTable = List(
    ALUOpType.getBranchType(ALUOpType.beq)  -> !xorRes.orR,
    ALUOpType.getBranchType(ALUOpType.blt)  -> slt,
    ALUOpType.getBranchType(ALUOpType.bltu) -> sltu
  )
146
  val taken = LookupTree(ALUOpType.getBranchType(func), branchOpTable) ^ ALUOpType.isBranchInvert(func)
L
LinJiawei 已提交
147

148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
  io.result := aluRes
  io.taken := taken
  io.mispredict := (io.pred_taken ^ taken) && io.isBranch
}

class Alu extends FunctionUnit with HasRedirectOut {

  val (src1, src2, func, pc, uop) = (
    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
  )

  val valid = io.in.valid
164
  val isBranch = ALUOpType.isBranch(func)
165 166 167 168 169 170 171
  val dataModule = Module(new AluDataModule)

  dataModule.io.src1 := src1
  dataModule.io.src2 := src2
  dataModule.io.func := func
  dataModule.io.pred_taken := uop.cf.pred_taken
  dataModule.io.isBranch := isBranch
L
LinJiawei 已提交
172 173

  redirectOutValid := io.out.valid && isBranch
L
LinJiawei 已提交
174
  redirectOut := DontCare
175
  redirectOut.level := RedirectLevel.flushAfter
L
LinJiawei 已提交
176
  redirectOut.roqIdx := uop.roqIdx
L
LinJiawei 已提交
177 178
  redirectOut.ftqIdx := uop.cf.ftqPtr
  redirectOut.ftqOffset := uop.cf.ftqOffset
179 180
  redirectOut.cfiUpdate.isMisPred := dataModule.io.mispredict
  redirectOut.cfiUpdate.taken := dataModule.io.taken
L
LinJiawei 已提交
181
  redirectOut.cfiUpdate.predTaken := uop.cf.pred_taken
L
LinJiawei 已提交
182

L
LinJiawei 已提交
183 184 185
  io.in.ready := io.out.ready
  io.out.valid := valid
  io.out.bits.uop <> io.in.bits.uop
186
  io.out.bits.data := dataModule.io.result
L
LinJiawei 已提交
187
}