xref: /XiangShan/src/main/scala/xiangshan/backend/fu/wrapper/VIPU.scala (revision a74b2cdae8a59d0b87e5c9055660d53f44137bc1)
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 chipsalliance.rocketchip.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   = Seq.fill(numVecModule)(Module(new VIAlu))
108  private val mgu     = Module(new Mgu(dataWidth))
109
110  /**
111  * [[decoder]]'s in connection
112  */
113  decoder.io.in.fuOpType := fuOpType
114  decoder.io.in.sew      := vsew(1,0)
115
116  /**
117  * [[vialu]]'s in connection
118  */
119  vialu.zipWithIndex.foreach {
120    case (mod, i) =>
121      mod.io.in.valid            := io.in.valid
122      mod.io.in.bits.opcode.op   := decoder.io.out.opcode
123      mod.io.in.bits.info.vm     := vm
124      mod.io.in.bits.info.ma     := vma
125      mod.io.in.bits.info.ta     := vta
126      mod.io.in.bits.info.vlmul  := vlmul
127      mod.io.in.bits.info.vl     := srcVConfig.vl
128      mod.io.in.bits.info.vstart := vstart
129      mod.io.in.bits.info.uopIdx := vuopIdx
130      mod.io.in.bits.info.vxrm   := vxrm
131      mod.io.in.bits.srcType(0)  := decoder.io.out.srcType2
132      mod.io.in.bits.srcType(1)  := decoder.io.out.srcType1
133      mod.io.in.bits.vdType      := decoder.io.out.vdType
134      mod.io.in.bits.vs1         :=  Mux1H(Seq(needClearVs1 -> 0.U,
135                                            needShiftVs1 -> SignExt(vs1(127,64), 128),
136                                         ((!needClearVs1) && (!needShiftVs1)) -> vs1))
137      mod.io.in.bits.vs2         := vs2
138      mod.io.in.bits.old_vd      := oldVd
139      mod.io.in.bits.mask        := outSrcMask
140  }
141
142  /**
143  * [[mgu]]'s in connection
144  */
145  private val outVd = Cat(vialu.reverse.map(_.io.out.bits.vd))
146  private val outWiden = fuOpType === VipuType.vwredsumu_vs || fuOpType === VipuType.vwredsum_vs
147  private val outEew = Mux(outWiden, outVecCtrl.vsew + 1.U, outVecCtrl.vsew)
148
149  mgu.io.in.vd           := outVd
150  mgu.io.in.oldVd        := outOldVd
151  mgu.io.in.mask         := outSrcMask
152  mgu.io.in.info.ta      := outVecCtrl.vta
153  mgu.io.in.info.ma      := outVecCtrl.vma
154  mgu.io.in.info.vl      := outVl
155  mgu.io.in.info.vstart  := outVecCtrl.vstart
156  mgu.io.in.info.eew     := outEew
157  mgu.io.in.info.vdIdx   := outVecCtrl.vuopIdx
158  mgu.io.in.info.narrow  := 0.B
159  mgu.io.in.info.dstMask := 0.B
160
161  io.out.bits.res.data := mgu.io.out.vd
162}
163