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