diff --git a/pipelined/regression/sim-fp-batch b/pipelined/regression/sim-fp-batch index 7e2c6a341..26085239d 100755 --- a/pipelined/regression/sim-fp-batch +++ b/pipelined/regression/sim-fp-batch @@ -7,4 +7,4 @@ # sqrt - test square root # all - test everything -vsim -c -do "do fp.do rv64fp fma" \ No newline at end of file +vsim -c -do "do fp.do rv64fp mul" \ No newline at end of file diff --git a/pipelined/src/fpu/fma.sv b/pipelined/src/fpu/fma.sv index 69d6fc8ee..71d990371 100644 --- a/pipelined/src/fpu/fma.sv +++ b/pipelined/src/fpu/fma.sv @@ -43,6 +43,7 @@ module fma( input logic XSgnM, YSgnM, // input signs - memory stage input logic [`NE-1:0] ZExpM, // input exponents - memory stage input logic [`NF:0] XManM, YManM, ZManM, // input mantissa - memory stage + input logic ZOrigDenormE, // is the original precision denormalized input logic XDenormE, YDenormE, ZDenormE, // is denorm input logic XZeroE, YZeroE, ZZeroE, // is zero - execute stage input logic XNaNM, YNaNM, ZNaNM, // is NaN @@ -72,6 +73,7 @@ module fma( logic PSgnE, PSgnM; logic [$clog2(3*`NF+7)-1:0] NormCntE, NormCntM; logic Mult; + logic ZOrigDenormM; fma1 fma1 (.XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE, .XManE, .YManE, .ZManE, .XDenormE, .YDenormE, .ZDenormE, .XZeroE, .YZeroE, .ZZeroE, @@ -81,11 +83,11 @@ module fma( // E/M pipeline registers flopenrc #(3*`NF+6) EMRegFma2(clk, reset, FlushM, ~StallM, SumE, SumM); flopenrc #(13) EMRegFma3(clk, reset, FlushM, ~StallM, ProdExpE, ProdExpM); - flopenrc #($clog2(3*`NF+7)+7) EMRegFma4(clk, reset, FlushM, ~StallM, - {AddendStickyE, KillProdE, InvZE, NormCntE, NegSumE, ZSgnEffE, PSgnE, FOpCtrlE[2]&~FOpCtrlE[1]&~FOpCtrlE[0]}, - {AddendStickyM, KillProdM, InvZM, NormCntM, NegSumM, ZSgnEffM, PSgnM, Mult}); + flopenrc #($clog2(3*`NF+7)+8) EMRegFma4(clk, reset, FlushM, ~StallM, + {AddendStickyE, KillProdE, InvZE, NormCntE, NegSumE, ZSgnEffE, PSgnE, FOpCtrlE[2]&~FOpCtrlE[1]&~FOpCtrlE[0], ZOrigDenormE}, + {AddendStickyM, KillProdM, InvZM, NormCntM, NegSumM, ZSgnEffM, PSgnM, Mult, ZOrigDenormM}); - fma2 fma2(.XSgnM, .YSgnM, .ZExpM, .XManM, .YManM, .ZManM, + fma2 fma2(.XSgnM, .YSgnM, .ZExpM, .XManM, .YManM, .ZManM, .ZOrigDenormM, .FrmM, .FmtM, .ProdExpM, .AddendStickyM, .KillProdM, .SumM, .NegSumM, .InvZM, .NormCntM, .ZSgnEffM, .PSgnM, .XZeroM, .YZeroM, .ZZeroM, .XInfM, .YInfM, .ZInfM, .XNaNM, .YNaNM, .ZNaNM, .XSNaNM, .YSNaNM, .ZSNaNM, .Mult, .FMAResM, .FMAFlgM); @@ -448,6 +450,7 @@ module fma2( input logic [3*`NF+5:0] SumM, // the positive sum input logic NegSumM, // was the sum negitive input logic InvZM, // do you invert Z + input logic ZOrigDenormM, // is the original precision denormalized input logic ZSgnEffM, // the modified Z sign - depends on instruction input logic PSgnM, // the product's sign input logic Mult, // multiply opperation @@ -530,7 +533,7 @@ module fma2( // Select the result /////////////////////////////////////////////////////////////////////////////// - resultselect resultselect(.XSgnM, .YSgnM, .ZExpM, .XManM, .YManM, .ZManM, + resultselect resultselect(.XSgnM, .YSgnM, .ZExpM, .XManM, .YManM, .ZManM, .ZOrigDenormM, .FrmM, .FmtM, .AddendStickyM, .KillProdM, .XInfM, .YInfM, .ZInfM, .XNaNM, .YNaNM, .ZNaNM, .RoundAdd, .ZSgnEffM, .PSgnM, .ResultSgn, .CalcPlus1, .Invalid, .Overflow, .Underflow, .ResultDenorm, .ResultExp, .ResultFrac, .FMAResM); @@ -1103,6 +1106,7 @@ module resultselect( input logic KillProdM, // set the product to zero before addition if the product is too small to matter input logic XInfM, YInfM, ZInfM, // inputs are infinity input logic XNaNM, YNaNM, ZNaNM, // inputs are NaN + input logic ZOrigDenormM, // is the original precision denormalized input logic ZSgnEffM, // the modified Z sign - depends on instruction input logic PSgnM, // the product's sign input logic ResultSgn, // the result's sign @@ -1122,7 +1126,7 @@ module resultselect( assign XNaNResult = {XSgnM, {`NE{1'b1}}, 1'b1, XManM[`NF-2:0]}; assign YNaNResult = {YSgnM, {`NE{1'b1}}, 1'b1, YManM[`NF-2:0]}; assign ZNaNResult = {ZSgnEffM, {`NE{1'b1}}, 1'b1, ZManM[`NF-2:0]}; - assign InvalidResult = {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; + assign InvalidResult = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; end else begin assign XNaNResult = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; end @@ -1138,7 +1142,7 @@ module resultselect( assign XNaNResult = FmtM ? {XSgnM, {`NE{1'b1}}, 1'b1, XManM[`NF-2:0]} : {{`FLEN-`LEN1{1'b1}}, XSgnM, {`NE1{1'b1}}, 1'b1, XManM[`NF-2:`NF-`NF1]}; assign YNaNResult = FmtM ? {YSgnM, {`NE{1'b1}}, 1'b1, YManM[`NF-2:0]} : {{`FLEN-`LEN1{1'b1}}, YSgnM, {`NE1{1'b1}}, 1'b1, YManM[`NF-2:`NF-`NF1]}; assign ZNaNResult = FmtM ? {ZSgnEffM, {`NE{1'b1}}, 1'b1, ZManM[`NF-2:0]} : {{`FLEN-`LEN1{1'b1}}, ZSgnEffM, {`NE1{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`NF1]}; - assign InvalidResult = FmtM ? {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{`FLEN-`LEN1{1'b1}}, ResultSgn, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; + assign InvalidResult = FmtM ? {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; end else begin assign XNaNResult = FmtM ? {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; end @@ -1147,7 +1151,7 @@ module resultselect( {ResultSgn, {`NE{1'b1}}, {`NF{1'b0}}} : ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`LEN1{1'b1}}, ResultSgn, {`NE1-1{1'b1}}, 1'b0, {`NF1{1'b1}}} : {{`FLEN-`LEN1{1'b1}}, ResultSgn, {`NE1{1'b1}}, (`NF1)'(0)}; - assign KillProdResult = FmtM ? {ResultSgn, {ZExpM, ZManM[`NF-1:0]} + (RoundAdd[`FLEN-2:0]&{`FLEN-1{AddendStickyM}})} : {{`FLEN-`LEN1{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`NE1-2:0], ZManM[`NF-1:`NF-`NF1]} + (RoundAdd[`NF-`NF1+`LEN1-2:`NF-`NF1]&{`LEN1-1{AddendStickyM}})}; + assign KillProdResult = FmtM ? {ResultSgn, {ZExpM, ZManM[`NF-1:0]} + (RoundAdd[`FLEN-2:0]&{`FLEN-1{AddendStickyM}})} : {{`FLEN-`LEN1{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`NE1-2:1], ZExpM[0]&~ZOrigDenormM, ZManM[`NF-1:`NF-`NF1]} + (RoundAdd[`NF-`NF1+`LEN1-2:`NF-`NF1]&{`LEN1-1{AddendStickyM}})}; assign UnderflowResult = FmtM ? {ResultSgn, {`FLEN-1{1'b0}}} + {(`FLEN-1)'(0),(CalcPlus1&(AddendStickyM|FrmM[1]))} : {{`FLEN-`LEN1{1'b1}}, {ResultSgn, (`LEN1-1)'(0)} + {(`LEN1-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; assign InfResult = FmtM ? {InfSgn, {`NE{1'b1}}, (`NF)'(0)} : {{`FLEN-`LEN1{1'b1}}, InfSgn, {`NE1{1'b1}}, (`NF1)'(0)}; assign NormResult = FmtM ? {ResultSgn, ResultExp, ResultFrac} : {{`FLEN-`LEN1{1'b1}}, ResultSgn, ResultExp[`NE1-1:0], ResultFrac[`NF-1:`NF-`NF1]}; @@ -1160,7 +1164,7 @@ module resultselect( XNaNResult = {XSgnM, {`NE{1'b1}}, 1'b1, XManM[`NF-2:0]}; YNaNResult = {YSgnM, {`NE{1'b1}}, 1'b1, YManM[`NF-2:0]}; ZNaNResult = {ZSgnEffM, {`NE{1'b1}}, 1'b1, ZManM[`NF-2:0]}; - InvalidResult = {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; + InvalidResult = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; end else begin XNaNResult = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; end @@ -1177,13 +1181,13 @@ module resultselect( XNaNResult = {{`FLEN-`LEN1{1'b1}}, XSgnM, {`NE1{1'b1}}, 1'b1, XManM[`NF-2:`NF-`NF1]}; YNaNResult = {{`FLEN-`LEN1{1'b1}}, YSgnM, {`NE1{1'b1}}, 1'b1, YManM[`NF-2:`NF-`NF1]}; ZNaNResult = {{`FLEN-`LEN1{1'b1}}, ZSgnEffM, {`NE1{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`NF1]}; - InvalidResult = {{`FLEN-`LEN1{1'b1}}, ResultSgn, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; + InvalidResult = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; end else begin XNaNResult = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; end OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`LEN1{1'b1}}, ResultSgn, {`NE1-1{1'b1}}, 1'b0, {`NF1{1'b1}}} : {{`FLEN-`LEN1{1'b1}}, ResultSgn, {`NE1{1'b1}}, (`NF1)'(0)}; - KillProdResult = {{`FLEN-`LEN1{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`NE1-2:0], ZManM[`NF-1:`NF-`NF1]} + (RoundAdd[`NF-`NF1+`LEN1-2:`NF-`NF1]&{`LEN1-1{AddendStickyM}})}; + KillProdResult = {{`FLEN-`LEN1{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`NE1-2:1], ZExpM[0]&~ZOrigDenormM, ZManM[`NF-1:`NF-`NF1]} + (RoundAdd[`NF-`NF1+`LEN1-2:`NF-`NF1]&{`LEN1-1{AddendStickyM}})}; UnderflowResult = {{`FLEN-`LEN1{1'b1}}, {ResultSgn, (`LEN1-1)'(0)} + {(`LEN1-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; InfResult = {{`FLEN-`LEN1{1'b1}}, InfSgn, {`NE1{1'b1}}, (`NF1)'(0)}; NormResult = {{`FLEN-`LEN1{1'b1}}, ResultSgn, ResultExp[`NE1-1:0], ResultFrac[`NF-1:`NF-`NF1]}; @@ -1193,14 +1197,14 @@ module resultselect( XNaNResult = {{`FLEN-`LEN2{1'b1}}, XSgnM, {`NE2{1'b1}}, 1'b1, XManM[`NF-2:`NF-`NF2]}; YNaNResult = {{`FLEN-`LEN2{1'b1}}, YSgnM, {`NE2{1'b1}}, 1'b1, YManM[`NF-2:`NF-`NF2]}; ZNaNResult = {{`FLEN-`LEN2{1'b1}}, ZSgnEffM, {`NE2{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`NF2]}; - InvalidResult = {{`FLEN-`LEN2{1'b1}}, ResultSgn, {`NE2{1'b1}}, 1'b1, (`NF2-1)'(0)}; + InvalidResult = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, (`NF2-1)'(0)}; end else begin XNaNResult = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, (`NF2-1)'(0)}; end OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`LEN2{1'b1}}, ResultSgn, {`NE2-1{1'b1}}, 1'b0, {`NF2{1'b1}}} : {{`FLEN-`LEN2{1'b1}}, ResultSgn, {`NE2{1'b1}}, (`NF2)'(0)}; - KillProdResult = {{`FLEN-`LEN2{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`NE2-2:0], ZManM[`NF-1:`NF-`NF2]} + (RoundAdd[`NF-`NF2+`LEN2-2:`NF-`NF2]&{`LEN2-1{AddendStickyM}})}; + KillProdResult = {{`FLEN-`LEN2{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`NE2-2:1], ZExpM[0]&~ZOrigDenormM, ZManM[`NF-1:`NF-`NF2]} + (RoundAdd[`NF-`NF2+`LEN2-2:`NF-`NF2]&{`LEN2-1{AddendStickyM}})}; UnderflowResult = {{`FLEN-`LEN2{1'b1}}, {ResultSgn, (`LEN2-1)'(0)} + {(`LEN2-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; InfResult = {{`FLEN-`LEN2{1'b1}}, InfSgn, {`NE2{1'b1}}, (`NF2)'(0)}; NormResult = {{`FLEN-`LEN2{1'b1}}, ResultSgn, ResultExp[`NE2-1:0], ResultFrac[`NF-1:`NF-`NF2]}; @@ -1231,7 +1235,7 @@ module resultselect( XNaNResult = {XSgnM, {`NE{1'b1}}, 1'b1, XManM[`NF-2:0]}; YNaNResult = {YSgnM, {`NE{1'b1}}, 1'b1, YManM[`NF-2:0]}; ZNaNResult = {ZSgnEffM, {`NE{1'b1}}, 1'b1, ZManM[`NF-2:0]}; - InvalidResult = {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; + InvalidResult = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; end else begin XNaNResult = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; end @@ -1248,13 +1252,13 @@ module resultselect( XNaNResult = {{`FLEN-`D_LEN{1'b1}}, XSgnM, {`D_NE{1'b1}}, 1'b1, XManM[`NF-2:`NF-`D_NF]}; YNaNResult = {{`FLEN-`D_LEN{1'b1}}, YSgnM, {`D_NE{1'b1}}, 1'b1, YManM[`NF-2:`NF-`D_NF]}; ZNaNResult = {{`FLEN-`D_LEN{1'b1}}, ZSgnEffM, {`D_NE{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`D_NF]}; - InvalidResult = {{`FLEN-`D_LEN{1'b1}}, ResultSgn, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)}; + InvalidResult = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)}; end else begin XNaNResult = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)}; end OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`D_LEN{1'b1}}, ResultSgn, {`D_NE-1{1'b1}}, 1'b0, {`D_NF{1'b1}}} : {{`FLEN-`D_LEN{1'b1}}, ResultSgn, {`D_NE{1'b1}}, (`D_NF)'(0)}; - KillProdResult = {{`FLEN-`D_LEN{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`D_NE-2:0], ZManM[`NF-1:`NF-`D_NF]} + (RoundAdd[`NF-`D_NF+`D_LEN-2:`NF-`D_NF]&{`D_LEN-1{AddendStickyM}})}; + KillProdResult = {{`FLEN-`D_LEN{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`D_NE-2:1], ZExpM[0]&~ZOrigDenormM, ZManM[`NF-1:`NF-`D_NF]} + (RoundAdd[`NF-`D_NF+`D_LEN-2:`NF-`D_NF]&{`D_LEN-1{AddendStickyM}})}; UnderflowResult = {{`FLEN-`D_LEN{1'b1}}, {ResultSgn, (`D_LEN-1)'(0)} + {(`D_LEN-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; InfResult = {{`FLEN-`D_LEN{1'b1}}, InfSgn, {`D_NE{1'b1}}, (`D_NF)'(0)}; NormResult = {{`FLEN-`D_LEN{1'b1}}, ResultSgn, ResultExp[`D_NE-1:0], ResultFrac[`NF-1:`NF-`D_NF]}; @@ -1264,14 +1268,14 @@ module resultselect( XNaNResult = {{`FLEN-`S_LEN{1'b1}}, XSgnM, {`S_NE{1'b1}}, 1'b1, XManM[`NF-2:`NF-`S_NF]}; YNaNResult = {{`FLEN-`S_LEN{1'b1}}, YSgnM, {`S_NE{1'b1}}, 1'b1, YManM[`NF-2:`NF-`S_NF]}; ZNaNResult = {{`FLEN-`S_LEN{1'b1}}, ZSgnEffM, {`S_NE{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`S_NF]}; - InvalidResult = {{`FLEN-`S_LEN{1'b1}}, ResultSgn, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)}; + InvalidResult = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)}; end else begin XNaNResult = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)}; end OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`S_LEN{1'b1}}, ResultSgn, {`S_NE-1{1'b1}}, 1'b0, {`S_NF{1'b1}}} : {{`FLEN-`S_LEN{1'b1}}, ResultSgn, {`S_NE{1'b1}}, (`S_NF)'(0)}; - KillProdResult = {{`FLEN-`S_LEN{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`NE2-2:0], ZManM[`NF-1:`NF-`S_NF]} + (RoundAdd[`NF-`S_NF+`S_LEN-2:`NF-`S_NF]&{`S_LEN-1{AddendStickyM}})}; + KillProdResult = {{`FLEN-`S_LEN{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`S_NE-2:1], ZExpM[0]&~ZOrigDenormM, ZManM[`NF-1:`NF-`S_NF]} + (RoundAdd[`NF-`S_NF+`S_LEN-2:`NF-`S_NF]&{`S_LEN-1{AddendStickyM}})}; UnderflowResult = {{`FLEN-`S_LEN{1'b1}}, {ResultSgn, (`S_LEN-1)'(0)} + {(`S_LEN-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; InfResult = {{`FLEN-`S_LEN{1'b1}}, InfSgn, {`S_NE{1'b1}}, (`S_NF)'(0)}; NormResult = {{`FLEN-`S_LEN{1'b1}}, ResultSgn, ResultExp[`S_NE-1:0], ResultFrac[`NF-1:`NF-`S_NF]}; @@ -1289,7 +1293,7 @@ module resultselect( OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`H_LEN{1'b1}}, ResultSgn, {`H_NE-1{1'b1}}, 1'b0, {`H_NF{1'b1}}} : {{`FLEN-`H_LEN{1'b1}}, ResultSgn, {`H_NE{1'b1}}, (`H_NF)'(0)}; - KillProdResult = {{`FLEN-`H_LEN{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`H_NE-2:0], ZManM[`NF-1:`NF-`H_NF]} + (RoundAdd[`NF-`H_NF+`H_LEN-2:`NF-`H_NF]&{`H_LEN-1{AddendStickyM}})}; + KillProdResult = {{`FLEN-`H_LEN{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`H_NE-2:1],ZExpM[0]&~ZOrigDenormM, ZManM[`NF-1:`NF-`H_NF]} + (RoundAdd[`NF-`H_NF+`H_LEN-2:`NF-`H_NF]&{`H_LEN-1{AddendStickyM}})}; UnderflowResult = {{`FLEN-`H_LEN{1'b1}}, {ResultSgn, (`H_LEN-1)'(0)} + {(`H_LEN-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; InfResult = {{`FLEN-`H_LEN{1'b1}}, InfSgn, {`H_NE{1'b1}}, (`H_NF)'(0)}; NormResult = {{`FLEN-`H_LEN{1'b1}}, ResultSgn, ResultExp[`H_NE-1:0], ResultFrac[`NF-1:`NF-`H_NF]}; diff --git a/pipelined/src/fpu/fpu.sv b/pipelined/src/fpu/fpu.sv index 7b05b33f2..32b676613 100755 --- a/pipelined/src/fpu/fpu.sv +++ b/pipelined/src/fpu/fpu.sv @@ -104,6 +104,7 @@ module fpu ( logic XInfQ, YInfQ; // is the input infinity - divide logic XExpMaxE; // is the exponent all ones (max value) logic XNormE; // is normal + logic ZOrigDenormE; logic FmtQ; logic FOpCtrlQ; @@ -176,7 +177,7 @@ module fpu ( // unpack unit // - splits FP inputs into their various parts // - does some classifications (SNaN, NaN, Denorm, Norm, Zero, Infifnity) - unpack unpack (.X(FSrcXE), .Y(FSrcYE), .Z(FSrcZE), .FmtE, + unpack unpack (.X(FSrcXE), .Y(FSrcYE), .Z(FSrcZE), .FmtE, .ZOrigDenormE, .XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE, .XManE, .YManE, .ZManE, .XNaNE, .YNaNE, .ZNaNE, .XSNaNE, .YSNaNE, .ZSNaNE, .XDenormE, .YDenormE, .ZDenormE, .XZeroE, .YZeroE, .ZZeroE, .XInfE, .YInfE, .ZInfE, .XExpMaxE, .XNormE); diff --git a/pipelined/src/fpu/unpack.sv b/pipelined/src/fpu/unpack.sv index a1d96b8b9..6adb23683 100644 --- a/pipelined/src/fpu/unpack.sv +++ b/pipelined/src/fpu/unpack.sv @@ -12,6 +12,7 @@ module unpack ( output logic XDenormE, YDenormE, ZDenormE, // is XYZ denormalized output logic XZeroE, YZeroE, ZZeroE, // is XYZ zero output logic XInfE, YInfE, ZInfE, // is XYZ infinity + output logic ZOrigDenormE, // is the original precision denormalized output logic XExpMaxE // does X have the maximum exponent (NaN or Inf) ); @@ -47,6 +48,8 @@ module unpack ( assign XExpMaxE = &XExpE; assign YExpMaxE = &YExpE; assign ZExpMaxE = &ZExpE; + + assign OrigDenormE = 1'b0; end else if (`FPSIZES == 2) begin // if there are 2 floating point formats supported @@ -69,7 +72,8 @@ module unpack ( // quad and half // double and half - logic [`LEN1-1:0] XLen1, YLen1, ZLen1; // Remove NaN boxing or NaN, if not properly NaN boxed + logic [`LEN1-1:0] XLen1, YLen1, ZLen1; // Remove NaN boxing or NaN, if not properly NaN boxed + logic XOrigDenormE, YOrigDenormE; // the original value of XYZ is denormalized // Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN assign XLen1 = &X[`FLEN-1:`LEN1] ? X[`LEN1-1:0] : {1'b0, {`NE1+1{1'b1}}, (`NF1-1)'(0)}; @@ -90,9 +94,15 @@ module unpack ( // also need to take into account possible zero/denorm/inf/NaN values // extract the exponent, converting the smaller exponent into the larger precision if nessisary - assign XExpE = FmtE ? X[`FLEN-2:`NF] : {XLen1[`LEN1-2], {`NE-`NE1{~XLen1[`LEN1-2]&~XExpZero|XExpMaxE}}, XLen1[`LEN1-3:`NF1]}; - assign YExpE = FmtE ? Y[`FLEN-2:`NF] : {YLen1[`LEN1-2], {`NE-`NE1{~YLen1[`LEN1-2]&~YExpZero|YExpMaxE}}, YLen1[`LEN1-3:`NF1]}; - assign ZExpE = FmtE ? Z[`FLEN-2:`NF] : {ZLen1[`LEN1-2], {`NE-`NE1{~ZLen1[`LEN1-2]&~ZExpZero|ZExpMaxE}}, ZLen1[`LEN1-3:`NF1]}; + // - if the original precision had a denormal number convert the exponent value 1 + assign XExpE = FmtE ? X[`FLEN-2:`NF] : XOrigDenormE ? {1'b0, {`NE-`NE1{1'b1}}, (`NE1-1)'(1)} : {XLen1[`LEN1-2], {`NE-`NE1{~XLen1[`LEN1-2]&~XExpZero|XExpMaxE}}, XLen1[`LEN1-3:`NF1]}; + assign YExpE = FmtE ? Y[`FLEN-2:`NF] : YOrigDenormE ? {1'b0, {`NE-`NE1{1'b1}}, (`NE1-1)'(1)} : {YLen1[`LEN1-2], {`NE-`NE1{~YLen1[`LEN1-2]&~YExpZero|YExpMaxE}}, YLen1[`LEN1-3:`NF1]}; + assign ZExpE = FmtE ? Z[`FLEN-2:`NF] : ZOrigDenormE ? {1'b0, {`NE-`NE1{1'b1}}, (`NE1-1)'(1)} : {ZLen1[`LEN1-2], {`NE-`NE1{~ZLen1[`LEN1-2]&~ZExpZero|ZExpMaxE}}, ZLen1[`LEN1-3:`NF1]}; + + // is the input (in it's original format) denormalized + assign XOrigDenormE = (FmtE ? 0 : |XLen1[`LEN1-2:`NF1]) & ~XFracZero; + assign YOrigDenormE = (FmtE ? 0 : |YLen1[`LEN1-2:`NF1]) & ~YFracZero; + assign ZOrigDenormE = (FmtE ? 0 : |ZLen1[`LEN1-2:`NF1]) & ~ZFracZero; // extract the fraction, add trailing zeroes to the mantissa if nessisary assign XFracE = FmtE ? X[`NF-1:0] : {XLen1[`NF1-1:0], (`NF-`NF1)'(0)}; @@ -129,8 +139,9 @@ module unpack ( // quad and double and half // quad and single and half - logic [`LEN1-1:0] XLen1, YLen1, ZLen1; // Remove NaN boxing or NaN, if not properly NaN boxed for larger percision - logic [`LEN2-1:0] XLen2, YLen2, ZLen2; // Remove NaN boxing or NaN, if not properly NaN boxed for smallest precision + logic [`LEN1-1:0] XLen1, YLen1, ZLen1; // Remove NaN boxing or NaN, if not properly NaN boxed for larger percision + logic [`LEN2-1:0] XLen2, YLen2, ZLen2; // Remove NaN boxing or NaN, if not properly NaN boxed for smallest precision + logic XOrigDenormE, YOrigDenormE; // the original value of XYZ is denormalized // Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN - for larger precision assign XLen1 = &X[`FLEN-1:`LEN1] ? X[`LEN1-1:0] : {1'b0, {`NE1+1{1'b1}}, (`NF1-1)'(0)}; @@ -142,6 +153,75 @@ module unpack ( assign YLen2 = &Y[`FLEN-1:`LEN2] ? Y[`LEN2-1:0] : {1'b0, {`NE2+1{1'b1}}, (`NF2-1)'(0)}; assign ZLen2 = &Z[`FLEN-1:`LEN2] ? Z[`LEN2-1:0] : {1'b0, {`NE2+1{1'b1}}, (`NF2-1)'(0)}; + // There are 2 case statements + // - one for other singals and one for sgn/exp/frac + // - need two for the dependencies in the expoenent calculation + always_comb begin + case (FmtE) + `FMT: begin // if input is largest precision (`FLEN - ie quad or double) + + // This is the original format so set OrigDenorm to 0 + XOrigDenormE = 1'b0; + YOrigDenormE = 1'b0; + ZOrigDenormE = 1'b0; + + // is the exponent non-zero + XExpNonzero = |X[`FLEN-2:`NF]; + YExpNonzero = |Y[`FLEN-2:`NF]; + ZExpNonzero = |Z[`FLEN-2:`NF]; + + // is the exponent all 1's + XExpMaxE = &X[`FLEN-2:`NF]; + YExpMaxE = &Y[`FLEN-2:`NF]; + ZExpMaxE = &Z[`FLEN-2:`NF]; + end + `FMT1: begin // if input is larger precsion (`LEN1 - double or single) + + // is the input (in it's original format) denormalized + XOrigDenormE = ~|XLen1[`LEN1-2:`NF1] & ~XFracZero; + YOrigDenormE = ~|YLen1[`LEN1-2:`NF1] & ~YFracZero; + ZOrigDenormE = ~|ZLen1[`LEN1-2:`NF1] & ~ZFracZero; + + // is the exponent non-zero + XExpNonzero = |XLen1[`LEN1-2:`NF1]; + YExpNonzero = |YLen1[`LEN1-2:`NF1]; + ZExpNonzero = |ZLen1[`LEN1-2:`NF1]; + + // is the exponent all 1's + XExpMaxE = &XLen1[`LEN1-2:`NF1]; + YExpMaxE = &YLen1[`LEN1-2:`NF1]; + ZExpMaxE = &ZLen1[`LEN1-2:`NF1]; + end + `FMT2: begin // if input is smallest precsion (`LEN2 - single or half) + + // is the input (in it's original format) denormalized + XOrigDenormE = ~|XLen2[`LEN2-2:`NF2] & ~XFracZero; + YOrigDenormE = ~|YLen2[`LEN2-2:`NF2] & ~YFracZero; + ZOrigDenormE = ~|ZLen2[`LEN2-2:`NF2] & ~ZFracZero; + + // is the exponent non-zero + XExpNonzero = |XLen2[`LEN2-2:`NF2]; + YExpNonzero = |YLen2[`LEN2-2:`NF2]; + ZExpNonzero = |ZLen2[`LEN2-2:`NF2]; + + // is the exponent all 1's + XExpMaxE = &XLen2[`LEN2-2:`NF2]; + YExpMaxE = &YLen2[`LEN2-2:`NF2]; + ZExpMaxE = &ZLen2[`LEN2-2:`NF2]; + end + default: begin + XOrigDenormE = 0; + YOrigDenormE = 0; + ZOrigDenormE = 0; + XExpNonzero = 0; + YExpNonzero = 0; + ZExpNonzero = 0; + XExpMaxE = 0; + YExpMaxE = 0; + ZExpMaxE = 0; + end + endcase + end always_comb begin case (FmtE) `FMT: begin // if input is largest precision (`FLEN - ie quad or double) @@ -159,16 +239,6 @@ module unpack ( XFracE = X[`NF-1:0]; YFracE = Y[`NF-1:0]; ZFracE = Z[`NF-1:0]; - - // is the exponent non-zero - XExpNonzero = |X[`FLEN-2:`NF]; - YExpNonzero = |Y[`FLEN-2:`NF]; - ZExpNonzero = |Z[`FLEN-2:`NF]; - - // is the exponent all 1's - XExpMaxE = &X[`FLEN-2:`NF]; - YExpMaxE = &Y[`FLEN-2:`NF]; - ZExpMaxE = &Z[`FLEN-2:`NF]; end `FMT1: begin // if input is larger precsion (`LEN1 - double or single) @@ -186,24 +256,14 @@ module unpack ( // also need to take into account possible zero/denorm/inf/NaN values // convert the larger precision's exponent to use the largest precision's bias - XExpE = {XLen1[`LEN1-2], {`NE-`NE1{~XLen1[`LEN1-2]&~XExpZero|XExpMaxE}}, XLen1[`LEN1-3:`NF1]}; - YExpE = {YLen1[`LEN1-2], {`NE-`NE1{~YLen1[`LEN1-2]&~YExpZero|YExpMaxE}}, YLen1[`LEN1-3:`NF1]}; - ZExpE = {ZLen1[`LEN1-2], {`NE-`NE1{~ZLen1[`LEN1-2]&~ZExpZero|ZExpMaxE}}, ZLen1[`LEN1-3:`NF1]}; + XExpE = XOrigDenormE ? {1'b0, {`NE-`NE1{1'b1}}, (`NE1-1)'(1)} : {XLen1[`LEN1-2], {`NE-`NE1{~XLen1[`LEN1-2]&~XExpZero|XExpMaxE}}, XLen1[`LEN1-3:`NF1]}; + YExpE = YOrigDenormE ? {1'b0, {`NE-`NE1{1'b1}}, (`NE1-1)'(1)} : {YLen1[`LEN1-2], {`NE-`NE1{~YLen1[`LEN1-2]&~YExpZero|YExpMaxE}}, YLen1[`LEN1-3:`NF1]}; + ZExpE = ZOrigDenormE ? {1'b0, {`NE-`NE1{1'b1}}, (`NE1-1)'(1)} : {ZLen1[`LEN1-2], {`NE-`NE1{~ZLen1[`LEN1-2]&~ZExpZero|ZExpMaxE}}, ZLen1[`LEN1-3:`NF1]}; // extract the fraction and add the nessesary trailing zeros XFracE = {XLen1[`NF1-1:0], (`NF-`NF1)'(0)}; YFracE = {YLen1[`NF1-1:0], (`NF-`NF1)'(0)}; ZFracE = {ZLen1[`NF1-1:0], (`NF-`NF1)'(0)}; - - // is the exponent non-zero - XExpNonzero = |XLen1[`LEN1-2:`NF1]; - YExpNonzero = |YLen1[`LEN1-2:`NF1]; - ZExpNonzero = |ZLen1[`LEN1-2:`NF1]; - - // is the exponent all 1's - XExpMaxE = &XLen1[`LEN1-2:`NF1]; - YExpMaxE = &YLen1[`LEN1-2:`NF1]; - ZExpMaxE = &ZLen1[`LEN1-2:`NF1]; end `FMT2: begin // if input is smallest precsion (`LEN2 - single or half) @@ -221,24 +281,14 @@ module unpack ( // also need to take into account possible zero/denorm/inf/NaN values // convert the smallest precision's exponent to use the largest precision's bias - XExpE = {XLen2[`LEN2-2], {`NE-`NE2{~XLen2[`LEN2-2]&~XExpZero|XExpMaxE}}, XLen2[`LEN2-3:`NF2]}; - YExpE = {YLen2[`LEN2-2], {`NE-`NE2{~YLen2[`LEN2-2]&~YExpZero|YExpMaxE}}, YLen2[`LEN2-3:`NF2]}; - ZExpE = {ZLen2[`LEN2-2], {`NE-`NE2{~ZLen2[`LEN2-2]&~ZExpZero|ZExpMaxE}}, ZLen2[`LEN2-3:`NF2]}; + XExpE = XOrigDenormE ? {1'b0, {`NE-`NE2{1'b1}}, (`NE2-1)'(1)} : {XLen2[`LEN2-2], {`NE-`NE2{~XLen2[`LEN2-2]&~XExpZero|XExpMaxE}}, XLen2[`LEN2-3:`NF2]}; + YExpE = YOrigDenormE ? {1'b0, {`NE-`NE2{1'b1}}, (`NE2-1)'(1)} : {YLen2[`LEN2-2], {`NE-`NE2{~YLen2[`LEN2-2]&~YExpZero|YExpMaxE}}, YLen2[`LEN2-3:`NF2]}; + ZExpE = ZOrigDenormE ? {1'b0, {`NE-`NE2{1'b1}}, (`NE2-1)'(1)} : {ZLen2[`LEN2-2], {`NE-`NE2{~ZLen2[`LEN2-2]&~ZExpZero|ZExpMaxE}}, ZLen2[`LEN2-3:`NF2]}; // extract the fraction and add the nessesary trailing zeros XFracE = {XLen2[`NF2-1:0], (`NF-`NF2)'(0)}; YFracE = {YLen2[`NF2-1:0], (`NF-`NF2)'(0)}; ZFracE = {ZLen2[`NF2-1:0], (`NF-`NF2)'(0)}; - - // is the exponent non-zero - XExpNonzero = |XLen2[`LEN2-2:`NF2]; - YExpNonzero = |YLen2[`LEN2-2:`NF2]; - ZExpNonzero = |ZLen2[`LEN2-2:`NF2]; - - // is the exponent all 1's - XExpMaxE = &XLen2[`LEN2-2:`NF2]; - YExpMaxE = &YLen2[`LEN2-2:`NF2]; - ZExpMaxE = &ZLen2[`LEN2-2:`NF2]; end default: begin XSgnE = 0; @@ -250,12 +300,6 @@ module unpack ( XFracE = 0; YFracE = 0; ZFracE = 0; - XExpNonzero = 0; - YExpNonzero = 0; - ZExpNonzero = 0; - XExpMaxE = 0; - YExpMaxE = 0; - ZExpMaxE = 0; end endcase end @@ -271,9 +315,10 @@ module unpack ( // `Q_FMT | `D_FMT | `S_FMT | `H_FMT precision's format value - Q=11 D=01 S=00 H=10 - logic [`LEN1-1:0] XLen1, YLen1, ZLen1; // Remove NaN boxing or NaN, if not properly NaN boxed for double percision - logic [`LEN2-1:0] XLen2, YLen2, ZLen2; // Remove NaN boxing or NaN, if not properly NaN boxed for single percision - logic [`LEN2-1:0] XLen3, YLen3, ZLen3; // Remove NaN boxing or NaN, if not properly NaN boxed for half percision + logic [`D_LEN-1:0] XLen1, YLen1, ZLen1; // Remove NaN boxing or NaN, if not properly NaN boxed for double percision + logic [`S_LEN-1:0] XLen2, YLen2, ZLen2; // Remove NaN boxing or NaN, if not properly NaN boxed for single percision + logic [`H_LEN-1:0] XLen3, YLen3, ZLen3; // Remove NaN boxing or NaN, if not properly NaN boxed for half percision + logic XOrigDenormE, YOrigDenormE; // the original value of XYZ is denormalized // Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN - for double precision assign XLen1 = &X[`Q_LEN-1:`D_LEN] ? X[`D_LEN-1:0] : {1'b0, {`D_NE+1{1'b1}}, (`D_NF-1)'(0)}; @@ -290,6 +335,83 @@ module unpack ( assign YLen3 = &Y[`Q_LEN-1:`H_LEN] ? Y[`H_LEN-1:0] : {1'b0, {`H_NE+1{1'b1}}, (`H_NF-1)'(0)}; assign ZLen3 = &Z[`Q_LEN-1:`H_LEN] ? Z[`H_LEN-1:0] : {1'b0, {`H_NE+1{1'b1}}, (`H_NF-1)'(0)}; + + // There are 2 case statements + // - one for other singals and one for sgn/exp/frac + // - need two for the dependencies in the expoenent calculation + always_comb begin + case (FmtE) + 2'b11: begin // if input is quad percision + + // This is the original format so set OrigDenorm to 0 + XOrigDenormE = 1'b0; + YOrigDenormE = 1'b0; + ZOrigDenormE = 1'b0; + + // is the exponent non-zero + XExpNonzero = |X[`Q_LEN-2:`Q_NF]; + YExpNonzero = |Y[`Q_LEN-2:`Q_NF]; + ZExpNonzero = |Z[`Q_LEN-2:`Q_NF]; + + // is the exponent all 1's + XExpMaxE = &X[`Q_LEN-2:`Q_NF]; + YExpMaxE = &Y[`Q_LEN-2:`Q_NF]; + ZExpMaxE = &Z[`Q_LEN-2:`Q_NF]; + end + 2'b01: begin // if input is double percision + + // is the exponent all 1's + XExpMaxE = &XLen1[`D_LEN-2:`D_NF]; + YExpMaxE = &YLen1[`D_LEN-2:`D_NF]; + ZExpMaxE = &ZLen1[`D_LEN-2:`D_NF]; + + // is the input (in it's original format) denormalized + XOrigDenormE = ~|XLen1[`D_LEN-2:`D_NF] & ~XFracZero; + YOrigDenormE = ~|YLen1[`D_LEN-2:`D_NF] & ~YFracZero; + ZOrigDenormE = ~|ZLen1[`D_LEN-2:`D_NF] & ~ZFracZero; + + // is the exponent non-zero + XExpNonzero = |XLen1[`D_LEN-2:`D_NF]; + YExpNonzero = |YLen1[`D_LEN-2:`D_NF]; + ZExpNonzero = |ZLen1[`D_LEN-2:`D_NF]; + end + 2'b00: begin // if input is single percision + + // is the exponent all 1's + XExpMaxE = &XLen2[`S_LEN-2:`S_NF]; + YExpMaxE = &YLen2[`S_LEN-2:`S_NF]; + ZExpMaxE = &ZLen2[`S_LEN-2:`S_NF]; + + // is the input (in it's original format) denormalized + XOrigDenormE = ~|XLen2[`S_LEN-2:`S_NF] & ~XFracZero; + YOrigDenormE = ~|YLen2[`S_LEN-2:`S_NF] & ~YFracZero; + ZOrigDenormE = ~|ZLen2[`S_LEN-2:`S_NF] & ~ZFracZero; + + // is the exponent non-zero + XExpNonzero = |XLen2[`S_LEN-2:`S_NF]; + YExpNonzero = |YLen2[`S_LEN-2:`S_NF]; + ZExpNonzero = |ZLen2[`S_LEN-2:`S_NF]; + end + 2'b10: begin // if input is half percision + + // is the exponent all 1's + XExpMaxE = &XLen3[`H_LEN-2:`H_NF]; + YExpMaxE = &YLen3[`H_LEN-2:`H_NF]; + ZExpMaxE = &ZLen3[`H_LEN-2:`H_NF]; + + // is the input (in it's original format) denormalized + XOrigDenormE = ~|XLen3[`H_LEN-2:`H_NF] & ~XFracZero; + YOrigDenormE = ~|YLen3[`H_LEN-2:`H_NF] & ~YFracZero; + ZOrigDenormE = ~|ZLen3[`H_LEN-2:`H_NF] & ~ZFracZero; + + // is the exponent non-zero + XExpNonzero = |XLen3[`H_LEN-2:`H_NF]; + YExpNonzero = |YLen3[`H_LEN-2:`H_NF]; + ZExpNonzero = |ZLen3[`H_LEN-2:`H_NF]; + end + endcase + end + always_comb begin case (FmtE) 2'b11: begin // if input is quad percision @@ -307,16 +429,6 @@ module unpack ( XFracE = X[`Q_NF-1:0]; YFracE = Y[`Q_NF-1:0]; ZFracE = Z[`Q_NF-1:0]; - - // is the exponent non-zero - XExpNonzero = |X[`Q_LEN-2:`Q_NF]; - YExpNonzero = |Y[`Q_LEN-2:`Q_NF]; - ZExpNonzero = |Z[`Q_LEN-2:`Q_NF]; - - // is the exponent all 1's - XExpMaxE = &X[`Q_LEN-2:`Q_NF]; - YExpMaxE = &Y[`Q_LEN-2:`Q_NF]; - ZExpMaxE = &Z[`Q_LEN-2:`Q_NF]; end 2'b01: begin // if input is double percision // extract sign bit @@ -333,24 +445,15 @@ module unpack ( // also need to take into account possible zero/denorm/inf/NaN values // convert the double precsion exponent into quad precsion - XExpE = {XLen1[`D_LEN-2], {`Q_NE-`D_NE{~XLen1[`D_LEN-2]&~XExpZero|XExpMaxE}}, XLen1[`D_LEN-3:`D_NF]}; - YExpE = {YLen1[`D_LEN-2], {`Q_NE-`D_NE{~YLen1[`D_LEN-2]&~YExpZero|YExpMaxE}}, YLen1[`D_LEN-3:`D_NF]}; - ZExpE = {ZLen1[`D_LEN-2], {`Q_NE-`D_NE{~ZLen1[`D_LEN-2]&~ZExpZero|ZExpMaxE}}, ZLen1[`D_LEN-3:`D_NF]}; + + XExpE = XOrigDenormE ? {1'b0, {`Q_NE-`D_NE{1'b1}}, (`D_NE-1)'(1)} : {XLen1[`D_LEN-2], {`Q_NE-`D_NE{~XLen1[`D_LEN-2]&~XExpZero|XExpMaxE}}, XLen1[`D_LEN-3:`D_NF]}; + YExpE = YOrigDenormE ? {1'b0, {`Q_NE-`D_NE{1'b1}}, (`D_NE-1)'(1)} : {YLen1[`D_LEN-2], {`Q_NE-`D_NE{~YLen1[`D_LEN-2]&~YExpZero|YExpMaxE}}, YLen1[`D_LEN-3:`D_NF]}; + ZExpE = ZOrigDenormE ? {1'b0, {`Q_NE-`D_NE{1'b1}}, (`D_NE-1)'(1)} : {ZLen1[`D_LEN-2], {`Q_NE-`D_NE{~ZLen1[`D_LEN-2]&~ZExpZero|ZExpMaxE}}, ZLen1[`D_LEN-3:`D_NF]}; // extract the fraction and add the nessesary trailing zeros XFracE = {XLen1[`D_NF-1:0], (`Q_NF-`D_NF)'(0)}; YFracE = {YLen1[`D_NF-1:0], (`Q_NF-`D_NF)'(0)}; ZFracE = {ZLen1[`D_NF-1:0], (`Q_NF-`D_NF)'(0)}; - - // is the exponent non-zero - XExpNonzero = |XLen1[`D_LEN-2:`D_NE]; - YExpNonzero = |YLen1[`D_LEN-2:`D_NE]; - ZExpNonzero = |ZLen1[`D_LEN-2:`D_NE]; - - // is the exponent all 1's - XExpMaxE = &XLen1[`D_LEN-2:`D_NE]; - YExpMaxE = &YLen1[`D_LEN-2:`D_NE]; - ZExpMaxE = &ZLen1[`D_LEN-2:`D_NE]; end 2'b00: begin // if input is single percision // extract sign bit @@ -367,24 +470,14 @@ module unpack ( // also need to take into account possible zero/denorm/inf/NaN values // convert the single precsion exponent into quad precsion - XExpE = {XLen2[`S_LEN-2], {`Q_NE-`S_NE{~XLen2[`S_LEN-2]&~XExpZero|XExpMaxE}}, XLen2[`S_LEN-3:`S_NF]}; - YExpE = {YLen2[`S_LEN-2], {`Q_NE-`S_NE{~YLen2[`S_LEN-2]&~YExpZero|YExpMaxE}}, YLen2[`S_LEN-3:`S_NF]}; - ZExpE = {ZLen2[`S_LEN-2], {`Q_NE-`S_NE{~ZLen2[`S_LEN-2]&~ZExpZero|ZExpMaxE}}, ZLen2[`S_LEN-3:`S_NF]}; + XExpE = XOrigDenormE ? {1'b0, {`Q_NE-`S_NE{1'b1}}, (`S_NE-1)'(1)} : {XLen2[`S_LEN-2], {`Q_NE-`S_NE{~XLen2[`S_LEN-2]&~XExpZero|XExpMaxE}}, XLen2[`S_LEN-3:`S_NF]}; + YExpE = YOrigDenormE ? {1'b0, {`Q_NE-`S_NE{1'b1}}, (`S_NE-1)'(1)} : {YLen2[`S_LEN-2], {`Q_NE-`S_NE{~YLen2[`S_LEN-2]&~YExpZero|YExpMaxE}}, YLen2[`S_LEN-3:`S_NF]}; + ZExpE = ZOrigDenormE ? {1'b0, {`Q_NE-`S_NE{1'b1}}, (`S_NE-1)'(1)} : {ZLen2[`S_LEN-2], {`Q_NE-`S_NE{~ZLen2[`S_LEN-2]&~ZExpZero|ZExpMaxE}}, ZLen2[`S_LEN-3:`S_NF]}; // extract the fraction and add the nessesary trailing zeros XFracE = {XLen2[`S_NF-1:0], (`Q_NF-`S_NF)'(0)}; YFracE = {YLen2[`S_NF-1:0], (`Q_NF-`S_NF)'(0)}; ZFracE = {ZLen2[`S_NF-1:0], (`Q_NF-`S_NF)'(0)}; - - // is the exponent non-zero - XExpNonzero = |XLen2[`S_LEN-2:`S_NF]; - YExpNonzero = |YLen2[`S_LEN-2:`S_NF]; - ZExpNonzero = |ZLen2[`S_LEN-2:`S_NF]; - - // is the exponent all 1's - XExpMaxE = &XLen2[`S_LEN-2:`S_NF]; - YExpMaxE = &YLen2[`S_LEN-2:`S_NF]; - ZExpMaxE = &ZLen2[`S_LEN-2:`S_NF]; end 2'b10: begin // if input is half percision // extract sign bit @@ -399,26 +492,16 @@ module unpack ( // sexp = 0000 bbbb bbbb (add this) b = bit d = ~b // dexp = 0bdd dbbb bbbb // also need to take into account possible zero/denorm/inf/NaN values - + // convert the half precsion exponent into quad precsion - XExpE = {XLen3[`H_LEN-2], {`Q_NE-`H_NE{~XLen3[`H_LEN-2]&~XExpZero|XExpMaxE}}, XLen3[`H_LEN-3:`H_NF]}; - YExpE = {YLen3[`H_LEN-2], {`Q_NE-`H_NE{~YLen3[`H_LEN-2]&~YExpZero|YExpMaxE}}, YLen3[`H_LEN-3:`H_NF]}; - ZExpE = {ZLen3[`H_LEN-2], {`Q_NE-`H_NE{~ZLen3[`H_LEN-2]&~ZExpZero|ZExpMaxE}}, ZLen3[`H_LEN-3:`H_NF]}; + XExpE = XOrigDenormE ? {1'b0, {`Q_NE-`H_NE{1'b1}}, (`H_NE-1)'(1)} : {XLen3[`H_LEN-2], {`Q_NE-`H_NE{~XLen3[`H_LEN-2]&~XExpZero|XExpMaxE}}, XLen3[`H_LEN-3:`H_NF]}; + YExpE = YOrigDenormE ? {1'b0, {`Q_NE-`H_NE{1'b1}}, (`H_NE-1)'(1)} : {YLen3[`H_LEN-2], {`Q_NE-`H_NE{~YLen3[`H_LEN-2]&~YExpZero|YExpMaxE}}, YLen3[`H_LEN-3:`H_NF]}; + ZExpE = ZOrigDenormE ? {1'b0, {`Q_NE-`H_NE{1'b1}}, (`H_NE-1)'(1)} : {ZLen3[`H_LEN-2], {`Q_NE-`H_NE{~ZLen3[`H_LEN-2]&~ZExpZero|ZExpMaxE}}, ZLen3[`H_LEN-3:`H_NF]}; // extract the fraction and add the nessesary trailing zeros XFracE = {XLen3[`H_NF-1:0], (`Q_NF-`H_NF)'(0)}; YFracE = {YLen3[`H_NF-1:0], (`Q_NF-`H_NF)'(0)}; ZFracE = {ZLen3[`H_NF-1:0], (`Q_NF-`H_NF)'(0)}; - - // is the exponent non-zero - XExpNonzero = |XLen3[`H_LEN-2:`H_NF]; - YExpNonzero = |YLen3[`H_LEN-2:`H_NF]; - ZExpNonzero = |ZLen3[`H_LEN-2:`H_NF]; - - // is the exponent all 1's - XExpMaxE = &XLen3[`H_LEN-2:`H_NF]; - YExpMaxE = &YLen3[`H_LEN-2:`H_NF]; - ZExpMaxE = &ZLen3[`H_LEN-2:`H_NF]; end endcase end diff --git a/pipelined/testbench/testbench-fp.sv b/pipelined/testbench/testbench-fp.sv index 42aa7312b..d79bc6d19 100644 --- a/pipelined/testbench/testbench-fp.sv +++ b/pipelined/testbench/testbench-fp.sv @@ -40,6 +40,7 @@ module testbenchfp; logic [1:0] FmaFmtVal, FmtVal; logic [2:0] UnitVal, OpCtrlVal, FrmVal; logic NaNGood; + logic ZOrigDenorm, FmaRneZOrigDenorm, FmaRzZOrigDenorm, FmaRuZOrigDenorm, FmaRdZOrigDenorm, FmaRnmZOrigDenorm; logic FmaRneNaNGood, FmaRzNaNGood, FmaRuNaNGood, FmaRdNaNGood, FmaRnmNaNGood; logic [`FLEN-1:0] X, Y, Z; // inputs read from TestFloat logic [`FLEN-1:0] FmaRneX, FmaRneY, FmaRneZ; // inputs read from TestFloat @@ -628,7 +629,7 @@ module testbenchfp; .XSgnE(FmaRneXSgn), .YSgnE(FmaRneYSgn), .ZSgnE(FmaRneZSgn), .FmaNum, .XExpE(FmaRneXExp), .YExpE(FmaRneYExp), .ZExpE(FmaRneZExp), .XManE(FmaRneXMan), .YManE(FmaRneYMan), .ZManE(FmaRneZMan), - .XNaNE(FmaRneXNaN), .YNaNE(FmaRneYNaN), .ZNaNE(FmaRneZNaN), + .XNaNE(FmaRneXNaN), .YNaNE(FmaRneYNaN), .ZNaNE(FmaRneZNaN), .ZOrigDenormE(FmaRneZOrigDenorm), .XSNaNE(FmaRneXSNaN), .YSNaNE(FmaRneYSNaN), .ZSNaNE(FmaRneZSNaN), .XDenormE(FmaRneXDenorm), .YDenormE(FmaRneYDenorm), .ZDenormE(FmaRneZDenorm), .XZeroE(FmaRneXZero), .YZeroE(FmaRneYZero), .ZZeroE(FmaRneZZero), @@ -638,7 +639,7 @@ module testbenchfp; .XSgnE(FmaRzXSgn), .YSgnE(FmaRzYSgn), .ZSgnE(FmaRzZSgn), .FmaNum, .FmaModFmt, .XExpE(FmaRzXExp), .YExpE(FmaRzYExp), .ZExpE(FmaRzZExp), .XManE(FmaRzXMan), .YManE(FmaRzYMan), .ZManE(FmaRzZMan), - .XNaNE(FmaRzXNaN), .YNaNE(FmaRzYNaN), .ZNaNE(FmaRzZNaN), + .XNaNE(FmaRzXNaN), .YNaNE(FmaRzYNaN), .ZNaNE(FmaRzZNaN), .ZOrigDenormE(FmaRzZOrigDenorm), .XSNaNE(FmaRzXSNaN), .YSNaNE(FmaRzYSNaN), .ZSNaNE(FmaRzZSNaN), .XDenormE(FmaRzXDenorm), .YDenormE(FmaRzYDenorm), .ZDenormE(FmaRzZDenorm), .XZeroE(FmaRzXZero), .YZeroE(FmaRzYZero), .ZZeroE(FmaRzZZero), @@ -648,7 +649,7 @@ module testbenchfp; .XSgnE(FmaRuXSgn), .YSgnE(FmaRuYSgn), .ZSgnE(FmaRuZSgn), .FmaNum, .FmaModFmt, .XExpE(FmaRuXExp), .YExpE(FmaRuYExp), .ZExpE(FmaRuZExp), .XManE(FmaRuXMan), .YManE(FmaRuYMan), .ZManE(FmaRuZMan), - .XNaNE(FmaRuXNaN), .YNaNE(FmaRuYNaN), .ZNaNE(FmaRuZNaN), + .XNaNE(FmaRuXNaN), .YNaNE(FmaRuYNaN), .ZNaNE(FmaRuZNaN), .ZOrigDenormE(FmaRuZOrigDenorm), .XSNaNE(FmaRuXSNaN), .YSNaNE(FmaRuYSNaN), .ZSNaNE(FmaRuZSNaN), .XDenormE(FmaRuXDenorm), .YDenormE(FmaRuYDenorm), .ZDenormE(FmaRuZDenorm), .XZeroE(FmaRuXZero), .YZeroE(FmaRuYZero), .ZZeroE(FmaRuZZero), @@ -658,7 +659,7 @@ module testbenchfp; .XSgnE(FmaRdXSgn), .YSgnE(FmaRdYSgn), .ZSgnE(FmaRdZSgn), .FmaNum, .FmaModFmt, .XExpE(FmaRdXExp), .YExpE(FmaRdYExp), .ZExpE(FmaRdZExp), .XManE(FmaRdXMan), .YManE(FmaRdYMan), .ZManE(FmaRdZMan), - .XNaNE(FmaRdXNaN), .YNaNE(FmaRdYNaN), .ZNaNE(FmaRdZNaN), + .XNaNE(FmaRdXNaN), .YNaNE(FmaRdYNaN), .ZNaNE(FmaRdZNaN), .ZOrigDenormE(FmaRdZOrigDenorm), .XSNaNE(FmaRdXSNaN), .YSNaNE(FmaRdYSNaN), .ZSNaNE(FmaRdZSNaN), .XDenormE(FmaRdXDenorm), .YDenormE(FmaRdYDenorm), .ZDenormE(FmaRdZDenorm), .XZeroE(FmaRdXZero), .YZeroE(FmaRdYZero), .ZZeroE(FmaRdZZero), @@ -667,7 +668,7 @@ module testbenchfp; readfmavectors readfmarnmvectors (.clk, .Frm(`RNM), .TestVector(FmaRnmVectors[VectorNum]), .VectorNum, .Ans(FmaRnmAns), .AnsFlags(FmaRnmAnsFlags), .XSgnE(FmaRnmXSgn), .YSgnE(FmaRnmYSgn), .ZSgnE(FmaRnmZSgn), .FmaNum, .FmaModFmt, .XExpE(FmaRnmXExp), .YExpE(FmaRnmYExp), .ZExpE(FmaRnmZExp), - .XManE(FmaRnmXMan), .YManE(FmaRnmYMan), .ZManE(FmaRnmZMan), + .XManE(FmaRnmXMan), .YManE(FmaRnmYMan), .ZManE(FmaRnmZMan), .ZOrigDenormE(FmaRnmZOrigDenorm), .XNaNE(FmaRnmXNaN), .YNaNE(FmaRnmYNaN), .ZNaNE(FmaRnmZNaN), .XSNaNE(FmaRnmXSNaN), .YSNaNE(FmaRnmYSNaN), .ZSNaNE(FmaRnmZSNaN), .XDenormE(FmaRnmXDenorm), .YDenormE(FmaRnmYDenorm), .ZDenormE(FmaRnmZDenorm), @@ -677,7 +678,7 @@ module testbenchfp; readvectors readvectors (.clk, .Fmt(FmtVal), .ModFmt, .TestVector(TestVectors[VectorNum]), .VectorNum, .Ans(Ans), .AnsFlags(AnsFlags), .SrcA, .XSgnE(XSgn), .YSgnE(YSgn), .ZSgnE(ZSgn), .Unit (UnitVal), .XExpE(XExp), .YExpE(YExp), .ZExpE(ZExp), .TestNum, .OpCtrl(OpCtrlVal), - .XManE(XMan), .YManE(YMan), .ZManE(ZMan), + .XManE(XMan), .YManE(YMan), .ZManE(ZMan), .ZOrigDenormE(ZOrigDenorm), .XNaNE(XNaN), .YNaNE(YNaN), .ZNaNE(ZNaN), .XSNaNE(XSNaN), .YSNaNE(YSNaN), .ZSNaNE(ZSNaN), .XDenormE(XDenorm), .YDenormE(YDenorm), .ZDenormE(ZDenorm), @@ -709,7 +710,7 @@ module testbenchfp; .NormCntE(FmaRneNormCnt), .ZSgnEffE(FmaRneZSgnEff), .PSgnE(FmaRnePSgn), .ProdExpE(FmaRneProdExp), .AddendStickyE(FmaRneAddendSticky), .KillProdE(FmaRneSumKillProd)); fma2 fma2rne(.XSgnM(FmaRneXSgn), .YSgnM(FmaRneYSgn), - .ZExpM(FmaRneZExp), + .ZExpM(FmaRneZExp), .ZOrigDenormM(FmaRneZOrigDenorm), .XManM(FmaRneXMan), .YManM(FmaRneYMan), .ZManM(FmaRneZMan), .XNaNM(FmaRneXNaN), .YNaNM(FmaRneYNaN), .ZNaNM(FmaRneZNaN), .XZeroM(FmaRneXZero), .YZeroM(FmaRneYZero), .ZZeroM(FmaRneZZero), @@ -728,7 +729,7 @@ module testbenchfp; .NormCntE(FmaRzNormCnt), .ZSgnEffE(FmaRzZSgnEff), .PSgnE(FmaRzPSgn), .ProdExpE(FmaRzProdExp), .AddendStickyE(FmaRzAddendSticky), .KillProdE(FmaRzSumKillProd)); fma2 fma2rz(.XSgnM(FmaRzXSgn), .YSgnM(FmaRzYSgn), - .ZExpM(FmaRzZExp), + .ZExpM(FmaRzZExp), .ZOrigDenormM(FmaRzZOrigDenorm), .XManM(FmaRzXMan), .YManM(FmaRzYMan), .ZManM(FmaRzZMan), .XNaNM(FmaRzXNaN), .YNaNM(FmaRzYNaN), .ZNaNM(FmaRzZNaN), .XZeroM(FmaRzXZero), .YZeroM(FmaRzYZero), .ZZeroM(FmaRzZZero), @@ -747,7 +748,7 @@ module testbenchfp; .NormCntE(FmaRuNormCnt), .ZSgnEffE(FmaRuZSgnEff), .PSgnE(FmaRuPSgn), .ProdExpE(FmaRuProdExp), .AddendStickyE(FmaRuAddendSticky), .KillProdE(FmaRuSumKillProd)); fma2 fma2ru(.XSgnM(FmaRuXSgn), .YSgnM(FmaRuYSgn), - .ZExpM(FmaRuZExp), + .ZExpM(FmaRuZExp), .ZOrigDenormM(FmaRuZOrigDenorm), .XManM(FmaRuXMan), .YManM(FmaRuYMan), .ZManM(FmaRuZMan), .XNaNM(FmaRuXNaN), .YNaNM(FmaRuYNaN), .ZNaNM(FmaRuZNaN), .XZeroM(FmaRuXZero), .YZeroM(FmaRuYZero), .ZZeroM(FmaRuZZero), @@ -766,7 +767,7 @@ module testbenchfp; .NormCntE(FmaRdNormCnt), .ZSgnEffE(FmaRdZSgnEff), .PSgnE(FmaRdPSgn), .ProdExpE(FmaRdProdExp), .AddendStickyE(FmaRdAddendSticky), .KillProdE(FmaRdSumKillProd)); fma2 fma2rd(.XSgnM(FmaRdXSgn), .YSgnM(FmaRdYSgn), - .ZExpM(FmaRdZExp), + .ZExpM(FmaRdZExp), .ZOrigDenormM(FmaRdZOrigDenorm), .XManM(FmaRdXMan), .YManM(FmaRdYMan), .ZManM(FmaRdZMan), .XNaNM(FmaRdXNaN), .YNaNM(FmaRdYNaN), .ZNaNM(FmaRdZNaN), .XZeroM(FmaRdXZero), .YZeroM(FmaRdYZero), .ZZeroM(FmaRdZZero), @@ -785,7 +786,7 @@ module testbenchfp; .NormCntE(FmaRnmNormCnt), .ZSgnEffE(FmaRnmZSgnEff), .PSgnE(FmaRnmPSgn), .ProdExpE(FmaRnmProdExp), .AddendStickyE(FmaRnmAddendSticky), .KillProdE(FmaRnmSumKillProd)); fma2 fma2rnm(.XSgnM(FmaRnmXSgn), .YSgnM(FmaRnmYSgn), - .ZExpM(FmaRnmZExp), + .ZExpM(FmaRnmZExp), .ZOrigDenormM(FmaRmeZOrigDenorm), .XManM(FmaRnmXMan), .YManM(FmaRnmYMan), .ZManM(FmaRnmZMan), .XNaNM(FmaRnmXNaN), .YNaNM(FmaRnmYNaN), .ZNaNM(FmaRnmZNaN), .XZeroM(FmaRnmXZero), .YZeroM(FmaRnmYZero), .ZZeroM(FmaRnmZZero), @@ -800,10 +801,10 @@ module testbenchfp; .XManE(XMan), .YManE(YMan), .ZManE(ZMan), .XDenormE(XDenorm), .YDenormE(YDenorm), .ZDenormE(ZDenorm), .XZeroE(XZero), .YZeroE(YZero), .ZZeroE(ZZero), - .FOpCtrlE(3'b0), .FmtE(ModFmt), .SumE, .NegSumE, .InvZE, .NormCntE, .ZSgnEffE, .PSgnE, + .FOpCtrlE(OpCtrlVal), .FmtE(ModFmt), .SumE, .NegSumE, .InvZE, .NormCntE, .ZSgnEffE, .PSgnE, .ProdExpE, .AddendStickyE, .KillProdE); fma2 fma2(.XSgnM(XSgn), .YSgnM(YSgn), - .ZExpM(ZExp), + .ZExpM(ZExp), .ZOrigDenormM(ZOrigDenorm), .XManM(XMan), .YManM(YMan), .ZManM(ZMan), .XNaNM(XNaN), .YNaNM(YNaN), .ZNaNM(ZNaN), .XZeroM(XZero), .YZeroM(YZero), .ZZeroM(ZZero), @@ -922,7 +923,6 @@ module testbenchfp; end end - // check results on falling edge of clk always @(negedge clk) begin case (UnitVal) @@ -940,6 +940,9 @@ module testbenchfp; `CVTFPUNIT: ResFlags = CvtFpFlgM; endcase + // check if the NaN value is good. IEEE754-2019 sections 6.3 and 6.2.3 specify: + // - the sign of the NaN does not matter for the opperations being tested + // - when 2 or more NaNs are inputed the NaN that is propigated doesn't matter case (FmaFmtVal) 4'b11: FmaRneNaNGood =((FmaRneAnsFlags[4]&(FmaRneRes[`Q_LEN-2:0] === {{`Q_NE+1{1'b1}}, {`Q_NF-1{1'b0}}})) | (FmaRneXNaN&(FmaRneRes[`Q_LEN-2:0] === {FmaRneX[`Q_LEN-2:`Q_NF],1'b1,FmaRneX[`Q_NF-2:0]})) | @@ -1035,16 +1038,20 @@ module testbenchfp; case (FmtVal) 4'b11: NaNGood = ((AnsFlags[4]&(Res[`Q_LEN-2:0] === {{`Q_NE+1{1'b1}}, {`Q_NF-1{1'b0}}})) | (XNaN&(Res[`Q_LEN-2:0] === {X[`Q_LEN-2:`Q_NF],1'b1,X[`Q_NF-2:0]})) | - (YNaN&(Res[`Q_LEN-2:0] === {Y[`Q_LEN-2:`Q_NF],1'b1,Y[`Q_NF-2:0]}))); + (YNaN&(Res[`Q_LEN-2:0] === {Y[`Q_LEN-2:`Q_NF],1'b1,Y[`Q_NF-2:0]})) | + (ZNaN&(Res[`Q_LEN-2:0] === {Z[`Q_LEN-2:`Q_NF],1'b1,Z[`Q_NF-2:0]}))); 4'b01: NaNGood = ((AnsFlags[4]&(Res[`D_LEN-2:0] === {{`D_NE+1{1'b1}}, {`D_NF-1{1'b0}}})) | (XNaN&(Res[`D_LEN-2:0] === {X[`D_LEN-2:`D_NF],1'b1,X[`D_NF-2:0]})) | - (YNaN&(Res[`D_LEN-2:0] === {Y[`D_LEN-2:`D_NF],1'b1,Y[`D_NF-2:0]}))); + (YNaN&(Res[`D_LEN-2:0] === {Y[`D_LEN-2:`D_NF],1'b1,Y[`D_NF-2:0]})) | + (ZNaN&(Res[`D_LEN-2:0] === {Z[`D_LEN-2:`D_NF],1'b1,Z[`D_NF-2:0]}))); 4'b00: NaNGood = ((AnsFlags[4]&(Res[`S_LEN-2:0] === {{`S_NE+1{1'b1}}, {`S_NF-1{1'b0}}})) | (XNaN&(Res[`S_LEN-2:0] === {X[`S_LEN-2:`S_NF],1'b1,X[`S_NF-2:0]})) | - (YNaN&(Res[`S_LEN-2:0] === {Y[`S_LEN-2:`S_NF],1'b1,Y[`S_NF-2:0]}))); + (YNaN&(Res[`S_LEN-2:0] === {Y[`S_LEN-2:`S_NF],1'b1,Y[`S_NF-2:0]})) | + (ZNaN&(Res[`S_LEN-2:0] === {Z[`S_LEN-2:`S_NF],1'b1,Z[`S_NF-2:0]}))); 4'b10: NaNGood = ((AnsFlags[4]&(Res[`H_LEN-2:0] === {{`H_NE+1{1'b1}}, {`H_NF-1{1'b0}}})) | (XNaN&(Res[`H_LEN-2:0] === {X[`H_LEN-2:`H_NF],1'b1,X[`H_NF-2:0]})) | - (YNaN&(Res[`H_LEN-2:0] === {Y[`H_LEN-2:`H_NF],1'b1,Y[`H_NF-2:0]}))); + (YNaN&(Res[`H_LEN-2:0] === {Y[`H_LEN-2:`H_NF],1'b1,Y[`H_NF-2:0]})) | + (ZNaN&(Res[`H_LEN-2:0] === {Z[`H_LEN-2:`H_NF],1'b1,Z[`H_NF-2:0]}))); endcase else if (UnitVal === `CVTFPUNIT) // if converting from floating point to floating point OpCtrl contains the final FP format case (OpCtrlVal[1:0]) @@ -1172,6 +1179,7 @@ module readfmavectors ( input logic [31:0] VectorNum, input logic [31:0] FmaNum, output logic [`FLEN-1:0] Ans, + output logic ZOrigDenormE, output logic [4:0] AnsFlags, output logic XSgnE, YSgnE, ZSgnE, // sign bits of XYZ output logic [`NE-1:0] XExpE, YExpE, ZExpE, // exponents of XYZ (converted to largest supported precision) @@ -1221,7 +1229,7 @@ module readfmavectors ( unpack unpack(.X, .Y, .Z, .FmtE(FmaModFmt), .XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE, .XManE, .YManE, .ZManE, .XNormE, .XNaNE, .YNaNE, .ZNaNE, .XSNaNE, .YSNaNE, .ZSNaNE, .XDenormE, .YDenormE, .ZDenormE, .XZeroE, .YZeroE, .ZZeroE, .XInfE, .YInfE, .ZInfE, - .XExpMaxE); + .XExpMaxE, .ZOrigDenormE); endmodule @@ -1261,6 +1269,7 @@ module readvectors ( output logic XZeroE, YZeroE, ZZeroE, // is XYZ zero output logic XInfE, YInfE, ZInfE, // is XYZ infinity output logic XNormE, XExpMaxE, + output logic ZOrigDenormE, output logic [`FLEN-1:0] X, Y, Z ); @@ -1274,14 +1283,12 @@ module readvectors ( case (Fmt) 2'b11: begin // quad X = TestVector[8+3*(`Q_LEN)-1:8+2*(`Q_LEN)]; - Y = TestVector[8+2*(`Q_LEN)-1:8+(`Q_LEN)]; if(OpCtrl === `MUL_OPCTRL) Y = TestVector[8+2*(`Q_LEN)-1:8+(`Q_LEN)]; else Y = {2'b0, {`Q_NE-1{1'b1}}, `Q_NF'h0}; if(OpCtrl === `MUL_OPCTRL) Z = 0; else Z = TestVector[8+2*(`Q_LEN)-1:8+(`Q_LEN)]; Ans = TestVector[8+(`Q_LEN-1):8]; end 2'b01: begin // double X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+3*(`D_LEN)-1:8+2*(`D_LEN)]}; - Y = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+2*(`D_LEN)-1:8+(`D_LEN)]}; if(OpCtrl === `MUL_OPCTRL) Y = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+2*(`D_LEN)-1:8+(`D_LEN)]}; else Y = {{`FLEN-`D_LEN{1'b1}}, 2'b0, {`D_NE-1{1'b1}}, `D_NF'h0}; if(OpCtrl === `MUL_OPCTRL) Z = {{`FLEN-`D_LEN{1'b1}}, {`D_LEN{1'b0}}}; @@ -1290,7 +1297,6 @@ module readvectors ( end 2'b00: begin // single X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+3*(`S_LEN)-1:8+2*(`S_LEN)]}; - Y = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+2*(`S_LEN)-1:8+1*(`S_LEN)]}; if(OpCtrl === `MUL_OPCTRL) Y = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+2*(`S_LEN)-1:8+(`S_LEN)]}; else Y = {{`FLEN-`S_LEN{1'b1}}, 2'b0, {`S_NE-1{1'b1}}, `S_NF'h0}; if(OpCtrl === `MUL_OPCTRL) Z = {{`FLEN-`S_LEN{1'b1}}, {`S_LEN{1'b0}}}; @@ -1299,7 +1305,6 @@ module readvectors ( end 2'b10: begin // half X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+3*(`H_LEN)-1:8+2*(`H_LEN)]}; - Y = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+2*(`H_LEN)-1:8+(`H_LEN)]}; if(OpCtrl === `MUL_OPCTRL) Y = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+2*(`H_LEN)-1:8+(`H_LEN)]}; else Y = {{`FLEN-`H_LEN{1'b1}}, 2'b0, {`H_NE-1{1'b1}}, `H_NF'h0}; if(OpCtrl === `MUL_OPCTRL) Z = {{`FLEN-`H_LEN{1'b1}}, {`H_LEN{1'b0}}}; @@ -1534,5 +1539,5 @@ module readvectors ( unpack unpack(.X, .Y, .Z, .FmtE(ModFmt), .XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE, .XManE, .YManE, .ZManE, .XNormE, .XNaNE, .YNaNE, .ZNaNE, .XSNaNE, .YSNaNE, .ZSNaNE, .XDenormE, .YDenormE, .ZDenormE, .XZeroE, .YZeroE, .ZZeroE, .XInfE, .YInfE, .ZInfE, - .XExpMaxE); + .XExpMaxE, .ZOrigDenormE); endmodule \ No newline at end of file