xref: /XiangShan/src/main/scala/xiangshan/backend/fu/Vsetu.scala (revision b03c55a5df5dc8793cb44b42dd60141566e57e78)
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 org.chipsalliance.cde.config.Parameters
20import chisel3._
21import chisel3.util._
22import xiangshan._
23import xiangshan.backend.fu.vector.Bundles.{VConfig, VType, Vl, VSew, VLmul, VsetVType}
24
25class VsetModuleIO(implicit p: Parameters) extends XSBundle {
26  private val vlWidth = p(XSCoreParamsKey).vlWidth
27
28  val in = Input(new Bundle {
29    val avl   : UInt = UInt(XLEN.W)
30    val vtype : VsetVType = VsetVType()
31    val func  : UInt = FuOpType()
32  })
33
34  val out = Output(new Bundle {
35    val vconfig: VConfig = VConfig()
36    val vlmax  : UInt = UInt(vlWidth.W)
37  })
38
39  // test bundle for internal state
40  val testOut = Output(new Bundle {
41    val log2Vlmax : UInt = UInt(3.W)
42    val vlmax     : UInt = UInt(vlWidth.W)
43  })
44}
45
46class VsetModule(implicit p: Parameters) extends XSModule {
47  val io = IO(new VsetModuleIO)
48
49  private val avl   = io.in.avl
50  private val func  = io.in.func
51  private val vtype = io.in.vtype
52
53  private val outVConfig = io.out.vconfig
54
55  private val vlWidth = p(XSCoreParamsKey).vlWidth
56
57  private val isSetVlmax = VSETOpType.isSetVlmax(func)
58  private val isVsetivli = VSETOpType.isVsetivli(func)
59
60  private val vlmul: UInt = vtype.vlmul
61  private val vsew : UInt = vtype.vsew
62
63  private val vl = WireInit(0.U(XLEN.W))
64
65  // EncodedLMUL = log(LMUL)
66  // EncodedSEW  = log(SEW) - 3
67  //        VLMAX  = VLEN * LMUL / SEW
68  // => log(VLMAX) = log(VLEN * LMUL / SEW)
69  // => log(VLMAX) = log(VLEN) + log(LMUL) - log(SEW)
70  // =>     VLMAX  = 1 << log(VLMAX)
71  //               = 1 << (log(VLEN) + log(LMUL) - log(SEW))
72
73  // vlen =  128
74  private val log2Vlen = log2Up(VLEN)
75  println(s"[VsetModule] log2Vlen: $log2Vlen")
76  println(s"[VsetModule] vlWidth: $vlWidth")
77
78  private val log2Vlmul = vlmul
79  // use 2 bits vsew to store vsew
80  private val log2Vsew = vsew(VSew.width - 1, 0) +& "b011".U
81
82  // vlen = 128, lmul = 8, sew = 8, log2Vlen = 7,
83  // vlmul = b011, vsew = 0, 7 + 3 - (0 + 3) = 7
84  // vlen = 128, lmul = 2, sew = 16
85  // vlmul = b001, vsew = 1, 7 + 1 - (1 + 3) = 4
86  private val log2Vlmax: UInt = log2Vlen.U(3.W) + log2Vlmul - log2Vsew
87  private val vlmax = (1.U(vlWidth.W) << log2Vlmax).asUInt
88
89  private val normalVL = Mux(avl > vlmax, vlmax, avl)
90
91  vl := Mux(isVsetivli, normalVL, Mux(isSetVlmax, vlmax, normalVL))
92
93  private val log2Elen = log2Up(ELEN)
94  private val log2VsewMax = Mux(log2Vlmul(2), log2Elen.U + log2Vlmul, log2Elen.U)
95
96  private val sewIllegal = VSew.isReserved(vsew) || (log2Vsew > log2VsewMax)
97  private val lmulIllegal = VLmul.isReserved(vlmul)
98  private val vtypeIllegal = vtype.reserved.orR
99
100  private val illegal = lmulIllegal | sewIllegal | vtypeIllegal | vtype.illegal
101
102  outVConfig.vl := Mux(illegal, 0.U, vl)
103  outVConfig.vtype.illegal := illegal
104  outVConfig.vtype.vta := Mux(illegal, 0.U, vtype.vta)
105  outVConfig.vtype.vma := Mux(illegal, 0.U, vtype.vma)
106  outVConfig.vtype.vlmul := Mux(illegal, 0.U, vtype.vlmul)
107  outVConfig.vtype.vsew := Mux(illegal, 0.U, vtype.vsew)
108
109  private val log2VlenDivVsew = log2Vlen.U(3.W) - log2Vsew
110  private val vlenDivVsew = 1.U(vlWidth.W) << log2VlenDivVsew
111  io.out.vlmax := Mux(vlmax >= vlenDivVsew, vlmax, vlenDivVsew)
112
113  io.testOut.vlmax := vlmax
114  io.testOut.log2Vlmax := log2Vlmax
115}
116