xref: /XiangShan/src/main/scala/xiangshan/backend/fu/Vsetu.scala (revision fe29a7c0f572f909ec49d3d6be38f17de56b8907)
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
18
19import chipsalliance.rocketchip.config.Parameters
20import chisel3._
21import chisel3.util._
22import utility.{ParallelMux, ZeroExt}
23import xiangshan._
24class VsetModule(implicit p: Parameters) extends XSModule {
25  val io = IO(new Bundle() {
26    val src0  = Input(UInt(XLEN.W))
27    val src1  = Input(UInt(XLEN.W))
28    val func  = Input(FuOpType())
29    val oldVConfig = Input(UInt(16.W))
30
31    val vconfig = Output(UInt(XLEN.W))
32    val vl      = Output(UInt(XLEN.W))
33  })
34
35  private val vtypeWidth = 8
36  private val vlWidth = 8
37
38  private val setOldVLFlag = VSETOpType.oldvlFlag(io.func)
39  private val setVLMAXFlag = VSETOpType.vlmaxFlag(io.func)
40  private val isVsetivli = VSETOpType.isVsetivli(io.func)
41
42  private val vtype = io.src1(7, 0)
43  private val vlmul = vtype(2, 0)
44  private val vsew = vtype(5, 3)
45
46  private val avlImm = ZeroExt(io.src1(14, 10), XLEN)
47  private val avl = Mux(VSETOpType.isVsetivli(io.func), avlImm, io.src0)
48  private val oldVL = io.oldVConfig(vtypeWidth + vlWidth - 1, vtypeWidth)
49
50  private val vl = WireInit(0.U(XLEN.W))
51
52  // vlen =  128
53  private val vlmaxVec = (0 to 7).map(i => if(i < 4) (16 << i).U(8.W) else (16 >> (8 - i)).U(8.W))
54  private val shamt = vlmul + (~vsew).asUInt + 1.U
55  private val vlmax = ParallelMux((0 to 7).map(_.U === shamt), vlmaxVec)
56
57  private val normalVL = Mux(avl > vlmax, vlmax, avl)
58
59  vl := Mux(isVsetivli, normalVL,
60    Mux(setOldVLFlag, ZeroExt(oldVL, XLEN),
61      Mux(setVLMAXFlag, vlmax, normalVL)))
62  io.vl := vl
63  io.vconfig := ZeroExt(Cat(vl(7, 0), vtype), XLEN)
64}
65