fixed some small errors in FMA

This commit is contained in:
Katherine Parry 2021-12-19 13:51:46 -08:00
parent 852c521328
commit ece9e9df84

View File

@ -28,6 +28,7 @@
// `define NE 11//(`Q_SUPPORTED ? 15 : `D_SUPPORTED ? 11 : 8) // `define NE 11//(`Q_SUPPORTED ? 15 : `D_SUPPORTED ? 11 : 8)
// `define NF 52//(`Q_SUPPORTED ? 112 : `D_SUPPORTED ? 52 : 23) // `define NF 52//(`Q_SUPPORTED ? 112 : `D_SUPPORTED ? 52 : 23)
// `define XLEN 64 // `define XLEN 64
`define NANPAYLOAD 1
module fma( module fma(
input logic clk, input logic clk,
input logic reset, input logic reset,
@ -117,9 +118,8 @@ module fma1(
logic [3*`NF+6:0] AlignedAddendInv; // aligned addend possibly inverted logic [3*`NF+6:0] AlignedAddendInv; // aligned addend possibly inverted
logic [2*`NF+1:0] ProdManKilled; // the product's mantissa possibly killed logic [2*`NF+1:0] ProdManKilled; // the product's mantissa possibly killed
logic [3*`NF+4:0] NegProdManKilled; // a negated ProdManKilled logic [3*`NF+4:0] NegProdManKilled; // a negated ProdManKilled
logic [8:0] PNormCnt, NNormCnt; // the positive and nagitive LOA results
logic [3*`NF+6:0] PreSum, NegPreSum; // positive and negitve versions of the sum logic [3*`NF+6:0] PreSum, NegPreSum; // positive and negitve versions of the sum
logic [`NE-1:0] XExpVal, YExpVal; // exponent value after taking into accound denormals
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Calculate the product // Calculate the product
// - When multipliying two fp numbers, add the exponents // - When multipliying two fp numbers, add the exponents
@ -130,7 +130,7 @@ module fma1(
// calculate the product's exponent // calculate the product's exponent
expadd expadd(.FmtE, .XExpE, .YExpE, .XZeroE, .YZeroE, .XDenormE, .YDenormE, expadd expadd(.FmtE, .XExpE, .YExpE, .XZeroE, .YZeroE, .XDenormE, .YDenormE, .XExpVal, .YExpVal,
.Denorm, .ProdExpE); .Denorm, .ProdExpE);
// multiplication of the mantissa's // multiplication of the mantissa's
@ -140,7 +140,7 @@ module fma1(
// Alignment shifter // Alignment shifter
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
align align(.ZExpE, .ZManE, .ZDenormE, .XZeroE, .YZeroE, .ZZeroE, .ProdExpE, .Denorm, align align(.ZExpE, .ZManE, .ZDenormE, .XZeroE, .YZeroE, .ZZeroE, .ProdExpE, .Denorm, .XExpVal, .YExpVal,
.AlignedAddendE, .AddendStickyE, .KillProdE); .AlignedAddendE, .AddendStickyE, .KillProdE);
// calculate the signs and take the opperation into account // calculate the signs and take the opperation into account
@ -150,9 +150,9 @@ module fma1(
// // Addition/LZA // // Addition/LZA
// /////////////////////////////////////////////////////////////////////////////// // ///////////////////////////////////////////////////////////////////////////////
add add(.AlignedAddendE, .ProdManE, .PSgnE, .ZSgnEffE, .KillProdE, .AlignedAddendInv, .ProdManKilled, .NegProdManKilled, .NegSumE, .PreSum, .NegPreSum, .InvZE, .XZeroE, .YZeroE); add add(.AlignedAddendE, .ProdManE, .PSgnE, .ZSgnEffE, .KillProdE, .AlignedAddendInv, .ProdManKilled, .NegSumE, .PreSum, .NegPreSum, .InvZE, .XZeroE, .YZeroE);
loa loa(.A(AlignedAddendInv+{162'b0,InvZE}), .P(ProdManKilled), .NegSumE, .NormCntE); loa loa(.A(AlignedAddendInv+{162'b0,InvZE}), .P(ProdManKilled), .NormCntE);
// Choose the positive sum and accompanying LZA result. // Choose the positive sum and accompanying LZA result.
assign SumE = NegSumE ? NegPreSum[3*`NF+5:0] : PreSum[3*`NF+5:0]; assign SumE = NegSumE ? NegPreSum[3*`NF+5:0] : PreSum[3*`NF+5:0];
@ -167,11 +167,11 @@ module expadd(
input logic [`NE-1:0] XExpE, YExpE, // input exponents input logic [`NE-1:0] XExpE, YExpE, // input exponents
input logic XDenormE, YDenormE, // are the inputs denormalized input logic XDenormE, YDenormE, // are the inputs denormalized
input logic XZeroE, YZeroE, // are the inputs zero input logic XZeroE, YZeroE, // are the inputs zero
output logic [`NE-1:0] XExpVal, YExpVal, // Exponent value after taking into account denormals
output logic [`NE-1:0] Denorm, // value of denormalized exponent output logic [`NE-1:0] Denorm, // value of denormalized exponent
output logic [`NE+1:0] ProdExpE // product's exponent B^(1023)NE+2 output logic [`NE+1:0] ProdExpE // product's exponent B^(1023)NE+2
); );
logic [`NE-1:0] XExpVal, YExpVal; // Exponent value after taking into account denormals
// denormalized numbers have diffrent values depending on which precison it is. // denormalized numbers have diffrent values depending on which precison it is.
// double - 1 // double - 1
@ -233,6 +233,7 @@ module align(
input logic [`NF:0] ZManE, // fractions in U(0.NF) format] input logic [`NF:0] ZManE, // fractions in U(0.NF) format]
input logic ZDenormE, // is the input denormal input logic ZDenormE, // is the input denormal
input logic XZeroE, YZeroE, ZZeroE, // is the input zero input logic XZeroE, YZeroE, ZZeroE, // is the input zero
input logic [`NE-1:0] XExpVal, YExpVal, // Exponent value after taking into account denormals
input logic [`NE+1:0] ProdExpE, // the product's exponent input logic [`NE+1:0] ProdExpE, // the product's exponent
input logic [`NE-1:0] Denorm, // the biased value of a denormalized number input logic [`NE-1:0] Denorm, // the biased value of a denormalized number
output logic [3*`NF+5:0] AlignedAddendE, // Z aligned for addition in U(NF+5.2NF+1) output logic [3*`NF+5:0] AlignedAddendE, // Z aligned for addition in U(NF+5.2NF+1)
@ -254,7 +255,8 @@ module align(
// - positive means the product is larger, so shift Z right // - positive means the product is larger, so shift Z right
// - Denormal numbers have a diffrent exponent value depending on the precision // - Denormal numbers have a diffrent exponent value depending on the precision
assign ZExpVal = ZDenormE ? Denorm : ZExpE; assign ZExpVal = ZDenormE ? Denorm : ZExpE;
assign AlignCnt = ProdExpE - {2'b0, ZExpVal} + (`NF+3); // assign AlignCnt = ProdExpE - {2'b0, ZExpVal} + (`NF+3);
assign AlignCnt = XZeroE|YZeroE ? -1 : {2'b0, XExpVal} + {2'b0, YExpVal} - 1020+`NF - {2'b0, ZExpVal};
// Defualt Addition without shifting // Defualt Addition without shifting
// | 54'b0 | 106'b(product) | 2'b0 | // | 54'b0 | 106'b(product) | 2'b0 |
@ -312,14 +314,14 @@ module add(
input logic PSgnE, ZSgnEffE,// the product and modified Z signs input logic PSgnE, ZSgnEffE,// the product and modified Z signs
input logic KillProdE, // should the product be set to 0 input logic KillProdE, // should the product be set to 0
input logic XZeroE, YZeroE, // is the input zero input logic XZeroE, YZeroE, // is the input zero
output logic [3*`NF+6:0] AlignedAddendInv, // aligned addend possibly inverted output logic [3*`NF+6:0] AlignedAddendInv, // aligned addend possibly inverted
output logic [2*`NF+1:0] ProdManKilled, // the product's mantissa possibly killed output logic [2*`NF+1:0] ProdManKilled, // the product's mantissa possibly killed
output logic [3*`NF+4:0] NegProdManKilled, // a negated ProdManKilled
output logic NegSumE, // was the sum negitive output logic NegSumE, // was the sum negitive
output logic InvZE, // do you invert Z output logic InvZE, // do you invert Z
output logic [3*`NF+6:0] PreSum, NegPreSum// possibly negitive sum output logic [3*`NF+6:0] PreSum, NegPreSum// possibly negitive sum
); );
logic [3*`NF+4:0] NegProdManKilled; // a negated ProdManKilled
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Addition // Addition
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -334,17 +336,17 @@ module add(
// Kill the product if the product is too small to effect the addition (determined in fma1.sv) // Kill the product if the product is too small to effect the addition (determined in fma1.sv)
assign ProdManKilled = ProdManE&{2*`NF+2{~KillProdE}}; assign ProdManKilled = ProdManE&{2*`NF+2{~KillProdE}};
// Negate ProdMan for LZA and the negitive sum calculation // Negate ProdMan for LZA and the negitive sum calculation
assign NegProdManKilled = {{`NF+3{~(XZeroE|YZeroE|KillProdE)}}, ~ProdManKilled&{2*`NF+2{~(XZeroE|YZeroE)}}}; assign NegProdManKilled = {{`NF+3{~(XZeroE|YZeroE|KillProdE)}}, ~ProdManKilled&{2*`NF+2{~(XZeroE|YZeroE|KillProdE)}}};
// Is the sum negitive
assign NegSumE = (AlignedAddendE > {54'b0, ProdManKilled, 2'b0})&InvZE; //***use this to avoid addition and final muxing???
// Do the addition // Do the addition
// - calculate a positive and negitive sum in parallel // - calculate a positive and negitive sum in parallel
assign PreSum = AlignedAddendInv + {55'b0, ProdManKilled, 2'b0} + {{3*`NF+6{1'b0}}, InvZE}; assign PreSum = AlignedAddendInv + {55'b0, ProdManKilled, 2'b0} + {{3*`NF+6{1'b0}}, InvZE};
assign NegPreSum = AlignedAddendE + {NegProdManKilled, 2'b0} + {{(3*`NF+3){1'b0}},~(XZeroE|YZeroE),2'b0}; assign NegPreSum = AlignedAddendE + {NegProdManKilled, 2'b0} + {{(3*`NF+3){1'b0}},~(XZeroE|YZeroE|KillProdE),2'b0};
// Is the sum negitive
assign NegSumE = PreSum[3*`NF+6];
endmodule endmodule
@ -352,17 +354,15 @@ endmodule
module loa( //https://ieeexplore.ieee.org/abstract/document/930098 module loa( //https://ieeexplore.ieee.org/abstract/document/930098
input logic [3*`NF+6:0] A, // addend input logic [3*`NF+6:0] A, // addend
input logic [2*`NF+1:0] P, // product input logic [2*`NF+1:0] P, // product
input logic NegSumE, // is the sum negitive
output logic [8:0] NormCntE // normalization shift count for the positive result output logic [8:0] NormCntE // normalization shift count for the positive result
); );
logic [3*`NF+6:0] T; logic [3*`NF+6:0] T;
logic [3*`NF+5:0] G; logic [3*`NF+6:0] G;
logic [3*`NF+5:0] Z; logic [3*`NF+6:0] Z;
assign T[3*`NF+6:2*`NF+4] = A[3*`NF+6:2*`NF+4]; assign T[3*`NF+6:2*`NF+4] = A[3*`NF+6:2*`NF+4];
assign G[3*`NF+5:2*`NF+4] = 0; assign G[3*`NF+6:2*`NF+4] = 0;
assign Z[3*`NF+5:2*`NF+4] = ~A[3*`NF+5:2*`NF+4]; assign Z[3*`NF+6:2*`NF+4] = ~A[3*`NF+6:2*`NF+4];
assign T[2*`NF+3:2] = A[2*`NF+3:2]^P; assign T[2*`NF+3:2] = A[2*`NF+3:2]^P;
assign G[2*`NF+3:2] = A[2*`NF+3:2]&P; assign G[2*`NF+3:2] = A[2*`NF+3:2]&P;
assign Z[2*`NF+3:2] = ~A[2*`NF+3:2]&~P; assign Z[2*`NF+3:2] = ~A[2*`NF+3:2]&~P;
@ -372,8 +372,14 @@ module loa( //https://ieeexplore.ieee.org/abstract/document/930098
// Apply function to determine Leading pattern // Apply function to determine Leading pattern
// - note: the paper linked above uses the numbering system where 0 is the most significant bit
//f[n] = ~T[n]&T[n-1] note: n is the MSB
//f[i] = (T[i+1]&(G[i]&~Z[i-1] | Z[i]&~G[i-1])) | (~T[i+1]&(Z[i]&~Z[i-1] | G[i]&~G[i-1]))
logic [3*`NF+6:0] f; logic [3*`NF+6:0] f;
assign f = NegSumE ? T^{~G[3*`NF+5:0],1'b1} : T^{~Z[3*`NF+5:0], 1'b1}; assign f[3*`NF+6] = ~T[3*`NF+6]&T[3*`NF+5];
assign f[3*`NF+5:0] = (T[3*`NF+6:1]&(G[3*`NF+5:0]&{~Z[3*`NF+4:0], 1'b0} | Z[3*`NF+5:0]&{~G[3*`NF+4:0], 1'b1})) | (~T[3*`NF+6:1]&(Z[3*`NF+5:0]&{~Z[3*`NF+4:0], 1'b0} | G[3*`NF+5:0]&{~G[3*`NF+4:0], 1'b1}));
lzc lzc(.f, .NormCntE); lzc lzc(.f, .NormCntE);
@ -426,7 +432,7 @@ module fma2(
logic [`NF-1:0] ResultFrac; // Result fraction logic [`NF-1:0] ResultFrac; // Result fraction
logic [`NE-1:0] ResultExp; // Result exponent logic [`NE-1:0] ResultExp; // Result exponent
logic ResultSgn; // Result sign logic ResultSgn, ResultSgnTmp; // Result sign
logic [`NE+1:0] SumExp; // exponent of the normalized sum logic [`NE+1:0] SumExp; // exponent of the normalized sum
logic [`NE+1:0] FullResultExp; // ResultExp with bits to determine sign and overflow logic [`NE+1:0] FullResultExp; // ResultExp with bits to determine sign and overflow
logic [`NF+2:0] NormSum; // normalized sum logic [`NF+2:0] NormSum; // normalized sum
@ -464,7 +470,7 @@ module fma2(
// round to infinity // round to infinity
// round to nearest max magnitude // round to nearest max magnitude
fmaround fmaround(.FmtM, .FrmM, .Sticky, .UfSticky, .NormSum, .AddendStickyM, .NormSumSticky, .ZZeroM, .InvZM, .ResultSgn, .SumExp, fmaround fmaround(.FmtM, .FrmM, .Sticky, .UfSticky, .NormSum, .AddendStickyM, .NormSumSticky, .ZZeroM, .InvZM, .ResultSgnTmp, .SumExp,
.CalcPlus1, .Plus1, .UfPlus1, .Minus1, .FullResultExp, .ResultFrac, .ResultExp, .Round, .Guard, .UfLSBNormSum); .CalcPlus1, .Plus1, .UfPlus1, .Minus1, .FullResultExp, .ResultFrac, .ResultExp, .Round, .Guard, .UfLSBNormSum);
@ -476,7 +482,7 @@ module fma2(
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
resultsign resultsign(.FrmM, .PSgnM, .ZSgnEffM, .Underflow, .InvZM, .NegSumM, .SumZero, .ResultSgn); resultsign resultsign(.FrmM, .PSgnM, .ZSgnEffM, .Underflow, .InvZM, .NegSumM, .SumZero, .ResultSgnTmp, .ResultSgn);
@ -512,11 +518,12 @@ module resultsign(
input logic InvZM, input logic InvZM,
input logic NegSumM, input logic NegSumM,
input logic SumZero, input logic SumZero,
output logic ResultSgnTmp,
output logic ResultSgn output logic ResultSgn
); );
logic ZeroSgn; logic ZeroSgn;
logic ResultSgnTmp; // logic ResultSgnTmp;
// Determine the sign if the sum is zero // Determine the sign if the sum is zero
// if cancelation then 0 unless round to -infinity // if cancelation then 0 unless round to -infinity
@ -554,15 +561,24 @@ module resultselect(
); );
logic [`FLEN-1:0] XNaNResult, YNaNResult, ZNaNResult, InvalidResult, OverflowResult, KillProdResult, UnderflowResult; // possible results logic [`FLEN-1:0] XNaNResult, YNaNResult, ZNaNResult, InvalidResult, OverflowResult, KillProdResult, UnderflowResult; // possible results
assign XNaNResult = FmtM ? {XSgnM, XExpM, 1'b1, XManM[`NF-2:0]} : {{32{1'b1}}, XSgnM, XExpM[7:0], 1'b1, XManM[50:29]}; generate if(`NANPAYLOAD) begin
assign YNaNResult = FmtM ? {YSgnM, YExpM, 1'b1, YManM[`NF-2:0]} : {{32{1'b1}}, YSgnM, YExpM[7:0], 1'b1, YManM[50:29]}; assign XNaNResult = FmtM ? {XSgnM, XExpM, 1'b1, XManM[`NF-2:0]} : {{32{1'b1}}, XSgnM, XExpM[7:0], 1'b1, XManM[50:29]};
assign ZNaNResult = FmtM ? {ZSgnEffM, ZExpM, 1'b1, ZManM[`NF-2:0]} : {{32{1'b1}}, ZSgnEffM, ZExpM[7:0], 1'b1, ZManM[50:29]}; assign YNaNResult = FmtM ? {YSgnM, YExpM, 1'b1, YManM[`NF-2:0]} : {{32{1'b1}}, YSgnM, YExpM[7:0], 1'b1, YManM[50:29]};
assign ZNaNResult = FmtM ? {ZSgnEffM, ZExpM, 1'b1, ZManM[`NF-2:0]} : {{32{1'b1}}, ZSgnEffM, ZExpM[7:0], 1'b1, ZManM[50:29]};
end else begin
assign XNaNResult = FmtM ? {XSgnM, XExpM, 1'b1, 51'b0} : {{32{1'b1}}, XSgnM, XExpM[7:0], 1'b1, 22'b0};
assign YNaNResult = FmtM ? {YSgnM, YExpM, 1'b1, 51'b0} : {{32{1'b1}}, YSgnM, YExpM[7:0], 1'b1, 22'b0};
assign ZNaNResult = FmtM ? {ZSgnEffM, ZExpM, 1'b1, 51'b0} : {{32{1'b1}}, ZSgnEffM, ZExpM[7:0], 1'b1, 22'b0};
end
endgenerate
assign OverflowResult = FmtM ? ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {ResultSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : assign OverflowResult = FmtM ? ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {ResultSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} :
{ResultSgn, {`NE{1'b1}}, {`NF{1'b0}}} : {ResultSgn, {`NE{1'b1}}, {`NF{1'b0}}} :
((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{32{1'b1}}, ResultSgn, 8'hfe, {23{1'b1}}} : ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{32{1'b1}}, ResultSgn, 8'hfe, {23{1'b1}}} :
{{32{1'b1}}, ResultSgn, 8'hff, 23'b0}; {{32{1'b1}}, ResultSgn, 8'hff, 23'b0};
assign InvalidResult = FmtM ? {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{32{1'b1}}, ResultSgn, 8'hff, 1'b1, 22'b0}; assign InvalidResult = FmtM ? {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{32{1'b1}}, ResultSgn, 8'hff, 1'b1, 22'b0};
assign KillProdResult = FmtM ? {ResultSgn, {ZExpM, ZManM[`NF-1:0]} - {62'b0, (Minus1&AddendStickyM) + (Plus1&AddendStickyM)}} : {{32{1'b1}}, ResultSgn, {ZExpM[`NE-1],ZExpM[6:0], ZManM[51:29]} - {30'b0, (Minus1&AddendStickyM)} + {30'b0, (Plus1&AddendStickyM)}}; assign KillProdResult = FmtM ? {ResultSgn, {ZExpM, ZManM[`NF-1:0]} - {62'b0, (Minus1&AddendStickyM)} + {62'b0, (Plus1&AddendStickyM)}} : {{32{1'b1}}, ResultSgn, {ZExpM[`NE-1],ZExpM[6:0], ZManM[51:29]} - {30'b0, (Minus1&AddendStickyM)} + {30'b0, (Plus1&AddendStickyM)}};
assign UnderflowResult = FmtM ? {ResultSgn, {`FLEN-1{1'b0}}} + {63'b0,(CalcPlus1&(AddendStickyM|FrmM[1]))} : {{32{1'b1}}, {ResultSgn, 31'b0} + {31'b0, (CalcPlus1&(AddendStickyM|FrmM[1]))}}; assign UnderflowResult = FmtM ? {ResultSgn, {`FLEN-1{1'b0}}} + {63'b0,(CalcPlus1&(AddendStickyM|FrmM[1]))} : {{32{1'b1}}, {ResultSgn, 31'b0} + {31'b0, (CalcPlus1&(AddendStickyM|FrmM[1]))}};
assign FMAResM = XNaNM ? XNaNResult : assign FMAResM = XNaNM ? XNaNResult :
YNaNM ? YNaNResult : YNaNM ? YNaNResult :
@ -579,81 +595,6 @@ module resultselect(
endmodule endmodule
// module normalize(
// input logic [3*`NF+5:0] SumM, // the positive sum
// input logic [`NE-1:0] ZExpM, // exponent of Z
// input logic [`NE+1:0] ProdExpM, // X exponent + Y exponent - bias
// input logic [8:0] NormCntM, // normalization shift count
// input logic FmtM, // precision 1 = double 0 = single
// input logic KillProdM, // is the product set to zero
// input logic AddendStickyM, // the sticky bit caclulated from the aligned addend
// input logic NegSumM, // was the sum negitive
// output logic [`NF+2:0] NormSum, // normalized sum
// output logic SumZero, // is the sum zero
// output logic NormSumSticky, UfSticky, // sticky bits
// output logic [`NE+1:0] SumExp, // exponent of the normalized sum
// output logic ResultDenorm // is the result denormalized
// );
// logic [`NE+1:0] FracLen; // length of the fraction
// logic [`NE+1:0] SumExpTmp; // exponent of the normalized sum not taking into account denormal or zero results
// logic [8:0] DenormShift; // right shift if the result is denormalized //***change this later
// logic [3*`NF+5:0] CorrSumShifted; // the shifted sum after LZA correction
// logic [3*`NF+7:0] SumShifted; // the shifted sum before LZA correction
// logic [`NE+1:0] SumExpTmpTmp; // the exponent of the normalized sum with the `FLEN bias
// logic PreResultDenorm; // is the result denormalized - calculated before LZA corection
// logic PreResultDenorm2; // is the result denormalized - calculated before LZA corection
// logic LZAPlus1; // add one to the sum's exponent due to LZA correction
// ///////////////////////////////////////////////////////////////////////////////
// // Normalization
// ///////////////////////////////////////////////////////////////////////////////
// // Determine if the sum is zero
// assign SumZero = ~(|SumM);
// // determine the length of the fraction based on precision
// assign FracLen = FmtM ? `NF+1 : 13'd24;
// // calculate the sum's exponent
// assign SumExpTmpTmp = KillProdM ? {2'b0, ZExpM} : ProdExpM + -({4'b0, NormCntM} + 1 - (`NF+4)); // ****try moving this into previous stage
// assign SumExpTmp = FmtM ? SumExpTmpTmp : (SumExpTmpTmp-1023+127)&{`NE+2{|SumExpTmpTmp}}; // ***move this ^ the subtraction by a constant isn't simplified
// logic SumDLTEZ, SumDGEFL, SumSLTEZ, SumSGEFL;
// assign SumDLTEZ = SumExpTmpTmp[`NE+1] | ~|SumExpTmpTmp;
// assign SumDGEFL = ($signed(SumExpTmpTmp)>=$signed(-(13'd`NF+13'd1)));
// assign SumSLTEZ = $signed(SumExpTmpTmp) <= $signed(13'd1023-13'd127);
// assign SumSGEFL = ($signed(SumExpTmpTmp)>=$signed(-13'd24+13'd1023-13'd127)) | ~|SumExpTmpTmp;
// assign PreResultDenorm2 = (FmtM ? SumDLTEZ : SumSLTEZ) & (FmtM ? SumDGEFL : SumSGEFL) & ~SumZero; //***make sure math good
// // always_comb begin
// // assert (PreResultDenorm == PreResultDenorm2) else $fatal ("PreResultDenorms not equal");
// // end
// // Determine if the result is denormal
// // assign PreResultDenorm = $signed(SumExpTmp)<=0 & ($signed(SumExpTmp)>=$signed(-FracLen)) & ~SumZero;
// // Determine the shift needed for denormal results
// // - if not denorm add 1 to shift out the leading 1
// assign DenormShift = PreResultDenorm2 ? SumExpTmp[8:0] : 1; //*** change this when changing the size of DenormShift also change to an and opperation
// // Normalize the sum
// assign SumShifted = {2'b0, SumM} << NormCntM+DenormShift; //*** fix mux's with constants in them //***NormCnt can be simplified
// // LZA correction
// assign LZAPlus1 = SumShifted[3*`NF+7];
// assign CorrSumShifted = LZAPlus1 ? SumShifted[3*`NF+6:1] : SumShifted[3*`NF+5:0];
// assign NormSum = CorrSumShifted[3*`NF+5:2*`NF+3];
// // Calculate the sticky bit
// assign NormSumSticky = (|CorrSumShifted[2*`NF+2:0]) | (|CorrSumShifted[136:2*`NF+3]&~FmtM);
// assign UfSticky = AddendStickyM | NormSumSticky;
// // Determine sum's exponent
// assign SumExp = (SumExpTmp+{12'b0, LZAPlus1}+{12'b0, ~|SumExpTmp&SumShifted[3*`NF+6]}) & {`NE+2{~(SumZero|ResultDenorm)}};
// // recalculate if the result is denormalized
// assign ResultDenorm = PreResultDenorm2&~SumShifted[3*`NF+6]&~SumShifted[3*`NF+7];
// endmodule
module normalize( module normalize(
input logic [3*`NF+5:0] SumM, // the positive sum input logic [3*`NF+5:0] SumM, // the positive sum
input logic [`NE-1:0] ZExpM, // exponent of Z input logic [`NE-1:0] ZExpM, // exponent of Z
@ -733,7 +674,7 @@ module normalize(
assign LZAPlus1 = SumShifted[3*`NF+7]; assign LZAPlus1 = SumShifted[3*`NF+7];
assign LZAPlus2 = SumShifted[3*`NF+8]; assign LZAPlus2 = SumShifted[3*`NF+8];
// the only possible mantissa for a plus two is all zeroes - a one has to propigate all the way through a sum. so we can leave the bottom statement alone // the only possible mantissa for a plus two is all zeroes - a one has to propigate all the way through a sum. so we can leave the bottom statement alone
assign CorrSumShifted = LZAPlus1 ? SumShifted[3*`NF+6:1] : SumShifted[3*`NF+5:0]; assign CorrSumShifted = LZAPlus1&~KillProdM ? SumShifted[3*`NF+6:1] : SumShifted[3*`NF+5:0];
assign NormSum = CorrSumShifted[3*`NF+5:2*`NF+3]; assign NormSum = CorrSumShifted[3*`NF+5:2*`NF+3];
// Calculate the sticky bit // Calculate the sticky bit
assign NormSumSticky = (|CorrSumShifted[2*`NF+2:0]) | (|CorrSumShifted[136:2*`NF+3]&~FmtM); assign NormSumSticky = (|CorrSumShifted[2*`NF+2:0]) | (|CorrSumShifted[136:2*`NF+3]&~FmtM);
@ -757,7 +698,7 @@ module fmaround(
input logic ZZeroM, // is Z zero input logic ZZeroM, // is Z zero
input logic InvZM, // invert Z input logic InvZM, // invert Z
input logic [`NE+1:0] SumExp, // exponent of the normalized sum input logic [`NE+1:0] SumExp, // exponent of the normalized sum
input logic ResultSgn, // the result's sign input logic ResultSgnTmp, // the result's sign
output logic CalcPlus1, Plus1, UfPlus1, Minus1, // do you add or subtract on from the result output logic CalcPlus1, Plus1, UfPlus1, Minus1, // do you add or subtract on from the result
output logic [`NE+1:0] FullResultExp, // ResultExp with bits to determine sign and overflow output logic [`NE+1:0] FullResultExp, // ResultExp with bits to determine sign and overflow
output logic [`NF-1:0] ResultFrac, // Result fraction output logic [`NF-1:0] ResultFrac, // Result fraction
@ -824,8 +765,8 @@ module fmaround(
case (FrmM) case (FrmM)
3'b000: CalcPlus1 = Guard & (Round | ((Sticky)&~(~Round&SubBySmallNum)) | (~Round&~(Sticky)&LSBNormSum&~SubBySmallNum));//round to nearest even 3'b000: CalcPlus1 = Guard & (Round | ((Sticky)&~(~Round&SubBySmallNum)) | (~Round&~(Sticky)&LSBNormSum&~SubBySmallNum));//round to nearest even
3'b001: CalcPlus1 = 0;//round to zero 3'b001: CalcPlus1 = 0;//round to zero
3'b010: CalcPlus1 = ResultSgn & ~(SubBySmallNum & ~Guard & ~Round);//round down 3'b010: CalcPlus1 = ResultSgnTmp & ~(SubBySmallNum & ~Guard & ~Round);//round down
3'b011: CalcPlus1 = ~ResultSgn & ~(SubBySmallNum & ~Guard & ~Round);//round up 3'b011: CalcPlus1 = ~ResultSgnTmp & ~(SubBySmallNum & ~Guard & ~Round);//round up
3'b100: CalcPlus1 = (Guard & (Round | ((Sticky)&~(~Round&SubBySmallNum)) | (~Round&~(Sticky)&~SubBySmallNum)));//round to nearest max magnitude 3'b100: CalcPlus1 = (Guard & (Round | ((Sticky)&~(~Round&SubBySmallNum)) | (~Round&~(Sticky)&~SubBySmallNum)));//round to nearest max magnitude
default: CalcPlus1 = 1'bx; default: CalcPlus1 = 1'bx;
endcase endcase
@ -833,8 +774,8 @@ module fmaround(
case (FrmM) case (FrmM)
3'b000: UfCalcPlus1 = UfGuard & (UfRound | (UfSticky&UfRound|~UfSubBySmallNum) | (~Sticky&UfLSBNormSum&~UfSubBySmallNum));//round to nearest even 3'b000: UfCalcPlus1 = UfGuard & (UfRound | (UfSticky&UfRound|~UfSubBySmallNum) | (~Sticky&UfLSBNormSum&~UfSubBySmallNum));//round to nearest even
3'b001: UfCalcPlus1 = 0;//round to zero 3'b001: UfCalcPlus1 = 0;//round to zero
3'b010: UfCalcPlus1 = ResultSgn & ~(UfSubBySmallNum & ~UfGuard & ~UfRound);//round down 3'b010: UfCalcPlus1 = ResultSgnTmp & ~(UfSubBySmallNum & ~UfGuard & ~UfRound);//round down
3'b011: UfCalcPlus1 = ~ResultSgn & ~(UfSubBySmallNum & ~UfGuard & ~UfRound);//round up 3'b011: UfCalcPlus1 = ~ResultSgnTmp & ~(UfSubBySmallNum & ~UfGuard & ~UfRound);//round up
3'b100: UfCalcPlus1 = (UfGuard & (UfRound | (UfSticky&~(~UfRound&UfSubBySmallNum)) | (~Sticky&~UfSubBySmallNum)));//round to nearest max magnitude 3'b100: UfCalcPlus1 = (UfGuard & (UfRound | (UfSticky&~(~UfRound&UfSubBySmallNum)) | (~Sticky&~UfSubBySmallNum)));//round to nearest max magnitude
default: UfCalcPlus1 = 1'bx; default: UfCalcPlus1 = 1'bx;
endcase endcase
@ -842,8 +783,8 @@ module fmaround(
case (FrmM) case (FrmM)
3'b000: CalcMinus1 = 0;//round to nearest even 3'b000: CalcMinus1 = 0;//round to nearest even
3'b001: CalcMinus1 = SubBySmallNum & ~Guard & ~Round;//round to zero 3'b001: CalcMinus1 = SubBySmallNum & ~Guard & ~Round;//round to zero
3'b010: CalcMinus1 = ~ResultSgn & ~Guard & ~Round & SubBySmallNum;//round down 3'b010: CalcMinus1 = ~ResultSgnTmp & ~Guard & ~Round & SubBySmallNum;//round down
3'b011: CalcMinus1 = ResultSgn & ~Guard & ~Round & SubBySmallNum;//round up 3'b011: CalcMinus1 = ResultSgnTmp & ~Guard & ~Round & SubBySmallNum;//round up
3'b100: CalcMinus1 = 0;//round to nearest max magnitude 3'b100: CalcMinus1 = 0;//round to nearest max magnitude
default: CalcMinus1 = 1'bx; default: CalcMinus1 = 1'bx;
endcase endcase