xref: /XiangShan/src/main/scala/xiangshan/backend/fu/wrapper/VIPU.scala (revision e3da8bad334fc71ba0d72f0607e2e93245ddaece)
1a74b2cdaSZiyue Zhang/****************************************************************************************
2*e3da8badSTang Haojin * Copyright (c) 2024 Beijing Institute of Open Source Chip (BOSC)
3*e3da8badSTang Haojin * Copyright (c) 2020-2024 Institute of Computing Technology, Chinese Academy of Sciences
4a74b2cdaSZiyue Zhang * Copyright (c) 2020-2021 Peng Cheng Laboratory
5a74b2cdaSZiyue Zhang *
6a74b2cdaSZiyue Zhang * XiangShan is licensed under Mulan PSL v2.
7a74b2cdaSZiyue Zhang * You can use this software according to the terms and conditions of the Mulan PSL v2.
8a74b2cdaSZiyue Zhang * You may obtain a copy of Mulan PSL v2 at:
9a74b2cdaSZiyue Zhang *       http://license.coscl.org.cn/MulanPSL2
10a74b2cdaSZiyue Zhang *
11a74b2cdaSZiyue Zhang * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
12a74b2cdaSZiyue Zhang * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
13a74b2cdaSZiyue Zhang * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
14a74b2cdaSZiyue Zhang *
15a74b2cdaSZiyue Zhang * See the Mulan PSL v2 for more details.
16a74b2cdaSZiyue Zhang ****************************************************************************************
17a74b2cdaSZiyue Zhang */
18a74b2cdaSZiyue Zhang
19a74b2cdaSZiyue Zhang
20a74b2cdaSZiyue Zhangpackage xiangshan.backend.fu.wrapper
21a74b2cdaSZiyue Zhang
2283ba63b3SXuan Huimport org.chipsalliance.cde.config.Parameters
23a74b2cdaSZiyue Zhangimport chisel3._
24a74b2cdaSZiyue Zhangimport chisel3.util._
2502029386Slewislzhimport freechips.rocketchip.rocket.DecodeLogic
26a74b2cdaSZiyue Zhangimport utility._
27a74b2cdaSZiyue Zhangimport xiangshan.{SelImm, SrcType, UopSplitType, XSCoreParamsKey, XSModule}
28a74b2cdaSZiyue Zhangimport xiangshan.backend.fu.FuConfig
29a74b2cdaSZiyue Zhangimport xiangshan.backend.fu.vector.Bundles.VSew
30a74b2cdaSZiyue Zhangimport xiangshan.backend.fu.vector.utils.VecDataSplitModule
31a74b2cdaSZiyue Zhangimport xiangshan.backend.fu.vector.{Mgu, Utils, VecPipedFuncUnit, VecSrcTypeModule}
32a74b2cdaSZiyue Zhangimport xiangshan.SrcType
33a74b2cdaSZiyue Zhangimport yunsuan.vector.alu.{VAluOpcode, VIAlu}
34a74b2cdaSZiyue Zhangimport yunsuan.{OpType, VipuType}
3502029386Slewislzh
36a74b2cdaSZiyue Zhangclass VIAluDecodeResultBundle extends Bundle {
37a74b2cdaSZiyue Zhang  val opcode = UInt(6.W)
3802029386Slewislzh  val srcType2 = UInt(3.W)
3902029386Slewislzh  val srcType1 = UInt(3.W)
4002029386Slewislzh  val vdType = UInt(3.W)
41a74b2cdaSZiyue Zhang}
42a74b2cdaSZiyue Zhang
43a74b2cdaSZiyue Zhangclass VIAluDecoder (implicit p: Parameters) extends XSModule {
44a74b2cdaSZiyue Zhang  val io = IO(new Bundle{
45a74b2cdaSZiyue Zhang    val in = Input(new Bundle{
46a74b2cdaSZiyue Zhang      val fuOpType = UInt(8.W)
47a74b2cdaSZiyue Zhang      val sew = UInt(2.W)
48a74b2cdaSZiyue Zhang    })
49a74b2cdaSZiyue Zhang    val out = Output(new VIAluDecodeResultBundle)
50a74b2cdaSZiyue Zhang  })
51a74b2cdaSZiyue Zhang
52a74b2cdaSZiyue Zhang  // u 00 s 01 f 10 mask 1111
5302029386Slewislzh  // Cat(1(1111),1(s)/0(u), 1(add1)/0(add0))
5402029386Slewislzh  val uSew   = BitPat("b000")
5502029386Slewislzh  val uSew2  = BitPat("b001")
5602029386Slewislzh  val sSew   = BitPat("b010")
5702029386Slewislzh  val sSew2  = BitPat("b011")
5802029386Slewislzh  val mask = BitPat("b100".U(3.W))
5902029386Slewislzh  val default = List(BitPat("b000000"),BitPat("b000"),BitPat("b000"),BitPat("b000"))
6002029386Slewislzh  val decodeTable : Array[(BitPat, List[BitPat])] = Array(
6102029386Slewislzh    BitPat(VipuType.vredsum_vs)   -> List(BitPat(VAluOpcode.vredsum), uSew, uSew, uSew),
6202029386Slewislzh    BitPat(VipuType.vredmaxu_vs)  -> List(BitPat(VAluOpcode.vredmax), uSew, uSew, uSew),
6302029386Slewislzh    BitPat(VipuType.vredmax_vs)   -> List(BitPat(VAluOpcode.vredmax), sSew, sSew, sSew),
6402029386Slewislzh    BitPat(VipuType.vredminu_vs)  -> List(BitPat(VAluOpcode.vredmin), uSew, uSew, uSew),
6502029386Slewislzh    BitPat(VipuType.vredmin_vs)   -> List(BitPat(VAluOpcode.vredmin), sSew, sSew, sSew),
6602029386Slewislzh    BitPat(VipuType.vredand_vs)   -> List(BitPat(VAluOpcode.vredand), uSew, uSew, uSew),
6702029386Slewislzh    BitPat(VipuType.vredor_vs)    -> List(BitPat(VAluOpcode.vredor), uSew, uSew, uSew),
6802029386Slewislzh    BitPat(VipuType.vredxor_vs)   -> List(BitPat(VAluOpcode.vredxor), uSew, uSew, uSew),
69a74b2cdaSZiyue Zhang
7002029386Slewislzh    BitPat(VipuType.vwredsumu_vs) -> List(BitPat(VAluOpcode.vredsum), uSew, uSew, uSew2),
7102029386Slewislzh    BitPat(VipuType.vwredsum_vs)  -> List(BitPat(VAluOpcode.vredsum), sSew, sSew, sSew2),
72a74b2cdaSZiyue Zhang
7302029386Slewislzh    BitPat(VipuType.vcpop_m)      -> List(BitPat(VAluOpcode.vcpop), mask, mask, uSew),
7402029386Slewislzh    BitPat(VipuType.vfirst_m)     -> List(BitPat(VAluOpcode.vfirst), mask, mask, uSew),
7502029386Slewislzh    BitPat(VipuType.vmsbf_m)      -> List(BitPat(VAluOpcode.vmsbf), mask, mask, mask),
7602029386Slewislzh    BitPat(VipuType.vmsif_m)      -> List(BitPat(VAluOpcode.vmsif), mask, mask, mask),
7702029386Slewislzh    BitPat(VipuType.vmsof_m)      -> List(BitPat(VAluOpcode.vmsof), mask, mask, mask),
78a74b2cdaSZiyue Zhang
7902029386Slewislzh    BitPat(VipuType.viota_m)      -> List(BitPat(VAluOpcode.viota), uSew, uSew, uSew),
8002029386Slewislzh    BitPat(VipuType.vid_v)        -> List(BitPat(VAluOpcode.vid), uSew, uSew, uSew),
8102029386Slewislzh    BitPat(VipuType.vmv_x_s)      -> List(BitPat(VAluOpcode.vmvxs), uSew, uSew, uSew)
8202029386Slewislzh  )
8302029386Slewislzh  val decoder = DecodeLogic(io.in.fuOpType, default, decodeTable)
8402029386Slewislzh  val outsig = Seq(io.out.opcode, io.out.srcType2, io.out.srcType1, io.out.vdType)
8502029386Slewislzh  outsig.zip(decoder).foreach({case (s, d) => s := d})
86a74b2cdaSZiyue Zhang}
87a74b2cdaSZiyue Zhang
88a74b2cdaSZiyue Zhangclass VIPU(cfg: FuConfig)(implicit p: Parameters) extends VecPipedFuncUnit(cfg) {
89a74b2cdaSZiyue Zhang  XSError(io.in.valid && io.in.bits.ctrl.fuOpType === VipuType.dummy, "VIPU OpType not supported")
90a74b2cdaSZiyue Zhang
91a74b2cdaSZiyue Zhang  // params alias
922d12882cSxiaofeibao  private val dataWidth = cfg.destDataBits
93a74b2cdaSZiyue Zhang  private val dataWidthOfDataModule = 64
94a74b2cdaSZiyue Zhang  private val numVecModule = dataWidth / dataWidthOfDataModule
95a74b2cdaSZiyue Zhang  private val needClearVs1 = (VipuType.vcpop_m === io.in.bits.ctrl.fuOpType && vuopIdx === 0.U) ||
96a74b2cdaSZiyue Zhang    (VipuType.viota_m === io.in.bits.ctrl.fuOpType && vuopIdx(log2Up(MaxUopSize)-1,1) === 0.U) ||
97a74b2cdaSZiyue Zhang    (VipuType.vid_v   === io.in.bits.ctrl.fuOpType && vuopIdx(log2Up(MaxUopSize)-1,1) === 0.U)    // dirty code TODO:  inset into IAlu
98*e3da8badSTang Haojin  private val lmul = MuxLookup(vlmul, 1.U(4.W))(Seq(
993bb22d12SZiyue Zhang    "b001".U -> 2.U,
1003bb22d12SZiyue Zhang    "b010".U -> 4.U,
1013bb22d12SZiyue Zhang    "b011".U -> 8.U
1023bb22d12SZiyue Zhang  ))
1033bb22d12SZiyue Zhang  private val needShiftVs1 = (VipuType.vwredsumu_vs === io.in.bits.ctrl.fuOpType || VipuType.vwredsum_vs === io.in.bits.ctrl.fuOpType) && vuopIdx < lmul
104a74b2cdaSZiyue Zhang
105a74b2cdaSZiyue Zhang  // modules
106a74b2cdaSZiyue Zhang  private val decoder = Module(new VIAluDecoder)
107e69876fbSZiyue Zhang  private val vialu   = Module(new VIAlu)
108a74b2cdaSZiyue Zhang
109a74b2cdaSZiyue Zhang  /**
110a74b2cdaSZiyue Zhang   * [[decoder]]'s in connection
111a74b2cdaSZiyue Zhang   */
112a74b2cdaSZiyue Zhang  decoder.io.in.fuOpType := fuOpType
113a74b2cdaSZiyue Zhang  decoder.io.in.sew      := vsew(1,0)
114a74b2cdaSZiyue Zhang
11502029386Slewislzh  val typeop2 = decoder.io.out.srcType2
11602029386Slewislzh  val typeop1 = decoder.io.out.srcType1
11702029386Slewislzh  val typevd = decoder.io.out.vdType
11802029386Slewislzh  val sew = decoder.io.in.sew
11993226391SZiyue Zhang
12002029386Slewislzh  val srcTypeVs2 = Cat(0.U | typeop2(2) , typeop2(1) | typeop2(2) , Fill(2,typeop2(2)) | (sew + typeop2(0)) )
12102029386Slewislzh  val srcTypeVs1 = Cat(0.U | typeop1(2) , typeop1(1) | typeop1(2) , Fill(2,typeop1(2)) | (sew + typeop1(0)) )
12202029386Slewislzh  val vdType =  Cat(0.U | typevd(2) , typevd(1) | typevd(2) , Fill(2,typevd(2)) | (sew + typevd(0)))
123a74b2cdaSZiyue Zhang  /**
124a74b2cdaSZiyue Zhang   * [[vialu]]'s in connection
125a74b2cdaSZiyue Zhang   */
126e69876fbSZiyue Zhang  vialu.io match {
127e69876fbSZiyue Zhang    case subIO =>
128e69876fbSZiyue Zhang      subIO.in.valid            := io.in.valid
129e69876fbSZiyue Zhang      subIO.in.bits.opcode.op   := decoder.io.out.opcode
130e69876fbSZiyue Zhang      subIO.in.bits.info.vm     := vm
131e69876fbSZiyue Zhang      subIO.in.bits.info.ma     := vma
132e69876fbSZiyue Zhang      subIO.in.bits.info.ta     := vta
133e69876fbSZiyue Zhang      subIO.in.bits.info.vlmul  := vlmul
134e69876fbSZiyue Zhang      subIO.in.bits.info.vl     := srcVConfig.vl
135e69876fbSZiyue Zhang      subIO.in.bits.info.vstart := vstart
136e69876fbSZiyue Zhang      subIO.in.bits.info.uopIdx := vuopIdx
137e69876fbSZiyue Zhang      subIO.in.bits.info.vxrm   := vxrm
13802029386Slewislzh      subIO.in.bits.srcType(0)  := srcTypeVs2
13902029386Slewislzh      subIO.in.bits.srcType(1)  := srcTypeVs1
14002029386Slewislzh      subIO.in.bits.vdType      := vdType
141e69876fbSZiyue Zhang      subIO.in.bits.vs1         := Mux1H(Seq(needClearVs1 -> 0.U,
1423bb22d12SZiyue Zhang        needShiftVs1 -> ZeroExt(vs1(127,64), 128),
143a74b2cdaSZiyue Zhang        ((!needClearVs1) && (!needShiftVs1)) -> vs1))
144e69876fbSZiyue Zhang      subIO.in.bits.vs2         := vs2
145e69876fbSZiyue Zhang      subIO.in.bits.old_vd      := oldVd
14693226391SZiyue Zhang      subIO.in.bits.mask        := srcMask
147a74b2cdaSZiyue Zhang  }
148a74b2cdaSZiyue Zhang
14993226391SZiyue Zhang  io.out.bits.res.data := vialu.io.out.bits.vd
150a74b2cdaSZiyue Zhang}
151