166c73034Schengguanghuipackage xiangshan.backend.fu.wrapper 266c73034Schengguanghui 383ba63b3SXuan Huimport org.chipsalliance.cde.config.Parameters 466c73034Schengguanghuiimport chisel3._ 566c73034Schengguanghuiimport chisel3.util._ 666c73034Schengguanghuiimport chisel3.util.experimental.decode._ 7bb2f3f51STang Haojinimport utility.XSError 866c73034Schengguanghuiimport xiangshan.backend.fu.FuConfig 966c73034Schengguanghuiimport xiangshan.backend.fu.vector.{Mgu, VecPipedFuncUnit} 10c33d4a9eSXuan Huimport xiangshan.ExceptionNO 1120b2b626SsinceforYyimport xiangshan.FuOpType 1266c73034Schengguanghuiimport yunsuan.VfpuType 139d3cebe7Schengguanghuiimport yunsuan.vector.VectorConvert.VectorCvt 145f8b6c9eSsinceforYyimport yunsuan.util._ 1566c73034Schengguanghui 1666c73034Schengguanghui 1766c73034Schengguanghuiclass VCVT(cfg: FuConfig)(implicit p: Parameters) extends VecPipedFuncUnit(cfg) { 1866c73034Schengguanghui XSError(io.in.valid && io.in.bits.ctrl.fuOpType === VfpuType.dummy, "Vfcvt OpType not supported") 1966c73034Schengguanghui 2066c73034Schengguanghui // params alias 212d12882cSxiaofeibao private val dataWidth = cfg.destDataBits 2266c73034Schengguanghui private val dataWidthOfDataModule = 64 2366c73034Schengguanghui private val numVecModule = dataWidth / dataWidthOfDataModule 2466c73034Schengguanghui 2566c73034Schengguanghui // io alias 26572278faSZiyue Zhang private val opcode = fuOpType(8, 0) 2766c73034Schengguanghui private val sew = vsew 289d3cebe7Schengguanghui 299d3cebe7Schengguanghui private val isRtz = opcode(2) & opcode(1) 309d3cebe7Schengguanghui private val isRod = opcode(2) & !opcode(1) & opcode(0) 319d3cebe7Schengguanghui private val isFrm = !isRtz && !isRod 32c6efb121SZiyue Zhang private val vfcvtRm = Mux1H( 339d3cebe7Schengguanghui Seq(isRtz, isRod, isFrm), 34c6efb121SZiyue Zhang Seq(1.U, 6.U, rm) 359d3cebe7Schengguanghui ) 369d3cebe7Schengguanghui 3766c73034Schengguanghui private val lmul = vlmul // -3->3 => 1/8 ->8 3866c73034Schengguanghui 3966c73034Schengguanghui val widen = opcode(4, 3) // 0->single 1->widen 2->norrow => width of result 4066c73034Schengguanghui val isSingleCvt = !widen(1) & !widen(0) 4166c73034Schengguanghui val isWidenCvt = !widen(1) & widen(0) 4266c73034Schengguanghui val isNarrowCvt = widen(1) & !widen(0) 43e8e02b74SsinceforYy val fire = io.in.valid 445f8b6c9eSsinceforYy val fireReg = GatedValidRegNext(fire) 4566c73034Schengguanghui 4666c73034Schengguanghui // output width 8, 16, 32, 64 4766c73034Schengguanghui val output1H = Wire(UInt(4.W)) 4866c73034Schengguanghui output1H := chisel3.util.experimental.decode.decoder( 4966c73034Schengguanghui widen ## sew, 5066c73034Schengguanghui TruthTable( 5166c73034Schengguanghui Seq( 5266c73034Schengguanghui BitPat("b00_01") -> BitPat("b0010"), // 16 5366c73034Schengguanghui BitPat("b00_10") -> BitPat("b0100"), // 32 5466c73034Schengguanghui BitPat("b00_11") -> BitPat("b1000"), // 64 5566c73034Schengguanghui 5666c73034Schengguanghui BitPat("b01_00") -> BitPat("b0010"), // 16 5766c73034Schengguanghui BitPat("b01_01") -> BitPat("b0100"), // 32 5866c73034Schengguanghui BitPat("b01_10") -> BitPat("b1000"), // 64 5966c73034Schengguanghui 6066c73034Schengguanghui BitPat("b10_00") -> BitPat("b0001"), // 8 6166c73034Schengguanghui BitPat("b10_01") -> BitPat("b0010"), // 16 6266c73034Schengguanghui BitPat("b10_10") -> BitPat("b0100"), // 32 6366c73034Schengguanghui ), 649d3cebe7Schengguanghui BitPat.N(4) 6566c73034Schengguanghui ) 6666c73034Schengguanghui ) 678d081717Sszw_kaixin if(backendParams.debugEn) { 6866c73034Schengguanghui dontTouch(output1H) 698d081717Sszw_kaixin } 7066c73034Schengguanghui val outputWidth1H = output1H 71572278faSZiyue Zhang val outIs32bits = RegNext(RegNext(outputWidth1H(2))) 72572278faSZiyue Zhang val outIsInt = !outCtrl.fuOpType(6) 73c0a99c00SGuanghui Cheng 74c0a99c00SGuanghui Cheng // May be useful in the future. 75c0a99c00SGuanghui Cheng // val outIsMvInst = outCtrl.fuOpType === FuOpType.FMVXF 76c0a99c00SGuanghui Cheng val outIsMvInst = false.B 7766c73034Schengguanghui 78e8e02b74SsinceforYy val outEew = RegEnable(RegEnable(Mux1H(output1H, Seq(0,1,2,3).map(i => i.U)), fire), fireReg) 7966c73034Schengguanghui private val needNoMask = outVecCtrl.fpu.isFpToVecInst 8066c73034Schengguanghui val maskToMgu = Mux(needNoMask, allMaskTrue, outSrcMask) 8166c73034Schengguanghui 8266c73034Schengguanghui // modules 8366c73034Schengguanghui private val vfcvt = Module(new VectorCvtTop(dataWidth, dataWidthOfDataModule)) 84ba899681Schengguanghui private val mgu = Module(new Mgu(dataWidth)) 8566c73034Schengguanghui 869d3cebe7Schengguanghui val vs2Vec = Wire(Vec(numVecModule, UInt(dataWidthOfDataModule.W))) 879d3cebe7Schengguanghui vs2Vec := vs2.asTypeOf(vs2Vec) 889d3cebe7Schengguanghui 8966c73034Schengguanghui /** 9066c73034Schengguanghui * [[vfcvt]]'s in connection 9166c73034Schengguanghui */ 9266c73034Schengguanghui vfcvt.uopIdx := vuopIdx(0) 939d3cebe7Schengguanghui vfcvt.src := vs2Vec 94572278faSZiyue Zhang vfcvt.opType := opcode(7,0) 9566c73034Schengguanghui vfcvt.sew := sew 96c6efb121SZiyue Zhang vfcvt.rm := vfcvtRm 9766c73034Schengguanghui vfcvt.outputWidth1H := outputWidth1H 9866c73034Schengguanghui vfcvt.isWiden := isWidenCvt 9966c73034Schengguanghui vfcvt.isNarrow := isNarrowCvt 100e8e02b74SsinceforYy vfcvt.fire := fire 1019626da3aSchengguanghui vfcvt.isFpToVecInst := vecCtrl.fpu.isFpToVecInst 1029d3cebe7Schengguanghui val vfcvtResult = vfcvt.io.result 1039d3cebe7Schengguanghui val vfcvtFflags = vfcvt.io.fflags 10466c73034Schengguanghui 10566c73034Schengguanghui /** fflags: 10666c73034Schengguanghui */ 10766c73034Schengguanghui val eNum1H = chisel3.util.experimental.decode.decoder(sew ## (isWidenCvt || isNarrowCvt), 10866c73034Schengguanghui TruthTable( 10966c73034Schengguanghui Seq( // 8, 4, 2, 1 11066c73034Schengguanghui BitPat("b001") -> BitPat("b1000"), //8 11166c73034Schengguanghui BitPat("b010") -> BitPat("b1000"), //8 11266c73034Schengguanghui BitPat("b011") -> BitPat("b0100"), //4 11366c73034Schengguanghui BitPat("b100") -> BitPat("b0100"), //4 11466c73034Schengguanghui BitPat("b101") -> BitPat("b0010"), //2 11566c73034Schengguanghui BitPat("b110") -> BitPat("b0010"), //2 11666c73034Schengguanghui ), 11766c73034Schengguanghui BitPat.N(4) 11866c73034Schengguanghui ) 11966c73034Schengguanghui ) 120021f6af6Schengguanghui val eNum1HEffect = Mux(isWidenCvt || isNarrowCvt, eNum1H << 1, eNum1H) 121021f6af6Schengguanghui val eNumMax1H = Mux(lmul.head(1).asBool, eNum1HEffect >> ((~lmul.tail(1)).asUInt +1.U), eNum1HEffect << lmul.tail(1)).asUInt(6, 0) 12266c73034Schengguanghui 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 123572278faSZiyue Zhang val vlForFflags = Mux(vecCtrl.fpu.isFpToVecInst, 1.U, vl) 124572278faSZiyue Zhang val eNumEffectIdx = Mux(vlForFflags > eNumMax, eNumMax, vlForFflags) 1259d3cebe7Schengguanghui 1269d3cebe7Schengguanghui val eNum = Mux1H(eNum1H, Seq(1, 2, 4, 8).map(num =>num.U)) 1279d3cebe7Schengguanghui val eStart = vuopIdx * eNum 128572278faSZiyue Zhang val maskForFflags = Mux(vecCtrl.fpu.isFpToVecInst, allMaskTrue, srcMask) 129572278faSZiyue Zhang val maskPart = maskForFflags >> eStart 1309d3cebe7Schengguanghui val mask = Mux1H(eNum1H, Seq(1, 2, 4, 8).map(num => maskPart(num-1, 0))) 13166c73034Schengguanghui val fflagsEn = Wire(Vec(4 * numVecModule, Bool())) 1329d3cebe7Schengguanghui 133ba899681Schengguanghui fflagsEn := mask.asBools.zipWithIndex.map{case(mask, i) => mask & (eNumEffectIdx > eStart + i.U) } 13466c73034Schengguanghui 135e8e02b74SsinceforYy val fflagsEnCycle2 = RegEnable(RegEnable(fflagsEn, fire), fireReg) 1369d3cebe7Schengguanghui val fflagsAll = Wire(Vec(8, UInt(5.W))) 1379d3cebe7Schengguanghui fflagsAll := vfcvtFflags.asTypeOf(fflagsAll) 13866c73034Schengguanghui val fflags = fflagsEnCycle2.zip(fflagsAll).map{case(en, fflag) => Mux(en, fflag, 0.U(5.W))}.reduce(_ | _) 139572278faSZiyue Zhang io.out.bits.res.fflags.get := Mux(outIsMvInst, 0.U, fflags) 14066c73034Schengguanghui 14166c73034Schengguanghui 14266c73034Schengguanghui /** 143ba899681Schengguanghui * [[mgu]]'s in connection 14466c73034Schengguanghui */ 145ba899681Schengguanghui val resultDataUInt = Wire(UInt(dataWidth.W)) 14666c73034Schengguanghui resultDataUInt := vfcvtResult 14766c73034Schengguanghui 148e8e02b74SsinceforYy private val narrow = RegEnable(RegEnable(isNarrowCvt, fire), fireReg) 14917f57ffdSZiyue Zhang private val narrowNeedCat = outVecCtrl.vuopIdx(0).asBool && narrow 150e03e0c5bSZiyue Zhang private val outNarrowVd = Mux(narrowNeedCat, Cat(resultDataUInt(dataWidth / 2 - 1, 0), outOldVd(dataWidth / 2 - 1, 0)), 151e03e0c5bSZiyue Zhang Cat(outOldVd(dataWidth - 1, dataWidth / 2), resultDataUInt(dataWidth / 2 - 1, 0))) 15217f57ffdSZiyue Zhang 153*ac5be754Sjunxiong-ji // mgu.io.in.vd := resultDataUInt 15417f57ffdSZiyue Zhang mgu.io.in.vd := Mux(narrow, outNarrowVd, resultDataUInt) 15566c73034Schengguanghui mgu.io.in.oldVd := outOldVd 15666c73034Schengguanghui mgu.io.in.mask := maskToMgu 15766c73034Schengguanghui mgu.io.in.info.ta := outVecCtrl.vta 15866c73034Schengguanghui mgu.io.in.info.ma := outVecCtrl.vma 15966c73034Schengguanghui mgu.io.in.info.vl := Mux(outVecCtrl.fpu.isFpToVecInst, 1.U, outVl) 16066c73034Schengguanghui mgu.io.in.info.vlmul := outVecCtrl.vlmul 16166c73034Schengguanghui mgu.io.in.info.valid := io.out.valid 16266c73034Schengguanghui mgu.io.in.info.vstart := Mux(outVecCtrl.fpu.isFpToVecInst, 0.U, outVecCtrl.vstart) 16366c73034Schengguanghui mgu.io.in.info.eew := outEew 16466c73034Schengguanghui mgu.io.in.info.vsew := outVecCtrl.vsew 16566c73034Schengguanghui mgu.io.in.info.vdIdx := outVecCtrl.vuopIdx 16617f57ffdSZiyue Zhang mgu.io.in.info.narrow := narrow 16766c73034Schengguanghui mgu.io.in.info.dstMask := outVecCtrl.isDstMask 16892c6b7edSzhanglinjuan mgu.io.in.isIndexedVls := false.B 16966c73034Schengguanghui 170572278faSZiyue Zhang // for scalar f2i cvt inst 171572278faSZiyue Zhang val isFp2VecForInt = outVecCtrl.fpu.isFpToVecInst && outIs32bits && outIsInt 172572278faSZiyue Zhang // for f2i mv inst 173572278faSZiyue Zhang val result = Mux(outIsMvInst, RegNext(RegNext(vs2.tail(64))), mgu.io.out.vd) 174572278faSZiyue Zhang 175572278faSZiyue Zhang io.out.bits.res.data := Mux(isFp2VecForInt, 176572278faSZiyue Zhang Fill(32, result(31)) ## result(31, 0), 177572278faSZiyue Zhang result 178572278faSZiyue Zhang ) 179c33d4a9eSXuan Hu io.out.bits.ctrl.exceptionVec.get(ExceptionNO.illegalInstr) := mgu.io.out.illegal 18066c73034Schengguanghui} 18166c73034Schengguanghui 1829d3cebe7Schengguanghuiclass VectorCvtTopIO(vlen: Int, xlen: Int) extends Bundle{ 183e8e02b74SsinceforYy val fire = Input(Bool()) 1849d3cebe7Schengguanghui val uopIdx = Input(Bool()) 18566c73034Schengguanghui val src = Input(Vec(vlen / xlen, UInt(xlen.W))) 18666c73034Schengguanghui val opType = Input(UInt(8.W)) 18766c73034Schengguanghui val sew = Input(UInt(2.W)) 18866c73034Schengguanghui val rm = Input(UInt(3.W)) 18966c73034Schengguanghui val outputWidth1H = Input(UInt(4.W)) 19066c73034Schengguanghui val isWiden = Input(Bool()) 19166c73034Schengguanghui val isNarrow = Input(Bool()) 1929626da3aSchengguanghui val isFpToVecInst = Input(Bool()) 19366c73034Schengguanghui 1949d3cebe7Schengguanghui val result = Output(UInt(vlen.W)) 1959d3cebe7Schengguanghui val fflags = Output(UInt((vlen/16*5).W)) 1969d3cebe7Schengguanghui} 1979d3cebe7Schengguanghui 1989d3cebe7Schengguanghui 1999d3cebe7Schengguanghui 2009d3cebe7Schengguanghui//according to uopindex, 1: high64 0:low64 2019d3cebe7Schengguanghuiclass VectorCvtTop(vlen: Int, xlen: Int) extends Module{ 2029d3cebe7Schengguanghui val io = IO(new VectorCvtTopIO(vlen, xlen)) 2039d3cebe7Schengguanghui 2049626da3aSchengguanghui val (fire, uopIdx, src, opType, sew, rm, outputWidth1H, isWiden, isNarrow, isFpToVecInst) = ( 2059626da3aSchengguanghui io.fire, io.uopIdx, io.src, io.opType, io.sew, io.rm, io.outputWidth1H, io.isWiden, io.isNarrow, io.isFpToVecInst 2069d3cebe7Schengguanghui ) 2075f8b6c9eSsinceforYy val fireReg = GatedValidRegNext(fire) 20866c73034Schengguanghui 2099626da3aSchengguanghui val in0 = Mux(isWiden && !isFpToVecInst, 2109d3cebe7Schengguanghui Mux(uopIdx, src(1).tail(32), src(0).tail(32)), 21166c73034Schengguanghui src(0) 21266c73034Schengguanghui ) 21366c73034Schengguanghui 21466c73034Schengguanghui val in1 = Mux(isWiden, 2159d3cebe7Schengguanghui Mux(uopIdx, src(1).head(32), src(0).head(32)), 21666c73034Schengguanghui src(1) 21766c73034Schengguanghui ) 21866c73034Schengguanghui 21966c73034Schengguanghui val vectorCvt0 = Module(new VectorCvt(xlen)) 220e8e02b74SsinceforYy vectorCvt0.fire := fire 22166c73034Schengguanghui vectorCvt0.src := in0 22266c73034Schengguanghui vectorCvt0.opType := opType 22366c73034Schengguanghui vectorCvt0.sew := sew 22466c73034Schengguanghui vectorCvt0.rm := rm 2259626da3aSchengguanghui vectorCvt0.isFpToVecInst := isFpToVecInst 22620b2b626SsinceforYy vectorCvt0.isFround := 0.U 22720b2b626SsinceforYy vectorCvt0.isFcvtmod := false.B 22866c73034Schengguanghui 22966c73034Schengguanghui val vectorCvt1 = Module(new VectorCvt(xlen)) 230e8e02b74SsinceforYy vectorCvt1.fire := fire 23166c73034Schengguanghui vectorCvt1.src := in1 23266c73034Schengguanghui vectorCvt1.opType := opType 23366c73034Schengguanghui vectorCvt1.sew := sew 23466c73034Schengguanghui vectorCvt1.rm := rm 2359626da3aSchengguanghui vectorCvt1.isFpToVecInst := isFpToVecInst 23620b2b626SsinceforYy vectorCvt1.isFround := 0.U 23720b2b626SsinceforYy vectorCvt1.isFcvtmod := false.B 23866c73034Schengguanghui 239e8e02b74SsinceforYy val isNarrowCycle2 = RegEnable(RegEnable(isNarrow, fire), fireReg) 240e8e02b74SsinceforYy val outputWidth1HCycle2 = RegEnable(RegEnable(outputWidth1H, fire), fireReg) 24166c73034Schengguanghui 24266c73034Schengguanghui //cycle2 2439d3cebe7Schengguanghui io.result := Mux(isNarrowCycle2, 24466c73034Schengguanghui vectorCvt1.io.result.tail(32) ## vectorCvt0.io.result.tail(32), 2459d3cebe7Schengguanghui vectorCvt1.io.result ## vectorCvt0.io.result) 24666c73034Schengguanghui 247ba899681Schengguanghui io.fflags := Mux1H(outputWidth1HCycle2, Seq( 24866c73034Schengguanghui vectorCvt1.io.fflags ## vectorCvt0.io.fflags, 24966c73034Schengguanghui Mux(isNarrowCycle2, vectorCvt1.io.fflags.tail(10) ## vectorCvt0.io.fflags.tail(10), vectorCvt1.io.fflags ## vectorCvt0.io.fflags), 25066c73034Schengguanghui Mux(isNarrowCycle2, vectorCvt1.io.fflags(4,0) ## vectorCvt0.io.fflags(4,0), vectorCvt1.io.fflags.tail(10) ## vectorCvt0.io.fflags.tail(10)), 25166c73034Schengguanghui vectorCvt1.io.fflags(4,0) ## vectorCvt0.io.fflags(4,0) 25266c73034Schengguanghui )) 25366c73034Schengguanghui} 25466c73034Schengguanghui 25566c73034Schengguanghui 256