diff --git a/src/fpu/fpu.sv b/src/fpu/fpu.sv index 4cf17890c..ba986dadc 100755 --- a/src/fpu/fpu.sv +++ b/src/fpu/fpu.sv @@ -281,7 +281,7 @@ module fpu import cvw::*; #(parameter cvw_t P) ( // fround fround #(P) fround(.X(XE), .Xs(XsE), .Xe(XeE), .Xm(XmE), - .XNaN(XNaNE), .XSNaN(XSNaNE), .XZero(XZeroE), .Fmt(FmtE), .Frm(FrmE), .Nf(NfE), + .XNaN(XNaNE), .XSNaN(XSNaNE), .Fmt(FmtE), .Frm(FrmE), .Nf(NfE), .ZfaFRoundNX(ZfaFRoundNXE), .FRound(FRoundE), .FRoundNV(FRoundNVE), .FRoundNX(FRoundNXE)); diff --git a/src/fpu/fround.sv b/src/fpu/fround.sv index 64700834a..307b8c4f8 100644 --- a/src/fpu/fround.sv +++ b/src/fpu/fround.sv @@ -34,7 +34,6 @@ module fround import cvw::*; #(parameter cvw_t P) ( input logic [P.NF:0] Xm, // input's fraction with leading integer bit (U1.NF) input logic XNaN, // X is NaN input logic XSNaN, // X is Signalling NaN - input logic XZero, // X is Zero input logic [P.FMTBITS-1:0] Fmt, // the input's precision (11=quad 01=double 00=single 10=half) input logic [2:0] Frm, // rounding mode input logic [P.LOGFLEN-1:0] Nf, // Number of fractional bits in selected format @@ -47,7 +46,7 @@ module fround import cvw::*; #(parameter cvw_t P) ( logic [P.NE-1:0] E, Xep1, EminusNf; logic [P.NF:0] IMask, Tmasknonneg, Tmaskneg, Tmask, HotE, HotEP1, Trunc, Rnd; logic [P.FLEN-1:0] W, PackedW; - logic Elt0, Eeqm1, Lnonneg, Lp, Rnonneg, Rp, Tp, RoundUp, Two, EgeNf, Exact; + logic Elt0, Eeqm1, Lnonneg, Lp, Rnonneg, Rp, Tp, RoundUp, Two, EgeNf; // Unbiased exponent assign E = Xe - P.BIAS[P.NE-1:0]; @@ -78,7 +77,7 @@ module fround import cvw::*; #(parameter cvw_t P) ( assign Eeqm1 = ($signed(E) == -1); // Logic for nonnegative mask and rounding bits - assign IMask = {1'b1, {P.NF{1'b0}}} >>> E; + assign IMask = {1'b1, {P.NF{1'b0}}} >>> E; /// if E > Nf, this produces all 0s instead of all 1s. Hence exact handling is needed below. assign Tmasknonneg = ~IMask >>> 1'b1; assign HotE = IMask & ~(IMask << 1'b1); assign HotEP1 = HotE >> 1'b1; @@ -121,7 +120,6 @@ module fround import cvw::*; #(parameter cvw_t P) ( assign EminusNf = E - Nf; /* verilator lint_on WIDTH */ assign EgeNf = ~EminusNf[P.NE-1] & (~E[P.NE-1] | E[P.NE-2:0] == '0); // E >= Nf if MSB of E-Nf is 0 and E was positive - assign Exact = (EgeNf | XZero) & ~XNaN; // result will be exact; no need to round // Rounding logic: determine whether to round up in magnitude always_comb begin @@ -136,7 +134,8 @@ module fround import cvw::*; #(parameter cvw_t P) ( // If result is not exact, select output in unpacked FLEN format initially if (XNaN) W = {1'b0, {P.NE{1'b1}}, 1'b1, {(P.NF-1){1'b0}}}; // Canonical NaN - else if (Elt0) // 0 <= |X| < 1 rounds to 0 or 1 + else if (EgeNf) W = {Xs, Xe, Xm[P.NF-1:0]}; // Exact, no rounding needed + else if (Elt0) // 0 <= |X| < 1 rounds to 0 or 1 if (RoundUp) W = {Xs, P.BIAS[P.NE-1:0], {P.NF{1'b0}}}; // round to +/- 1 else W = {Xs, {(P.FLEN-1){1'b0}}}; // round to +/- 0 else begin // |X| >= 1 rounds to an integer @@ -146,11 +145,10 @@ module fround import cvw::*; #(parameter cvw_t P) ( end end - packoutput #(P) packoutput(W, Fmt, PackedW); // pack and NaN-box based on selected format. - mux2 #(P.FLEN) resultmux(PackedW, X, Exact, FRound); + packoutput #(P) packoutput(W, Fmt, FRound); // pack and NaN-box based on selected format. // Flags assign FRoundNV = XSNaN; // invalid if input is signaling NaN - assign FRoundNX = ZfaFRoundNX & ~(XNaN | Exact) & (Rp | Tp); // Inexact if Round or Sticky bit set for FRoundNX instruction + assign FRoundNX = ZfaFRoundNX & ~(XNaN | EgeNf) & (Rp | Tp); // Inexact if Round or Sticky bit set for FRoundNX instruction endmodule