Skip to content

Commit

Permalink
Zfa: Support Zfa extension
Browse files Browse the repository at this point in the history
* Support fli.s, fli.d, fminm.s, fminm.d, fmaxm.s, fmaxm.d
* Support fround.s, fround.d, froundnx.s, froundnx.d, fcvtmod.w.d
* Support fleq.s, fleq.d, fltq.s, fltq.d
  • Loading branch information
sinceforYy committed Aug 28, 2024
1 parent 2a514e0 commit 31230a5
Show file tree
Hide file tree
Showing 8 changed files with 193 additions and 25 deletions.
69 changes: 62 additions & 7 deletions src/main/scala/yunsuan/fpu/FloatAdder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ class FloatAdder() extends Module {
val is_flt = io.op_code === FaddOpCode.flt
val is_fle = io.op_code === FaddOpCode.fle
val is_fclass = io.op_code === FaddOpCode.fclass
val resultNeedBox = RegEnable(is_add || is_sub || is_min || is_max || is_fsgnj || is_fsgnjn || is_fsgnjx, fire)
val is_fminm = io.op_code === FaddOpCode.fminm
val is_fmaxm = io.op_code === FaddOpCode.fmaxm
val resultNeedBox = RegEnable(is_add || is_sub || is_min || is_max || is_fsgnj || is_fsgnjn || is_fsgnjx || is_fminm || is_fmaxm, fire)
val fp_f64_result = F64_result
val fp_f32_result = Cat(Fill(32, resultNeedBox), F32_result)
val fp_f16_result = Cat(Fill(48, resultNeedBox), F16_result)
Expand Down Expand Up @@ -177,8 +179,10 @@ private[fpu] class FloatAdderF32F16MixedPipeline(val is_print:Boolean = false,va
)
val fp_a_is_NAN = io.fp_aIsFpCanonicalNAN | Efp_a_is_all_one & fp_a_mantissa_isnot_zero
val fp_a_is_SNAN = !io.fp_aIsFpCanonicalNAN & Efp_a_is_all_one & fp_a_mantissa_isnot_zero & !fp_a_to32(significandWidth-2)
val fp_a_is_QNAN = !io.fp_aIsFpCanonicalNAN & Efp_a_is_all_one & fp_a_mantissa_isnot_zero & fp_a_to32(significandWidth-2)
val fp_b_is_NAN = io.fp_bIsFpCanonicalNAN | Efp_b_is_all_one & fp_b_mantissa_isnot_zero
val fp_b_is_SNAN = !io.fp_bIsFpCanonicalNAN & Efp_b_is_all_one & fp_b_mantissa_isnot_zero & !fp_b_to32(significandWidth-2)
val fp_b_is_QNAN = !io.fp_bIsFpCanonicalNAN & Efp_b_is_all_one & fp_b_mantissa_isnot_zero & fp_b_to32(significandWidth-2)
val fp_a_is_infinite = !io.fp_aIsFpCanonicalNAN & Efp_a_is_all_one & (!fp_a_mantissa_isnot_zero)
val fp_b_is_infinite = !io.fp_bIsFpCanonicalNAN & Efp_b_is_all_one & (!fp_b_mantissa_isnot_zero)
val fp_a_is_zero = !io.fp_aIsFpCanonicalNAN & Efp_a_is_zero & !fp_a_mantissa_isnot_zero
Expand Down Expand Up @@ -228,6 +232,10 @@ private[fpu] class FloatAdderF32F16MixedPipeline(val is_print:Boolean = false,va
val is_fsgnjn = io.op_code === FaddOpCode.fsgnjn
val is_fsgnjx = io.op_code === FaddOpCode.fsgnjx
val is_fclass = io.op_code === FaddOpCode.fclass
val is_fminm = io.op_code === FaddOpCode.fminm
val is_fmaxm = io.op_code === FaddOpCode.fmaxm
val is_fleq = io.op_code === FaddOpCode.fleq
val is_fltq = io.op_code === FaddOpCode.fltq

val fp_a_sign = fp_a_to32.head(1)
val fp_b_sign = fp_b_to32.head(1)
Expand All @@ -250,6 +258,8 @@ private[fpu] class FloatAdderF32F16MixedPipeline(val is_print:Boolean = false,va
val result_flt = Wire(UInt(floatWidth.W))
val result_fle = Wire(UInt(floatWidth.W))
val result_fclass = Wire(UInt(floatWidth.W))
val result_fminm = Wire(UInt(floatWidth.W))
val result_fmaxm = Wire(UInt(floatWidth.W))
val in_NAN = Mux(res_is_f32, Cat(0.U(1.W),Fill(9, 1.U(1.W)),0.U(22.W)), Cat(0.U(17.W),Fill(6, 1.U(1.W)),0.U(9.W)))
val fp_aFix = Mux(io.fp_aIsFpCanonicalNAN, in_NAN, io.fp_a)
val fp_bFix = Mux(io.fp_bIsFpCanonicalNAN, in_NAN, io.fp_b)
Expand Down Expand Up @@ -308,18 +318,32 @@ private[fpu] class FloatAdderF32F16MixedPipeline(val is_print:Boolean = false,va
fp_a_is_SNAN,
fp_a_is_NAN & !fp_a_is_SNAN
)))
result_fminm := Mux(!fp_a_is_NAN & !fp_b_is_NAN,
Mux(fp_b_is_less || (fp_b_sign.asBool && fp_b_is_zero && fp_a_is_zero),
fp_b_16_or_32,
fp_a_16_or_32),
out_NAN
)
result_fmaxm := Mux(!fp_a_is_NAN & !fp_b_is_NAN,
Mux(fp_b_is_greater.asBool || (!fp_b_sign.asBool && fp_b_is_zero && fp_a_is_zero),
fp_b_16_or_32,
fp_a_16_or_32),
out_NAN
)

val result_stage0 = Mux1H(
Seq(
is_min,
is_max,
is_feq,
is_flt,
is_fle,
is_flt | is_fltq,
is_fle | is_fleq,
is_fsgnj,
is_fsgnjn,
is_fsgnjx,
is_fclass,
is_fminm,
is_fmaxm,
),
Seq(
result_min,
Expand All @@ -331,11 +355,15 @@ private[fpu] class FloatAdderF32F16MixedPipeline(val is_print:Boolean = false,va
result_fsgnjn,
result_fsgnjx,
result_fclass,
result_fminm,
result_fmaxm,
)
)
val fflags_NV_stage0 = ((is_min | is_max) & (fp_a_is_SNAN | fp_b_is_SNAN)) |
((is_feq ) & (fp_a_is_SNAN | fp_b_is_SNAN)) |
((is_flt | is_fle ) & (fp_a_is_NAN | fp_b_is_NAN))
((is_flt | is_fle ) & (fp_a_is_NAN | fp_b_is_NAN)) |
((is_fminm | is_fmaxm) & (fp_a_is_SNAN | fp_b_is_SNAN)) |
((is_fltq | is_fleq) & (fp_a_is_SNAN | fp_b_is_SNAN))
val fflags_stage0 = Cat(fflags_NV_stage0,0.U(4.W))
io.fp_c := Mux(RegEnable(is_add | is_sub , fire),float_adder_result,RegEnable(result_stage0, fire))
io.fflags := Mux(RegEnable(is_add | is_sub , fire),float_adder_fflags,RegEnable(fflags_stage0, fire))
Expand Down Expand Up @@ -390,8 +418,10 @@ private[fpu] class FloatAdderF64Pipeline(val is_print:Boolean = false,val hasMin
val Efp_b_is_all_one = Efp_b.andR
val fp_a_is_NAN = io.fp_aIsFpCanonicalNAN | Efp_a_is_all_one & fp_a_mantissa_isnot_zero
val fp_a_is_SNAN = !io.fp_aIsFpCanonicalNAN & Efp_a_is_all_one & fp_a_mantissa_isnot_zero & !fp_a_to64(significandWidth-2)
val fp_a_is_QNAN = !io.fp_aIsFpCanonicalNAN & Efp_a_is_all_one & fp_a_mantissa_isnot_zero & fp_a_to64(significandWidth-2)
val fp_b_is_NAN = io.fp_bIsFpCanonicalNAN | Efp_b_is_all_one & fp_b_mantissa_isnot_zero
val fp_b_is_SNAN = !io.fp_bIsFpCanonicalNAN & Efp_b_is_all_one & fp_b_mantissa_isnot_zero & !fp_b_to64(significandWidth-2)
val fp_b_is_QNAN = !io.fp_bIsFpCanonicalNAN & Efp_b_is_all_one & fp_b_mantissa_isnot_zero & fp_b_to64(significandWidth-2)
val fp_a_is_infinite = !io.fp_aIsFpCanonicalNAN & Efp_a_is_all_one & (!fp_a_mantissa_isnot_zero)
val fp_b_is_infinite = !io.fp_bIsFpCanonicalNAN & Efp_b_is_all_one & (!fp_b_mantissa_isnot_zero)
val fp_a_is_zero = !io.fp_aIsFpCanonicalNAN & Efp_a_is_zero & !fp_a_mantissa_isnot_zero
Expand Down Expand Up @@ -435,6 +465,10 @@ private[fpu] class FloatAdderF64Pipeline(val is_print:Boolean = false,val hasMin
val is_fsgnjn = io.op_code === FaddOpCode.fsgnjn
val is_fsgnjx = io.op_code === FaddOpCode.fsgnjx
val is_fclass = io.op_code === FaddOpCode.fclass
val is_fminm = io.op_code === FaddOpCode.fminm
val is_fmaxm = io.op_code === FaddOpCode.fmaxm
val is_fleq = io.op_code === FaddOpCode.fleq
val is_fltq = io.op_code === FaddOpCode.fltq
val fp_a_sign = io.fp_a.head(1)
val fp_b_sign = io.fp_b.head(1)
val fp_b_sign_is_greater = fp_a_sign & !fp_b_sign
Expand All @@ -455,6 +489,8 @@ private[fpu] class FloatAdderF64Pipeline(val is_print:Boolean = false,val hasMin
val result_feq = Wire(UInt(floatWidth.W))
val result_flt = Wire(UInt(floatWidth.W))
val result_fle = Wire(UInt(floatWidth.W))
val result_fminm = Wire(UInt(floatWidth.W))
val result_fmaxm = Wire(UInt(floatWidth.W))
val in_NAN = Cat(0.U, Fill(exponentWidth, 1.U), 1.U, Fill(significandWidth - 2, 0.U))
val fp_aFix = Mux(io.fp_aIsFpCanonicalNAN, in_NAN, io.fp_a)
val fp_bFix = Mux(io.fp_bIsFpCanonicalNAN, in_NAN, io.fp_b)
Expand Down Expand Up @@ -506,17 +542,32 @@ private[fpu] class FloatAdderF64Pipeline(val is_print:Boolean = false,val hasMin
fp_a_is_SNAN,
fp_a_is_NAN & !fp_a_is_SNAN
)))
result_fminm := Mux(!fp_a_is_NAN & !fp_b_is_NAN,
Mux(fp_b_is_less || (fp_b_sign.asBool && fp_b_is_zero && fp_a_is_zero),
io.fp_b,
io.fp_a),
out_NAN
)
result_fmaxm := Mux(!fp_a_is_NAN & !fp_b_is_NAN,
Mux(fp_b_is_greater.asBool || (!fp_b_sign.asBool && fp_b_is_zero && fp_a_is_zero),
io.fp_b,
io.fp_a),
out_NAN
)

val result_stage0 = Mux1H(
Seq(
is_min,
is_max,
is_feq,
is_flt,
is_fle,
is_flt | is_fltq,
is_fle | is_fleq,
is_fsgnj,
is_fsgnjn,
is_fsgnjx,
is_fclass,
is_fminm,
is_fmaxm,
),
Seq(
result_min,
Expand All @@ -528,11 +579,15 @@ private[fpu] class FloatAdderF64Pipeline(val is_print:Boolean = false,val hasMin
result_fsgnjn,
result_fsgnjx,
result_fclass,
result_fminm,
result_fmaxm,
)
)
val fflags_NV_stage0 = ((is_min | is_max) & (fp_a_is_SNAN | fp_b_is_SNAN)) |
(is_feq & (fp_a_is_SNAN | fp_b_is_SNAN)) |
((is_flt | is_fle ) & (fp_a_is_NAN | fp_b_is_NAN))
((is_flt | is_fle ) & (fp_a_is_NAN | fp_b_is_NAN)) |
((is_fminm | is_fmaxm) & (fp_a_is_SNAN | fp_b_is_SNAN)) |
((is_fltq | is_fleq) & (fp_a_is_SNAN | fp_b_is_SNAN))
val fflags_stage0 = Cat(fflags_NV_stage0, 0.U(4.W))
io.fp_c := Mux(RegEnable(is_add | is_sub, fire), float_adder_result, RegEnable(result_stage0, fire))
io.fflags := Mux(RegEnable(is_add | is_sub, fire), float_adder_fflags, RegEnable(fflags_stage0, fire))
Expand Down
4 changes: 4 additions & 0 deletions src/main/scala/yunsuan/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,10 @@ object VfcvtType {
def fsgnj = "b00110".U(width.W)
def fsgnjx = "b01000".U(width.W)
def fsgnjn = "b00111".U(width.W)
def fminm = "b11110".U(width.W)
def fmaxm = "b10011".U(width.W)
def fleq = "b11100".U(width.W)
def fltq = "b11011".U(width.W)
}
object FmaOpCode {
def width = 4
Expand Down
4 changes: 4 additions & 0 deletions src/main/scala/yunsuan/scalar/Convert.scala
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ class FpCvtIO(width: Int) extends Bundle {
val sew = Input(UInt(2.W))
val rm = Input(UInt(3.W))
val isFpToVecInst = Input(Bool())
val isFround = Input(UInt(2.W))
val isFcvtmod = Input(Bool())

val result = Output(UInt(width.W))
val fflags = Output(UInt(5.W))
Expand Down Expand Up @@ -151,6 +153,8 @@ class FPCVT(xlen :Int) extends Module{
fcvt.io.opType := io.opType
fcvt.io.rm := io.rm
fcvt.io.isFpToVecInst := io.isFpToVecInst
fcvt.io.isFround := io.isFround
fcvt.io.isFcvtmod := io.isFcvtmod
fcvt.io.input1H := input1H
fcvt.io.output1H := output1H

Expand Down
Loading

0 comments on commit 31230a5

Please sign in to comment.