forked from Github_Repos/cvw
Created PostBox signal to NaN-box malformed NaNs of excess length. Fixes Issue #55
This commit is contained in:
parent
98135f424e
commit
dc19f8a8ec
@ -110,6 +110,7 @@ module fpu (
|
||||
logic XInfE, YInfE, ZInfE; // is the input infinity - execute stage
|
||||
logic XInfM, YInfM, ZInfM; // is the input infinity - memory stage
|
||||
logic XExpMaxE; // is the exponent all ones (max value)
|
||||
logic [`FLEN-1:0] XPostBoxE; // X after fixing bad NaN box. Needed for 1-input operations
|
||||
|
||||
// Fma Signals
|
||||
logic FmaAddSubE; // Multiply by 1.0 when adding or subtracting
|
||||
@ -200,7 +201,6 @@ module fpu (
|
||||
mux3 #(`FLEN) fzemux (FRD3E, FResultW, PreFpResM, ForwardZE, PreZE);
|
||||
|
||||
// Select NAN-boxed value of Y = 1.0 in proper format for fma to add/subtract X*Y+Z
|
||||
generate
|
||||
if(`FPSIZES == 1) assign BoxedOneE = {2'b0, {`NE-1{1'b1}}, (`NF)'(0)};
|
||||
else if(`FPSIZES == 2)
|
||||
mux2 #(`FLEN) fonemux ({{`FLEN-`LEN1{1'b1}}, 2'b0, {`NE1-1{1'b1}}, (`NF1)'(0)}, {2'b0, {`NE-1{1'b1}}, (`NF)'(0)}, FmtE, BoxedOneE); // NaN boxing zeroes
|
||||
@ -209,13 +209,11 @@ module fpu (
|
||||
{{`FLEN-`D_LEN{1'b1}}, 2'b0, {`D_NE-1{1'b1}}, (`D_NF)'(0)},
|
||||
{{`FLEN-`H_LEN{1'b1}}, 2'b0, {`H_NE-1{1'b1}}, (`H_NF)'(0)},
|
||||
{2'b0, {`NE-1{1'b1}}, (`NF)'(0)}, FmtE, BoxedOneE); // NaN boxing zeroes
|
||||
endgenerate
|
||||
assign FmaAddSubE = OpCtrlE[2]&OpCtrlE[1]&(FResSelE==2'b01)&(PostProcSelE==2'b10);
|
||||
mux2 #(`FLEN) fyaddmux (PreYE, BoxedOneE, FmaAddSubE, YE); // Force Y to be 1 for add/subtract
|
||||
|
||||
// Select NAN-boxed value of Z = 0.0 in proper format for FMA for multiply X*Y+Z
|
||||
// For add and subtract, Z comes from second source operand
|
||||
generate
|
||||
if(`FPSIZES == 1) assign BoxedZeroE = 0;
|
||||
else if(`FPSIZES == 2)
|
||||
mux2 #(`FLEN) fmulzeromux ({{`FLEN-`LEN1{1'b1}}, {`LEN1{1'b0}}}, (`FLEN)'(0), FmtE, BoxedZeroE); // NaN boxing zeroes
|
||||
@ -224,7 +222,6 @@ module fpu (
|
||||
{{`FLEN-`D_LEN{1'b1}}, {`D_LEN{1'b0}}},
|
||||
{{`FLEN-`H_LEN{1'b1}}, {`H_LEN{1'b0}}},
|
||||
(`FLEN)'(0), FmtE, BoxedZeroE); // NaN boxing zeroes
|
||||
endgenerate
|
||||
assign FmaZSelE = {OpCtrlE[2]&OpCtrlE[1], OpCtrlE[2]&~OpCtrlE[1]};
|
||||
mux3 #(`FLEN) fzmulmux (PreZE, BoxedZeroE, PreYE, FmaZSelE, ZE);
|
||||
|
||||
@ -234,7 +231,7 @@ module fpu (
|
||||
.XNaN(XNaNE), .YNaN(YNaNE), .ZNaN(ZNaNE), .XSNaN(XSNaNE), .XEn(XEnE),
|
||||
.YSNaN(YSNaNE), .ZSNaN(ZSNaNE), .XSubnorm(XSubnormE),
|
||||
.XZero(XZeroE), .YZero(YZeroE), .ZZero(ZZeroE), .XInf(XInfE), .YInf(YInfE),
|
||||
.ZEn(ZEnE), .ZInf(ZInfE), .XExpMax(XExpMaxE));
|
||||
.ZEn(ZEnE), .ZInf(ZInfE), .XExpMax(XExpMaxE), .XPostBox(XPostBoxE));
|
||||
|
||||
// fused multiply add: fadd/sub, fmul, fmadd/fnmadd/fmsub/fnmsub
|
||||
fma fma (.Xs(XsE), .Ys(YsE), .Zs(ZsE), .Xe(XeE), .Ye(YeE), .Ze(ZeE), .Xm(XmE), .Ym(YmE), .Zm(ZmE),
|
||||
@ -255,7 +252,7 @@ module fpu (
|
||||
.CmpFpRes(CmpFpResE), .CmpIntRes(CmpIntResE));
|
||||
|
||||
// sign injection: fsgnj/fsgnjx/fsgnjn
|
||||
fsgninj fsgninj(.OpCtrl(OpCtrlE[1:0]), .Xs(XsE), .Ys(YsE), .X(XE), .Fmt(FmtE), .SgnRes(SgnResE));
|
||||
fsgninj fsgninj(.OpCtrl(OpCtrlE[1:0]), .Xs(XsE), .Ys(YsE), .X(XPostBoxE), .Fmt(FmtE), .SgnRes(SgnResE));
|
||||
|
||||
// classify: fclass
|
||||
fclassify fclassify (.Xs(XsE), .XSubnorm(XSubnormE), .XZero(XZeroE), .XNaN(XNaNE),
|
||||
@ -268,7 +265,6 @@ module fpu (
|
||||
|
||||
|
||||
// NaN Box SrcA to convert integer to requested FP size
|
||||
generate
|
||||
if(`FPSIZES == 1) assign AlignedSrcAE = {{`FLEN-`XLEN{1'b1}}, ForwardedSrcAE};
|
||||
else if(`FPSIZES == 2)
|
||||
mux2 #(`FLEN) SrcAMux ({{`FLEN-`LEN1{1'b1}}, ForwardedSrcAE[`LEN1-1:0]}, {{`FLEN-`XLEN{1'b1}}, ForwardedSrcAE}, FmtE, AlignedSrcAE);
|
||||
@ -277,14 +273,12 @@ module fpu (
|
||||
{{`FLEN-`D_LEN{1'b1}}, ForwardedSrcAE[`D_LEN-1:0]},
|
||||
{{`FLEN-`H_LEN{1'b1}}, ForwardedSrcAE[`H_LEN-1:0]},
|
||||
{{`FLEN-`XLEN{1'b1}}, ForwardedSrcAE}, FmtE, AlignedSrcAE); // NaN boxing zeroes
|
||||
endgenerate
|
||||
|
||||
// select a result that may be written to the FP register
|
||||
mux3 #(`FLEN) FResMux(SgnResE, AlignedSrcAE, CmpFpResE, {OpCtrlE[2], &OpCtrlE[1:0]}, PreFpResE);
|
||||
assign PreNVE = CmpNVE&(OpCtrlE[2]|FWriteIntE);
|
||||
|
||||
// select the result that may be written to the integer register - to IEU
|
||||
generate
|
||||
if(`FPSIZES == 1)
|
||||
assign SgnExtXE = XE;
|
||||
else if(`FPSIZES == 2)
|
||||
@ -294,7 +288,7 @@ module fpu (
|
||||
{{`FLEN-`S_LEN{XsE}}, XE[`S_LEN-1:0]},
|
||||
{{`FLEN-`D_LEN{XsE}}, XE[`D_LEN-1:0]},
|
||||
XE, FmtE, SgnExtXE);
|
||||
endgenerate
|
||||
|
||||
if (`FLEN>`XLEN)
|
||||
assign IntSrcXE = SgnExtXE[`XLEN-1:0];
|
||||
else
|
||||
|
@ -39,7 +39,8 @@ module unpack (
|
||||
output logic XSubnorm, // is X subnormal
|
||||
output logic XZero, YZero, ZZero, // is XYZ zero
|
||||
output logic XInf, YInf, ZInf, // is XYZ infinity
|
||||
output logic XExpMax // does X have the maximum exponent (NaN or Inf)
|
||||
output logic XExpMax, // does X have the maximum exponent (NaN or Inf)
|
||||
output logic [`FLEN-1:0] XPostBox // X after being properly NaN-boxed
|
||||
);
|
||||
|
||||
logic XExpNonZero, YExpNonZero, ZExpNonZero; // is the exponent of XYZ non-zero
|
||||
@ -48,14 +49,17 @@ module unpack (
|
||||
|
||||
unpackinput unpackinputX (.In(X), .Fmt, .Sgn(Xs), .Exp(Xe), .Man(Xm), .En(XEn),
|
||||
.NaN(XNaN), .SNaN(XSNaN), .ExpNonZero(XExpNonZero),
|
||||
.Zero(XZero), .Inf(XInf), .ExpMax(XExpMax), .FracZero(XFracZero), .Subnorm(XSubnorm));
|
||||
.Zero(XZero), .Inf(XInf), .ExpMax(XExpMax), .FracZero(XFracZero),
|
||||
.Subnorm(XSubnorm), .PostBox(XPostBox));
|
||||
|
||||
unpackinput unpackinputY (.In(Y), .Fmt, .Sgn(Ys), .Exp(Ye), .Man(Ym), .En(YEn),
|
||||
.NaN(YNaN), .SNaN(YSNaN), .ExpNonZero(YExpNonZero),
|
||||
.Zero(YZero), .Inf(YInf), .ExpMax(YExpMax), .FracZero(YFracZero), .Subnorm());
|
||||
.Zero(YZero), .Inf(YInf), .ExpMax(YExpMax), .FracZero(YFracZero),
|
||||
.Subnorm(), .PostBox());
|
||||
|
||||
unpackinput unpackinputZ (.In(Z), .Fmt, .Sgn(Zs), .Exp(Ze), .Man(Zm), .En(ZEn),
|
||||
.NaN(ZNaN), .SNaN(ZSNaN), .ExpNonZero(ZExpNonZero),
|
||||
.Zero(ZZero), .Inf(ZInf), .ExpMax(ZExpMax), .FracZero(ZFracZero), .Subnorm());
|
||||
.Zero(ZZero), .Inf(ZInf), .ExpMax(ZExpMax), .FracZero(ZFracZero),
|
||||
.Subnorm(), .PostBox());
|
||||
|
||||
endmodule
|
@ -41,11 +41,12 @@ module unpackinput (
|
||||
output logic ExpNonZero, // is the exponent not zero
|
||||
output logic FracZero, // is the fraction zero
|
||||
output logic ExpMax, // does In have the maximum exponent (NaN or Inf)
|
||||
output logic Subnorm // is the number subnormal
|
||||
output logic Subnorm, // is the number subnormal
|
||||
output logic [`FLEN-1:0] PostBox // Number reboxed correctly as a NaN
|
||||
);
|
||||
|
||||
logic [`NF-1:0] Frac; // Fraction of XYZ
|
||||
logic BadNaNBox; // is the NaN boxing bad
|
||||
logic BadNaNBox; // incorrectly NaN Boxed
|
||||
|
||||
if (`FPSIZES == 1) begin // if there is only one floating point format supported
|
||||
assign BadNaNBox = 0;
|
||||
@ -54,6 +55,7 @@ module unpackinput (
|
||||
assign ExpNonZero = |In[`FLEN-2:`NF]; // is the exponent non-zero
|
||||
assign Exp = {In[`FLEN-2:`NF+1], In[`NF]|~ExpNonZero}; // exponent. subnormal numbers have effective biased exponent of 1
|
||||
assign ExpMax = &In[`FLEN-2:`NF]; // is the exponent all 1's
|
||||
assign PostBox = In;
|
||||
|
||||
end else if (`FPSIZES == 2) begin // if there are 2 floating point formats supported
|
||||
// largest format | smaller format
|
||||
@ -75,6 +77,11 @@ module unpackinput (
|
||||
// double and half
|
||||
|
||||
assign BadNaNBox = ~(Fmt|(&In[`FLEN-1:`LEN1])); // Check NaN boxing
|
||||
always_comb
|
||||
if (BadNaNBox) begin
|
||||
PostBox = {{(`FLEN-`LEN1){1'b1}}, 1'b1, {(`NE1+1){1'b1}}, In[`LEN1-`NE1-3:0]};
|
||||
end else
|
||||
PostBox = In;
|
||||
|
||||
// choose sign bit depending on format - 1=larger precsion 0=smaller precision
|
||||
assign Sgn = Fmt ? In[`FLEN-1] : In[`LEN1-1];
|
||||
@ -128,6 +135,17 @@ module unpackinput (
|
||||
default: BadNaNBox = 1'bx;
|
||||
endcase
|
||||
|
||||
always_comb
|
||||
if (BadNaNBox) begin
|
||||
case (Fmt)
|
||||
`FMT: PostBox = In;
|
||||
`FMT1: PostBox = {{(`FLEN-`LEN1){1'b1}}, 1'b1, {(`NE1+1){1'b1}}, In[`LEN1-`NE1-3:0]};
|
||||
`FMT2: PostBox = {{(`FLEN-`LEN2){1'b1}}, 1'b1, {(`NE2+1){1'b1}}, In[`LEN2-`NE2-3:0]};
|
||||
default: PostBox = 'x;
|
||||
endcase
|
||||
end else
|
||||
PostBox = In;
|
||||
|
||||
// extract the sign bit
|
||||
always_comb
|
||||
case (Fmt)
|
||||
@ -200,6 +218,17 @@ module unpackinput (
|
||||
2'b10: BadNaNBox = ~&In[`Q_LEN-1:`H_LEN];
|
||||
endcase
|
||||
|
||||
always_comb
|
||||
if (BadNaNBox) begin
|
||||
case (Fmt)
|
||||
2'b11: PostBox = In;
|
||||
2'b01: PostBox = {{(`Q_LEN-`D_LEN){1'b1}}, 1'b1, {(`D_NE+1){1'b1}}, In[`D_LEN-`D_NE-3:0]};
|
||||
2'b00: PostBox = {{(`Q_LEN-`S_LEN){1'b1}}, 1'b1, {(`S_NE+1){1'b1}}, In[`S_LEN-`S_NE-3:0]};
|
||||
2'b10: PostBox = {{(`Q_LEN-`H_LEN){1'b1}}, 1'b1, {(`H_NE+1){1'b1}}, In[`H_LEN-`H_NE-3:0]};
|
||||
endcase
|
||||
end else
|
||||
PostBox = In;
|
||||
|
||||
// extract sign bit
|
||||
always_comb
|
||||
case (Fmt)
|
||||
|
Loading…
Reference in New Issue
Block a user