diff --git a/src/main/scala/yunsuan/vector/VectorConvert/CVT64.scala b/src/main/scala/yunsuan/vector/VectorConvert/CVT64.scala index 368f34e..cc97a32 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 @@ -26,6 +26,18 @@ class CVT64(width: Int = 64) extends CVT(width){ val inIsFpNext = opType.head(1).asBool val outIsFpNext = opType.tail(1).head(1).asBool val hasSignIntNext = opType(0).asBool + val s0_fpCanonicalNAN = isFpToVecInst & inIsFpNext & (input1H(1) & !src.head(48).andR | input1H(2) & !src.head(32).andR) + 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 s2_fpCanonicalNAN = RegEnable(RegEnable(s0_fpCanonicalNAN, fire), fireReg) + val s2_outIsF64 = RegEnable(RegEnable(s0_outIsF64, fire), fireReg) + val s2_outIsU32 = RegEnable(RegEnable(s0_outIsU32, fire), fireReg) + val s2_outIsS32 = RegEnable(RegEnable(s0_outIsS32, fire), fireReg) + val s2_outIsU64 = RegEnable(RegEnable(s0_outIsU64, fire), fireReg) + val s2_outIsS64 = RegEnable(RegEnable(s0_outIsS64, fire), fireReg) val int1HSrcNext = input1H val float1HSrcNext = input1H.head(3)//exclude f8 @@ -609,7 +621,16 @@ class CVT64(width: Int = 64) extends CVT(width){ fflagsNext := Cat(nv, dz, of, uf, nx) - io.result := result - io.fflags := fflags + io.result := Mux(s2_fpCanonicalNAN, + Mux1H( + Seq(s2_outIsF64, s2_outIsU32, s2_outIsS32, s2_outIsU64, s2_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)) + ), + 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