This commit is contained in:
David Harris 2022-07-19 02:58:13 +00:00
commit 38fac8e05c
8 changed files with 77 additions and 63 deletions

View File

@ -45,6 +45,7 @@ module fma(
output logic As, // the aligned addend's sign (modified Z sign for other opperations) output logic As, // the aligned addend's sign (modified Z sign for other opperations)
output logic Ps, // the product's sign output logic Ps, // the product's sign
output logic Ss, // the sum's sign output logic Ss, // the sum's sign
output logic [`NE+1:0] Se,
output logic [$clog2(3*`NF+7)-1:0] NCnt // normalization shift count output logic [$clog2(3*`NF+7)-1:0] NCnt // normalization shift count
); );
@ -82,7 +83,7 @@ module fma(
// // Addition/LZA // // Addition/LZA
// /////////////////////////////////////////////////////////////////////////////// // ///////////////////////////////////////////////////////////////////////////////
add add(.Am, .Pm, .Ps, .As, .KillProd, .ZmSticky, .AmInv, .PmKilled, .NegSum, .InvA, .Sm, .Ss); add add(.Am, .Pm, .Ze, .Pe, .Ps, .As, .KillProd, .ZmSticky, .AmInv, .PmKilled, .NegSum, .InvA, .Sm, .Se, .Ss);
loa loa(.A(AmInv+{(3*`NF+6)'(0),InvA&~((ZmSticky&~KillProd))}), .P({PmKilled, 1'b0, InvA&Ps&ZmSticky&KillProd}), .NCnt); loa loa(.A(AmInv+{(3*`NF+6)'(0),InvA&~((ZmSticky&~KillProd))}), .P({PmKilled, 1'b0, InvA&Ps&ZmSticky&KillProd}), .NCnt);
endmodule endmodule
@ -223,11 +224,14 @@ module add(
input logic Ps, As,// the product sign and the alligend addeded's sign (Modified Z sign for other opperations) input logic Ps, As,// the product sign and the alligend addeded's sign (Modified Z sign for other opperations)
input logic KillProd, // should the product be set to 0 input logic KillProd, // should the product be set to 0
input logic ZmSticky, input logic ZmSticky,
input logic [`NE-1:0] Ze,
input logic [`NE+1:0] Pe,
output logic [3*`NF+6:0] AmInv, // aligned addend possibly inverted output logic [3*`NF+6:0] AmInv, // aligned addend possibly inverted
output logic [2*`NF+1:0] PmKilled, // the product's mantissa possibly killed output logic [2*`NF+1:0] PmKilled, // the product's mantissa possibly killed
output logic NegSum, // was the sum negitive output logic NegSum, // was the sum negitive
output logic InvA, // do you invert the aligned addend output logic InvA, // do you invert the aligned addend
output logic Ss, output logic Ss,
output logic [`NE+1:0] Se,
output logic [3*`NF+5:0] Sm // the positive sum output logic [3*`NF+5:0] Sm // the positive sum
); );
logic [3*`NF+6:0] PreSum, NegPreSum; // possibly negitive sum logic [3*`NF+6:0] PreSum, NegPreSum; // possibly negitive sum
@ -264,6 +268,7 @@ module add(
// if -p + z is the Sum positive // if -p + z is the Sum positive
// if -p - z then the Sum is negitive // if -p - z then the Sum is negitive
assign Ss = NegSum^Ps; //*** move to execute stage assign Ss = NegSum^Ps; //*** move to execute stage
assign Se = KillProd ? {2'b0, Ze} : Pe;
endmodule endmodule

View File

@ -35,14 +35,16 @@ module fmashiftcalc(
input logic [$clog2(3*`NF+7)-1:0] FmaNCnt, // normalization shift count input logic [$clog2(3*`NF+7)-1:0] FmaNCnt, // normalization shift count
input logic [`FMTBITS-1:0] Fmt, // precision 1 = double 0 = single input logic [`FMTBITS-1:0] Fmt, // precision 1 = double 0 = single
input logic FmaKillProd, // is the product set to zero input logic FmaKillProd, // is the product set to zero
output logic [`NE+1:0] FmaNe, // exponent of the normalized sum not taking into account denormal or zero results input logic [`NE+1:0] FmaSe,
output logic [`NE+1:0] NormSumExp, // exponent of the normalized sum not taking into account denormal or zero results
output logic FmaSZero, // is the result denormalized - calculated before LZA corection output logic FmaSZero, // is the result denormalized - calculated before LZA corection
output logic FmaPreResultDenorm, // is the result denormalized - calculated before LZA corection output logic FmaPreResultDenorm, // is the result denormalized - calculated before LZA corection
output logic [$clog2(3*`NF+7)-1:0] FmaShiftAmt, // normalization shift count output logic [$clog2(3*`NF+7)-1:0] FmaShiftAmt, // normalization shift count
output logic [3*`NF+8:0] FmaShiftIn // is the sum zero output logic [3*`NF+8:0] FmaShiftIn // is the sum zero
); );
logic [$clog2(3*`NF+7)-1:0] DenormShift; // right shift if the result is denormalized //***change this later logic [$clog2(3*`NF+7)-1:0] DenormShift; // right shift if the result is denormalized //***change this later
logic [`NE+1:0] NormSumExp; // the exponent of the normalized sum with the `FLEN bias logic [`NE+1:0] PreNormSumExp; // the exponent of the normalized sum with the `FLEN bias
logic [`NE+1:0] BiasCorr;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Normalization // Normalization
@ -50,37 +52,38 @@ module fmashiftcalc(
//*** insert bias-bias simplification in fcvt.sv/phone pictures //*** insert bias-bias simplification in fcvt.sv/phone pictures
// Determine if the sum is zero // Determine if the sum is zero
assign FmaSZero = ~(|FmaSm); assign FmaSZero = ~(|FmaSm);
// calculate the sum's exponent // calculate the sum's exponent
// ProdExp - NormCnt - 1 + NF+4 = ProdExp + ~NormCnt + 1 - 1 + NF+4 = ProdExp + ~NormCnt + NF+4 assign PreNormSumExp = FmaSe + {{`NE+2-$unsigned($clog2(3*`NF+7)){1'b1}}, ~FmaNCnt} + (`NE+2)'(`NF+4);
assign NormSumExp = (FmaKillProd ? {2'b0, Ze} : FmaPe) + {{`NE+2-$unsigned($clog2(3*`NF+7)){1'b1}}, ~FmaNCnt} + (`NE+2)'(`NF+4);
//convert the sum's exponent into the proper percision //convert the sum's exponent into the proper percision
if (`FPSIZES == 1) begin if (`FPSIZES == 1) begin
assign FmaNe = NormSumExp; assign NormSumExp = PreNormSumExp;
end else if (`FPSIZES == 2) begin end else if (`FPSIZES == 2) begin
assign FmaNe = Fmt ? NormSumExp : (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`BIAS1))&{`NE+2{|NormSumExp}}; assign BiasCorr = Fmt ? (`NE+2)'(0) : (`NE+2)'(`BIAS1-`BIAS);
assign NormSumExp = PreNormSumExp+BiasCorr;
end else if (`FPSIZES == 3) begin end else if (`FPSIZES == 3) begin
always_comb begin always_comb begin
case (Fmt) case (Fmt)
`FMT: FmaNe = NormSumExp; `FMT: BiasCorr = '0;
`FMT1: FmaNe = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`BIAS1))&{`NE+2{|NormSumExp}}; `FMT1: BiasCorr = (`NE+2)'(`BIAS1-`BIAS);
`FMT2: FmaNe = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`BIAS2))&{`NE+2{|NormSumExp}}; `FMT2: BiasCorr = (`NE+2)'(`BIAS2-`BIAS);
default: FmaNe = {`NE+2{1'bx}}; default: BiasCorr = 'x;
endcase endcase
end end
assign NormSumExp = PreNormSumExp+BiasCorr;
end else if (`FPSIZES == 4) begin end else if (`FPSIZES == 4) begin
always_comb begin always_comb begin
case (Fmt) case (Fmt)
2'h3: FmaNe = NormSumExp; 2'h3: BiasCorr = '0;
2'h1: FmaNe = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`D_BIAS))&{`NE+2{|NormSumExp}}; 2'h1: BiasCorr = (`NE+2)'(`D_BIAS-`Q_BIAS);
2'h0: FmaNe = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`S_BIAS))&{`NE+2{|NormSumExp}}; 2'h0: BiasCorr = (`NE+2)'(`S_BIAS-`Q_BIAS);
2'h2: FmaNe = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`H_BIAS))&{`NE+2{|NormSumExp}}; 2'h2: BiasCorr = (`NE+2)'(`H_BIAS-`Q_BIAS);
endcase endcase
end end
assign NormSumExp = PreNormSumExp+BiasCorr;
end end
@ -88,26 +91,26 @@ module fmashiftcalc(
if (`FPSIZES == 1) begin if (`FPSIZES == 1) begin
logic Sum0LEZ, Sum0GEFL; logic Sum0LEZ, Sum0GEFL;
assign Sum0LEZ = NormSumExp[`NE+1] | ~|NormSumExp; assign Sum0LEZ = PreNormSumExp[`NE+1] | ~|PreNormSumExp;
assign Sum0GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`NF)-(`NE+2)'(2)); assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF-2));
assign FmaPreResultDenorm = Sum0LEZ & Sum0GEFL & ~FmaSZero; assign FmaPreResultDenorm = Sum0LEZ & Sum0GEFL & ~FmaSZero;
end else if (`FPSIZES == 2) begin end else if (`FPSIZES == 2) begin
logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL; logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL;
assign Sum0LEZ = NormSumExp[`NE+1] | ~|NormSumExp; assign Sum0LEZ = PreNormSumExp[`NE+1] | ~|PreNormSumExp;
assign Sum0GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`NF)-(`NE+2)'(2)); assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF-2));
assign Sum1LEZ = $signed(NormSumExp) <= $signed( (`NE+2)'(`BIAS)-(`NE+2)'(`BIAS1)); assign Sum1LEZ = $signed(PreNormSumExp) <= $signed((`NE+2)'(`BIAS-`BIAS1));
assign Sum1GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`NF1+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`BIAS1)) | ~|NormSumExp; assign Sum1GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF1-2+`BIAS-`BIAS1)) | ~|PreNormSumExp;
assign FmaPreResultDenorm = (Fmt ? Sum0LEZ : Sum1LEZ) & (Fmt ? Sum0GEFL : Sum1GEFL) & ~FmaSZero; assign FmaPreResultDenorm = (Fmt ? Sum0LEZ : Sum1LEZ) & (Fmt ? Sum0GEFL : Sum1GEFL) & ~FmaSZero;
end else if (`FPSIZES == 3) begin end else if (`FPSIZES == 3) begin
logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL, Sum2LEZ, Sum2GEFL; logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL, Sum2LEZ, Sum2GEFL;
assign Sum0LEZ = NormSumExp[`NE+1] | ~|NormSumExp; assign Sum0LEZ = PreNormSumExp[`NE+1] | ~|PreNormSumExp;
assign Sum0GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`NF)-(`NE+2)'(2)); assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF-2));
assign Sum1LEZ = $signed(NormSumExp) <= $signed( (`NE+2)'(`BIAS)-(`NE+2)'(`BIAS1)); assign Sum1LEZ = $signed(PreNormSumExp) <= $signed((`NE+2)'(`BIAS-`BIAS1));
assign Sum1GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`NF1+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`BIAS1)) | ~|NormSumExp; assign Sum1GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF1-2+`BIAS-`BIAS1)) | ~|PreNormSumExp;
assign Sum2LEZ = $signed(NormSumExp) <= $signed( (`NE+2)'(`BIAS)-(`NE+2)'(`BIAS2)); assign Sum2LEZ = $signed(PreNormSumExp) <= $signed((`NE+2)'(`BIAS-`BIAS2));
assign Sum2GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`NF2+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`BIAS2)) | ~|NormSumExp; assign Sum2GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF2-2+`BIAS-`BIAS2)) | ~|PreNormSumExp;
always_comb begin always_comb begin
case (Fmt) case (Fmt)
`FMT: FmaPreResultDenorm = Sum0LEZ & Sum0GEFL & ~FmaSZero; `FMT: FmaPreResultDenorm = Sum0LEZ & Sum0GEFL & ~FmaSZero;
@ -119,21 +122,21 @@ module fmashiftcalc(
end else if (`FPSIZES == 4) begin end else if (`FPSIZES == 4) begin
logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL, Sum2LEZ, Sum2GEFL, Sum3LEZ, Sum3GEFL; logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL, Sum2LEZ, Sum2GEFL, Sum3LEZ, Sum3GEFL;
assign Sum0LEZ = NormSumExp[`NE+1] | ~|NormSumExp; assign Sum0LEZ = PreNormSumExp[`NE+1] | ~|PreNormSumExp;
assign Sum0GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`NF )-(`NE+2)'(2)); assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF-2));
assign Sum1LEZ = $signed(NormSumExp) <= $signed( (`NE+2)'(`BIAS)-(`NE+2)'(`D_BIAS)); assign Sum1LEZ = $signed(PreNormSumExp) <= $signed((`NE+2)'(`BIAS-`D_BIAS));
assign Sum1GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`D_NF+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`D_BIAS)) | ~|NormSumExp; assign Sum1GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`D_NF-2+`BIAS-`D_BIAS)) | ~|PreNormSumExp;
assign Sum2LEZ = $signed(NormSumExp) <= $signed( (`NE+2)'(`BIAS)-(`NE+2)'(`S_BIAS)); assign Sum2LEZ = $signed(PreNormSumExp) <= $signed((`NE+2)'(`BIAS-`S_BIAS));
assign Sum2GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`S_NF+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`S_BIAS)) | ~|NormSumExp; assign Sum2GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`S_NF-2+`BIAS-`S_BIAS)) | ~|PreNormSumExp;
assign Sum3LEZ = $signed(NormSumExp) <= $signed( (`NE+2)'(`BIAS)-(`NE+2)'(`H_BIAS)); assign Sum3LEZ = $signed(PreNormSumExp) <= $signed((`NE+2)'(`BIAS-`H_BIAS));
assign Sum3GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`H_NF+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`H_BIAS)) | ~|NormSumExp; assign Sum3GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`H_NF-2+`BIAS-`H_BIAS)) | ~|PreNormSumExp;
always_comb begin always_comb begin
case (Fmt) case (Fmt)
2'h3: FmaPreResultDenorm = Sum0LEZ & Sum0GEFL & ~FmaSZero; 2'h3: FmaPreResultDenorm = Sum0LEZ & Sum0GEFL & ~FmaSZero;
2'h1: FmaPreResultDenorm = Sum1LEZ & Sum1GEFL & ~FmaSZero; 2'h1: FmaPreResultDenorm = Sum1LEZ & Sum1GEFL & ~FmaSZero;
2'h0: FmaPreResultDenorm = Sum2LEZ & Sum2GEFL & ~FmaSZero; 2'h0: FmaPreResultDenorm = Sum2LEZ & Sum2GEFL & ~FmaSZero;
2'h2: FmaPreResultDenorm = Sum3LEZ & Sum3GEFL & ~FmaSZero; 2'h2: FmaPreResultDenorm = Sum3LEZ & Sum3GEFL & ~FmaSZero;
endcase // *** remove checking to see if it's underflowed and only check for less than zero for denorm checking endcase
end end
end end
@ -144,13 +147,16 @@ module fmashiftcalc(
// - if kill prod dont add to exp // - if kill prod dont add to exp
// Determine if the result is denormal // Determine if the result is denormal
// assign FmaPreResultDenorm = $signed(FmaNe)<=0 & ($signed(FmaNe)>=$signed(-FracLen)) & ~FmaSZero; // assign FmaPreResultDenorm = $signed(NormSumExp)<=0 & ($signed(NormSumExp)>=$signed(-FracLen)) & ~FmaSZero;
// Determine the shift needed for denormal results // Determine the shift needed for denormal results
// - if not denorm add 1 to shift out the leading 1 // - if not denorm add 1 to shift out the leading 1
assign DenormShift = FmaPreResultDenorm ? FmaNe[$clog2(3*`NF+7)-1:0] : 1; assign DenormShift = FmaPreResultDenorm ? NormSumExp[$clog2(3*`NF+7)-1:0] : 1;
// set and calculate the shift input and amount // set and calculate the shift input and amount
// - shift once if killing a product and the result is denormalized // - shift once if killing a product and the result is denormalized
assign FmaShiftIn = {3'b0, FmaSm}; assign FmaShiftIn = {3'b0, FmaSm};
assign FmaShiftAmt = FmaNCnt+DenormShift; if (`FPSIZES == 1)
assign FmaShiftAmt = FmaPreResultDenorm ? FmaSe[$clog2(3*`NF+7)-1:0]+($clog2(3*`NF+7))'(`NF+3): FmaNCnt+1;
else
assign FmaShiftAmt = FmaPreResultDenorm ? FmaSe[$clog2(3*`NF+7)-1:0]+($clog2(3*`NF+7))'(`NF+3)+BiasCorr[$clog2(3*`NF+7)-1:0]: FmaNCnt+1;
endmodule endmodule

View File

@ -109,6 +109,7 @@ module fpu (
logic [3*`NF+5:0] SumE, SumM; logic [3*`NF+5:0] SumE, SumM;
logic [`NE+1:0] ProdExpE, ProdExpM; logic [`NE+1:0] ProdExpE, ProdExpM;
logic AddendStickyE, AddendStickyM; logic AddendStickyE, AddendStickyM;
logic [`NE+1:0] SeE,SeM;
logic KillProdE, KillProdM; logic KillProdE, KillProdM;
logic InvAE, InvAM; logic InvAE, InvAM;
logic NegSumE, NegSumM; logic NegSumE, NegSumM;
@ -256,7 +257,7 @@ module fpu (
.Xm(XManE), .Ym(YManE), .Zm(ZManE), .Xm(XManE), .Ym(YManE), .Zm(ZManE),
.XZero(XZeroE), .YZero(YZeroE), .ZZero(ZZeroE), .XZero(XZeroE), .YZero(YZeroE), .ZZero(ZZeroE),
.FOpCtrl(FOpCtrlE), .Fmt(FmtE), .FOpCtrl(FOpCtrlE), .Fmt(FmtE),
.As(ZSgnEffE), .Ps(PSgnE), .Ss(SsE), .As(ZSgnEffE), .Ps(PSgnE), .Ss(SsE), .Se(SeE),
.Sm(SumE), .Pe(ProdExpE), .Sm(SumE), .Pe(ProdExpE),
.NegSum(NegSumE), .InvA(InvAE), .NCnt(FmaNormCntE), .NegSum(NegSumE), .InvA(InvAE), .NCnt(FmaNormCntE),
.ZmSticky(AddendStickyE), .KillProd(KillProdE)); .ZmSticky(AddendStickyE), .KillProd(KillProdE));
@ -335,9 +336,9 @@ module fpu (
{FRegWriteM, FResSelM, PostProcSelM, FrmM, FmtM, FOpCtrlM, FWriteIntM}); {FRegWriteM, FResSelM, PostProcSelM, FrmM, FmtM, FOpCtrlM, FWriteIntM});
flopenrc #(3*`NF+6) EMRegFma2(clk, reset, FlushM, ~StallM, SumE, SumM); flopenrc #(3*`NF+6) EMRegFma2(clk, reset, FlushM, ~StallM, SumE, SumM);
flopenrc #(`NE+2) EMRegFma3(clk, reset, FlushM, ~StallM, ProdExpE, ProdExpM); flopenrc #(`NE+2) EMRegFma3(clk, reset, FlushM, ~StallM, ProdExpE, ProdExpM);
flopenrc #($clog2(3*`NF+7)+7) EMRegFma4(clk, reset, FlushM, ~StallM, flopenrc #($clog2(3*`NF+7)+9+`NE) EMRegFma4(clk, reset, FlushM, ~StallM,
{AddendStickyE, KillProdE, InvAE, FmaNormCntE, NegSumE, ZSgnEffE, PSgnE, SsE}, {AddendStickyE, KillProdE, InvAE, FmaNormCntE, NegSumE, ZSgnEffE, PSgnE, SsE, SeE},
{AddendStickyM, KillProdM, InvAM, FmaNormCntM, NegSumM, ZSgnEffM, PSgnM, SsM}); {AddendStickyM, KillProdM, InvAM, FmaNormCntM, NegSumM, ZSgnEffM, PSgnM, SsM, SeM});
flopenrc #(`NE+`LOGCVTLEN+`CVTLEN+4) EMRegCvt(clk, reset, FlushM, ~StallM, flopenrc #(`NE+`LOGCVTLEN+`CVTLEN+4) EMRegCvt(clk, reset, FlushM, ~StallM,
{CvtCalcExpE, CvtShiftAmtE, CvtResDenormUfE, CvtResSgnE, IntZeroE, CvtLzcInE}, {CvtCalcExpE, CvtShiftAmtE, CvtResDenormUfE, CvtResSgnE, IntZeroE, CvtLzcInE},
{CvtCalcExpM, CvtShiftAmtM, CvtResDenormUfM, CvtResSgnM, IntZeroM, CvtLzcInM}); {CvtCalcExpM, CvtShiftAmtM, CvtResDenormUfM, CvtResSgnM, IntZeroM, CvtLzcInM});
@ -359,7 +360,7 @@ module fpu (
postprocess postprocess(.Xs(XSgnM), .Ys(YSgnM), .Ze(ZExpM), .Xm(XManM), .Ym(YManM), .Zm(ZManM), .Frm(FrmM), .Fmt(FmtM), .FmaPe(ProdExpM), .DivEarlyTermShift(EarlyTermShiftM), postprocess postprocess(.Xs(XSgnM), .Ys(YSgnM), .Ze(ZExpM), .Xm(XManM), .Ym(YManM), .Zm(ZManM), .Frm(FrmM), .Fmt(FmtM), .FmaPe(ProdExpM), .DivEarlyTermShift(EarlyTermShiftM),
.FmaZmS(AddendStickyM), .FmaKillProd(KillProdM), .XZero(XZeroM), .YZero(YZeroM), .ZZero(ZZeroM), .XInf(XInfM), .YInf(YInfM), .DivQm(QuotM), .FmaSs(SsM), .FmaZmS(AddendStickyM), .FmaKillProd(KillProdM), .XZero(XZeroM), .YZero(YZeroM), .ZZero(ZZeroM), .XInf(XInfM), .YInf(YInfM), .DivQm(QuotM), .FmaSs(SsM),
.ZInf(ZInfM), .XNaN(XNaNM), .YNaN(YNaNM), .ZNaN(ZNaNM), .XSNaN(XSNaNM), .YSNaN(YSNaNM), .ZSNaN(ZSNaNM), .FmaSm(SumM), .DivQe(DivCalcExpM), .DivDone(DivDoneM), .ZInf(ZInfM), .XNaN(XNaNM), .YNaN(YNaNM), .ZNaN(ZNaNM), .XSNaN(XSNaNM), .YSNaN(YSNaNM), .ZSNaN(ZSNaNM), .FmaSm(SumM), .DivQe(DivCalcExpM), .DivDone(DivDoneM),
.FmaNegSum(NegSumM), .FmaInvA(InvAM), .ZDenorm(ZDenormM), .FmaAs(ZSgnEffM), .FmaPs(PSgnM), .FOpCtrl(FOpCtrlM), .FmaNCnt(FmaNormCntM), .FmaNegSum(NegSumM), .FmaInvA(InvAM), .ZDenorm(ZDenormM), .FmaAs(ZSgnEffM), .FmaPs(PSgnM), .FOpCtrl(FOpCtrlM), .FmaNCnt(FmaNormCntM), .FmaSe(SeM),
.CvtCe(CvtCalcExpM), .CvtResDenormUf(CvtResDenormUfM),.CvtShiftAmt(CvtShiftAmtM), .CvtCs(CvtResSgnM), .ToInt(FWriteIntM), .DivS(DivStickyM), .CvtCe(CvtCalcExpM), .CvtResDenormUf(CvtResDenormUfM),.CvtShiftAmt(CvtShiftAmtM), .CvtCs(CvtResSgnM), .ToInt(FWriteIntM), .DivS(DivStickyM),
.CvtLzcIn(CvtLzcInM), .IntZero(IntZeroM), .PostProcSel(PostProcSelM), .PostProcRes(PostProcResM), .PostProcFlg(PostProcFlgM), .FCvtIntRes(FCvtIntResM)); .CvtLzcIn(CvtLzcInM), .IntZero(IntZeroM), .PostProcSel(PostProcSelM), .PostProcRes(PostProcResM), .PostProcFlg(PostProcFlgM), .FCvtIntRes(FCvtIntResM));

View File

@ -46,6 +46,7 @@ module postprocess (
//fma signals //fma signals
input logic FmaAs, // the modified Z sign - depends on instruction input logic FmaAs, // the modified Z sign - depends on instruction
input logic FmaPs, // the product's sign input logic FmaPs, // the product's sign
input logic [`NE+1:0] FmaSe,
input logic [`NE+1:0] FmaPe, // Product exponent input logic [`NE+1:0] FmaPe, // Product exponent
input logic [3*`NF+5:0] FmaSm, // the positive sum input logic [3*`NF+5:0] FmaSm, // the positive sum
input logic FmaZmS, // sticky bit that is calculated during alignment input logic FmaZmS, // sticky bit that is calculated during alignment
@ -93,10 +94,10 @@ module postprocess (
logic UfL; logic UfL;
logic [`FMTBITS-1:0] OutFmt; logic [`FMTBITS-1:0] OutFmt;
// fma signals // fma signals
logic [`NE+1:0] FmaSe; // exponent of the normalized sum logic [`NE+1:0] FmaMe; // exponent of the normalized sum
logic FmaSZero; // is the sum zero logic FmaSZero; // is the sum zero
logic [3*`NF+8:0] FmaShiftIn; // shift input logic [3*`NF+8:0] FmaShiftIn; // shift input
logic [`NE+1:0] FmaNe; // exponent of the normalized sum not taking into account denormal or zero results logic [`NE+1:0] NormSumExp; // exponent of the normalized sum not taking into account denormal or zero results
logic FmaPreResultDenorm; // is the result denormalized - calculated before LZA corection logic FmaPreResultDenorm; // is the result denormalized - calculated before LZA corection
logic [$clog2(3*`NF+7)-1:0] FmaShiftAmt; // normalization shift count logic [$clog2(3*`NF+7)-1:0] FmaShiftAmt; // normalization shift count
// division singals // division singals
@ -151,7 +152,7 @@ module postprocess (
cvtshiftcalc cvtshiftcalc(.ToInt, .CvtCe, .CvtResDenormUf, .Xm, .CvtLzcIn, cvtshiftcalc cvtshiftcalc(.ToInt, .CvtCe, .CvtResDenormUf, .Xm, .CvtLzcIn,
.XZero, .IntToFp, .OutFmt, .CvtResUf, .CvtShiftIn); .XZero, .IntToFp, .OutFmt, .CvtResUf, .CvtShiftIn);
fmashiftcalc fmashiftcalc(.FmaSm, .Ze, .FmaPe, .FmaNCnt, .Fmt, .FmaKillProd, .FmaNe, fmashiftcalc fmashiftcalc(.FmaSm, .Ze, .FmaPe, .FmaNCnt, .Fmt, .FmaKillProd, .NormSumExp, .FmaSe,
.FmaSZero, .FmaPreResultDenorm, .FmaShiftAmt, .FmaShiftIn); .FmaSZero, .FmaPreResultDenorm, .FmaShiftAmt, .FmaShiftIn);
divshiftcalc divshiftcalc(.Fmt, .DivQe, .DivQm, .DivEarlyTermShift, .DivResDenorm, .DivDenormShift, .DivShiftAmt, .DivShiftIn); divshiftcalc divshiftcalc(.Fmt, .DivQe, .DivQm, .DivEarlyTermShift, .DivResDenorm, .DivDenormShift, .DivShiftAmt, .DivShiftIn);
@ -182,9 +183,9 @@ module postprocess (
normshift normshift (.ShiftIn, .ShiftAmt, .Shifted); normshift normshift (.ShiftIn, .ShiftAmt, .Shifted);
shiftcorrection shiftcorrection(.FmaOp, .FmaPreResultDenorm, .FmaNe, shiftcorrection shiftcorrection(.FmaOp, .FmaPreResultDenorm, .NormSumExp,
.DivResDenorm, .DivDenormShift, .DivOp, .DivQe, .DivResDenorm, .DivDenormShift, .DivOp, .DivQe,
.Qe, .FmaSZero, .Shifted, .FmaSe, .Mf); .Qe, .FmaSZero, .Shifted, .FmaMe, .Mf);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Rounding // Rounding
@ -201,7 +202,7 @@ module postprocess (
.FmaSs, .Xs, .Ys, .CvtCs, .Ms); .FmaSs, .Xs, .Ys, .CvtCs, .Ms);
round round(.OutFmt, .Frm, .S, .FmaZmS, .Plus1, .PostProcSel, .CvtCe, .Qe, round round(.OutFmt, .Frm, .S, .FmaZmS, .Plus1, .PostProcSel, .CvtCe, .Qe,
.Ms, .FmaSe, .FmaOp, .CvtOp, .CvtResDenormUf, .Mf, .ToInt, .CvtResUf, .Ms, .FmaMe, .FmaOp, .CvtOp, .CvtResDenormUf, .Mf, .ToInt, .CvtResUf,
.DivS, .DivDone, .DivS, .DivDone,
.DivOp, .UfPlus1, .FullRe, .Rf, .Re, .R, .UfL, .Me); .DivOp, .UfPlus1, .FullRe, .Rf, .Re, .R, .UfL, .Me);
@ -209,7 +210,7 @@ module postprocess (
// Sign calculation // Sign calculation
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
resultsign resultsign(.Frm, .FmaPs, .FmaAs, .FmaSe, .R, .S, resultsign resultsign(.Frm, .FmaPs, .FmaAs, .FmaMe, .R, .S,
.FmaOp, .ZInf, .InfIn, .FmaSZero, .Mult, .Ms, .Ws); .FmaOp, .ZInf, .InfIn, .FmaSZero, .Mult, .Ms, .Ws);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -34,7 +34,7 @@ module resultsign(
input logic ZInf, input logic ZInf,
input logic InfIn, input logic InfIn,
input logic FmaOp, input logic FmaOp,
input logic [`NE+1:0] FmaSe, input logic [`NE+1:0] FmaMe,
input logic FmaSZero, input logic FmaSZero,
input logic Mult, input logic Mult,
input logic R, input logic R,
@ -50,7 +50,7 @@ module resultsign(
// if cancelation then 0 unless round to -infinity // if cancelation then 0 unless round to -infinity
// if multiply then Psgn // if multiply then Psgn
// otherwise psign // otherwise psign
assign Zeros = (FmaPs^FmaAs)&~(FmaSe[`NE+1] | ((FmaSe == 0) & (R|S)))&~Mult ? Frm[1:0] == 2'b10 : FmaPs; assign Zeros = (FmaPs^FmaAs)&~(FmaMe[`NE+1] | ((FmaMe == 0) & (R|S)))&~Mult ? Frm[1:0] == 2'b10 : FmaPs;
// is the result negitive // is the result negitive

View File

@ -48,7 +48,7 @@ module round(
input logic CvtResUf, input logic CvtResUf,
input logic [`CORRSHIFTSZ-1:0] Mf, input logic [`CORRSHIFTSZ-1:0] Mf,
input logic FmaZmS, // addend's sticky bit input logic FmaZmS, // addend's sticky bit
input logic [`NE+1:0] FmaSe, // exponent of the normalized sum input logic [`NE+1:0] FmaMe, // exponent of the normalized sum
input logic Ms, // the result's sign input logic Ms, // the result's sign
input logic [`NE:0] CvtCe, // the calculated expoent input logic [`NE:0] CvtCe, // the calculated expoent
input logic [`NE+1:0] Qe, // the calculated expoent input logic [`NE+1:0] Qe, // the calculated expoent
@ -176,7 +176,7 @@ module round(
// only add the Addend sticky if doing an FMA opperation // only add the Addend sticky if doing an FMA opperation
// - the shifter shifts too far left when there's an underflow (shifting out all possible sticky bits) // - the shifter shifts too far left when there's an underflow (shifting out all possible sticky bits)
assign UfS = FmaZmS&FmaOp | NormS | CvtResUf&CvtOp | FmaSe[`NE+1]&FmaOp | DivS&DivOp; assign UfS = FmaZmS&FmaOp | NormS | CvtResUf&CvtOp | FmaMe[`NE+1]&FmaOp | DivS&DivOp;
// determine round and LSB of the rounded value // determine round and LSB of the rounded value
// - underflow round bit is used to determint the underflow flag // - underflow round bit is used to determint the underflow flag
@ -299,7 +299,7 @@ module round(
always_comb always_comb
case(PostProcSel) case(PostProcSel)
2'b10: Me = FmaSe; // fma 2'b10: Me = FmaMe; // fma
2'b00: Me = {CvtCe[`NE], CvtCe}&{`NE+2{~CvtResDenormUf|CvtResUf}}; // cvt 2'b00: Me = {CvtCe[`NE], CvtCe}&{`NE+2{~CvtResDenormUf|CvtResUf}}; // cvt
2'b01: Me = DivDone ? Qe : '0; // divide 2'b01: Me = DivDone ? Qe : '0; // divide
default: Me = '0; default: Me = '0;

View File

@ -35,12 +35,12 @@ module shiftcorrection(
input logic DivResDenorm, input logic DivResDenorm,
input logic [`NE+1:0] DivQe, input logic [`NE+1:0] DivQe,
input logic [`NE+1:0] DivDenormShift, input logic [`NE+1:0] DivDenormShift,
input logic [`NE+1:0] FmaNe, // exponent of the normalized sum not taking into account denormal or zero results input logic [`NE+1:0] NormSumExp, // exponent of the normalized sum not taking into account denormal or zero results
input logic FmaPreResultDenorm, // is the result denormalized - calculated before LZA corection input logic FmaPreResultDenorm, // is the result denormalized - calculated before LZA corection
input logic FmaSZero, input logic FmaSZero,
output logic [`CORRSHIFTSZ-1:0] Mf, // the shifted sum before LZA correction output logic [`CORRSHIFTSZ-1:0] Mf, // the shifted sum before LZA correction
output logic [`NE+1:0] Qe, output logic [`NE+1:0] Qe,
output logic [`NE+1:0] FmaSe // exponent of the normalized sum output logic [`NE+1:0] FmaMe // exponent of the normalized sum
); );
logic [3*`NF+5:0] CorrSumShifted; // the shifted sum after LZA correction logic [3*`NF+5:0] CorrSumShifted; // the shifted sum after LZA correction
logic [`CORRSHIFTSZ-1:0] CorrQuotShifted; logic [`CORRSHIFTSZ-1:0] CorrQuotShifted;
@ -58,7 +58,7 @@ module shiftcorrection(
assign Mf = FmaOp ? {CorrSumShifted, {`CORRSHIFTSZ-(3*`NF+6){1'b0}}} : DivOp&~DivResDenorm ? CorrQuotShifted : Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`CORRSHIFTSZ]; assign Mf = FmaOp ? {CorrSumShifted, {`CORRSHIFTSZ-(3*`NF+6){1'b0}}} : DivOp&~DivResDenorm ? CorrQuotShifted : Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`CORRSHIFTSZ];
// Determine sum's exponent // Determine sum's exponent
// if plus1 If plus2 if said denorm but norm plus 1 if said denorm but norm plus 2 // if plus1 If plus2 if said denorm but norm plus 1 if said denorm but norm plus 2
assign FmaSe = (FmaNe+{{`NE+1{1'b0}}, LZAPlus1}+{{`NE{1'b0}}, LZAPlus2, 1'b0}+{{`NE+1{1'b0}}, ~ResDenorm&FmaPreResultDenorm}+{{`NE+1{1'b0}}, &FmaNe&Shifted[3*`NF+6]}) & {`NE+2{~(FmaSZero|ResDenorm)}}; assign FmaMe = (NormSumExp+{{`NE+1{1'b0}}, LZAPlus1}+{{`NE{1'b0}}, LZAPlus2, 1'b0}+{{`NE+1{1'b0}}, ~ResDenorm&FmaPreResultDenorm}+{{`NE+1{1'b0}}, &NormSumExp&Shifted[3*`NF+6]}) & {`NE+2{~(FmaSZero|ResDenorm)}};
// recalculate if the result is denormalized // recalculate if the result is denormalized
assign ResDenorm = FmaPreResultDenorm&~Shifted[`NORMSHIFTSZ-3]&~Shifted[`NORMSHIFTSZ-2]; assign ResDenorm = FmaPreResultDenorm&~Shifted[`NORMSHIFTSZ-3]&~Shifted[`NORMSHIFTSZ-2];

View File

@ -96,6 +96,7 @@ module testbenchfp;
logic Mult; logic Mult;
logic Ss; logic Ss;
logic [`NE+1:0] Pe; logic [`NE+1:0] Pe;
logic [`NE+1:0] Se;
logic ZmSticky; logic ZmSticky;
logic KillProd; logic KillProd;
logic [$clog2(3*`NF+7)-1:0] NCnt; logic [$clog2(3*`NF+7)-1:0] NCnt;
@ -675,7 +676,7 @@ module testbenchfp;
fma fma(.Xs(XSgn), .Ys(YSgn), .Zs(ZSgn), fma fma(.Xs(XSgn), .Ys(YSgn), .Zs(ZSgn),
.Xe(XExp), .Ye(YExp), .Ze(ZExp), .Xe(XExp), .Ye(YExp), .Ze(ZExp),
.Xm(XMan), .Ym(YMan), .Zm(ZMan), .Xm(XMan), .Ym(YMan), .Zm(ZMan),
.XZero, .YZero, .ZZero, .Ss, .XZero, .YZero, .ZZero, .Ss, .Se,
.FOpCtrl(OpCtrlVal), .Fmt(ModFmt), .Sm, .NegSum, .InvA, .NCnt, .As, .Ps, .FOpCtrl(OpCtrlVal), .Fmt(ModFmt), .Sm, .NegSum, .InvA, .NCnt, .As, .Ps,
.Pe, .ZmSticky, .KillProd); .Pe, .ZmSticky, .KillProd);
@ -686,7 +687,7 @@ module testbenchfp;
.XZero(XZero), .YZero(YZero), .ZZero(ZZero), .CvtShiftAmt(CvtShiftAmtE), .XZero(XZero), .YZero(YZero), .ZZero(ZZero), .CvtShiftAmt(CvtShiftAmtE),
.XInf(XInf), .YInf(YInf), .ZInf(ZInf), .CvtCs(CvtResSgnE), .ToInt(WriteIntVal), .XInf(XInf), .YInf(YInf), .ZInf(ZInf), .CvtCs(CvtResSgnE), .ToInt(WriteIntVal),
.XSNaN(XSNaN), .YSNaN(YSNaN), .ZSNaN(ZSNaN), .CvtLzcIn(CvtLzcInE), .IntZero, .XSNaN(XSNaN), .YSNaN(YSNaN), .ZSNaN(ZSNaN), .CvtLzcIn(CvtLzcInE), .IntZero,
.FmaKillProd(KillProd), .FmaZmS(ZmSticky), .FmaPe(Pe), .DivDone, .FmaKillProd(KillProd), .FmaZmS(ZmSticky), .FmaPe(Pe), .DivDone, .FmaSe(Se),
.FmaSm(Sm), .FmaNegSum(NegSum), .FmaInvA(InvA), .FmaNCnt(NCnt), .DivEarlyTermShift(EarlyTermShift), .FmaAs(As), .FmaPs(Ps), .Fmt(ModFmt), .Frm(FrmVal), .FmaSm(Sm), .FmaNegSum(NegSum), .FmaInvA(InvA), .FmaNCnt(NCnt), .DivEarlyTermShift(EarlyTermShift), .FmaAs(As), .FmaPs(Ps), .Fmt(ModFmt), .Frm(FrmVal),
.PostProcFlg(Flg), .PostProcRes(FpRes), .FCvtIntRes(IntRes)); .PostProcFlg(Flg), .PostProcRes(FpRes), .FCvtIntRes(IntRes));