diff --git a/pipelined/src/fpu/fmashiftcalc.sv b/pipelined/src/fpu/fmashiftcalc.sv index a6c1a1c6..6d1c40bc 100644 --- a/pipelined/src/fpu/fmashiftcalc.sv +++ b/pipelined/src/fpu/fmashiftcalc.sv @@ -43,6 +43,7 @@ module fmashiftcalc( ); 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] BiasCorr; /////////////////////////////////////////////////////////////////////////////// // Normalization @@ -50,37 +51,40 @@ module fmashiftcalc( //*** insert bias-bias simplification in fcvt.sv/phone pictures // Determine if the sum is zero assign FmaSZero = ~(|FmaSm); - + logic [`NE+1:0] FmaSe; + assign FmaSe = FmaKillProd ? {2'b0, Ze} : FmaPe; // calculate the sum's exponent - // ProdExp - NormCnt - 1 + NF+4 = ProdExp + ~NormCnt + 1 - 1 + NF+4 = ProdExp + ~NormCnt + NF+4 - assign NormSumExp = (FmaKillProd ? {2'b0, Ze} : FmaPe) + {{`NE+2-$unsigned($clog2(3*`NF+7)){1'b1}}, ~FmaNCnt} + (`NE+2)'(`NF+4); + assign NormSumExp = FmaSe + {{`NE+2-$unsigned($clog2(3*`NF+7)){1'b1}}, ~FmaNCnt} + (`NE+2)'(`NF+4); //convert the sum's exponent into the proper percision if (`FPSIZES == 1) begin assign FmaNe = NormSumExp; 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 FmaNe = NormSumExp+BiasCorr; + end else if (`FPSIZES == 3) begin always_comb begin case (Fmt) - `FMT: FmaNe = NormSumExp; - `FMT1: FmaNe = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`BIAS1))&{`NE+2{|NormSumExp}}; - `FMT2: FmaNe = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`BIAS2))&{`NE+2{|NormSumExp}}; - default: FmaNe = {`NE+2{1'bx}}; + `FMT: BiasCorr = '0; + `FMT1: BiasCorr = (`NE+2)'(`BIAS1-`BIAS); + `FMT2: BiasCorr = (`NE+2)'(`BIAS2-`BIAS); + default: BiasCorr = 'x; endcase end + assign FmaNe = NormSumExp+BiasCorr; end else if (`FPSIZES == 4) begin always_comb begin case (Fmt) - 2'h3: FmaNe = NormSumExp; - 2'h1: FmaNe = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`D_BIAS))&{`NE+2{|NormSumExp}}; - 2'h0: FmaNe = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`S_BIAS))&{`NE+2{|NormSumExp}}; - 2'h2: FmaNe = (NormSumExp-(`NE+2)'(`BIAS)+(`NE+2)'(`H_BIAS))&{`NE+2{|NormSumExp}}; + 2'h3: BiasCorr = '0; + 2'h1: BiasCorr = (`NE+2)'(`D_BIAS-`Q_BIAS); + 2'h0: BiasCorr = (`NE+2)'(`S_BIAS-`Q_BIAS); + 2'h2: BiasCorr = (`NE+2)'(`H_BIAS-`Q_BIAS); endcase end + assign FmaNe = NormSumExp+BiasCorr; end @@ -89,25 +93,25 @@ module fmashiftcalc( if (`FPSIZES == 1) begin logic Sum0LEZ, Sum0GEFL; assign Sum0LEZ = NormSumExp[`NE+1] | ~|NormSumExp; - assign Sum0GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`NF)-(`NE+2)'(2)); + assign Sum0GEFL = $signed(NormSumExp) >= $signed((`NE+2)'(-`NF-2)); assign FmaPreResultDenorm = Sum0LEZ & Sum0GEFL & ~FmaSZero; end else if (`FPSIZES == 2) begin logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL; assign Sum0LEZ = NormSumExp[`NE+1] | ~|NormSumExp; - assign Sum0GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`NF)-(`NE+2)'(2)); - assign Sum1LEZ = $signed(NormSumExp) <= $signed( (`NE+2)'(`BIAS)-(`NE+2)'(`BIAS1)); - assign Sum1GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`NF1+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`BIAS1)) | ~|NormSumExp; + assign Sum0GEFL = $signed(NormSumExp) >= $signed((`NE+2)'(-`NF-2)); + assign Sum1LEZ = $signed(NormSumExp) <= $signed((`NE+2)'(`BIAS-`BIAS1)); + assign Sum1GEFL = $signed(NormSumExp) >= $signed((`NE+2)'(-`NF1-2+`BIAS-`BIAS1)) | ~|NormSumExp; assign FmaPreResultDenorm = (Fmt ? Sum0LEZ : Sum1LEZ) & (Fmt ? Sum0GEFL : Sum1GEFL) & ~FmaSZero; end else if (`FPSIZES == 3) begin logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL, Sum2LEZ, Sum2GEFL; assign Sum0LEZ = NormSumExp[`NE+1] | ~|NormSumExp; - assign Sum0GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`NF)-(`NE+2)'(2)); - assign Sum1LEZ = $signed(NormSumExp) <= $signed( (`NE+2)'(`BIAS)-(`NE+2)'(`BIAS1)); - assign Sum1GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`NF1+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`BIAS1)) | ~|NormSumExp; - assign Sum2LEZ = $signed(NormSumExp) <= $signed( (`NE+2)'(`BIAS)-(`NE+2)'(`BIAS2)); - assign Sum2GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`NF2+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`BIAS2)) | ~|NormSumExp; + assign Sum0GEFL = $signed(NormSumExp) >= $signed((`NE+2)'(-`NF-2)); + assign Sum1LEZ = $signed(NormSumExp) <= $signed((`NE+2)'(`BIAS-`BIAS1)); + assign Sum1GEFL = $signed(NormSumExp) >= $signed((`NE+2)'(-`NF1-2+`BIAS-`BIAS1)) | ~|NormSumExp; + assign Sum2LEZ = $signed(NormSumExp) <= $signed((`NE+2)'(`BIAS-`BIAS2)); + assign Sum2GEFL = $signed(NormSumExp) >= $signed((`NE+2)'(-`NF2-2+`BIAS-`BIAS2)) | ~|NormSumExp; always_comb begin case (Fmt) `FMT: FmaPreResultDenorm = Sum0LEZ & Sum0GEFL & ~FmaSZero; @@ -120,20 +124,20 @@ module fmashiftcalc( end else if (`FPSIZES == 4) begin logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL, Sum2LEZ, Sum2GEFL, Sum3LEZ, Sum3GEFL; assign Sum0LEZ = NormSumExp[`NE+1] | ~|NormSumExp; - assign Sum0GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`NF )-(`NE+2)'(2)); - assign Sum1LEZ = $signed(NormSumExp) <= $signed( (`NE+2)'(`BIAS)-(`NE+2)'(`D_BIAS)); - assign Sum1GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`D_NF+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`D_BIAS)) | ~|NormSumExp; - assign Sum2LEZ = $signed(NormSumExp) <= $signed( (`NE+2)'(`BIAS)-(`NE+2)'(`S_BIAS)); - assign Sum2GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`S_NF+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`S_BIAS)) | ~|NormSumExp; - assign Sum3LEZ = $signed(NormSumExp) <= $signed( (`NE+2)'(`BIAS)-(`NE+2)'(`H_BIAS)); - assign Sum3GEFL = $signed(NormSumExp) >= $signed(-(`NE+2)'(`H_NF+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`H_BIAS)) | ~|NormSumExp; + assign Sum0GEFL = $signed(NormSumExp) >= $signed((`NE+2)'(-`NF-2)); + assign Sum1LEZ = $signed(NormSumExp) <= $signed((`NE+2)'(`BIAS-`D_BIAS)); + assign Sum1GEFL = $signed(NormSumExp) >= $signed((`NE+2)'(-`D_NF-2+`BIAS-`D_BIAS)) | ~|NormSumExp; + assign Sum2LEZ = $signed(NormSumExp) <= $signed((`NE+2)'(`BIAS-`S_BIAS)); + assign Sum2GEFL = $signed(NormSumExp) >= $signed((`NE+2)'(-`S_NF-2+`BIAS-`S_BIAS)) | ~|NormSumExp; + assign Sum3LEZ = $signed(NormSumExp) <= $signed((`NE+2)'(`BIAS-`H_BIAS)); + assign Sum3GEFL = $signed(NormSumExp) >= $signed((`NE+2)'(-`H_NF-2+`BIAS-`H_BIAS)) | ~|NormSumExp; always_comb begin case (Fmt) 2'h3: FmaPreResultDenorm = Sum0LEZ & Sum0GEFL & ~FmaSZero; 2'h1: FmaPreResultDenorm = Sum1LEZ & Sum1GEFL & ~FmaSZero; 2'h0: FmaPreResultDenorm = Sum2LEZ & Sum2GEFL & ~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 @@ -152,5 +156,8 @@ module fmashiftcalc( // set and calculate the shift input and amount // - shift once if killing a product and the result is denormalized 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