xref: /XiangShan/src/main/scala/xiangshan/backend/fu/vector/VIPU.scala (revision f6e6a3456de9c27becb43cf8a013b2fda9e74f13)
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.vector
20
21import chipsalliance.rocketchip.config.Parameters
22import chisel3._
23import chisel3.util._
24import utils._
25import utility._
26import yunsuan.vector.VectorIntAdder
27import yunsuan.vector.alu.{VAluOpcode, VIAlu}
28import yunsuan.{VectorElementFormat, VipuType}
29import xiangshan.{SelImm, SrcType, UopDivType, XSCoreParamsKey, XSModule}
30
31import scala.collection.Seq
32
33class VIPU(implicit p: Parameters) extends VPUSubModule(p(XSCoreParamsKey).VLEN) {
34  XSError(io.in.valid && io.in.bits.uop.ctrl.fuOpType === VipuType.dummy, "VIPU OpType not supported")
35
36// extra io
37  val vxrm = IO(Input(UInt(2.W)))
38
39// def some signal
40  val dataReg = Reg(io.out.bits.data.cloneType)
41  val dataWire = Wire(dataReg.cloneType)
42  val s_idle :: s_compute :: s_finish :: Nil = Enum(3)
43  val state = RegInit(s_idle)
44  val vialu = Module(new VIAluWrapper)
45  val outValid = vialu.io.out.valid
46  val outFire = vialu.io.out.fire()
47
48// reg input signal
49  val s0_uopReg = Reg(io.in.bits.uop.cloneType)
50  val inHs = io.in.fire()
51  when(inHs && state === s_idle){
52    s0_uopReg := io.in.bits.uop
53  }
54  dataReg := Mux(outValid, dataWire, dataReg)
55
56// fsm
57  switch (state) {
58    is (s_idle) {
59      state := Mux(inHs, s_compute, s_idle)
60    }
61    is (s_compute) {
62      state := Mux(outValid, Mux(outFire, s_idle, s_finish),
63                             s_compute)
64    }
65    is (s_finish) {
66      state := Mux(io.out.fire(), s_idle, s_finish)
67    }
68  }
69
70// connect VIAlu
71  dataWire := vialu.io.out.bits.data
72  vialu.io.in.bits <> io.in.bits
73  vialu.io.redirectIn := DontCare  // TODO :
74  vialu.vxrm := vxrm
75  io.out.bits.data :=  Mux(state === s_compute && outFire, dataWire, dataReg)
76  io.out.bits.uop := s0_uopReg
77
78  vialu.io.in.valid := io.in.valid && state === s_idle
79  io.out.valid := state === s_compute && outValid || state === s_finish
80  vialu.io.out.ready := io.out.ready
81  io.in.ready := state === s_idle
82}
83
84class VIAluDecodeResultBundle extends Bundle {
85  val opcode = UInt(6.W)
86  val srcType = Vec(2, UInt(4.W))
87  val vdType = UInt(4.W)
88}
89
90class VIAluDecoder (implicit p: Parameters) extends XSModule {
91  val io = IO(new Bundle{
92    val in = Input(new Bundle{
93      val fuOpType = UInt(8.W)
94      val sew = UInt(2.W)
95    })
96    val out = Output(new VIAluDecodeResultBundle)
97  })
98
99//  val DecodeDefault = List(VAluOpcode.dummy,  VpuDataType.dummy, VpuDataType.dummy, VpuDataType.dummy)
100//  val DecodeTable = Array(
101//    BitPat("b" + Cat(VipuType.add, "b00".U).litValue().toString()) -> List(VAluOpcode.vadd,  VpuDataType.s8, VpuDataType.s8, VpuDataType.s8),
102//    BitPat("b" + Cat(VipuType.add, "b01".U).litValue().toString()) -> List(VAluOpcode.vadd,  VpuDataType.s16, VpuDataType.s16, VpuDataType.s16),
103//    BitPat("b" + Cat(VipuType.add, "b10".U).litValue().toString()) -> List(VAluOpcode.vadd,  VpuDataType.s32, VpuDataType.s32, VpuDataType.s32),
104//    BitPat("b" + Cat(VipuType.add, "b11".U).litValue().toString()) -> List(VAluOpcode.vadd,  VpuDataType.s64, VpuDataType.s64, VpuDataType.s64),
105//  )
106//  val opcode :: srcType1 :: srcType2 :: vdType :: Nil = ListLookup(Cat(io.in.fuOpType, io.in.sew), DecodeDefault, DecodeTable)
107
108// u 00 s 01 f 10 mask 1111
109  val out = LookupTree(io.in.fuOpType, List(
110    VipuType.add -> Cat(VAluOpcode.vadd, Cat(1.U(2.W), io.in.sew), Cat(1.U(2.W), io.in.sew), Cat(1.U(2.W), io.in.sew)).asUInt()
111  )).asTypeOf(new VIAluDecodeResultBundle)
112
113  io.out <> out
114}
115
116class VIAluWrapper(implicit p: Parameters)  extends VPUSubModule(p(XSCoreParamsKey).VLEN) {
117  XSError(io.in.valid && io.in.bits.uop.ctrl.fuOpType === VipuType.dummy, "VIPU OpType not supported")
118
119// extra io
120  val vxrm = IO(Input(UInt(2.W)))
121
122// rename signal
123  val in = io.in.bits
124  val ctrl = in.uop.ctrl
125  val vtype = ctrl.vconfig.vtype
126
127// generate src1 and src2
128  val imm = VecInit(Seq.fill(VLEN/XLEN)(VecImmExtractor(ctrl.selImm, vtype.vsew, ctrl.imm))).asUInt
129  val _src1 = Mux(SrcType.isImm(ctrl.srcType(0)), imm, Mux(ctrl.uopDivType === UopDivType.VEC_MV_LMUL, VecExtractor(vtype.vsew, io.in.bits.src(0)), io.in.bits.src(0)))
130  val _src2 = in.src(1)
131  val src1 = Mux(VipuType.needReverse(ctrl.fuOpType), _src2, _src1)
132  val src2 = Mux(VipuType.needReverse(ctrl.fuOpType), _src1, _src2)
133
134// connect VIAlu
135  val decoder = Module(new VIAluDecoder)
136  val vialu = Module(new VIAlu)
137  decoder.io.in.fuOpType := in.uop.ctrl.fuType
138  decoder.io.in.sew := in.uop.ctrl.vconfig.vtype.vsew(1,0)
139
140  vialu.io.in.bits.opcode := decoder.io.out.opcode
141  vialu.io.in.bits.info.vm := in.uop.ctrl.vm
142  vialu.io.in.bits.info.ma := in.uop.ctrl.vconfig.vtype.vma
143  vialu.io.in.bits.info.ta := in.uop.ctrl.vconfig.vtype.vta
144  vialu.io.in.bits.info.vlmul := in.uop.ctrl.vconfig.vtype.vlmul
145  vialu.io.in.bits.info.vl := in.uop.ctrl.vconfig.vl
146  vialu.io.in.bits.info.vstart := 0.U // TODO :
147  vialu.io.in.bits.info.uopIdx := in.uop.ctrl.uopIdx.value
148  vialu.io.in.bits.info.vxrm := vxrm
149  vialu.io.in.bits.srcType(0) := decoder.io.out.srcType(0)
150  vialu.io.in.bits.srcType(1) := decoder.io.out.srcType(1)
151  vialu.io.in.bits.vdType := decoder.io.out.vdType
152  vialu.io.in.bits.vs1 := src1
153  vialu.io.in.bits.vs2 := src2
154  vialu.io.in.bits.old_vd := in.src(2)
155  vialu.io.in.bits.mask := in.src(3)
156
157  val vdOut = vialu.io.out.bits.vd
158  val vxsatOut = vialu.io.out.bits.vxsat
159
160  vialu.io.in.valid := io.in.valid
161
162// connect io
163  io.out.bits.data := vdOut
164  io.out.bits.uop := DontCare
165  io.out.valid := vialu.io.out.valid
166  io.in.ready := DontCare
167}
168
169object VecImmExtractor {
170  def Imm_OPIVIS(imm: UInt): UInt = {
171    SignExt(imm(4,0), 8)
172  }
173  def Imm_OPIVIU(imm: UInt): UInt = {
174    ZeroExt(imm(4,0), 8)
175  }
176
177  def imm_sew(sew: UInt, imm: UInt): UInt = {
178    val _imm = SignExt(imm(7,0), 64)
179    LookupTree(sew(1,0), List(
180      "b00".U -> VecInit(Seq.fill(8)(_imm(7,0))).asUInt,
181      "b01".U -> VecInit(Seq.fill(4)(_imm(15,0))).asUInt,
182      "b10".U -> VecInit(Seq.fill(2)(_imm(31,0))).asUInt,
183      "b11".U -> _imm(63,0),
184    ))
185  }
186
187  def apply(immType: UInt, sew: UInt, imm: UInt): UInt = {
188    val _imm = Mux(immType === SelImm.IMM_OPIVIS, Imm_OPIVIS(imm), Imm_OPIVIU(imm))
189    imm_sew(sew, _imm(7,0))
190  }
191}
192