xref: /XiangShan/src/main/scala/xiangshan/backend/fu/wrapper/VIPU.scala (revision 83ba63b34cf09b33c0a9e1b3203138e51af4491b)
1/****************************************************************************************
2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3* Copyright (c) 2020-2021 Peng Cheng Laboratory
4*
5* XiangShan is licensed under Mulan PSL v2.
6* You can use this software according to the terms and conditions of the Mulan PSL v2.
7* You may obtain a copy of Mulan PSL v2 at:
8*       http://license.coscl.org.cn/MulanPSL2
9*
10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13*
14* See the Mulan PSL v2 for more details.
15****************************************************************************************
16*/
17
18
19package xiangshan.backend.fu.wrapper
20
21import org.chipsalliance.cde.config.Parameters
22import chisel3._
23import chisel3.util._
24import utility._
25import utils.XSError
26import xiangshan.{SelImm, SrcType, UopSplitType, XSCoreParamsKey, XSModule}
27import xiangshan.backend.fu.FuConfig
28import xiangshan.backend.fu.vector.Bundles.VSew
29import xiangshan.backend.fu.vector.utils.VecDataSplitModule
30import xiangshan.backend.fu.vector.{Mgu, Utils, VecPipedFuncUnit, VecSrcTypeModule}
31import xiangshan.SrcType
32import yunsuan.vector.alu.{VAluOpcode, VIAlu}
33import yunsuan.{OpType, VipuType}
34import scala.collection.Seq
35
36class VIAluDecodeResultBundle extends Bundle {
37  val opcode = UInt(6.W)
38  val srcType2 = UInt(4.W)
39  val srcType1 = UInt(4.W)
40  val vdType = UInt(4.W)
41}
42
43class VIAluDecoder (implicit p: Parameters) extends XSModule {
44  val io = IO(new Bundle{
45    val in = Input(new Bundle{
46      val fuOpType = UInt(8.W)
47      val sew = UInt(2.W)
48    })
49    val out = Output(new VIAluDecodeResultBundle)
50  })
51
52  // u 00 s 01 f 10 mask 1111
53  val uSew   = Cat(0.U(2.W), io.in.sew)
54  val uSew2  = Cat(0.U(2.W), (io.in.sew+1.U))
55  val uSewf2 = Cat(0.U(2.W), (io.in.sew-1.U))
56  val uSewf4 = Cat(0.U(2.W), (io.in.sew-2.U))
57  val uSewf8 = Cat(0.U(2.W), (io.in.sew-3.U))
58  val sSew   = Cat(1.U(2.W), io.in.sew)
59  val sSew2  = Cat(1.U(2.W), (io.in.sew+1.U))
60  val sSewf2 = Cat(1.U(2.W), (io.in.sew - 1.U))
61  val sSewf4 = Cat(1.U(2.W), (io.in.sew - 2.U))
62  val sSewf8 = Cat(1.U(2.W), (io.in.sew - 3.U))
63  val mask   = "b1111".U(4.W)
64
65  val out = LookupTree(io.in.fuOpType, List(
66    // --------------------- opcode     srcType2 1 vdType
67    VipuType.vredsum_vs   -> Cat(VAluOpcode.vredsum, uSew, uSew, uSew).asUInt,
68    VipuType.vredmaxu_vs  -> Cat(VAluOpcode.vredmax, uSew, uSew, uSew).asUInt,
69    VipuType.vredmax_vs   -> Cat(VAluOpcode.vredmax, sSew, sSew, sSew).asUInt,
70    VipuType.vredminu_vs  -> Cat(VAluOpcode.vredmin, uSew, uSew, uSew).asUInt,
71    VipuType.vredmin_vs   -> Cat(VAluOpcode.vredmin, sSew, sSew, sSew).asUInt,
72    VipuType.vredand_vs   -> Cat(VAluOpcode.vredand, uSew, uSew, uSew).asUInt,
73    VipuType.vredor_vs    -> Cat(VAluOpcode.vredor, uSew, uSew, uSew).asUInt,
74    VipuType.vredxor_vs   -> Cat(VAluOpcode.vredxor, uSew, uSew, uSew).asUInt,
75
76    VipuType.vwredsumu_vs -> Cat(VAluOpcode.vredsum, uSew, uSew, uSew2).asUInt,
77    VipuType.vwredsum_vs  -> Cat(VAluOpcode.vredsum, sSew, sSew, sSew2).asUInt,
78
79    VipuType.vcpop_m      -> Cat(VAluOpcode.vcpop, mask, mask, uSew).asUInt,
80    VipuType.vfirst_m     -> Cat(VAluOpcode.vfirst, mask, mask, uSew).asUInt,
81    VipuType.vmsbf_m      -> Cat(VAluOpcode.vmsbf, mask, mask, mask).asUInt,
82    VipuType.vmsif_m      -> Cat(VAluOpcode.vmsif, mask, mask, mask).asUInt,
83    VipuType.vmsof_m      -> Cat(VAluOpcode.vmsof, mask, mask, mask).asUInt,
84
85    VipuType.viota_m      -> Cat(VAluOpcode.viota, uSew, uSew, uSew).asUInt,
86    VipuType.vid_v        -> Cat(VAluOpcode.vid, uSew, uSew, uSew).asUInt
87
88   )).asTypeOf(new VIAluDecodeResultBundle)
89
90   io.out <> out
91}
92
93class VIPU(cfg: FuConfig)(implicit p: Parameters) extends VecPipedFuncUnit(cfg) {
94  XSError(io.in.valid && io.in.bits.ctrl.fuOpType === VipuType.dummy, "VIPU OpType not supported")
95
96  // params alias
97  private val dataWidth = cfg.dataBits
98  private val dataWidthOfDataModule = 64
99  private val numVecModule = dataWidth / dataWidthOfDataModule
100  private val needClearVs1 = (VipuType.vcpop_m === io.in.bits.ctrl.fuOpType && vuopIdx === 0.U) ||
101                             (VipuType.viota_m === io.in.bits.ctrl.fuOpType && vuopIdx(log2Up(MaxUopSize)-1,1) === 0.U) ||
102                             (VipuType.vid_v   === io.in.bits.ctrl.fuOpType && vuopIdx(log2Up(MaxUopSize)-1,1) === 0.U)    // dirty code TODO:  inset into IAlu
103  private val needShiftVs1 = (VipuType.vwredsumu_vs === io.in.bits.ctrl.fuOpType || VipuType.vwredsum_vs === io.in.bits.ctrl.fuOpType) && vuopIdx < vlmul
104
105  // modules
106  private val decoder = Module(new VIAluDecoder)
107  private val vialu   = Module(new VIAlu)
108
109  /**
110    * [[decoder]]'s in connection
111    */
112  decoder.io.in.fuOpType := fuOpType
113  decoder.io.in.sew      := vsew(1,0)
114
115
116  /**
117    * [[vialu]]'s in connection
118    */
119  vialu.io match {
120    case subIO =>
121      subIO.in.valid            := io.in.valid
122      subIO.in.bits.opcode.op   := decoder.io.out.opcode
123      subIO.in.bits.info.vm     := vm
124      subIO.in.bits.info.ma     := vma
125      subIO.in.bits.info.ta     := vta
126      subIO.in.bits.info.vlmul  := vlmul
127      subIO.in.bits.info.vl     := srcVConfig.vl
128      subIO.in.bits.info.vstart := vstart
129      subIO.in.bits.info.uopIdx := vuopIdx
130      subIO.in.bits.info.vxrm   := vxrm
131      subIO.in.bits.srcType(0)  := decoder.io.out.srcType2
132      subIO.in.bits.srcType(1)  := decoder.io.out.srcType1
133      subIO.in.bits.vdType      := decoder.io.out.vdType
134      subIO.in.bits.vs1         :=  Mux1H(Seq(needClearVs1 -> 0.U,
135                                              needShiftVs1 -> SignExt(vs1(127,64), 128),
136                                           ((!needClearVs1) && (!needShiftVs1)) -> vs1))
137      subIO.in.bits.vs2         := vs2
138      subIO.in.bits.old_vd      := oldVd
139      subIO.in.bits.mask        := srcMask
140  }
141
142  io.out.bits.res.data := vialu.io.out.bits.vd
143}
144