mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Simplifying fround
This commit is contained in:
parent
9bd5bd837b
commit
5094122048
@ -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));
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user