From 9d4a14b209566f53add2434ba3801f8bcc6b3ecc Mon Sep 17 00:00:00 2001 From: David Harris Date: Sun, 21 Jan 2024 11:39:51 -0800 Subject: [PATCH] coverage improvements --- sim/coverage-exclusions-rv64gc.do | 13 +++++++++++++ src/fpu/fdivsqrt/fdivsqrtfsm.sv | 4 ++-- src/fpu/postproc/round.sv | 10 ++++++---- src/fpu/postproc/specialcase.sv | 2 +- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/sim/coverage-exclusions-rv64gc.do b/sim/coverage-exclusions-rv64gc.do index 6117c6395..a7c2249bc 100644 --- a/sim/coverage-exclusions-rv64gc.do +++ b/sim/coverage-exclusions-rv64gc.do @@ -34,11 +34,24 @@ do GetLineNum.do # DH 4/22/23: Exclude all LZAs coverage exclude -srcfile lzc.sv +################# +# FPU Exclusions +################# # DH 4/22/23: FDIVSQRT can't go directly from done to busy again coverage exclude -scope /dut/core/fpu/fpu/fdivsqrt/fdivsqrtfsm -ftrans state DONE->BUSY # DH 4/22/23: The busy->idle transition only occurs if a FlushE occurs while the divider is busy. The flush is caused by a trap or return, # which won't happen while the divider is busy. coverage exclude -scope /dut/core/fpu/fpu/fdivsqrt/fdivsqrtfsm -ftrans state BUSY->IDLE +# All Memory-stage stalls have resolved by time fdivsqrt finishes regular operation in this configuration, so can't test StallM +coverage exclude -scope /dut/core/fpu/fpu/fdivsqrt/fdivsqrtfsm -linerange [GetLineNum ../src/fpu/fdivsqrt/fdivsqrtfsm.sv "exclusion-tag: fdivsqrtfsm stallm"] -item b 1 +coverage exclude -scope /dut/core/fpu/fpu/fdivsqrt/fdivsqrtfsm -linerange [GetLineNum ../src/fpu/fdivsqrt/fdivsqrtfsm.sv "exclusion-tag: fdivsqrtfsm stallm"] -item s 1 +# Division by zero never sets sticky/guard/overflow/round to cause inexact or underflow result, but check out of paranoia +coverage exclude -scope /dut/core/fpu/fpu/postprocess/flags -linerange [GetLineNum ../src/fpu/postproc/flags.sv "assign FpInexact"] -item e 1 -fecexprrow 15 +coverage exclude -scope /dut/core/fpu/fpu/postprocess/flags -linerange [GetLineNum ../src/fpu/postproc/flags.sv "assign Underflow"] -item e 1 -fecexprrow 22 + +################## +# Cache Exclusions +################## ### Exclude D$ states and logic for the I$ instance # This is cleaner than trying to set an I$-specific pragma in cachefsm.sv (which would exclude it for the D$ instance too) diff --git a/src/fpu/fdivsqrt/fdivsqrtfsm.sv b/src/fpu/fdivsqrt/fdivsqrtfsm.sv index 862d53b25..cd890ed87 100644 --- a/src/fpu/fdivsqrt/fdivsqrtfsm.sv +++ b/src/fpu/fdivsqrt/fdivsqrtfsm.sv @@ -70,8 +70,8 @@ module fdivsqrtfsm import cvw::*; #(parameter cvw_t P) ( end else if (state == BUSY) begin if (step == 1 | WZeroE) state <= #1 DONE; // finished steps or terminate early on zero residual step <= step - 1; - end else if (state == DONE) begin - if (StallM) state <= #1 DONE; + end else if (state == DONE) begin // Can't still be stalled in configs tested, but keep this check for paranoia + if (StallM) state <= #1 DONE; // exclusion-tag: fdivsqrtfsm stallm else state <= #1 IDLE; end end diff --git a/src/fpu/postproc/round.sv b/src/fpu/postproc/round.sv index 460786135..445f563d9 100644 --- a/src/fpu/postproc/round.sv +++ b/src/fpu/postproc/round.sv @@ -68,6 +68,7 @@ module round import cvw::*; #(parameter cvw_t P) ( logic CalcPlus1; // calculated plus1 logic FpPlus1; // do you add one to the fp result logic [P.FLEN:0] RoundAdd; // how much to add to the result + logic CvtToInt; // Convert to integer operation // what position is XLEN in? // options: @@ -111,6 +112,7 @@ module round import cvw::*; #(parameter cvw_t P) ( // determine what format the final result is in: int or fp assign IntRes = ToInt; assign FpRes = ~IntRes; + assign CvtToInt = ToInt; // under current encodings, CvtOp always is 1 when ToInt is selected, so leave it out // sticky bit calculation if (P.FPSIZES == 1) begin @@ -244,9 +246,9 @@ module round import cvw::*; #(parameter cvw_t P) ( endcase end - assign Guard = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN-1] : FpGuard; - assign LsbRes = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN] : FpLsbRes; - assign Round = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN-2] : FpRound; + assign Guard = CvtToInt ? Mf[P.CORRSHIFTSZ-P.XLEN-1] : FpGuard; + assign LsbRes = CvtToInt ? Mf[P.CORRSHIFTSZ-P.XLEN] : FpLsbRes; + assign Round = CvtToInt ? Mf[P.CORRSHIFTSZ-P.XLEN-2] : FpRound; always_comb begin // Determine if you add 1 @@ -272,7 +274,7 @@ module round import cvw::*; #(parameter cvw_t P) ( // If an answer is exact don't round assign Plus1 = CalcPlus1 & (Sticky|Round|Guard); - assign FpPlus1 = Plus1&~(ToInt&CvtOp); + assign FpPlus1 = Plus1&~(CvtToInt); assign UfPlus1 = UfCalcPlus1 & (Sticky|Round); // place Plus1 into the proper position for the format diff --git a/src/fpu/postproc/specialcase.sv b/src/fpu/postproc/specialcase.sv index 76784e4a1..ba30daaf2 100644 --- a/src/fpu/postproc/specialcase.sv +++ b/src/fpu/postproc/specialcase.sv @@ -342,7 +342,7 @@ module specialcase import cvw::*; #(parameter cvw_t P) ( else OfIntRes2 = OfIntRes; if (Zfa) Int64Res = {{(P.XLEN-32){CvtNegRes[P.XLEN-1]}}, CvtNegRes[31:0]}; else Int64Res = CvtNegRes[P.XLEN-1:0]; - if (Zfa) SelCvtOfRes = InfIn | NaNIn; // fcvtmod.w.d only overflows to 0 on NaN or Infinity + if (Zfa) SelCvtOfRes = InfIn | NaNIn | (CvtCe > 32 + 52); // fcvtmod.w.d only overflows to 0 on NaN or Infinity, or if the shift is so large that only zeros are left else SelCvtOfRes = IntInvalid; // regular fcvt gives an overflow if out of range end else