1package xiangshan.backend.fu.wrapper 2 3import org.chipsalliance.cde.config.Parameters 4import chisel3._ 5import chisel3.util._ 6import chisel3.util.experimental.decode._ 7import utils.XSError 8import xiangshan.backend.fu.FuConfig 9import xiangshan.backend.fu.vector.{Mgu, VecPipedFuncUnit} 10import xiangshan.ExceptionNO 11import yunsuan.VfpuType 12import yunsuan.vector.VectorConvert.VectorCvt 13 14 15class VCVT(cfg: FuConfig)(implicit p: Parameters) extends VecPipedFuncUnit(cfg) { 16 XSError(io.in.valid && io.in.bits.ctrl.fuOpType === VfpuType.dummy, "Vfcvt OpType not supported") 17 18 // params alias 19 private val dataWidth = cfg.dataBits 20 private val dataWidthOfDataModule = 64 21 private val numVecModule = dataWidth / dataWidthOfDataModule 22 23 // io alias 24 private val opcode = fuOpType(7, 0) 25 private val sew = vsew 26 27 private val isRtz = opcode(2) & opcode(1) 28 private val isRod = opcode(2) & !opcode(1) & opcode(0) 29 private val isFrm = !isRtz && !isRod 30 private val rm = Mux1H( 31 Seq(isRtz, isRod, isFrm), 32 Seq(1.U, 6.U, frm) 33 ) 34 35 private val lmul = vlmul // -3->3 => 1/8 ->8 36 37 val widen = opcode(4, 3) // 0->single 1->widen 2->norrow => width of result 38 val isSingleCvt = !widen(1) & !widen(0) 39 val isWidenCvt = !widen(1) & widen(0) 40 val isNarrowCvt = widen(1) & !widen(0) 41 42 // output width 8, 16, 32, 64 43 val output1H = Wire(UInt(4.W)) 44 output1H := chisel3.util.experimental.decode.decoder( 45 widen ## sew, 46 TruthTable( 47 Seq( 48 BitPat("b00_01") -> BitPat("b0010"), // 16 49 BitPat("b00_10") -> BitPat("b0100"), // 32 50 BitPat("b00_11") -> BitPat("b1000"), // 64 51 52 BitPat("b01_00") -> BitPat("b0010"), // 16 53 BitPat("b01_01") -> BitPat("b0100"), // 32 54 BitPat("b01_10") -> BitPat("b1000"), // 64 55 56 BitPat("b10_00") -> BitPat("b0001"), // 8 57 BitPat("b10_01") -> BitPat("b0010"), // 16 58 BitPat("b10_10") -> BitPat("b0100"), // 32 59 ), 60 BitPat.N(4) 61 ) 62 ) 63 dontTouch(output1H) 64 val outputWidth1H = output1H 65 66 val outEew = RegNext(RegNext(Mux1H(output1H, Seq(0,1,2,3).map(i => i.U)))) 67 private val needNoMask = outVecCtrl.fpu.isFpToVecInst 68 val maskToMgu = Mux(needNoMask, allMaskTrue, outSrcMask) 69 70 // modules 71 private val vfcvt = Module(new VectorCvtTop(dataWidth, dataWidthOfDataModule)) 72 private val mgu = Module(new Mgu(dataWidth)) 73 74 val vs2Vec = Wire(Vec(numVecModule, UInt(dataWidthOfDataModule.W))) 75 vs2Vec := vs2.asTypeOf(vs2Vec) 76 77 /** 78 * [[vfcvt]]'s in connection 79 */ 80 vfcvt.uopIdx := vuopIdx(0) 81 vfcvt.src := vs2Vec 82 vfcvt.opType := opcode 83 vfcvt.sew := sew 84 vfcvt.rm := rm 85 vfcvt.outputWidth1H := outputWidth1H 86 vfcvt.isWiden := isWidenCvt 87 vfcvt.isNarrow := isNarrowCvt 88 val vfcvtResult = vfcvt.io.result 89 val vfcvtFflags = vfcvt.io.fflags 90 91 /** fflags: 92 */ 93 val eNum1H = chisel3.util.experimental.decode.decoder(sew ## (isWidenCvt || isNarrowCvt), 94 TruthTable( 95 Seq( // 8, 4, 2, 1 96 BitPat("b001") -> BitPat("b1000"), //8 97 BitPat("b010") -> BitPat("b1000"), //8 98 BitPat("b011") -> BitPat("b0100"), //4 99 BitPat("b100") -> BitPat("b0100"), //4 100 BitPat("b101") -> BitPat("b0010"), //2 101 BitPat("b110") -> BitPat("b0010"), //2 102 ), 103 BitPat.N(4) 104 ) 105 ) 106 val eNumMax1H = Mux(lmul.head(1).asBool, eNum1H >> ((~lmul.tail(1)).asUInt +1.U), eNum1H << lmul.tail(1)).asUInt(6, 0) 107 val eNumMax = Mux1H(eNumMax1H, Seq(1,2,4,8,16,32,64).map(i => i.U)) //only for cvt intr, don't exist 128 in cvt 108 val eNumEffectIdx = Mux(vl > eNumMax, eNumMax, vl) 109 110 val eNum = Mux1H(eNum1H, Seq(1, 2, 4, 8).map(num =>num.U)) 111 val eStart = vuopIdx * eNum 112 val maskPart = srcMask >> eStart 113 val mask = Mux1H(eNum1H, Seq(1, 2, 4, 8).map(num => maskPart(num-1, 0))) 114 val fflagsEn = Wire(Vec(4 * numVecModule, Bool())) 115 116 fflagsEn := mask.asBools.zipWithIndex.map{case(mask, i) => mask & (eNumEffectIdx > eStart + i.U) } 117 118 val fflagsEnCycle2 = RegNext(RegNext(fflagsEn)) 119 val fflagsAll = Wire(Vec(8, UInt(5.W))) 120 fflagsAll := vfcvtFflags.asTypeOf(fflagsAll) 121 val fflags = fflagsEnCycle2.zip(fflagsAll).map{case(en, fflag) => Mux(en, fflag, 0.U(5.W))}.reduce(_ | _) 122 io.out.bits.res.fflags.get := fflags 123 124 125 /** 126 * [[mgu]]'s in connection 127 */ 128 val resultDataUInt = Wire(UInt(dataWidth.W)) 129 resultDataUInt := vfcvtResult 130 131 mgu.io.in.vd := resultDataUInt 132 mgu.io.in.oldVd := outOldVd 133 mgu.io.in.mask := maskToMgu 134 mgu.io.in.info.ta := outVecCtrl.vta 135 mgu.io.in.info.ma := outVecCtrl.vma 136 mgu.io.in.info.vl := Mux(outVecCtrl.fpu.isFpToVecInst, 1.U, outVl) 137 mgu.io.in.info.vlmul := outVecCtrl.vlmul 138 mgu.io.in.info.valid := io.out.valid 139 mgu.io.in.info.vstart := Mux(outVecCtrl.fpu.isFpToVecInst, 0.U, outVecCtrl.vstart) 140 mgu.io.in.info.eew := outEew 141 mgu.io.in.info.vsew := outVecCtrl.vsew 142 mgu.io.in.info.vdIdx := outVecCtrl.vuopIdx 143 mgu.io.in.info.narrow := RegNext(RegNext(isNarrowCvt)) 144 mgu.io.in.info.dstMask := outVecCtrl.isDstMask 145 146 io.out.bits.res.data := mgu.io.out.vd 147 io.out.bits.ctrl.exceptionVec.get(ExceptionNO.illegalInstr) := mgu.io.out.illegal 148} 149 150class VectorCvtTopIO(vlen: Int, xlen: Int) extends Bundle{ 151 val uopIdx = Input(Bool()) 152 val src = Input(Vec(vlen / xlen, UInt(xlen.W))) 153 val opType = Input(UInt(8.W)) 154 val sew = Input(UInt(2.W)) 155 val rm = Input(UInt(3.W)) 156 val outputWidth1H = Input(UInt(4.W)) 157 val isWiden = Input(Bool()) 158 val isNarrow = Input(Bool()) 159 160 val result = Output(UInt(vlen.W)) 161 val fflags = Output(UInt((vlen/16*5).W)) 162} 163 164 165 166//according to uopindex, 1: high64 0:low64 167class VectorCvtTop(vlen: Int, xlen: Int) extends Module{ 168 val io = IO(new VectorCvtTopIO(vlen, xlen)) 169 170 val (uopIdx, src, opType, sew, rm, outputWidth1H, isWiden, isNarrow) = ( 171 io.uopIdx, io.src, io.opType, io.sew, io.rm, io.outputWidth1H, io.isWiden, io.isNarrow 172 ) 173 174 val in0 = Mux(isWiden, 175 Mux(uopIdx, src(1).tail(32), src(0).tail(32)), 176 src(0) 177 ) 178 179 val in1 = Mux(isWiden, 180 Mux(uopIdx, src(1).head(32), src(0).head(32)), 181 src(1) 182 ) 183 184 val vectorCvt0 = Module(new VectorCvt(xlen)) 185 vectorCvt0.src := in0 186 vectorCvt0.opType := opType 187 vectorCvt0.sew := sew 188 vectorCvt0.rm := rm 189 190 val vectorCvt1 = Module(new VectorCvt(xlen)) 191 vectorCvt1.src := in1 192 vectorCvt1.opType := opType 193 vectorCvt1.sew := sew 194 vectorCvt1.rm := rm 195 196 val isNarrowCycle2 = RegNext(RegNext(isNarrow)) 197 val outputWidth1HCycle2 = RegNext(RegNext(outputWidth1H)) 198 199 //cycle2 200 io.result := Mux(isNarrowCycle2, 201 vectorCvt1.io.result.tail(32) ## vectorCvt0.io.result.tail(32), 202 vectorCvt1.io.result ## vectorCvt0.io.result) 203 204 io.fflags := Mux1H(outputWidth1HCycle2, Seq( 205 vectorCvt1.io.fflags ## vectorCvt0.io.fflags, 206 Mux(isNarrowCycle2, vectorCvt1.io.fflags.tail(10) ## vectorCvt0.io.fflags.tail(10), vectorCvt1.io.fflags ## vectorCvt0.io.fflags), 207 Mux(isNarrowCycle2, vectorCvt1.io.fflags(4,0) ## vectorCvt0.io.fflags(4,0), vectorCvt1.io.fflags.tail(10) ## vectorCvt0.io.fflags.tail(10)), 208 vectorCvt1.io.fflags(4,0) ## vectorCvt0.io.fflags(4,0) 209 )) 210} 211 212 213