mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Simplified fround exact case
This commit is contained in:
parent
5094122048
commit
1873064be5
@ -43,7 +43,7 @@ module fround import cvw::*; #(parameter cvw_t P) (
|
|||||||
output logic FRoundNX // fround inexact
|
output logic FRoundNX // fround inexact
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [P.NE-1:0] E, Xep1, EminusNf;
|
logic [P.NE-1:0] E, Xep1;
|
||||||
logic [P.NF:0] IMask, Tmasknonneg, Tmaskneg, Tmask, HotE, HotEP1, Trunc, Rnd;
|
logic [P.NF:0] IMask, Tmasknonneg, Tmaskneg, Tmask, HotE, HotEP1, Trunc, Rnd;
|
||||||
logic [P.FLEN-1:0] W, PackedW;
|
logic [P.FLEN-1:0] W, PackedW;
|
||||||
logic Elt0, Eeqm1, Lnonneg, Lp, Rnonneg, Rp, Tp, RoundUp, Two, EgeNf;
|
logic Elt0, Eeqm1, Lnonneg, Lp, Rnonneg, Rp, Tp, RoundUp, Two, EgeNf;
|
||||||
@ -99,7 +99,7 @@ module fround import cvw::*; #(parameter cvw_t P) (
|
|||||||
// if (X is NaN)
|
// if (X is NaN)
|
||||||
// W = Canonical NaN
|
// W = Canonical NaN
|
||||||
// Invalid = (X is signaling NaN)
|
// Invalid = (X is signaling NaN)
|
||||||
// else if (E >= Nf or X is +/- 0)
|
// else if (E >= Nf)
|
||||||
// W = X // is exact; this also handles infinity
|
// W = X // is exact; this also handles infinity
|
||||||
// else
|
// else
|
||||||
// RoundUp = RoundingLogic(Xs, L', R', T', rm) // Table 16.4
|
// RoundUp = RoundingLogic(Xs, L', R', T', rm) // Table 16.4
|
||||||
@ -116,10 +116,9 @@ module fround import cvw::*; #(parameter cvw_t P) (
|
|||||||
///////////////////////////
|
///////////////////////////
|
||||||
|
|
||||||
// Exact logic
|
// Exact logic
|
||||||
/* verilator lint_off WIDTH */
|
// verilator lint_off WIDTHEXPAND
|
||||||
assign EminusNf = E - Nf;
|
assign EgeNf = (E >= Nf) & Xe[P.NE-1]; // Check if E >= Nf. Also check that Xe is positive to avoid wraparound problems
|
||||||
/* verilator lint_on WIDTH */
|
// verilator lint_on WIDTHEXPAND
|
||||||
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
|
|
||||||
|
|
||||||
// Rounding logic: determine whether to round up in magnitude
|
// Rounding logic: determine whether to round up in magnitude
|
||||||
always_comb begin
|
always_comb begin
|
||||||
@ -133,22 +132,22 @@ module fround import cvw::*; #(parameter cvw_t P) (
|
|||||||
endcase
|
endcase
|
||||||
|
|
||||||
// If result is not exact, select output in unpacked FLEN format initially
|
// 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
|
if (XNaN) W = {1'b0, {P.NE{1'b1}}, 1'b1, {(P.NF-1){1'b0}}}; // Canonical NaN
|
||||||
else if (EgeNf) W = {Xs, Xe, Xm[P.NF-1:0]}; // Exact, no rounding needed
|
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
|
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
|
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 W = {Xs, {(P.FLEN-1){1'b0}}}; // round to +/- 0
|
||||||
else begin // |X| >= 1 rounds to an integer
|
else begin // |X| >= 1 rounds to an integer
|
||||||
if (RoundUp & Two) W = {Xs, Xep1, {(P.NF){1'b0}}}; // Round up to 2.0
|
if (RoundUp & Two) W = {Xs, Xep1, {(P.NF){1'b0}}}; // Round up to 2.0
|
||||||
else if (RoundUp) W = {Xs, Xe, Rnd[P.NF-1:0]}; // Round up to Rnd
|
else if (RoundUp) W = {Xs, Xe, Rnd[P.NF-1:0]}; // Round up to Rnd
|
||||||
else W = {Xs, Xe, Trunc[P.NF-1:0]}; // Round down to Trunc
|
else W = {Xs, Xe, Trunc[P.NF-1:0]}; // Round down to Trunc
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
packoutput #(P) packoutput(W, Fmt, FRound); // pack and NaN-box based on selected format.
|
packoutput #(P) packoutput(W, Fmt, FRound); // pack and NaN-box based on selected format.
|
||||||
|
|
||||||
// Flags
|
// Flags
|
||||||
assign FRoundNV = XSNaN; // invalid if input is signaling NaN
|
assign FRoundNV = XSNaN; // invalid if input is signaling NaN
|
||||||
assign FRoundNX = ZfaFRoundNX & ~(XNaN | EgeNf) & (Rp | Tp); // Inexact if Round or Sticky bit set for FRoundNX instruction
|
assign FRoundNX = ZfaFRoundNX & ~EgeNf & (Rp | Tp); // Inexact if Round or Sticky bit set for FRoundNX instruction
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
Loading…
Reference in New Issue
Block a user