From e146f9396c1e5df951d141a57ece0bd0010c0be9 Mon Sep 17 00:00:00 2001 From: chengguanghui Date: Sun, 7 Apr 2024 11:19:08 +0800 Subject: [PATCH] vfcvt: add fpCanonicalNAN for scalar fvt inst --- .../yunsuan/vector/VectorConvert/CVT64.scala | 38 +++++++++++++++++-- .../vector/VectorConvert/Convert.scala | 13 ++++--- .../yunsuan/vector/VectorConvert/VCVT.scala | 5 ++- src/test/scala/top/VectorSimTop.scala | 1 + 4 files changed, 46 insertions(+), 11 deletions(-) diff --git a/src/main/scala/yunsuan/vector/VectorConvert/CVT64.scala b/src/main/scala/yunsuan/vector/VectorConvert/CVT64.scala index 368f34e..e97c559 100644 --- a/src/main/scala/yunsuan/vector/VectorConvert/CVT64.scala +++ b/src/main/scala/yunsuan/vector/VectorConvert/CVT64.scala @@ -16,8 +16,8 @@ class CVT64(width: Int = 64) extends CVT(width){ val widthExpAdder = 13 // 13bits is enough // input - val (fire, src, sew, opType, rmNext, input1H, output1H) = - (io.fire, io.src, io.sew, io.opType, io.rm, io.input1H, io.output1H) + val (fire, src, sew, opType, rmNext, input1H, output1H, isFpToVecInst) = + (io.fire, io.src, io.sew, io.opType, io.rm, io.input1H, io.output1H, io.isFpToVecInst) val fireReg = GatedValidRegNext(fire) // control for cycle 0 @@ -27,6 +27,27 @@ class CVT64(width: Int = 64) extends CVT(width){ val outIsFpNext = opType.tail(1).head(1).asBool val hasSignIntNext = opType(0).asBool + val s0_outIsF64 = outIsFpNext && output1H(3) + val s0_outIsU32 = !outIsFpNext && output1H(2) && !hasSignIntNext + val s0_outIsS32 = !outIsFpNext && output1H(2) && hasSignIntNext + val s0_outIsU64 = !outIsFpNext && output1H(3) && !hasSignIntNext + val s0_outIsS64 = !outIsFpNext && output1H(3) && hasSignIntNext + val s0_fpCanonicalNAN = isFpToVecInst & inIsFpNext & (input1H(1) & !src.head(48).andR | input1H(2) & !src.head(32).andR) + + val s1_outIsF64 = RegEnable(s0_outIsF64, fire) + val s1_outIsU32 = RegEnable(s0_outIsU32, fire) + val s1_outIsS32 = RegEnable(s0_outIsS32, fire) + val s1_outIsU64 = RegEnable(s0_outIsU64, fire) + val s1_outIsS64 = RegEnable(s0_outIsS64, fire) + val s1_fpCanonicalNAN = RegEnable(s0_fpCanonicalNAN, fire) + + val s2_outIsF64 = RegEnable(s1_outIsF64, fireReg) + val s2_outIsU32 = RegEnable(s1_outIsU32, fireReg) + val s2_outIsS32 = RegEnable(s1_outIsS32, fireReg) + val s2_outIsU64 = RegEnable(s1_outIsU64, fireReg) + val s2_outIsS64 = RegEnable(s1_outIsS64, fireReg) + val s2_fpCanonicalNAN = RegEnable(s1_fpCanonicalNAN, fireReg) + val int1HSrcNext = input1H val float1HSrcNext = input1H.head(3)//exclude f8 @@ -609,7 +630,16 @@ class CVT64(width: Int = 64) extends CVT(width){ fflagsNext := Cat(nv, dz, of, uf, nx) - io.result := result - io.fflags := fflags + val s1_resultForfpCanonicalNAN = Mux1H( + Seq(s1_outIsF64, s1_outIsU32, s1_outIsS32, s1_outIsU64, s1_outIsS64), + Seq(~0.U((f64.expWidth+1).W) ## 0.U((f64.fracWidth-1).W), + ~0.U(32.W), + ~0.U(31.W), + ~0.U(64.W), + ~0.U(63.W)) + ) + val s2_resultForfpCanonicalNAN = RegEnable(s1_resultForfpCanonicalNAN, fireReg) + io.result := Mux(s2_fpCanonicalNAN, s2_resultForfpCanonicalNAN, result) + io.fflags := Mux(s2_fpCanonicalNAN && !s2_outIsF64, "b10000".U, fflags) } diff --git a/src/main/scala/yunsuan/vector/VectorConvert/Convert.scala b/src/main/scala/yunsuan/vector/VectorConvert/Convert.scala index 90368a6..d891936 100644 --- a/src/main/scala/yunsuan/vector/VectorConvert/Convert.scala +++ b/src/main/scala/yunsuan/vector/VectorConvert/Convert.scala @@ -11,6 +11,7 @@ class VectorCvtIO(width: Int) extends Bundle { val opType = Input(UInt(8.W)) val sew = Input(UInt(2.W)) val rm = Input(UInt(3.W)) + val isFpToVecInst = Input(Bool()) val result = Output(UInt(width.W)) val fflags = Output(UInt(20.W)) @@ -19,7 +20,7 @@ class VectorCvtIO(width: Int) extends Bundle { class VectorCvt(xlen :Int) extends Module{ val io = IO(new VectorCvtIO(xlen)) - val (fire, src, opType, sew, rm) = (io.fire, io.src, io.opType, io.sew, io.rm) + val (fire, src, opType, sew, rm, isFpToVecInst) = (io.fire, io.src, io.opType, io.sew, io.rm, io.isFpToVecInst) val widen = opType(4, 3) // 0->single 1->widen 2->norrow => width of result // input width 8, 16, 32, 64 @@ -82,16 +83,16 @@ class VectorCvt(xlen :Int) extends Module{ element32 := src.asTypeOf(element32) element64 := src.asTypeOf(element64) - val in0 = Mux1H(inputWidth1H, Seq(element8(0), element16(0), element32(0), element64(0))) + val in0 = element64(0) val in1 = Mux1H(inputWidth1H, Seq(element8(1), element16(1), element32(1), 0.U))// input 0=> result 0 while norrow eg. 64b->32b val in2 = Mux1H(inputWidth1H, Seq(element8(2), element16(2), 0.U, 0.U)) val in3 = Mux1H(inputWidth1H, Seq(element8(3), element16(3), 0.U, 0.U)) - val (result0, fflags0) = VCVT(64)(fire, in0, opType, sew, rm, input1H, output1H) - val (result1, fflags1) = VCVT(32)(fire, in1, opType, sew, rm, input1H, output1H) - val (result2, fflags2) = VCVT(16)(fire, in2, opType, sew, rm, input1H, output1H) - val (result3, fflags3) = VCVT(16)(fire, in3, opType, sew, rm, input1H, output1H) + val (result0, fflags0) = VCVT(64)(fire, in0, opType, sew, rm, input1H, output1H, isFpToVecInst) + val (result1, fflags1) = VCVT(32)(fire, in1, opType, sew, rm, input1H, output1H, isFpToVecInst) + val (result2, fflags2) = VCVT(16)(fire, in2, opType, sew, rm, input1H, output1H, isFpToVecInst) + val (result3, fflags3) = VCVT(16)(fire, in3, opType, sew, rm, input1H, output1H, isFpToVecInst) io.result := Mux1H(outputWidth1H, Seq( result3(7,0) ## result2(7,0) ## result1(7,0) ## result0(7,0), diff --git a/src/main/scala/yunsuan/vector/VectorConvert/VCVT.scala b/src/main/scala/yunsuan/vector/VectorConvert/VCVT.scala index 7325c30..bb2db97 100644 --- a/src/main/scala/yunsuan/vector/VectorConvert/VCVT.scala +++ b/src/main/scala/yunsuan/vector/VectorConvert/VCVT.scala @@ -11,6 +11,7 @@ class CVTIO(width: Int) extends Bundle { val rm = Input(UInt(3.W)) val input1H = Input(UInt(4.W)) val output1H = Input(UInt(4.W)) + val isFpToVecInst = Input(Bool()) val result = Output(UInt(width.W)) val fflags = Output(UInt(5.W)) } @@ -37,7 +38,8 @@ object VCVT { sew: UInt, rm: UInt, input1H: UInt, - output1H: UInt + output1H: UInt, + isFpToVecInst: Bool ): (UInt, UInt) = { val vcvtWraper = Module(new VCVT(width)) vcvtWraper.io.fire := fire @@ -47,6 +49,7 @@ object VCVT { vcvtWraper.io.rm := rm vcvtWraper.io.input1H := input1H vcvtWraper.io.output1H := output1H + vcvtWraper.io.isFpToVecInst := isFpToVecInst (vcvtWraper.io.result, vcvtWraper.io.fflags) } } \ No newline at end of file diff --git a/src/test/scala/top/VectorSimTop.scala b/src/test/scala/top/VectorSimTop.scala index bdc2800..ba7e559 100644 --- a/src/test/scala/top/VectorSimTop.scala +++ b/src/test/scala/top/VectorSimTop.scala @@ -262,6 +262,7 @@ class SimTop() extends VPUTestModule { vcvt.io.opType := opcode vcvt.io.rm := rm vcvt.io.src := src1 // 128 bit->vcvt + vcvt.io.isFpToVecInst := false.B vcvt_result.vxsat := 0.U vcvt_result.result(i) := vcvt.io.result vcvt_result.fflags(i) := vcvt.io.fflags