From 79cccfca823862bb61af781fe7595305fb6d2cc2 Mon Sep 17 00:00:00 2001 From: David Harris Date: Wed, 3 Apr 2024 14:05:07 -0700 Subject: [PATCH 1/4] Progress toward run_vcs --- site-setup.sh | 5 +++-- src/uncore/clint_apb.sv | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/site-setup.sh b/site-setup.sh index cf28a93f1..1ffca5fd4 100755 --- a/site-setup.sh +++ b/site-setup.sh @@ -12,11 +12,12 @@ export MGLS_LICENSE_FILE=27002@zircon.eng.hmc.edu # Change this to your Siemens license server for Questa export SNPSLMD_LICENSE_FILE=27020@zircon.eng.hmc.edu # Change this to your Synopsys license server for Design Compiler export QUESTA_HOME=/cad/mentor/questa_sim-2023.4/questasim # Change this for your path to Questa, excluding bin -export SNPS_HOME=/cad/synopsys/SYN # Change this for your path to Design Compiler, excluding bin +export DC_HOME=/cad/synopsys/SYN # Change this for your path to Synopsys Design Compiler, excluding bin +export VCS_HOME=/cad/synopsys/vcs/U-2023.03-SP2-4 # Change this for your path to Synopsys VCS, exccluding bin # Tools # Questa and Synopsys -export PATH=$QUESTA_HOME/bin:$SNPS_HOME/bin:$PATH +export PATH=$QUESTA_HOME/bin:$DC_HOME/bin:$VCS_HOME/bin:$PATH # GCC export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$RISCV/riscv-gnu-toolchain/lib:$RISCV/riscv-gnu-toolchain/riscv64-unknown-elf/lib diff --git a/src/uncore/clint_apb.sv b/src/uncore/clint_apb.sv index 9122c3dab..997c1bd39 100644 --- a/src/uncore/clint_apb.sv +++ b/src/uncore/clint_apb.sv @@ -150,6 +150,7 @@ module clint_apb import cvw::*; #(parameter cvw_t P) ( endmodule +/* module timeregsync import cvw::*; #(parameter cvw_t P) ( input logic clk, resetn, input logic we0, we1, @@ -169,6 +170,7 @@ module timeregsync import cvw::*; #(parameter cvw_t P) ( else q <= q + 1; endmodule + module timereg import cvw::*; #(parameter cvw_t P) ( input logic PCLK, PRESETn, TIMECLK, input logic we0, we1, @@ -245,3 +247,4 @@ module graytobinary #(parameter N) ( assign b[i] = g[i] ^ b[i+1]; end endmodule +*/ \ No newline at end of file From ae8d581f4ea081bc4bc615072a7e17f00136ca2c Mon Sep 17 00:00:00 2001 From: David Harris Date: Wed, 3 Apr 2024 17:09:19 -0700 Subject: [PATCH 2/4] Started implementing Verilator for testfloat --- sim/sim-testfloat-verilator | 27 +++++++++++++++++++++++++++ testbench/testbench-fp.sv | 34 +++++++++++++++++++--------------- 2 files changed, 46 insertions(+), 15 deletions(-) create mode 100755 sim/sim-testfloat-verilator diff --git a/sim/sim-testfloat-verilator b/sim/sim-testfloat-verilator new file mode 100755 index 000000000..c08484275 --- /dev/null +++ b/sim/sim-testfloat-verilator @@ -0,0 +1,27 @@ +#!/usr/bin/bash + +# sim-testfloat-verilator +# David_Harris@hmc.edu 3 April 2024 +# Run Testfloat simulations with Verilator +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + +# cvtint - test integer conversion unit (fcvtint) +# cvtfp - test floating-point conversion unit (fcvtfp) +# cmp - test comparison unit's LT, LE, EQ opperations (fcmp) +# add - test addition +# fma - test fma +# mul - test mult with fma +# sub - test subtraction +# div - test division +# sqrt - test square root +# all - test everything + +#vsim -c -do "do testfloat.do fdqh_ieee_rv64gc $1" + +verilator -GTEST="\"all\"" -GTEST_SIZE="\"all\"" --timescale "1ns/1ns" --timing --binary --top-module testbenchfp "-I../config/shared" "-I../config/deriv/fdqh_ieee_rv64gc" ../src/cvw.sv ../testbench/testbench-fp.sv ../src/fpu/*.sv ../src/fpu/*/*.sv ../src/generic/*.sv ../src/generic/flop/*.sv --relative-includes + +#vlog +incdir+../config/deriv/$1 +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench-fp.sv ../src/fpu/*.sv ../src/fpu/*/*.sv ../src/generic/*.sv ../src/generic/flop/*.sv -suppress 2583,7063,8607,2697 + +# Change TEST_SIZE to only test certain FP width +# values are QP, DP, SP, HP or all for all tests +#vsim -voptargs=+acc work.testbenchfp -GTEST=$2 -GTEST_SIZE="all" diff --git a/testbench/testbench-fp.sv b/testbench/testbench-fp.sv index 626e73bb4..ce4fd19e1 100644 --- a/testbench/testbench-fp.sv +++ b/testbench/testbench-fp.sv @@ -30,8 +30,8 @@ import cvw::*; module testbenchfp; // Two parameters TEST, TEST_SIZE used with testfloat.do in sim dir // to run specific precisions (e.g., quad or all) - parameter TEST="none"; - parameter TEST_SIZE="none"; + parameter string TEST="none"; + parameter string TEST_SIZE="none"; `include "parameter-defs.vh" @@ -85,7 +85,7 @@ module testbenchfp; logic [P.LOGCVTLEN-1:0] CvtShiftAmtE; // how much to shift by logic [P.DIVb:0] Quot; logic CvtResSubnormUfE; - logic DivStart=0; + logic DivStart; logic FDivBusyE; logic OldFDivBusyE; logic reset = 1'b0; @@ -653,7 +653,7 @@ module testbenchfp; static string pp = `PATH; string testname; string tt0; - tt0 = $psprintf("%s", Tests[TestNum]); + tt0 = $sformatf("%s", Tests[TestNum]); testname = {pp, tt0}; //$display("Here you are %s", testname); $display("\n\nRunning %s vectors ", Tests[TestNum]); @@ -673,7 +673,7 @@ module testbenchfp; // - 1 for the larger precision // - 0 for the smaller precision always_comb begin - if (P.FMTBITS == 1) ModFmt = FmtVal == P.FMT; + if (P.FMTBITS == 1) ModFmt = {1'b0, FmtVal == P.FMT}; else ModFmt = FmtVal; end @@ -819,8 +819,8 @@ module testbenchfp; case (UnitVal) `FMAUNIT: Res = FpRes; `DIVUNIT: Res = FpRes; - `CMPUNIT: Res = CmpRes; - `CVTINTUNIT: if (WriteIntVal) Res = IntRes; else Res = FpRes; + `CMPUNIT: Res = {{(FLEN-XLEN){1'b0}}, CmpRes}; + `CVTINTUNIT: if (WriteIntVal) Res = {{(FLEN-XLEN){1'b0}}, IntRes}; else Res = FpRes; `CVTFPUNIT: Res = FpRes; endcase @@ -859,6 +859,10 @@ module testbenchfp; DivStart = 1'b0; nextstate = S0; end + default: begin + DivStart = 1'b0; + nextstate = S0; + end endcase // case (state) end @@ -1149,22 +1153,22 @@ module readvectors import cvw::*; #(parameter cvw_t P) ( 2'b11: begin // quad X = TestVector[12+2*(P.Q_LEN)-1:12+(P.Q_LEN)]; Y = TestVector[12+(P.Q_LEN)-1:12]; - Ans = TestVector[8]; + Ans = {{P.FLEN{1'b0}}, TestVector[8]}; end 2'b01: if (P.D_SUPPORTED) begin // double X = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[12+2*(P.D_LEN)-1:12+(P.D_LEN)]}; Y = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[12+(P.D_LEN)-1:12]}; - Ans = TestVector[8]; + Ans = {{P.FLEN{1'b0}}, TestVector[8]}; end 2'b00: if (P.S_SUPPORTED) begin // single X = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[12+2*(P.S_LEN)-1:12+(P.S_LEN)]}; Y = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[12+(P.S_LEN)-1:12]}; - Ans = TestVector[8]; + Ans = {{P.FLEN{1'b0}}, TestVector[8]}; end 2'b10: begin // half X = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[12+2*(P.H_LEN)-1:12+(P.H_LEN)]}; Y = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[12+(P.H_LEN)-1:12]}; - Ans = TestVector[8]; + Ans = {{P.FLEN{1'b0}}, TestVector[8]}; end endcase `CVTFPUNIT: @@ -1254,7 +1258,7 @@ module readvectors import cvw::*; #(parameter cvw_t P) ( case (Fmt) 2'b11: begin // quad // {is the integer a long, is the opperation to an integer} - casex ({OpCtrl[2:1]}) + casez ({OpCtrl[2:1]}) 2'b11: begin // long -> quad X = {P.FLEN{1'bx}}; SrcA = TestVector[8+P.Q_LEN+P.XLEN-1:8+(P.Q_LEN)]; @@ -1280,7 +1284,7 @@ module readvectors import cvw::*; #(parameter cvw_t P) ( end 2'b01: if (P.D_SUPPORTED) begin // double // {Int->Fp?, is the integer a long} - casex ({OpCtrl[2:1]}) + casez ({OpCtrl[2:1]}) 2'b11: begin // long -> double X = {P.FLEN{1'bx}}; SrcA = TestVector[8+P.D_LEN+P.XLEN-1:8+(P.D_LEN)]; @@ -1306,7 +1310,7 @@ module readvectors import cvw::*; #(parameter cvw_t P) ( end 2'b00: if (P.S_SUPPORTED) begin // single // {is the integer a long, is the opperation to an integer} - casex ({OpCtrl[2:1]}) + casez ({OpCtrl[2:1]}) 2'b11: begin // long -> single X = {P.FLEN{1'bx}}; SrcA = TestVector[8+P.S_LEN+P.XLEN-1:8+(P.S_LEN)]; @@ -1332,7 +1336,7 @@ module readvectors import cvw::*; #(parameter cvw_t P) ( end 2'b10: begin // half // {is the integer a long, is the opperation to an integer} - casex ({OpCtrl[2:1]}) + casez ({OpCtrl[2:1]}) 2'b11: begin // long -> half X = {P.FLEN{1'bx}}; SrcA = TestVector[8+P.H_LEN+P.XLEN-1:8+(P.H_LEN)]; From ccd0e9cd0cb43f3162bfaf301533c4a5c8af6b67 Mon Sep 17 00:00:00 2001 From: David Harris Date: Wed, 3 Apr 2024 17:26:41 -0700 Subject: [PATCH 3/4] Clean up testbench-fp for Verilator --- sim/run_vcs.sh | 3 ++- testbench/testbench-fp.sv | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/sim/run_vcs.sh b/sim/run_vcs.sh index 8acbd1b99..ef9d84e45 100755 --- a/sim/run_vcs.sh +++ b/sim/run_vcs.sh @@ -19,6 +19,7 @@ clean() { # Clean and run simulation with VCS clean -vcs +lint=all,noGCWM -simprofile -sverilog +vc -Mupdate -line -full64 -kdb -lca -debug_access+all+reverse -v2k_generate ${SOURCE_PATH} +define+TEST=$TESTSUITE $SIMFILES -o $OUTPUT -error=NOODV +#vcs +lint=all,noGCWM -simprofile -sverilog +vc -Mupdate -line -full64 -kdb -lca -debug_access+all+reverse -v2k_generate ${SOURCE_PATH} +define+TEST=$TESTSUITE $SIMFILES -o $OUTPUT -error=NOODV +vcs +lint=all,noGCWM -simprofile -sverilog +vc -Mupdate -line -full64 -kdb -lca -debug_access+all+reverse -v2k_generate ${SOURCE_PATH} -pvalue+testbench.TEST=$TESTSUITE $SIMFILES -o $OUTPUT -error=NOODV ./$OUTPUT | tee program.out diff --git a/testbench/testbench-fp.sv b/testbench/testbench-fp.sv index ce4fd19e1..474b54a89 100644 --- a/testbench/testbench-fp.sv +++ b/testbench/testbench-fp.sv @@ -1153,22 +1153,22 @@ module readvectors import cvw::*; #(parameter cvw_t P) ( 2'b11: begin // quad X = TestVector[12+2*(P.Q_LEN)-1:12+(P.Q_LEN)]; Y = TestVector[12+(P.Q_LEN)-1:12]; - Ans = {{P.FLEN{1'b0}}, TestVector[8]}; + Ans = {{P.FLEN-1{1'b0}}, TestVector[8]}; end 2'b01: if (P.D_SUPPORTED) begin // double X = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[12+2*(P.D_LEN)-1:12+(P.D_LEN)]}; Y = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[12+(P.D_LEN)-1:12]}; - Ans = {{P.FLEN{1'b0}}, TestVector[8]}; + Ans = {{P.FLEN-1{1'b0}}, TestVector[8]}; end 2'b00: if (P.S_SUPPORTED) begin // single X = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[12+2*(P.S_LEN)-1:12+(P.S_LEN)]}; Y = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[12+(P.S_LEN)-1:12]}; - Ans = {{P.FLEN{1'b0}}, TestVector[8]}; + Ans = {{P.FLEN-1{1'b0}}, TestVector[8]}; end 2'b10: begin // half X = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[12+2*(P.H_LEN)-1:12+(P.H_LEN)]}; Y = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[12+(P.H_LEN)-1:12]}; - Ans = {{P.FLEN{1'b0}}, TestVector[8]}; + Ans = {{P.FLEN-1{1'b0}}, TestVector[8]}; end endcase `CVTFPUNIT: @@ -1273,12 +1273,12 @@ module readvectors import cvw::*; #(parameter cvw_t P) ( 2'b01: begin // quad -> long X = {TestVector[8+P.XLEN+P.Q_LEN-1:8+(P.XLEN)]}; SrcA = {P.XLEN{1'bx}}; - Ans = {TestVector[8+(P.XLEN-1):8]}; + Ans = {{(P.FLEN-64){1'b0}}, TestVector[8+(P.XLEN-1):8]}; end 2'b00: begin // quad -> int X = {TestVector[8+32+P.Q_LEN-1:8+(32)]}; SrcA = {P.XLEN{1'bx}}; - Ans = {{P.XLEN-32{TestVector[8+32-1]}},TestVector[8+(32-1):8]}; + Ans = {{P.FLEN-32{TestVector[8+32-1]}},TestVector[8+(32-1):8]}; end endcase end @@ -1299,12 +1299,12 @@ module readvectors import cvw::*; #(parameter cvw_t P) ( 2'b01: begin // double -> long X = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+P.XLEN+P.D_LEN-1:8+(P.XLEN)]}; SrcA = {P.XLEN{1'bx}}; - Ans = {TestVector[8+(P.XLEN-1):8]}; + Ans = {{(P.FLEN-64){1'b0}}, TestVector[8+(P.XLEN-1):8]}; end 2'b00: begin // double -> int X = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+32+P.D_LEN-1:8+(32)]}; SrcA = {P.XLEN{1'bx}}; - Ans = {{P.XLEN-32{TestVector[8+32-1]}},TestVector[8+(32-1):8]}; + Ans = {{P.FLEN-32{TestVector[8+32-1]}},TestVector[8+(32-1):8]}; end endcase end @@ -1325,12 +1325,12 @@ module readvectors import cvw::*; #(parameter cvw_t P) ( 2'b01: begin // single -> long X = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+P.XLEN+P.S_LEN-1:8+(P.XLEN)]}; SrcA = {P.XLEN{1'bx}}; - Ans = {TestVector[8+(P.XLEN-1):8]}; + Ans = {{(P.FLEN-64){1'b0}}, TestVector[8+(P.XLEN-1):8]}; end 2'b00: begin // single -> int X = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+32+P.S_LEN-1:8+(32)]}; SrcA = {P.XLEN{1'bx}}; - Ans = {{P.XLEN-32{TestVector[8+32-1]}},TestVector[8+(32-1):8]}; + Ans = {{P.FLEN-32{TestVector[8+32-1]}},TestVector[8+(32-1):8]}; end endcase end @@ -1351,12 +1351,12 @@ module readvectors import cvw::*; #(parameter cvw_t P) ( 2'b01: begin // half -> long X = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[8+P.XLEN+P.H_LEN-1:8+(P.XLEN)]}; SrcA = {P.XLEN{1'bx}}; - Ans = {TestVector[8+(P.XLEN-1):8]}; + Ans = {{(P.FLEN-64){1'b0}}, TestVector[8+(P.XLEN-1):8]}; end 2'b00: begin // half -> int X = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[8+32+P.H_LEN-1:8+(32)]}; SrcA = {P.XLEN{1'bx}}; - Ans = {{P.XLEN-32{TestVector[8+32-1]}}, TestVector[8+(32-1):8]}; + Ans = {{P.FLEN-32{TestVector[8+32-1]}}, TestVector[8+(32-1):8]}; end endcase end From 499e4d6a6e4cc500b292cf8a5f210d31bc2b6f35 Mon Sep 17 00:00:00 2001 From: David Harris Date: Wed, 3 Apr 2024 17:28:31 -0700 Subject: [PATCH 4/4] Changed 2 to 1 in FmaPreResultSubnorm logic, fixing issue 655 about multiply on f/fh. Not entirely confident this is the right change, but can't find any failures. See https://docs.google.com/document/d/1p7zb4Vvd1LMBLRgEpXjHyp7etCaFaiBVrBZJM8jediE/edit --- src/fpu/postproc/fmashiftcalc.sv | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/fpu/postproc/fmashiftcalc.sv b/src/fpu/postproc/fmashiftcalc.sv index 81e7fb6d9..d6d9cec15 100644 --- a/src/fpu/postproc/fmashiftcalc.sv +++ b/src/fpu/postproc/fmashiftcalc.sv @@ -83,23 +83,23 @@ module fmashiftcalc import cvw::*; #(parameter cvw_t P) ( if (P.FPSIZES == 1) begin logic Sum0LEZ, Sum0GEFL; assign Sum0LEZ = PreNormSumExp[P.NE+1] | ~|PreNormSumExp; - assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF-2)); + assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF-1)); // changed from -2 dh 4/3/24 for issue 655 assign FmaPreResultSubnorm = Sum0LEZ & Sum0GEFL & ~FmaSZero; end else if (P.FPSIZES == 2) begin logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL; assign Sum0LEZ = PreNormSumExp[P.NE+1] | ~|PreNormSumExp; - assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF-2)); + assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF-1)); // changed from -2 dh 4/3/24 for issue 655 assign Sum1LEZ = $signed(PreNormSumExp) <= $signed((P.NE+2)'(P.BIAS-P.BIAS1)); - assign Sum1GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF1-2+P.BIAS-P.BIAS1)) | ~|PreNormSumExp; + assign Sum1GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF1-1+P.BIAS-P.BIAS1)) | ~|PreNormSumExp; assign FmaPreResultSubnorm = (Fmt ? Sum0LEZ : Sum1LEZ) & (Fmt ? Sum0GEFL : Sum1GEFL) & ~FmaSZero; end else if (P.FPSIZES == 3) begin logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL, Sum2LEZ, Sum2GEFL; assign Sum0LEZ = PreNormSumExp[P.NE+1] | ~|PreNormSumExp; - assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF-2)); + assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF-1)); assign Sum1LEZ = $signed(PreNormSumExp) <= $signed((P.NE+2)'(P.BIAS-P.BIAS1)); - assign Sum1GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF1-2+P.BIAS-P.BIAS1)) | ~|PreNormSumExp; + assign Sum1GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF1-1+P.BIAS-P.BIAS1)) | ~|PreNormSumExp; assign Sum2LEZ = $signed(PreNormSumExp) <= $signed((P.NE+2)'(P.BIAS-P.BIAS2)); - assign Sum2GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF2-2+P.BIAS-P.BIAS2)) | ~|PreNormSumExp; + assign Sum2GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF2-1+P.BIAS-P.BIAS2)) | ~|PreNormSumExp; always_comb begin case (Fmt) P.FMT: FmaPreResultSubnorm = Sum0LEZ & Sum0GEFL; // & ~FmaSZero; // checking sum is not zero is harmless but turns out to be unnecessary @@ -111,13 +111,13 @@ module fmashiftcalc import cvw::*; #(parameter cvw_t P) ( end else if (P.FPSIZES == 4) begin logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL, Sum2LEZ, Sum2GEFL, Sum3LEZ, Sum3GEFL; assign Sum0LEZ = PreNormSumExp[P.NE+1] | ~|PreNormSumExp; - assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF-2)); + assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF-1)); assign Sum1LEZ = $signed(PreNormSumExp) <= $signed((P.NE+2)'(P.BIAS-P.D_BIAS)); - assign Sum1GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.D_NF-2+P.BIAS-P.D_BIAS)) | ~|PreNormSumExp; + assign Sum1GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.D_NF-1+P.BIAS-P.D_BIAS)) | ~|PreNormSumExp; assign Sum2LEZ = $signed(PreNormSumExp) <= $signed((P.NE+2)'(P.BIAS-P.S_BIAS)); - assign Sum2GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.S_NF-2+P.BIAS-P.S_BIAS)) | ~|PreNormSumExp; + assign Sum2GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.S_NF-1+P.BIAS-P.S_BIAS)) | ~|PreNormSumExp; assign Sum3LEZ = $signed(PreNormSumExp) <= $signed((P.NE+2)'(P.BIAS-P.H_BIAS)); - assign Sum3GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.H_NF-2+P.BIAS-P.H_BIAS)) | ~|PreNormSumExp; + assign Sum3GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.H_NF-1+P.BIAS-P.H_BIAS)) | ~|PreNormSumExp; always_comb begin case (Fmt) 2'h3: FmaPreResultSubnorm = Sum0LEZ & Sum0GEFL & ~FmaSZero;