1package xiangshan.backend.decode 2 3import org.chipsalliance.cde.config.Parameters 4import chisel3._ 5import chisel3.util._ 6import xiangshan._ 7import xiangshan.backend.fu.vector.Bundles.{VType, VsetVType} 8import xiangshan.backend.decode.isa.bitfield.{InstVType, Riscv32BitInst, XSInstBitFields} 9import xiangshan.backend.fu.VsetModule 10 11/** 12 * IO of VTypeGen 13 */ 14class VTypeGenIO(implicit p: Parameters) extends XSBundle { 15 val insts = Flipped(Vec(DecodeWidth, ValidIO(UInt(32.W)))) 16 val walkToArchVType = Input(Bool()) 17 val walkVType = Flipped(Valid(new VType)) 18 val canUpdateVType = Input(Bool()) 19 val vtype = Output(new VType) 20 val vsetvlVType = Input(new VType) 21 val commitVType = new Bundle { 22 val vtype = Flipped(Valid(new VType)) 23 val hasVsetvl = Input(Bool()) 24 } 25} 26/** 27 * Vtype is the vector configuration register, which is the main part of vector extension. 28 * It contains the vector length and the vector mask. This class is a module that generates vtype for each instruction. 29 */ 30class VTypeGen(implicit p: Parameters) extends XSModule{ 31 val io = IO(new VTypeGenIO) 32 /** valid signals of instructions */ 33 private val instValidVec = io.insts.map(_.valid) 34 /** instructions code */ 35 private val instFieldVec = io.insts.map(_.bits.asTypeOf(new XSInstBitFields)) 36 // Only check vsetvli and vsetivli here. 37 // vsetvl will flush pipe, need not to generate new vtype in decode stage. 38 private val isVsetVec = VecInit(instFieldVec.map(fields => 39 (fields.OPCODE === "b1010111".U) && (fields.WIDTH === "b111".U) && ( 40 fields.ALL(31) === "b0".U || 41 fields.ALL(31, 30) === "b11".U 42 ) 43 ).zip(instValidVec).map { case (isVset, valid) => valid && isVset}) 44 45 /** one-hot encoded first vset instruction's location */ 46 private val firstVsetOH: Vec[Bool] = VecInit(PriorityEncoderOH(isVsetVec)) 47 /** instruction field of first vset instruction */ 48 private val firstVsetInstField: XSInstBitFields = PriorityMux(firstVsetOH, instFieldVec) 49 50 /** first vset instruction is a vsetvli */ 51 private val isVsetvli= (firstVsetInstField.OPCODE === "b1010111".U) && 52 (firstVsetInstField.WIDTH === "b111".U) && 53 (firstVsetInstField.ALL(31) === "b0".U) 54 55 /** register of vtype in architectural state */ 56 private val vtypeArch = RegInit(VType.initVtype()) 57 /** register of vtype in speculative state */ 58 private val vtypeSpec = RegInit(VType.initVtype()) 59 60 /** next register of vtype in architectural state */ 61 private val vtypeArchNext = WireInit(vtypeArch) 62 /** next register of vtype in architectural state */ 63 private val vtypeSpecNext = WireInit(vtypeSpec) 64 65 vtypeArch := vtypeArchNext 66 vtypeSpec := vtypeSpecNext 67 68 /** New vtype field set by new vset instruction. Set vtype according to instruction type of vset */ 69 private val instVType: InstVType = Mux(isVsetvli, firstVsetInstField.ZIMM_VSETVLI.asTypeOf(new InstVType), 70 firstVsetInstField.ZIMM_VSETIVLI.asTypeOf(new InstVType)) 71 /** Convert InstVType to VsetVType */ 72 private val vtypei: VsetVType = VsetVType.fromInstVType(instVType) 73 74 /** New vtype configuration set by new vset instruction. */ 75 private val vsetModule = Module(new VsetModule) 76 vsetModule.io.in.avl := 0.U 77 vsetModule.io.in.vtype := vtypei 78 vsetModule.io.in.func := VSETOpType.uvsetvcfg_xi 79 80 /** New vtype generated by vsetModule */ 81 private val vtypeNew = vsetModule.io.out.vconfig.vtype 82 83 /** Set the source of vtypeArch from commit instructions */ 84 when(io.commitVType.hasVsetvl) { 85 vtypeArchNext := io.vsetvlVType 86 }.elsewhen(io.commitVType.vtype.valid) { 87 vtypeArchNext := io.commitVType.vtype.bits 88 } 89 90 /** whether there is a vset instruction among input instructions */ 91 private val inHasVset = isVsetVec.asUInt.orR 92 93 /** 94 * Set the source of vtypeSpec from the following sources: 95 * 1. committed vsetvl instruction, which flushes the pipeline. 96 * 2. walk-vtype, which is used to update vtype when walking. 97 * 3. walking to architectural vtype 98 * 4. new vset instruction 99 */ 100 when(io.commitVType.hasVsetvl) { 101 // when vsetvl instruction commit, also update vtypeSpec, because vsetvl flush pipe 102 vtypeSpecNext := io.vsetvlVType 103 }.elsewhen(io.walkVType.valid) { 104 vtypeSpecNext := io.walkVType.bits 105 }.elsewhen(io.walkToArchVType) { 106 vtypeSpecNext := vtypeArch 107 }.elsewhen(inHasVset && io.canUpdateVType) { 108 vtypeSpecNext := vtypeNew 109 } 110 111 /** pass speculative vtype to output */ 112 io.vtype := vtypeSpec 113 114 // just make verilog more readable 115 dontTouch(isVsetVec) 116} 117