xref: /XiangShan/src/main/scala/xiangshan/backend/fu/wrapper/MulUnit.scala (revision 2d12882c44bc634571590c140ebfe61457380501)
1730cfbc0SXuan Hupackage xiangshan.backend.fu.wrapper
2730cfbc0SXuan Hu
383ba63b3SXuan Huimport org.chipsalliance.cde.config.Parameters
4730cfbc0SXuan Huimport chisel3._
5730cfbc0SXuan Huimport utility.{LookupTree, SignExt, ZeroExt}
6730cfbc0SXuan Huimport xiangshan.MULOpType
7730cfbc0SXuan Huimport xiangshan.backend.fu.{ArrayMulDataModule, FuncUnit, HasPipelineReg, MulDivCtrl}
8730cfbc0SXuan Huimport xiangshan.backend.fu.FuConfig
9730cfbc0SXuan Hu
10730cfbc0SXuan Huclass MulUnit(cfg: FuConfig)(implicit p: Parameters) extends FuncUnit(cfg)
11730cfbc0SXuan Hu  with HasPipelineReg
12730cfbc0SXuan Hu{
13730cfbc0SXuan Hu  override def latency: Int = 2
14730cfbc0SXuan Hu
15*2d12882cSxiaofeibao  private val xlen = cfg.destDataBits
16730cfbc0SXuan Hu
176a35d972SXuan Hu  val func = io.in.bits.ctrl.fuOpType
186a35d972SXuan Hu  val src = io.in.bits.data.src
19730cfbc0SXuan Hu
20730cfbc0SXuan Hu  val op = MULOpType.getOp(func)
21730cfbc0SXuan Hu
22770e9338SXuan Hu  private val mdCtrl = Wire(new MulDivCtrl)
23770e9338SXuan Hu  mdCtrl.isW := MULOpType.isW(func)
24770e9338SXuan Hu  mdCtrl.isHi := MULOpType.isH(func)
25770e9338SXuan Hu  mdCtrl.sign := DontCare
26730cfbc0SXuan Hu
27730cfbc0SXuan Hu  val sext = SignExt(_: UInt, xlen + 1)
28730cfbc0SXuan Hu  val zext = ZeroExt(_: UInt, xlen + 1)
29730cfbc0SXuan Hu  val mulInputCvtTable: Seq[(UInt, (UInt => UInt, UInt => UInt))] = List(
30730cfbc0SXuan Hu    MULOpType.getOp(MULOpType.mul)    -> (zext, zext),
31730cfbc0SXuan Hu    MULOpType.getOp(MULOpType.mulh)   -> (sext, sext),
32730cfbc0SXuan Hu    MULOpType.getOp(MULOpType.mulhsu) -> (sext, zext),
33730cfbc0SXuan Hu    MULOpType.getOp(MULOpType.mulhu)  -> (zext, zext),
34730cfbc0SXuan Hu    MULOpType.getOp(MULOpType.mulw7)  -> (_.asUInt(6, 0), zext),
35730cfbc0SXuan Hu  )
36730cfbc0SXuan Hu
37730cfbc0SXuan Hu  // len should be xlen + 1
38*2d12882cSxiaofeibao  private val len = cfg.destDataBits + 1
39730cfbc0SXuan Hu  private val mulDataModule = Module(new ArrayMulDataModule(len))
40730cfbc0SXuan Hu
41730cfbc0SXuan Hu  mulDataModule.io.a := LookupTree(
42730cfbc0SXuan Hu    op,
43730cfbc0SXuan Hu    mulInputCvtTable.map { case (k, v) => (k, v._1(src(0))) }
44730cfbc0SXuan Hu  )
45730cfbc0SXuan Hu
46730cfbc0SXuan Hu  mulDataModule.io.b := LookupTree(
47730cfbc0SXuan Hu    op,
48730cfbc0SXuan Hu    mulInputCvtTable.map { case (k, v) => (k, v._2(src(1))) }
49730cfbc0SXuan Hu  )
50730cfbc0SXuan Hu
51730cfbc0SXuan Hu  mulDataModule.io.regEnables := VecInit((1 to latency) map (i => regEnable(i)))
52730cfbc0SXuan Hu  private val result = mulDataModule.io.result
53730cfbc0SXuan Hu
54770e9338SXuan Hu  private var mdCtrlVec = Seq(mdCtrl)
55730cfbc0SXuan Hu  for (i <- 1 to latency) {
56770e9338SXuan Hu    mdCtrlVec = mdCtrlVec :+ PipelineReg(i)(mdCtrlVec(i - 1))
57730cfbc0SXuan Hu  }
58770e9338SXuan Hu  private val res = Mux(mdCtrlVec.last.isHi, result(2 * xlen - 1, xlen), result(xlen - 1, 0))
59730cfbc0SXuan Hu
60770e9338SXuan Hu  io.out.bits.res.data := Mux(mdCtrlVec.last.isW, SignExt(res(31, 0), xlen), res)
61730cfbc0SXuan Hu}
62