xref: /XiangShan/src/main/scala/xiangshan/backend/fu/vector/VPUSubModule.scala (revision 65df1368ae17485cede8fee974d8d180a46c5c80)
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
17package xiangshan.backend.fu.vector
18
19import chipsalliance.rocketchip.config.Parameters
20import chisel3._
21import chisel3.util.{Mux1H, _}
22import xiangshan.backend.fu.FunctionUnit
23import xiangshan.{SelImm, SrcType}
24import utility._
25
26abstract class VPUDataModule(len: Int = 128)(implicit p: Parameters) extends FunctionUnit(len: Int)
27{
28  val rm = IO(Input(UInt(3.W)))
29  val fflags = IO(Output(UInt(5.W)))
30  val vstart = IO(Input(UInt(XLEN.W)))
31  val vxrm = IO(Input(UInt(2.W)))
32  val vxsat = IO(Output(UInt(1.W)))
33  val needReverse = Wire(Bool())
34  val needClearMask = Wire(Bool())
35  val src1Sew = Wire(UInt(2.W))
36
37  // rename signal
38  val in = io.in.bits
39  val ctrl = in.uop.ctrl
40  val vtype = ctrl.vconfig.vtype
41
42  // for generate src1 and src2
43  src1Sew := vtype.vsew(1,0)
44  private val imm = VecInit(Seq.fill(VLEN/XLEN)(VecImmExtractor(ctrl.selImm, src1Sew, ctrl.imm))).asUInt
45  private val src1 = VecExtractor(src1Sew, io.in.bits.src(0))
46  val _vs1 = Mux(SrcType.isImm(ctrl.srcType(0)), imm,
47             Mux(in.uop.ctrl.srcType(0) === SrcType.vp, io.in.bits.src(0), src1))
48  val _vs2 = in.src(1)
49  // generate src1 and src2
50  val vs1 = Mux(needReverse, _vs2, _vs1)
51  val vs2 = Mux(needReverse, _vs1, _vs2)
52  val mask = Mux(needClearMask, 0.U, in.src(3))
53
54  // connect io
55  io.out.bits.uop := DontCare
56  io.in.ready := DontCare
57  fflags := DontCare
58  vxsat := DontCare
59
60}
61
62
63abstract class VPUSubModule(len: Int = 128)(implicit p: Parameters) extends FunctionUnit(len: Int)
64{
65  val rm = IO(Input(UInt(3.W)))
66  val fflags = IO(Output(UInt(5.W)))
67  val vstart = IO(Input(UInt(XLEN.W)))
68  val vxrm = IO(Input(UInt(2.W)))
69  val vxsat = IO(Output(UInt(1.W)))
70
71  val dataModule: Seq[VPUDataModule]
72  val select : Seq[Bool]
73
74  def connectDataModule = {
75  // def some signal
76    val dataReg = Reg(io.out.bits.data.cloneType)
77    val dataWire = Wire(dataReg.cloneType)
78    val s_idle :: s_compute :: s_finish :: Nil = Enum(3)
79    val state = RegInit(s_idle)
80
81    val outValid = dataModule.map(_.io.out.valid).reduce(_||_)
82    val outFire = dataModule.map(_.io.out.fire()).reduce(_||_)
83  // reg input signal
84    val s0_uopReg = Reg(io.in.bits.uop.cloneType)
85    val s0_selectReg = Reg(VecInit(select).asUInt().cloneType)
86    val inHs = io.in.fire()
87    when(inHs && state === s_idle){
88        s0_uopReg := io.in.bits.uop
89        s0_selectReg := VecInit(select).asUInt()
90      }
91    dataReg := Mux(outValid, dataWire, dataReg)
92
93  // fsm
94    switch (state) {
95      is (s_idle) {
96        state := Mux(inHs, s_compute, s_idle)
97      }
98      is (s_compute) {
99        state := Mux(outValid, Mux(outFire, s_idle, s_finish),
100                              s_compute)
101      }
102      is (s_finish) {
103        state := Mux(io.out.fire(), s_idle, s_finish)
104      }
105    }
106
107  // connect
108    dataWire := Mux1H(s0_selectReg, dataModule.map(_.io.out.bits.data))
109    dataModule.zipWithIndex.foreach{ case(l, i) =>
110      l.io.in.bits <> io.in.bits
111      l.io.redirectIn := DontCare
112      l.rm := rm
113      l.vxrm := vxrm
114      l.vstart := vstart
115      l.io.in.valid := io.in.valid && state === s_idle && select(i)
116      l.io.out.ready := io.out.ready
117    }
118    vxsat := Mux1H(s0_selectReg, dataModule.map(_.vxsat))
119    fflags := Mux1H(s0_selectReg, dataModule.map(_.fflags))
120
121    io.out.bits.data :=  Mux(state === s_compute && outFire, dataWire, dataReg)
122    io.out.bits.uop := s0_uopReg
123    io.out.valid := state === s_compute && outValid || state === s_finish
124    io.in.ready := state === s_idle
125  }
126}
127
128
129object VecImmExtractor {
130  def Imm_OPIVIS(imm: UInt): UInt = {
131    SignExt(imm(4,0), 8)
132  }
133  def Imm_OPIVIU(imm: UInt): UInt = {
134    ZeroExt(imm(4,0), 8)
135  }
136
137  def imm_sew(sew: UInt, imm: UInt): UInt = {
138    val _imm = SignExt(imm(7,0), 64)
139    LookupTree(sew(1,0), List(
140      "b00".U -> VecInit(Seq.fill(8)(_imm(7,0))).asUInt,
141      "b01".U -> VecInit(Seq.fill(4)(_imm(15,0))).asUInt,
142      "b10".U -> VecInit(Seq.fill(2)(_imm(31,0))).asUInt,
143      "b11".U -> _imm(63,0),
144    ))
145  }
146
147  def apply(immType: UInt, sew: UInt, imm: UInt): UInt = {
148    val _imm = Mux(immType === SelImm.IMM_OPIVIS, Imm_OPIVIS(imm), Imm_OPIVIU(imm))
149    imm_sew(sew, _imm(7,0))
150  }
151}
152
153object VecExtractor{
154  def xf2v_sew(sew: UInt, xf:UInt): UInt = {
155    LookupTree(sew(1, 0), List(
156      "b00".U -> VecInit(Seq.fill(16)(xf(7, 0))).asUInt,
157      "b01".U -> VecInit(Seq.fill(8)(xf(15, 0))).asUInt,
158      "b10".U -> VecInit(Seq.fill(4)(xf(31, 0))).asUInt,
159      "b11".U -> VecInit(Seq.fill(2)(xf(63, 0))).asUInt,
160    ))
161  }
162
163  def apply(sew: UInt, xf: UInt): UInt = {
164    xf2v_sew(sew, xf)
165  }
166}