/*************************************************************************************** * Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences * Copyright (c) 2020-2021 Peng Cheng Laboratory * * XiangShan is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: * http://license.coscl.org.cn/MulanPSL2 * * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * * See the Mulan PSL v2 for more details. ***************************************************************************************/ package xiangshan.backend.fu import org.chipsalliance.cde.config.Parameters import chisel3._ import chisel3.util._ import xiangshan._ import xiangshan.backend.fu.vector.Bundles.{VConfig, VType, Vl, VSew, VLmul, VsetVType} class VsetModuleIO(implicit p: Parameters) extends XSBundle { private val vlWidth = p(XSCoreParamsKey).vlWidth val in = Input(new Bundle { val avl : UInt = UInt(XLEN.W) val vtype : VsetVType = VsetVType() val func : UInt = FuOpType() }) val out = Output(new Bundle { val vconfig: VConfig = VConfig() val vlmax : UInt = UInt(vlWidth.W) }) // test bundle for internal state val testOut = Output(new Bundle { val log2Vlmax : UInt = UInt(3.W) val vlmax : UInt = UInt(vlWidth.W) }) } class VsetModule(implicit p: Parameters) extends XSModule { val io = IO(new VsetModuleIO) private val avl = io.in.avl private val func = io.in.func private val vtype = io.in.vtype private val outVConfig = io.out.vconfig private val vlWidth = p(XSCoreParamsKey).vlWidth private val isSetVlmax = VSETOpType.isSetVlmax(func) private val isVsetivli = VSETOpType.isVsetivli(func) private val vlmul: UInt = vtype.vlmul private val vsew : UInt = vtype.vsew private val vl = WireInit(0.U(XLEN.W)) // EncodedLMUL = log(LMUL) // EncodedSEW = log(SEW) - 3 // VLMAX = VLEN * LMUL / SEW // => log(VLMAX) = log(VLEN * LMUL / SEW) // => log(VLMAX) = log(VLEN) + log(LMUL) - log(SEW) // => VLMAX = 1 << log(VLMAX) // = 1 << (log(VLEN) + log(LMUL) - log(SEW)) // vlen = 128 private val log2Vlen = log2Up(VLEN) println(s"[VsetModule] log2Vlen: $log2Vlen") println(s"[VsetModule] vlWidth: $vlWidth") private val log2Vlmul = vlmul // use 2 bits vsew to store vsew private val log2Vsew = vsew(VSew.width - 1, 0) +& "b011".U // vlen = 128, lmul = 8, sew = 8, log2Vlen = 7, // vlmul = b011, vsew = 0, 7 + 3 - (0 + 3) = 7 // vlen = 128, lmul = 2, sew = 16 // vlmul = b001, vsew = 1, 7 + 1 - (1 + 3) = 4 private val log2Vlmax: UInt = log2Vlen.U(3.W) + log2Vlmul - log2Vsew private val vlmax = (1.U(vlWidth.W) << log2Vlmax).asUInt private val normalVL = Mux(avl > vlmax, vlmax, avl) vl := Mux(isVsetivli, normalVL, Mux(isSetVlmax, vlmax, normalVL)) private val log2Elen = log2Up(ELEN) private val log2VsewMax = Mux(log2Vlmul(2), log2Elen.U + log2Vlmul, log2Elen.U) private val sewIllegal = VSew.isReserved(vsew) || (log2Vsew > log2VsewMax) private val lmulIllegal = VLmul.isReserved(vlmul) private val vtypeIllegal = vtype.reserved.orR private val illegal = lmulIllegal | sewIllegal | vtypeIllegal | vtype.illegal outVConfig.vl := Mux(illegal, 0.U, vl) outVConfig.vtype.illegal := illegal outVConfig.vtype.vta := Mux(illegal, 0.U, vtype.vta) outVConfig.vtype.vma := Mux(illegal, 0.U, vtype.vma) outVConfig.vtype.vlmul := Mux(illegal, 0.U, vtype.vlmul) outVConfig.vtype.vsew := Mux(illegal, 0.U, vtype.vsew) private val log2VlenDivVsew = log2Vlen.U(3.W) - log2Vsew private val vlenDivVsew = 1.U(vlWidth.W) << log2VlenDivVsew io.out.vlmax := Mux(vlmax >= vlenDivVsew, vlmax, vlenDivVsew) io.testOut.vlmax := vlmax io.testOut.log2Vlmax := log2Vlmax }