xref: /XiangShan/src/main/scala/xiangshan/backend/fu/Vsetu.scala (revision a32c56f428c85705bf274a3011ddbec711d929d9)
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.ZeroExt
23import xiangshan._
24import xiangshan.backend.fu.vector.Bundles.{VConfig, VType, Vl}
25
26class VsetModuleIO(implicit p: Parameters) extends XSBundle {
27  private val vlWidth = p(XSCoreParamsKey).vlWidth
28
29  val in = Input(new Bundle {
30    val avl   : UInt = Vl()
31    val vtype : VType = VType()
32    val func  : UInt = FuOpType()
33    val oldVl : UInt = Vl() // Todo: check if it can be optimized
34  })
35
36  val out = Output(new Bundle {
37    val vconfig: VConfig = VConfig()
38  })
39
40  // test bundle for internal state
41  val testOut = Output(new Bundle {
42    val log2Vlmax : UInt = UInt(3.W)
43    val vlmax     : UInt = UInt(vlWidth.W)
44  })
45}
46
47class VsetModule(implicit p: Parameters) extends XSModule {
48  val io = IO(new VsetModuleIO)
49
50  private val avl   = io.in.avl
51  private val oldVL = io.in.oldVl
52  private val func  = io.in.func
53  private val vtype = io.in.vtype
54
55  private val outVConfig = io.out.vconfig
56
57  private val vlWidth = p(XSCoreParamsKey).vlWidth
58
59  private val isKeepVl   = VSETOpType.isKeepVl(func)
60  private val isSetVlmax = VSETOpType.isSetVlmax(func)
61  private val isVsetivli = VSETOpType.isVsetivli(func)
62
63  private val vlmul: UInt = vtype.vlmul
64  private val vsew : UInt = vtype.vsew
65
66
67  private val vl = WireInit(0.U(XLEN.W))
68
69  // VLMAX = VLEN * LMUL / SEW
70  //       = VLEN << (Cat(~vlmul(2), vlmul(1,0)) >> (vsew + 1.U)
71  //       = VLEN >> shamt
72  // shamt = (vsew + 1.U) - (Cat(~vlmul(2), vlmul(1,0))
73
74  // vlen =  128
75  private val log2Vlen = log2Up(VLEN)
76  println(s"[VsetModule] log2Vlen: $log2Vlen")
77  println(s"[VsetModule] vlWidth: $vlWidth")
78  // mf8-->b001, m1-->b100, m8-->b111
79  private val ilmul = Cat(!vlmul(2), vlmul(1, 0))
80
81  // vlen = 128, lmul = 8, sew = 8, log2Vlen = 7,
82  // vlmul = b011, ilmul - 4 = b111 - 4 = 3, vsew = 0, vsew + 3 = 3, 7 + (7 - 4) - (0 + 3) = 7
83  // vlen = 128, lmul = 2, sew = 16
84  // vlmul = b001, ilmul - 4 = b101 - 4 = 3, vsew = 1, 7 + (5 - 4) - (1 + 3) = 4
85  private val log2Vlmax: UInt = log2Vlen.U(3.W) + (ilmul - "b100".U) - (vsew + "b011".U)
86  private val vlmax = (1.U(vlWidth.W) << (log2Vlmax - 1.U)).asUInt
87
88//  private val vlmaxVec: Seq[UInt] = (0 to 7).map(i => if(i < 4) (16 << i).U(8.W) else (16 >> (8 - i)).U(8.W))
89//  private val shamt = vlmul + (~vsew).asUInt + 1.U
90//  private val vlmax = ParallelMux((0 to 7).map(_.U === shamt), vlmaxVec)
91
92  private val normalVL = Mux(avl > vlmax, vlmax, avl)
93
94  vl := MuxCase(normalVL, Seq(
95    isVsetivli -> normalVL,
96    isKeepVl   -> ZeroExt(oldVL, XLEN),
97    isSetVlmax -> vlmax,
98  ))
99
100  outVConfig.vl := vl
101  outVConfig.vtype.illegal := false.B // Todo
102  outVConfig.vtype.vta := vtype.vta
103  outVConfig.vtype.vma := vtype.vma
104  outVConfig.vtype.vlmul := vtype.vlmul
105  outVConfig.vtype.vsew := vtype.vsew
106
107  io.testOut.vlmax := vlmax
108  io.testOut.log2Vlmax := log2Vlmax
109}
110