From e696c47f856bd15b8fd97c4969664ad1e7e3a63a Mon Sep 17 00:00:00 2001 From: Ryan Wolk Date: Sat, 2 May 2026 16:44:22 -0700 Subject: [PATCH 1/7] Initial B18 Coverage --- config.svh | 2 +- coverage/covergroups/B18.svh | 635 +++++++++++++++++++++++++++++++++++ 2 files changed, 636 insertions(+), 1 deletion(-) create mode 100644 coverage/covergroups/B18.svh diff --git a/config.svh b/config.svh index 346556f..847a4db 100644 --- a/config.svh +++ b/config.svh @@ -33,7 +33,7 @@ // `define COVER_B15 `define COVER_B16 // `define COVER_B17 -// `define COVER_B18 +`define COVER_B18 `define COVER_B19 // `define COVER_B20 `define COVER_B21 diff --git a/coverage/covergroups/B18.svh b/coverage/covergroups/B18.svh new file mode 100644 index 0000000..efd2803 --- /dev/null +++ b/coverage/covergroups/B18.svh @@ -0,0 +1,635 @@ +// Copyright (C) 2025-26 Harvey Mudd College +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. + +// Ryan Wolk (rwolk@g.hmc.edu) + +covergroup B18_cg (virtual coverfloat_interface CFI); + + option.per_instance = 0; + + // Source Format Helpers + + F16_src_fmt: coverpoint (CFI.operandFmt == FMT_HALF) { + type_option.weight = 0; + bins f16 = {1}; + } + + BF16_src_fmt: coverpoint (CFI.operandFmt == FMT_BF16) { + type_option.weight = 0; + bins bf16 = {1}; + } + + F32_src_fmt: coverpoint (CFI.operandFmt == FMT_SINGLE) { + type_option.weight = 0; + bins f32 = {1}; + } + + F64_src_fmt: coverpoint (CFI.operandFmt == FMT_DOUBLE) { + type_option.weight = 0; + bins f64 = {1}; + } + + F128_src_fmt: coverpoint (CFI.operandFmt == FMT_QUAD) { + type_option.weight = 0; + bins f128 = {1}; + } + + // FMA Instructions + + FMA_ops: coverpoint CFI.op { + type_option.weight = 0; + bins fmadd = { OP_FMADD }; + bins fmsub = { OP_FMSUB }; + bins fnmadd = { OP_FNMADD }; + bins fnmsub = { OP_FNMSUB }; + } + + /****************************************************************** + * Case I: Rounding Results + ******************************************************************/ + + // The FMA Pre-Addition Result is of the form 2.2nf, so here there are + // 2.(23 bits of mantissa) (guard: nf-1) (sticky: nf-2 --> 0) + F32_product_lsb: coverpoint |CFI.fmaPreAddition[F32_M_BITS] { + type_option.weight = 0; + bins lsb0 = { 0 }; + bins lsb1 = { 1 }; + } + F32_product_guard: coverpoint CFI.fmaPreAddition[F32_M_BITS-1] { + type_option.weight = 0; + bins guard0 = { 0 }; + bins guard1 = { 1 }; + } + F32_product_sticky: coverpoint |CFI.fmaPreAddition[F32_M_BITS-2:0] { + type_option.weight = 0; + bins sticky0 = { 0 }; + bins sticky1 = { 1 }; + } + F32_interm_guard_zero: coverpoint CFI.intermM[INTERM_M_BITS - F32_M_BITS - 1] { + type_option.weight = 0; + bins zero = { 0 }; + } + F32_interm_sticky_zero: coverpoint |CFI.intermM[INTERM_M_BITS - F32_M_BITS - 2 : 0] { + type_option.weight = 0; + bins zero = { 0 }; + } + + F64_product_lsb: coverpoint |CFI.fmaPreAddition[F64_M_BITS] { + type_option.weight = 0; + bins lsb0 = { 0 }; + bins lsb1 = { 1 }; + } + F64_product_guard: coverpoint CFI.fmaPreAddition[F64_M_BITS-1] { + type_option.weight = 0; + bins guard0 = { 0 }; + bins guard1 = { 1 }; + } + F64_product_sticky: coverpoint |CFI.fmaPreAddition[F64_M_BITS-2:0] { + type_option.weight = 0; + bins sticky0 = { 0 }; + bins sticky1 = { 1 }; + } + F64_interm_guard_zero: coverpoint CFI.intermM[INTERM_M_BITS - F64_M_BITS - 1] { + type_option.weight = 0; + bins zero = { 0 }; + } + F64_interm_sticky_zero: coverpoint |CFI.intermM[INTERM_M_BITS - F64_M_BITS - 2 : 0] { + type_option.weight = 0; + bins zero = { 0 }; + } + + F128_product_lsb: coverpoint |CFI.fmaPreAddition[F128_M_BITS] { + type_option.weight = 0; + bins lsb0 = { 0 }; + bins lsb1 = { 1 }; + } + F128_product_guard: coverpoint CFI.fmaPreAddition[F128_M_BITS-1] { + type_option.weight = 0; + bins guard0 = { 0 }; + bins guard1 = { 1 }; + } + F128_product_sticky: coverpoint |CFI.fmaPreAddition[F128_M_BITS-2:0] { + type_option.weight = 0; + bins sticky0 = { 0 }; + bins sticky1 = { 1 }; + } + F128_interm_guard_zero: coverpoint CFI.intermM[INTERM_M_BITS - F128_M_BITS - 1] { + type_option.weight = 0; + bins zero = { 0 }; + } + F128_interm_sticky_zero: coverpoint |CFI.intermM[INTERM_M_BITS - F128_M_BITS - 2 : 0] { + type_option.weight = 0; + bins zero = { 0 }; + } + + F16_product_lsb: coverpoint |CFI.fmaPreAddition[F16_M_BITS] { + type_option.weight = 0; + bins lsb0 = { 0 }; + bins lsb1 = { 1 }; + } + F16_product_guard: coverpoint CFI.fmaPreAddition[F16_M_BITS-1] { + type_option.weight = 0; + bins guard0 = { 0 }; + bins guard1 = { 1 }; + } + F16_product_sticky: coverpoint |CFI.fmaPreAddition[F16_M_BITS-2:0] { + type_option.weight = 0; + bins sticky0 = { 0 }; + bins sticky1 = { 1 }; + } + F16_interm_guard_zero: coverpoint CFI.intermM[INTERM_M_BITS - F16_M_BITS - 1] { + type_option.weight = 0; + bins zero = { 0 }; + } + F16_interm_sticky_zero: coverpoint |CFI.intermM[INTERM_M_BITS - F16_M_BITS - 2 : 0] { + type_option.weight = 0; + bins zero = { 0 }; + } + + BF16_product_lsb: coverpoint |CFI.fmaPreAddition[BF16_M_BITS] { + type_option.weight = 0; + bins lsb0 = { 0 }; + bins lsb1 = { 1 }; + } + BF16_product_guard: coverpoint CFI.fmaPreAddition[BF16_M_BITS-1] { + type_option.weight = 0; + bins guard0 = { 0 }; + bins guard1 = { 1 }; + } + BF16_product_sticky: coverpoint |CFI.fmaPreAddition[BF16_M_BITS-2:0] { + type_option.weight = 0; + bins sticky0 = { 0 }; + bins sticky1 = { 1 }; + } + BF16_interm_guard_zero: coverpoint CFI.intermM[INTERM_M_BITS - BF16_M_BITS - 1] { + type_option.weight = 0; + bins zero = { 0 }; + } + BF16_interm_sticky_zero: coverpoint |CFI.intermM[INTERM_M_BITS - BF16_M_BITS - 2 : 0] { + type_option.weight = 0; + bins zero = { 0 }; + } + + // Useful coverpoint for both case ii and case iii + F32_sign: coverpoint CFI.result[31] { + type_option.weight = 0; + bins pos = {0}; + bins neg = {1}; + } + + F64_sign: coverpoint CFI.result[63] { + type_option.weight = 0; + bins pos = {0}; + bins neg = {1}; + } + + F128_sign: coverpoint CFI.result[127] { + type_option.weight = 0; + bins pos = {0}; + bins neg = {1}; + } + + F16_sign: coverpoint CFI.result[15] { + type_option.weight = 0; + bins pos = {0}; + bins neg = {1}; + } + + BF16_sign: coverpoint CFI.result[15] { + type_option.weight = 0; + bins pos = {0}; + bins neg = {1}; + } + + /************************************************************************ + Underflow Boundary Helper Coverpoints (from B4, written by Corey Hickson) + ************************************************************************/ + + // cases i & ii + F32_maxNorm_pm_3ulp: coverpoint CFI.intermM[(INTERM_M_BITS - F32_M_BITS) -: 3] + iff (CFI.intermX == F32_MAXNORM_EXP && CFI.intermM[(INTERM_M_BITS - 1) -: F32_M_BITS - 1] == '1) { + type_option.weight = 0; + + bins maxNorm_pm_3ulp[] = {[3'b001 : 3'b111]}; + } + + F64_maxNorm_pm_3ulp: coverpoint CFI.intermM[(INTERM_M_BITS - F64_M_BITS) -: 3] + iff (CFI.intermX == F64_MAXNORM_EXP && CFI.intermM[(INTERM_M_BITS - 1) -: F64_M_BITS - 1] == '1) { + type_option.weight = 0; + + bins maxNorm_pm_3ulp[] = {[3'b001 : 3'b111]}; + } + + F128_maxNorm_pm_3ulp: coverpoint CFI.intermM[(INTERM_M_BITS - F128_M_BITS) -: 3] + iff (CFI.intermX == F128_MAXNORM_EXP && CFI.intermM[(INTERM_M_BITS - 1) -: F128_M_BITS - 1] == '1) { + type_option.weight = 0; + + bins maxNorm_pm_3ulp[] = {[3'b001 : 3'b111]}; + } + + F16_maxNorm_pm_3ulp: coverpoint CFI.intermM[(INTERM_M_BITS - F16_M_BITS) -: 3] + iff (CFI.intermX == F16_MAXNORM_EXP && CFI.intermM[(INTERM_M_BITS - 1) -: F16_M_BITS - 1] == '1) { + type_option.weight = 0; + + bins maxNorm_pm_3ulp[] = {[3'b001 : 3'b111]}; + } + + BF16_maxNorm_pm_3ulp: coverpoint CFI.intermM[(INTERM_M_BITS - BF16_M_BITS) -: 3] + iff (CFI.intermX == BF16_MAXNORM_EXP && CFI.intermM[(INTERM_M_BITS - 1) -: BF16_M_BITS - 1] == '1) { + type_option.weight = 0; + + bins maxNorm_pm_3ulp[] = {[3'b001 : 3'b111]}; + } + + // cases vii & viii + F32_gt_maxNorm_p_3ulp: coverpoint CFI.intermM iff (CFI.intermX == F32_MAXNORM_EXP) { + type_option.weight = 0; + + bins gt_maxNorm = {[ ('1 << (INTERM_M_BITS - F32_M_BITS - 2)) : $]}; + } + + F64_gt_maxNorm_p_3ulp: coverpoint CFI.intermM iff (CFI.intermX == F64_MAXNORM_EXP) { + type_option.weight = 0; + + bins gt_maxNorm = {[ ('1 << (INTERM_M_BITS - F64_M_BITS - 2)) : $]}; + } + + F128_gt_maxNorm_p_3ulp: coverpoint CFI.intermM iff (CFI.intermX == F128_MAXNORM_EXP) { + type_option.weight = 0; + + bins gt_maxNorm = {[ ('1 << (INTERM_M_BITS - F128_M_BITS - 2)) : $]}; + } + + F16_gt_maxNorm_p_3ulp: coverpoint CFI.intermM iff (CFI.intermX == F16_MAXNORM_EXP) { + type_option.weight = 0; + + bins gt_maxNorm = {[ ('1 << (INTERM_M_BITS - F16_M_BITS - 2)) : $]}; + } + + BF16_gt_maxNorm_p_3ulp: coverpoint CFI.intermM iff (CFI.intermX == BF16_MAXNORM_EXP) { + type_option.weight = 0; + + bins gt_maxNorm = {[ ('1 << (INTERM_M_BITS - BF16_M_BITS - 2)) : $]}; + } + + // case v + F32_maxNorm_pm3_exp_range: coverpoint CFI.intermX { + type_option.weight = 0; + + bins exp_range[] = {[ F32_MAXNORM_EXP - 3 : F32_MAXNORM_EXP + 3 ]}; + } + F64_maxNorm_pm3_exp_range: coverpoint CFI.intermX { + type_option.weight = 0; + + bins exp_range[] = {[ F64_MAXNORM_EXP - 3 : F64_MAXNORM_EXP + 3 ]}; + } + F128_maxNorm_pm3_exp_range: coverpoint CFI.intermX { + type_option.weight = 0; + + bins exp_range[] = {[ F128_MAXNORM_EXP - 3 : F128_MAXNORM_EXP + 3 ]}; + } + F16_maxNorm_pm3_exp_range: coverpoint CFI.intermX { + type_option.weight = 0; + + bins exp_range[] = {[ F16_MAXNORM_EXP - 3 : F16_MAXNORM_EXP + 3 ]}; + } + BF16_maxNorm_pm3_exp_range: coverpoint CFI.intermX { + type_option.weight = 0; + + bins exp_range[] = {[ BF16_MAXNORM_EXP - 3 : BF16_MAXNORM_EXP + 3 ]}; + } + + + /************************************************************************ + Underflow Boundary Helper Coverpoints (from B5, commit: f5a2369 by Corey Hickson) + ************************************************************************/ + + // cases i & ii + FP_subnorm: coverpoint (CFI.intermX == 0 && CFI.intermM != 0) { + type_option.weight = 0; + + bins subnorm = {1}; + } + + // cases iii & iv + + // Guard bit sticky bit + F32_minSubNorm_p_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F32_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F32_M_BITS - 2) : 0]} + // implicit leading 0 (subnorm) single 1 in LSB (except for Guard and sticky) + iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -: F32_M_BITS +1] == 1) { + type_option.weight = 0; + + bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; + } + + // Guard bit sticky bit + F32_minSubNorm_m_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F32_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F32_M_BITS - 2) : 0]} + // implicit leading 0 (subnorm) all zeros fraction (except for Guard and sticky) + iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -: F32_M_BITS +1] == 0) { + type_option.weight = 0; + + bins minSubNorm_m_3ulp[] = {[2'b01 : 2'b11]}; + } + + // Guard bit sticky bit + F64_minSubNorm_p_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F64_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F64_M_BITS - 2) : 0]} + // implicit leading 0 (subnorm) single 1 in LSB (except for Guard and sticky) + iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -: F64_M_BITS +1] == 1) { + type_option.weight = 0; + + bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; + } + + // Guard bit sticky bit + F64_minSubNorm_m_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F64_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F64_M_BITS - 2) : 0]} + // implicit leading 0 (subnorm) all zeros fraction (except for Guard and sticky) + iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -: F64_M_BITS +1] == 0) { + type_option.weight = 0; + + bins minSubNorm_m_3ulp[] = {[2'b01 : 2'b11]}; + } + + // Guard bit sticky bit + F128_minSubNorm_p_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F128_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F128_M_BITS - 2) : 0]} + // implicit leading 0 (subnorm) single 1 in LSB (except for Guard and sticky) + iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -: F128_M_BITS +1] == 1) { + type_option.weight = 0; + + bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; + } + + // Guard bit sticky bit + F128_minSubNorm_m_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F128_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F128_M_BITS - 2) : 0]} + // implicit leading 0 (subnorm) all zeros fraction (except for Guard and sticky) + iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -: F128_M_BITS +1] == 0) { + type_option.weight = 0; + + bins minSubNorm_m_3ulp[] = {[2'b01 : 2'b11]}; + } + + // Guard bit sticky bit + F16_minSubNorm_p_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F16_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F16_M_BITS - 2) : 0]} + // implicit leading 0 (subnorm) single 1 in LSB (except for Guard and sticky) + iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -: F16_M_BITS +1] == 1) { + type_option.weight = 0; + + bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; + } + + // Guard bit sticky bit + F16_minSubNorm_m_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F16_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F16_M_BITS - 2) : 0]} + // implicit leading 0 (subnorm) all zeros fraction (except for Guard and sticky) + iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -: F16_M_BITS +1] == 0) { + type_option.weight = 0; + + bins minSubNorm_m_3ulp[] = {[2'b01 : 2'b11]}; + } + + // Guard bit sticky bit + BF16_minSubNorm_p_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - BF16_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - BF16_M_BITS - 2) : 0]} + // implicit leading 0 (subnorm) single 1 in LSB (except for Guard and sticky) + iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -: BF16_M_BITS +1] == 1) { + type_option.weight = 0; + + bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; + } + + // Guard bit sticky bit + BF16_minSubNorm_m_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - BF16_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - BF16_M_BITS - 2) : 0]} + // implicit leading 0 (subnorm) all zeros fraction (except for Guard and sticky) + iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -: BF16_M_BITS +1] == 0) { + type_option.weight = 0; + + bins minSubNorm_m_3ulp[] = {[2'b01 : 2'b11]}; + } + + // cases v & vi + + // Guard bit sticky bit + F32_minNorm_p_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F32_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F32_M_BITS - 2) : 0]} + // implicit leading 1 (norm) all zero fraction (except for Guard and sticky) + iff (CFI.intermX != 0 && CFI.intermM[INTERM_M_BITS -1 -: F32_M_BITS] == 0) { + type_option.weight = 0; + + bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; + } + + // Guard bit sticky bit + F32_minNorm_m_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F32_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F32_M_BITS - 2) : 0]} + // implicit leading 0 (subnorm) all ones fraction (except for Guard and sticky) + iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -1 -: F32_M_BITS] == '1) { + type_option.weight = 0; + + bins minNorm_m_3ulp[] = {[2'b01 : 2'b11]}; + } + + // Guard bit sticky bit + F64_minNorm_p_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F64_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F64_M_BITS - 2) : 0]} + // implicit leading 1 (norm) all zero fraction (except for Guard and sticky) + iff (CFI.intermX != 0 && CFI.intermM[INTERM_M_BITS -1 -: F64_M_BITS] == 0) { + type_option.weight = 0; + + bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; + } + + // Guard bit sticky bit + F64_minNorm_m_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F64_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F64_M_BITS - 2) : 0]} + // implicit leading 0 (subnorm) all ones fraction (except for Guard and sticky) + iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -1 -: F64_M_BITS] == '1) { + type_option.weight = 0; + + bins minNorm_m_3ulp[] = {[2'b01 : 2'b11]}; + } + + // Guard bit sticky bit + F128_minNorm_p_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F128_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F128_M_BITS - 2) : 0]} + // implicit leading 1 (norm) all zero fraction (except for Guard and sticky) + iff (CFI.intermX != 0 && CFI.intermM[INTERM_M_BITS -1 -: F128_M_BITS] == 0) { + type_option.weight = 0; + + bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; + } + + // Guard bit sticky bit + F128_minNorm_m_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F128_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F128_M_BITS - 2) : 0]} + // implicit leading 0 (subnorm) all ones fraction (except for Guard and sticky) + iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -1 -: F128_M_BITS] == '1) { + type_option.weight = 0; + + bins minNorm_m_3ulp[] = {[2'b01 : 2'b11]}; + } + + // Guard bit sticky bit + F16_minNorm_p_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F16_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F16_M_BITS - 2) : 0]} + // implicit leading 1 (norm) all zero fraction (except for Guard and sticky) + iff (CFI.intermX != 0 && CFI.intermM[INTERM_M_BITS -1 -: F16_M_BITS] == 0) { + type_option.weight = 0; + + bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; + } + + // Guard bit sticky bit + F16_minNorm_m_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F16_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F16_M_BITS - 2) : 0]} + // implicit leading 0 (subnorm) all ones fraction (except for Guard and sticky) + iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -1 -: F16_M_BITS] == '1) { + type_option.weight = 0; + + bins minNorm_m_3ulp[] = {[2'b01 : 2'b11]}; + } + + // Guard bit sticky bit + BF16_minNorm_p_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - BF16_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - BF16_M_BITS - 2) : 0]} + // implicit leading 1 (norm) all zero fraction (except for Guard and sticky) + iff (CFI.intermX != 0 && CFI.intermM[INTERM_M_BITS -1 -: BF16_M_BITS] == 0) { + type_option.weight = 0; + + bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; + } + + // Guard bit sticky bit + BF16_minNorm_m_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - BF16_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - BF16_M_BITS - 2) : 0]} + // implicit leading 0 (subnorm) all ones fraction (except for Guard and sticky) + iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -1 -: BF16_M_BITS] == '1) { + type_option.weight = 0; + + bins minNorm_m_3ulp[] = {[2'b01 : 2'b11]}; + } + + + // cases vii & viii + F32_btw_minSubNorm_zero: coverpoint CFI.intermM iff (CFI.intermX == 0) { + type_option.weight = 0; + + // shift 1 into the ULP position, subtract one to be in the exclusive range (0 , minSubNorm) + bins btw_minSubNorm_zero = {[1 : ((INTERM_M_BITS'(1) << (INTERM_M_BITS - F32_M_BITS)) - 1)]}; + } + + F64_btw_minSubNorm_zero: coverpoint CFI.intermM iff (CFI.intermX == 0) { + type_option.weight = 0; + + // shift 1 into the ULP position, subtract one to be in the exclusive range (0 , minSubNorm) + bins btw_minSubNorm_zero = {[1 : ((INTERM_M_BITS'(1) << (INTERM_M_BITS - F64_M_BITS)) - 1)]}; + } + + F128_btw_minSubNorm_zero: coverpoint CFI.intermM iff (CFI.intermX == 0) { + type_option.weight = 0; + + // shift 1 into the ULP position, subtract one to be in the exclusive range (0 , minSubNorm) + bins btw_minSubNorm_zero = {[1 : ((INTERM_M_BITS'(1) << (INTERM_M_BITS - F128_M_BITS)) - 1)]}; + } + + F16_btw_minSubNorm_zero: coverpoint CFI.intermM iff (CFI.intermX == 0) { + type_option.weight = 0; + + // shift 1 into the ULP position, subtract one to be in the exclusive range (0 , minSubNorm) + bins btw_minSubNorm_zero = {[1 : ((INTERM_M_BITS'(1) << (INTERM_M_BITS - F16_M_BITS)) - 1)]}; + } + + BF16_btw_minSubNorm_zero: coverpoint CFI.intermM iff (CFI.intermX == 0) { + type_option.weight = 0; + + // shift 1 into the ULP position, subtract one to be in the exclusive range (0 , minSubNorm) + bins btw_minSubNorm_zero = {[1 : ((INTERM_M_BITS'(1) << (INTERM_M_BITS - BF16_M_BITS)) - 1)]}; + } + + // case ix + FP_minNorm_p5_exp_range: coverpoint CFI.intermX { + type_option.weight = 0; + + // minnorm.exp is 1 (unbiased) regardless of precision, so this covers the range [minnorm.exp , minnorm.exp + 5] + bins exp_range[] = {[1:6]}; + } + + `ifdef COVER_F32 + B18_case_i_f32: cross F32_src_fmt, FMA_ops, F32_product_lsb, F32_product_guard, F32_product_sticky, F32_interm_guard_zero, F32_interm_sticky_zero; + + B18_case_ii_b4_maxNorm_pm_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_maxNorm_pm_3ulp; + B18_case_ii_b4_gt_maxNorm_p_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_gt_maxNorm_p_3ulp; + B18_case_ii_b4_maxNorm_pm3_exp_range_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_maxNorm_pm3_exp_range; + + B18_case_iii_b5_subnorm_f32: cross F32_src_fmt, FMA_ops, F32_sign, FP_subnorm; + B18_case_iii_b5_minSubNorm_p_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_minSubNorm_p_3ulp; + B18_case_iii_b5_minSubNorm_m_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_minSubNorm_m_3ulp; + B18_case_iii_b5_minNorm_p_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_minNorm_p_3ulp; + B18_case_iii_b5_minNorm_m_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_minNorm_m_3ulp; + B18_case_iii_b5_btw_minSubNorm_zero_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_btw_minSubNorm_zero; + B18_case_iii_b5_minNorm_p5_exp_range_f32: cross F32_src_fmt, FMA_ops, FP_minNorm_p5_exp_range; // No Sign in Aharoni et al + `endif + + `ifdef COVER_F64 + B18_case_i_f64: cross F64_src_fmt, FMA_ops, F64_product_lsb, F64_product_guard, F64_product_sticky, F64_interm_guard_zero, F64_interm_sticky_zero; + + B18_case_ii_b4_maxNorm_pm_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_maxNorm_pm_3ulp; + B18_case_ii_b4_gt_maxNorm_p_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_gt_maxNorm_p_3ulp; + B18_case_ii_b4_maxNorm_pm3_exp_range_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_maxNorm_pm3_exp_range; + + B18_case_iii_b5_subnorm_f64: cross F64_src_fmt, FMA_ops, F64_sign, FP_subnorm; + B18_case_iii_b5_minSubNorm_p_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_minSubNorm_p_3ulp; + B18_case_iii_b5_minSubNorm_m_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_minSubNorm_m_3ulp; + B18_case_iii_b5_minNorm_p_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_minNorm_p_3ulp; + B18_case_iii_b5_minNorm_m_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_minNorm_m_3ulp; + B18_case_iii_b5_btw_minSubNorm_zero_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_btw_minSubNorm_zero; + B18_case_iii_b5_minNorm_p5_exp_range_f64: cross F64_src_fmt, FMA_ops, FP_minNorm_p5_exp_range; // No Sign in Aharoni et al + `endif + + `ifdef COVER_F128 + B18_case_i_f128: cross F128_src_fmt, FMA_ops, F128_product_lsb, F128_product_guard, F128_product_sticky, F128_interm_guard_zero, F128_interm_sticky_zero; + + B18_case_ii_b4_maxNorm_pm_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_maxNorm_pm_3ulp; + B18_case_ii_b4_gt_maxNorm_p_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_gt_maxNorm_p_3ulp; + B18_case_ii_b4_maxNorm_pm3_exp_range_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_maxNorm_pm3_exp_range; + + B18_case_iii_b5_subnorm_f128: cross F128_src_fmt, FMA_ops, F128_sign, FP_subnorm; + B18_case_iii_b5_minSubNorm_p_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_minSubNorm_p_3ulp; + B18_case_iii_b5_minSubNorm_m_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_minSubNorm_m_3ulp; + B18_case_iii_b5_minNorm_p_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_minNorm_p_3ulp; + B18_case_iii_b5_minNorm_m_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_minNorm_m_3ulp; + B18_case_iii_b5_btw_minSubNorm_zero_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_btw_minSubNorm_zero; + B18_case_iii_b5_minNorm_p5_exp_range_f128: cross F128_src_fmt, FMA_ops, FP_minNorm_p5_exp_range; // No Sign in Aharoni et al + `endif + + `ifdef COVER_F16 + B18_case_i_f16: cross F16_src_fmt, FMA_ops, F16_product_lsb, F16_product_guard, F16_product_sticky, F16_interm_guard_zero, F16_interm_sticky_zero; + + B18_case_ii_b4_maxNorm_pm_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_maxNorm_pm_3ulp; + B18_case_ii_b4_gt_maxNorm_p_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_gt_maxNorm_p_3ulp; + B18_case_ii_b4_maxNorm_pm3_exp_range_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_maxNorm_pm3_exp_range; + + B18_case_iii_b5_subnorm_f16: cross F16_src_fmt, FMA_ops, F16_sign, FP_subnorm; + B18_case_iii_b5_minSubNorm_p_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_minSubNorm_p_3ulp; + B18_case_iii_b5_minSubNorm_m_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_minSubNorm_m_3ulp; + B18_case_iii_b5_minNorm_p_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_minNorm_p_3ulp; + B18_case_iii_b5_minNorm_m_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_minNorm_m_3ulp; + B18_case_iii_b5_btw_minSubNorm_zero_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_btw_minSubNorm_zero; + B18_case_iii_b5_minNorm_p5_exp_range_f16: cross F16_src_fmt, FMA_ops, FP_minNorm_p5_exp_range; // No Sign in Aharoni et al + `endif + + `ifdef COVER_BF16 + B18_case_i_bf16: cross BF16_src_fmt, FMA_ops, BF16_product_lsb, BF16_product_guard, BF16_product_sticky, BF16_interm_guard_zero, BF16_interm_sticky_zero; + + B18_case_ii_b4_maxNorm_pm_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_maxNorm_pm_3ulp; + B18_case_ii_b4_gt_maxNorm_p_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_gt_maxNorm_p_3ulp; + B18_case_ii_b4_maxNorm_pm3_exp_range_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_maxNorm_pm3_exp_range; + + B18_case_iii_b5_subnorm_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, FP_subnorm; + B18_case_iii_b5_minSubNorm_p_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_minSubNorm_p_3ulp; + B18_case_iii_b5_minSubNorm_m_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_minSubNorm_m_3ulp; + B18_case_iii_b5_minNorm_p_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_minNorm_p_3ulp; + B18_case_iii_b5_minNorm_m_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_minNorm_m_3ulp; + B18_case_iii_b5_btw_minSubNorm_zero_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_btw_minSubNorm_zero; + B18_case_iii_b5_minNorm_p5_exp_range_bf16: cross BF16_src_fmt, FMA_ops, FP_minNorm_p5_exp_range; // No Sign in Aharoni et al + `endif + +endgroup From 6cb8959b7bfbe35de9874b6849e3a5cdeea51849 Mon Sep 17 00:00:00 2001 From: Ryan Wolk Date: Tue, 5 May 2026 17:12:33 -0700 Subject: [PATCH 2/7] Actually track pre addition information for B18 --- coverage/coverfloat_pkg.sv | 38 ++++ coverage/covergroups/B18.svh | 376 ++++++++++++++++++++++------------- 2 files changed, 274 insertions(+), 140 deletions(-) diff --git a/coverage/coverfloat_pkg.sv b/coverage/coverfloat_pkg.sv index e416068..e705925 100644 --- a/coverage/coverfloat_pkg.sv +++ b/coverage/coverfloat_pkg.sv @@ -204,6 +204,13 @@ package coverfloat_pkg; logic [111:0] one; } max_int_struct; + // Helpers for finding the first fractional digit in FMA_PreAddition + parameter int F32_FMA_PRE_ADDITION_NF = 2 * F32_M_BITS; + parameter int F64_FMA_PRE_ADDITION_NF = 2 * F64_M_BITS; + parameter int F128_FMA_PRE_ADDITION_NF = 2 * F128_M_BITS; + parameter int F16_FMA_PRE_ADDITION_NF = 2 * F16_M_BITS; + parameter int BF16_FMA_PRE_ADDITION_NF = 2 * BF16_M_BITS; + // Some Constants For B28 // This value seems like an odd choice ... because it is a trivial task for rfi, // it seems like the intention should be 1.1111 * 2^(precision-2) as that is the maximum value @@ -539,6 +546,37 @@ package coverfloat_pkg; endfunction + function automatic int get_effective_product_exponent( + input logic[127:0] a, + input logic[127:0] b, + input logic[255:0] pre_addition, + input logic [7:0] fmt + ); + int shift_one; + + case (fmt) + FMT_BF16: begin + shift_one = pre_addition[BF16_FMA_PRE_ADDITION_NF+1]; + end + FMT_HALF: begin + shift_one = pre_addition[F16_FMA_PRE_ADDITION_NF+1]; + end + FMT_SINGLE: begin + shift_one = pre_addition[F32_FMA_PRE_ADDITION_NF+1]; + end + FMT_DOUBLE: begin + shift_one = pre_addition[F64_FMA_PRE_ADDITION_NF+1]; + end + FMT_QUAD: begin + shift_one = pre_addition[F128_FMA_PRE_ADDITION_NF+1]; + end + endcase + + return get_product_exponent(a, b, fmt) + shift_one; + + endfunction + + function automatic int get_unbiased_exponent( input logic [127:0] input_val, input logic [7:0] fmt diff --git a/coverage/covergroups/B18.svh b/coverage/covergroups/B18.svh index efd2803..fcc07ed 100644 --- a/coverage/covergroups/B18.svh +++ b/coverage/covergroups/B18.svh @@ -214,98 +214,128 @@ covergroup B18_cg (virtual coverfloat_interface CFI); } /************************************************************************ - Underflow Boundary Helper Coverpoints (from B4, written by Corey Hickson) - ************************************************************************/ + * Overflow Boundary Helper Coverpoints (from B4, written by Corey Hickson) + ************************************************************************/ // cases i & ii - F32_maxNorm_pm_3ulp: coverpoint CFI.intermM[(INTERM_M_BITS - F32_M_BITS) -: 3] - iff (CFI.intermX == F32_MAXNORM_EXP && CFI.intermM[(INTERM_M_BITS - 1) -: F32_M_BITS - 1] == '1) { + F32_maxNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 1)], |CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 2) : 0]} + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) == F32_MAXNORM_EXP && CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - 1) -: F32_M_BITS - 1] == '1) { + type_option.weight = 0; + + bins maxNorm_pm_3ulp[] = {[2'b01 : 2'b11]}; + } + F32_maxNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS)], |CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 1) : 0]} // Minus one to the exponent means the ulp was shifted 1 to the left + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) == (F32_MAXNORM_EXP - 1) && CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - 1) -: F32_M_BITS] == '1) { type_option.weight = 0; - bins maxNorm_pm_3ulp[] = {[3'b001 : 3'b111]}; + bins maxNorm_pm_3ulp[] = {[2'b01 : 2'b11]}; } - F64_maxNorm_pm_3ulp: coverpoint CFI.intermM[(INTERM_M_BITS - F64_M_BITS) -: 3] - iff (CFI.intermX == F64_MAXNORM_EXP && CFI.intermM[(INTERM_M_BITS - 1) -: F64_M_BITS - 1] == '1) { + F64_maxNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 1)], |CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 2) : 0]} + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) == F64_MAXNORM_EXP && CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - 1) -: F64_M_BITS - 1] == '1) { type_option.weight = 0; - bins maxNorm_pm_3ulp[] = {[3'b001 : 3'b111]}; + bins maxNorm_pm_3ulp[] = {[2'b01 : 2'b11]}; } + F64_maxNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 1)], |CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 2) : 0]} // Minus one to the exponent means the ulp was shifted 1 to the left + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) == (F64_MAXNORM_EXP - 1) && CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - 1) -: F64_M_BITS] == '1) { + type_option.weight = 0; + + bins maxNorm_pm_3ulp[] = {[2'b01 : 2'b11]}; + } + + F128_maxNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 1)], |CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 2) : 0]} + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) == F128_MAXNORM_EXP && CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - 1) -: F128_M_BITS - 1] == '1) { + type_option.weight = 0; - F128_maxNorm_pm_3ulp: coverpoint CFI.intermM[(INTERM_M_BITS - F128_M_BITS) -: 3] - iff (CFI.intermX == F128_MAXNORM_EXP && CFI.intermM[(INTERM_M_BITS - 1) -: F128_M_BITS - 1] == '1) { + bins maxNorm_pm_3ulp[] = {[2'b01 : 2'b11]}; + } + F128_maxNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS)], |CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 1) : 0]} // Minus one to the exponent means the ulp was shifted 1 to the left + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) == (F128_MAXNORM_EXP - 1) && CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - 1) -: F128_M_BITS] == '1) { type_option.weight = 0; - bins maxNorm_pm_3ulp[] = {[3'b001 : 3'b111]}; + bins maxNorm_pm_3ulp[] = {[2'b01 : 2'b11]}; } - F16_maxNorm_pm_3ulp: coverpoint CFI.intermM[(INTERM_M_BITS - F16_M_BITS) -: 3] - iff (CFI.intermX == F16_MAXNORM_EXP && CFI.intermM[(INTERM_M_BITS - 1) -: F16_M_BITS - 1] == '1) { + F16_maxNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 1)], |CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 2) : 0]} + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) == F16_MAXNORM_EXP && CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - 1) -: F16_M_BITS - 1] == '1) { + type_option.weight = 0; + + bins maxNorm_pm_3ulp[] = {[2'b01 : 2'b11]}; + } + F16_maxNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS)], |CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 1) : 0]} // Minus one to the exponent means the ulp was shifted 1 to the left + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) == (F16_MAXNORM_EXP - 1) && CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - 1) -: F16_M_BITS] == '1) { type_option.weight = 0; - bins maxNorm_pm_3ulp[] = {[3'b001 : 3'b111]}; + bins maxNorm_pm_3ulp[] = {[2'b01 : 2'b11]}; } - BF16_maxNorm_pm_3ulp: coverpoint CFI.intermM[(INTERM_M_BITS - BF16_M_BITS) -: 3] - iff (CFI.intermX == BF16_MAXNORM_EXP && CFI.intermM[(INTERM_M_BITS - 1) -: BF16_M_BITS - 1] == '1) { + BF16_maxNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 1)], |CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 2) : 0]} + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) == BF16_MAXNORM_EXP && CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - 1) -: BF16_M_BITS - 1] == '1) { type_option.weight = 0; - bins maxNorm_pm_3ulp[] = {[3'b001 : 3'b111]}; + bins maxNorm_pm_3ulp[] = {[2'b01 : 2'b11]}; } + BF16_maxNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS)], |CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 1) : 0]} // Minus one to the exponent means the ulp was shifted 1 to the left + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) == (BF16_MAXNORM_EXP - 1) && CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - 1) -: BF16_M_BITS] == '1) { + type_option.weight = 0; - // cases vii & viii - F32_gt_maxNorm_p_3ulp: coverpoint CFI.intermM iff (CFI.intermX == F32_MAXNORM_EXP) { + bins maxNorm_pm_3ulp[] = {[2'b01 : 2'b11]}; + } + + // cases iii & iv + F32_gt_maxNorm_p_3ulp: coverpoint CFI.fmaPreAddition iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) == F32_MAXNORM_EXP) { type_option.weight = 0; - bins gt_maxNorm = {[ ('1 << (INTERM_M_BITS - F32_M_BITS - 2)) : $]}; + bins gt_maxNorm = {[ ('1 << (F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 2)) : $]}; } - F64_gt_maxNorm_p_3ulp: coverpoint CFI.intermM iff (CFI.intermX == F64_MAXNORM_EXP) { + F64_gt_maxNorm_p_3ulp: coverpoint CFI.fmaPreAddition iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) == F64_MAXNORM_EXP) { type_option.weight = 0; - bins gt_maxNorm = {[ ('1 << (INTERM_M_BITS - F64_M_BITS - 2)) : $]}; + bins gt_maxNorm = {[ ('1 << (F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 2)) : $]}; } - F128_gt_maxNorm_p_3ulp: coverpoint CFI.intermM iff (CFI.intermX == F128_MAXNORM_EXP) { + F128_gt_maxNorm_p_3ulp: coverpoint CFI.fmaPreAddition iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) == F128_MAXNORM_EXP) { type_option.weight = 0; - bins gt_maxNorm = {[ ('1 << (INTERM_M_BITS - F128_M_BITS - 2)) : $]}; + bins gt_maxNorm = {[ ('1 << (F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 2)) : $]}; } - F16_gt_maxNorm_p_3ulp: coverpoint CFI.intermM iff (CFI.intermX == F16_MAXNORM_EXP) { + F16_gt_maxNorm_p_3ulp: coverpoint CFI.fmaPreAddition iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) == F16_MAXNORM_EXP) { type_option.weight = 0; - bins gt_maxNorm = {[ ('1 << (INTERM_M_BITS - F16_M_BITS - 2)) : $]}; + bins gt_maxNorm = {[ ('1 << (F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 2)) : $]}; } - BF16_gt_maxNorm_p_3ulp: coverpoint CFI.intermM iff (CFI.intermX == BF16_MAXNORM_EXP) { + BF16_gt_maxNorm_p_3ulp: coverpoint CFI.fmaPreAddition iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) == BF16_MAXNORM_EXP) { type_option.weight = 0; - bins gt_maxNorm = {[ ('1 << (INTERM_M_BITS - BF16_M_BITS - 2)) : $]}; + bins gt_maxNorm = {[ ('1 << (BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 2)) : $]}; } // case v - F32_maxNorm_pm3_exp_range: coverpoint CFI.intermX { + F32_maxNorm_pm3_exp_range: coverpoint get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) { type_option.weight = 0; bins exp_range[] = {[ F32_MAXNORM_EXP - 3 : F32_MAXNORM_EXP + 3 ]}; } - F64_maxNorm_pm3_exp_range: coverpoint CFI.intermX { + F64_maxNorm_pm3_exp_range: coverpoint get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) { type_option.weight = 0; bins exp_range[] = {[ F64_MAXNORM_EXP - 3 : F64_MAXNORM_EXP + 3 ]}; } - F128_maxNorm_pm3_exp_range: coverpoint CFI.intermX { + F128_maxNorm_pm3_exp_range: coverpoint get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) { type_option.weight = 0; bins exp_range[] = {[ F128_MAXNORM_EXP - 3 : F128_MAXNORM_EXP + 3 ]}; } - F16_maxNorm_pm3_exp_range: coverpoint CFI.intermX { + F16_maxNorm_pm3_exp_range: coverpoint get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) { type_option.weight = 0; bins exp_range[] = {[ F16_MAXNORM_EXP - 3 : F16_MAXNORM_EXP + 3 ]}; } - BF16_maxNorm_pm3_exp_range: coverpoint CFI.intermX { + BF16_maxNorm_pm3_exp_range: coverpoint get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) { type_option.weight = 0; bins exp_range[] = {[ BF16_MAXNORM_EXP - 3 : BF16_MAXNORM_EXP + 3 ]}; @@ -317,7 +347,27 @@ covergroup B18_cg (virtual coverfloat_interface CFI); ************************************************************************/ // cases i & ii - FP_subnorm: coverpoint (CFI.intermX == 0 && CFI.intermM != 0) { + F32_subnorm: coverpoint (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) <= 0 && CFI.fmaPreAddition != 0) { + type_option.weight = 0; + + bins subnorm = {1}; + } + F64_subnorm: coverpoint (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) <= 0 && CFI.fmaPreAddition != 0) { + type_option.weight = 0; + + bins subnorm = {1}; + } + F128_subnorm: coverpoint (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) <= 0 && CFI.fmaPreAddition != 0) { + type_option.weight = 0; + + bins subnorm = {1}; + } + F16_subnorm: coverpoint (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) <= 0 && CFI.fmaPreAddition != 0) { + type_option.weight = 0; + + bins subnorm = {1}; + } + BF16_subnorm: coverpoint (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) <= 0 && CFI.fmaPreAddition != 0) { type_option.weight = 0; bins subnorm = {1}; @@ -326,90 +376,90 @@ covergroup B18_cg (virtual coverfloat_interface CFI); // cases iii & iv // Guard bit sticky bit - F32_minSubNorm_p_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F32_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F32_M_BITS - 2) : 0]} + F32_minSubNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 1)], |CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 2) : 0]} // implicit leading 0 (subnorm) single 1 in LSB (except for Guard and sticky) - iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -: F32_M_BITS +1] == 1) { + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) <= 0 && CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF -: F32_M_BITS +1] == 1) { type_option.weight = 0; bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; } // Guard bit sticky bit - F32_minSubNorm_m_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F32_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F32_M_BITS - 2) : 0]} + F32_minSubNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 1)], |CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 2) : 0]} // implicit leading 0 (subnorm) all zeros fraction (except for Guard and sticky) - iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -: F32_M_BITS +1] == 0) { + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) <= 0 && CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF -: F32_M_BITS +1] == 0) { type_option.weight = 0; bins minSubNorm_m_3ulp[] = {[2'b01 : 2'b11]}; } // Guard bit sticky bit - F64_minSubNorm_p_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F64_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F64_M_BITS - 2) : 0]} + F64_minSubNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 1)], |CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 2) : 0]} // implicit leading 0 (subnorm) single 1 in LSB (except for Guard and sticky) - iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -: F64_M_BITS +1] == 1) { + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) <= 0 && CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF -: F64_M_BITS +1] == 1) { type_option.weight = 0; bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; } // Guard bit sticky bit - F64_minSubNorm_m_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F64_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F64_M_BITS - 2) : 0]} + F64_minSubNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 1)], |CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 2) : 0]} // implicit leading 0 (subnorm) all zeros fraction (except for Guard and sticky) - iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -: F64_M_BITS +1] == 0) { + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) <= 0 && CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF -: F64_M_BITS +1] == 0) { type_option.weight = 0; bins minSubNorm_m_3ulp[] = {[2'b01 : 2'b11]}; } // Guard bit sticky bit - F128_minSubNorm_p_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F128_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F128_M_BITS - 2) : 0]} + F128_minSubNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 1)], |CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 2) : 0]} // implicit leading 0 (subnorm) single 1 in LSB (except for Guard and sticky) - iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -: F128_M_BITS +1] == 1) { + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) <= 0 && CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF -: F128_M_BITS +1] == 1) { type_option.weight = 0; bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; } // Guard bit sticky bit - F128_minSubNorm_m_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F128_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F128_M_BITS - 2) : 0]} + F128_minSubNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 1)], |CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 2) : 0]} // implicit leading 0 (subnorm) all zeros fraction (except for Guard and sticky) - iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -: F128_M_BITS +1] == 0) { + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) <= 0 && CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF -: F128_M_BITS +1] == 0) { type_option.weight = 0; bins minSubNorm_m_3ulp[] = {[2'b01 : 2'b11]}; } // Guard bit sticky bit - F16_minSubNorm_p_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F16_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F16_M_BITS - 2) : 0]} + F16_minSubNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 1)], |CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 2) : 0]} // implicit leading 0 (subnorm) single 1 in LSB (except for Guard and sticky) - iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -: F16_M_BITS +1] == 1) { + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) <= 0 && CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF -: F16_M_BITS +1] == 1) { type_option.weight = 0; bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; } // Guard bit sticky bit - F16_minSubNorm_m_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F16_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F16_M_BITS - 2) : 0]} + F16_minSubNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 1)], |CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 2) : 0]} // implicit leading 0 (subnorm) all zeros fraction (except for Guard and sticky) - iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -: F16_M_BITS +1] == 0) { + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) <= 0 && CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF -: F16_M_BITS +1] == 0) { type_option.weight = 0; bins minSubNorm_m_3ulp[] = {[2'b01 : 2'b11]}; } // Guard bit sticky bit - BF16_minSubNorm_p_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - BF16_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - BF16_M_BITS - 2) : 0]} + BF16_minSubNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 1)], |CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 2) : 0]} // implicit leading 0 (subnorm) single 1 in LSB (except for Guard and sticky) - iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -: BF16_M_BITS +1] == 1) { + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) <= 0 && CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF -: BF16_M_BITS +1] == 1) { type_option.weight = 0; bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; } // Guard bit sticky bit - BF16_minSubNorm_m_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - BF16_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - BF16_M_BITS - 2) : 0]} + BF16_minSubNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 1)], |CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 2) : 0]} // implicit leading 0 (subnorm) all zeros fraction (except for Guard and sticky) - iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -: BF16_M_BITS +1] == 0) { + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) <= 0 && CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF -: BF16_M_BITS +1] == 0) { type_option.weight = 0; bins minSubNorm_m_3ulp[] = {[2'b01 : 2'b11]}; @@ -418,90 +468,90 @@ covergroup B18_cg (virtual coverfloat_interface CFI); // cases v & vi // Guard bit sticky bit - F32_minNorm_p_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F32_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F32_M_BITS - 2) : 0]} + F32_minNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 1)], |CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 2) : 0]} // implicit leading 1 (norm) all zero fraction (except for Guard and sticky) - iff (CFI.intermX != 0 && CFI.intermM[INTERM_M_BITS -1 -: F32_M_BITS] == 0) { + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) != 0 && CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF -1 -: F32_M_BITS] == 0) { type_option.weight = 0; bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; } // Guard bit sticky bit - F32_minNorm_m_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F32_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F32_M_BITS - 2) : 0]} + F32_minNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 1)], |CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 2) : 0]} // implicit leading 0 (subnorm) all ones fraction (except for Guard and sticky) - iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -1 -: F32_M_BITS] == '1) { + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) <= 0 && CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF -1 -: F32_M_BITS] == '1) { type_option.weight = 0; bins minNorm_m_3ulp[] = {[2'b01 : 2'b11]}; } // Guard bit sticky bit - F64_minNorm_p_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F64_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F64_M_BITS - 2) : 0]} + F64_minNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 1)], |CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 2) : 0]} // implicit leading 1 (norm) all zero fraction (except for Guard and sticky) - iff (CFI.intermX != 0 && CFI.intermM[INTERM_M_BITS -1 -: F64_M_BITS] == 0) { + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) != 0 && CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF -1 -: F64_M_BITS] == 0) { type_option.weight = 0; bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; } // Guard bit sticky bit - F64_minNorm_m_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F64_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F64_M_BITS - 2) : 0]} + F64_minNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 1)], |CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 2) : 0]} // implicit leading 0 (subnorm) all ones fraction (except for Guard and sticky) - iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -1 -: F64_M_BITS] == '1) { + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) <= 0 && CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF -1 -: F64_M_BITS] == '1) { type_option.weight = 0; bins minNorm_m_3ulp[] = {[2'b01 : 2'b11]}; } // Guard bit sticky bit - F128_minNorm_p_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F128_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F128_M_BITS - 2) : 0]} + F128_minNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 1)], |CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 2) : 0]} // implicit leading 1 (norm) all zero fraction (except for Guard and sticky) - iff (CFI.intermX != 0 && CFI.intermM[INTERM_M_BITS -1 -: F128_M_BITS] == 0) { + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) != 0 && CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF -1 -: F128_M_BITS] == 0) { type_option.weight = 0; bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; } // Guard bit sticky bit - F128_minNorm_m_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F128_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F128_M_BITS - 2) : 0]} + F128_minNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 1)], |CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 2) : 0]} // implicit leading 0 (subnorm) all ones fraction (except for Guard and sticky) - iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -1 -: F128_M_BITS] == '1) { + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) <= 0 && CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF -1 -: F128_M_BITS] == '1) { type_option.weight = 0; bins minNorm_m_3ulp[] = {[2'b01 : 2'b11]}; } // Guard bit sticky bit - F16_minNorm_p_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F16_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F16_M_BITS - 2) : 0]} + F16_minNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 1)], |CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 2) : 0]} // implicit leading 1 (norm) all zero fraction (except for Guard and sticky) - iff (CFI.intermX != 0 && CFI.intermM[INTERM_M_BITS -1 -: F16_M_BITS] == 0) { + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) != 0 && CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF -1 -: F16_M_BITS] == 0) { type_option.weight = 0; bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; } // Guard bit sticky bit - F16_minNorm_m_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - F16_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - F16_M_BITS - 2) : 0]} + F16_minNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 1)], |CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 2) : 0]} // implicit leading 0 (subnorm) all ones fraction (except for Guard and sticky) - iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -1 -: F16_M_BITS] == '1) { + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) <= 0 && CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF -1 -: F16_M_BITS] == '1) { type_option.weight = 0; bins minNorm_m_3ulp[] = {[2'b01 : 2'b11]}; } // Guard bit sticky bit - BF16_minNorm_p_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - BF16_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - BF16_M_BITS - 2) : 0]} + BF16_minNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 1)], |CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 2) : 0]} // implicit leading 1 (norm) all zero fraction (except for Guard and sticky) - iff (CFI.intermX != 0 && CFI.intermM[INTERM_M_BITS -1 -: BF16_M_BITS] == 0) { + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) != 0 && CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF -1 -: BF16_M_BITS] == 0) { type_option.weight = 0; bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; } // Guard bit sticky bit - BF16_minNorm_m_3ulp: coverpoint {CFI.intermM[(INTERM_M_BITS - BF16_M_BITS - 1)], |CFI.intermM[(INTERM_M_BITS - BF16_M_BITS - 2) : 0]} + BF16_minNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 1)], |CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 2) : 0]} // implicit leading 0 (subnorm) all ones fraction (except for Guard and sticky) - iff (CFI.intermX == 0 && CFI.intermM[INTERM_M_BITS -1 -: BF16_M_BITS] == '1) { + iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) <= 0 && CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF -1 -: BF16_M_BITS] == '1) { type_option.weight = 0; bins minNorm_m_3ulp[] = {[2'b01 : 2'b11]}; @@ -509,127 +559,173 @@ covergroup B18_cg (virtual coverfloat_interface CFI); // cases vii & viii - F32_btw_minSubNorm_zero: coverpoint CFI.intermM iff (CFI.intermX == 0) { + F32_btw_minSubNorm_zero: coverpoint CFI.fmaPreAddition iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) <= 0) { type_option.weight = 0; // shift 1 into the ULP position, subtract one to be in the exclusive range (0 , minSubNorm) - bins btw_minSubNorm_zero = {[1 : ((INTERM_M_BITS'(1) << (INTERM_M_BITS - F32_M_BITS)) - 1)]}; + bins btw_minSubNorm_zero = {[1 : ((F32_FMA_PRE_ADDITION_NF'(1) << (F32_FMA_PRE_ADDITION_NF - F32_M_BITS)) - 1)]}; } - F64_btw_minSubNorm_zero: coverpoint CFI.intermM iff (CFI.intermX == 0) { + F64_btw_minSubNorm_zero: coverpoint CFI.fmaPreAddition iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) <= 0) { type_option.weight = 0; // shift 1 into the ULP position, subtract one to be in the exclusive range (0 , minSubNorm) - bins btw_minSubNorm_zero = {[1 : ((INTERM_M_BITS'(1) << (INTERM_M_BITS - F64_M_BITS)) - 1)]}; + bins btw_minSubNorm_zero = {[1 : ((F64_FMA_PRE_ADDITION_NF'(1) << (F64_FMA_PRE_ADDITION_NF - F64_M_BITS)) - 1)]}; } - F128_btw_minSubNorm_zero: coverpoint CFI.intermM iff (CFI.intermX == 0) { + F128_btw_minSubNorm_zero: coverpoint CFI.fmaPreAddition iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) <= 0) { type_option.weight = 0; // shift 1 into the ULP position, subtract one to be in the exclusive range (0 , minSubNorm) - bins btw_minSubNorm_zero = {[1 : ((INTERM_M_BITS'(1) << (INTERM_M_BITS - F128_M_BITS)) - 1)]}; + bins btw_minSubNorm_zero = {[1 : ((F128_FMA_PRE_ADDITION_NF'(1) << (F128_FMA_PRE_ADDITION_NF - F128_M_BITS)) - 1)]}; } - F16_btw_minSubNorm_zero: coverpoint CFI.intermM iff (CFI.intermX == 0) { + F16_btw_minSubNorm_zero: coverpoint CFI.fmaPreAddition iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) <= 0) { type_option.weight = 0; // shift 1 into the ULP position, subtract one to be in the exclusive range (0 , minSubNorm) - bins btw_minSubNorm_zero = {[1 : ((INTERM_M_BITS'(1) << (INTERM_M_BITS - F16_M_BITS)) - 1)]}; + bins btw_minSubNorm_zero = {[1 : ((F16_FMA_PRE_ADDITION_NF'(1) << (F16_FMA_PRE_ADDITION_NF - F16_M_BITS)) - 1)]}; } - BF16_btw_minSubNorm_zero: coverpoint CFI.intermM iff (CFI.intermX == 0) { + BF16_btw_minSubNorm_zero: coverpoint CFI.fmaPreAddition iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) <= 0) { type_option.weight = 0; // shift 1 into the ULP position, subtract one to be in the exclusive range (0 , minSubNorm) - bins btw_minSubNorm_zero = {[1 : ((INTERM_M_BITS'(1) << (INTERM_M_BITS - BF16_M_BITS)) - 1)]}; + bins btw_minSubNorm_zero = {[1 : ((BF16_FMA_PRE_ADDITION_NF'(1) << (BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS)) - 1)]}; } // case ix - FP_minNorm_p5_exp_range: coverpoint CFI.intermX { + F32_minNorm_p5_exp_range: coverpoint get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) { + type_option.weight = 0; + + // minnorm.exp is 1 (unbiased) regardless of precision, so this covers the range [minnorm.exp , minnorm.exp + 5] + bins exp_range[] = {[1:6]}; + } + F64_minNorm_p5_exp_range: coverpoint get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) { + type_option.weight = 0; + + // minnorm.exp is 1 (unbiased) regardless of precision, so this covers the range [minnorm.exp , minnorm.exp + 5] + bins exp_range[] = {[1:6]}; + } + F128_minNorm_p5_exp_range: coverpoint get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) { + type_option.weight = 0; + + // minnorm.exp is 1 (unbiased) regardless of precision, so this covers the range [minnorm.exp , minnorm.exp + 5] + bins exp_range[] = {[1:6]}; + } + F16_minNorm_p5_exp_range: coverpoint get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) { + type_option.weight = 0; + + // minnorm.exp is 1 (unbiased) regardless of precision, so this covers the range [minnorm.exp , minnorm.exp + 5] + bins exp_range[] = {[1:6]}; + } + BF16_minNorm_p5_exp_range: coverpoint get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) { type_option.weight = 0; // minnorm.exp is 1 (unbiased) regardless of precision, so this covers the range [minnorm.exp , minnorm.exp + 5] bins exp_range[] = {[1:6]}; } + /**************************************************** + * Coverpoints to detect overflow and underflow flags + ****************************************************/ + + FP_no_overflow: coverpoint (CFI.exceptionBits & FLAG_OVERFLOW_MASK) { + type_option.weight = 0; + + bins no_overflow = { 0 }; + } + + FP_no_underflow: coverpoint (CFI.exceptionBits & FLAG_OVERFLOW_MASK) { + type_option.weight = 0; + + bins no_overflow = { 0 }; + } + + `ifdef COVER_F32 B18_case_i_f32: cross F32_src_fmt, FMA_ops, F32_product_lsb, F32_product_guard, F32_product_sticky, F32_interm_guard_zero, F32_interm_sticky_zero; - B18_case_ii_b4_maxNorm_pm_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_maxNorm_pm_3ulp; - B18_case_ii_b4_gt_maxNorm_p_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_gt_maxNorm_p_3ulp; - B18_case_ii_b4_maxNorm_pm3_exp_range_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_maxNorm_pm3_exp_range; - - B18_case_iii_b5_subnorm_f32: cross F32_src_fmt, FMA_ops, F32_sign, FP_subnorm; - B18_case_iii_b5_minSubNorm_p_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_minSubNorm_p_3ulp; - B18_case_iii_b5_minSubNorm_m_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_minSubNorm_m_3ulp; - B18_case_iii_b5_minNorm_p_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_minNorm_p_3ulp; - B18_case_iii_b5_minNorm_m_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_minNorm_m_3ulp; - B18_case_iii_b5_btw_minSubNorm_zero_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_btw_minSubNorm_zero; - B18_case_iii_b5_minNorm_p5_exp_range_f32: cross F32_src_fmt, FMA_ops, FP_minNorm_p5_exp_range; // No Sign in Aharoni et al + B18_case_ii_b4_maxNorm_p_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_maxNorm_p_3ulp, FP_no_overflow; + B18_case_ii_b4_maxNorm_m_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_maxNorm_m_3ulp, FP_no_overflow; + B18_case_ii_b4_gt_maxNorm_p_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_gt_maxNorm_p_3ulp, FP_no_overflow; + B18_case_ii_b4_maxNorm_pm3_exp_range_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_maxNorm_pm3_exp_range, FP_no_overflow; + + B18_case_iii_b5_subnorm_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_subnorm, FP_no_underflow; + B18_case_iii_b5_minSubNorm_p_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_minSubNorm_p_3ulp, FP_no_underflow; + B18_case_iii_b5_minSubNorm_m_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_minSubNorm_m_3ulp, FP_no_underflow; + B18_case_iii_b5_minNorm_p_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_minNorm_p_3ulp, FP_no_underflow; + B18_case_iii_b5_minNorm_m_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_minNorm_m_3ulp, FP_no_underflow; + B18_case_iii_b5_btw_minSubNorm_zero_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_btw_minSubNorm_zero, FP_no_underflow; + B18_case_iii_b5_minNorm_p5_exp_range_f32: cross F32_src_fmt, FMA_ops, F32_minNorm_p5_exp_range, FP_no_underflow; // No Sign in Aharoni et al `endif `ifdef COVER_F64 B18_case_i_f64: cross F64_src_fmt, FMA_ops, F64_product_lsb, F64_product_guard, F64_product_sticky, F64_interm_guard_zero, F64_interm_sticky_zero; - B18_case_ii_b4_maxNorm_pm_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_maxNorm_pm_3ulp; - B18_case_ii_b4_gt_maxNorm_p_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_gt_maxNorm_p_3ulp; - B18_case_ii_b4_maxNorm_pm3_exp_range_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_maxNorm_pm3_exp_range; - - B18_case_iii_b5_subnorm_f64: cross F64_src_fmt, FMA_ops, F64_sign, FP_subnorm; - B18_case_iii_b5_minSubNorm_p_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_minSubNorm_p_3ulp; - B18_case_iii_b5_minSubNorm_m_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_minSubNorm_m_3ulp; - B18_case_iii_b5_minNorm_p_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_minNorm_p_3ulp; - B18_case_iii_b5_minNorm_m_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_minNorm_m_3ulp; - B18_case_iii_b5_btw_minSubNorm_zero_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_btw_minSubNorm_zero; - B18_case_iii_b5_minNorm_p5_exp_range_f64: cross F64_src_fmt, FMA_ops, FP_minNorm_p5_exp_range; // No Sign in Aharoni et al + B18_case_ii_b4_maxNorm_p_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_maxNorm_p_3ulp, FP_no_overflow; + B18_case_ii_b4_maxNorm_m_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_maxNorm_m_3ulp, FP_no_overflow; + B18_case_ii_b4_gt_maxNorm_p_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_gt_maxNorm_p_3ulp, FP_no_overflow; + B18_case_ii_b4_maxNorm_pm3_exp_range_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_maxNorm_pm3_exp_range, FP_no_overflow; + + B18_case_iii_b5_subnorm_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_subnorm, FP_no_underflow; + B18_case_iii_b5_minSubNorm_p_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_minSubNorm_p_3ulp, FP_no_underflow; + B18_case_iii_b5_minSubNorm_m_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_minSubNorm_m_3ulp, FP_no_underflow; + B18_case_iii_b5_minNorm_p_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_minNorm_p_3ulp, FP_no_underflow; + B18_case_iii_b5_minNorm_m_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_minNorm_m_3ulp, FP_no_underflow; + B18_case_iii_b5_btw_minSubNorm_zero_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_btw_minSubNorm_zero, FP_no_underflow; + B18_case_iii_b5_minNorm_p5_exp_range_f64: cross F64_src_fmt, FMA_ops, F64_minNorm_p5_exp_range, FP_no_underflow; // No Sign in Aharoni et al `endif `ifdef COVER_F128 B18_case_i_f128: cross F128_src_fmt, FMA_ops, F128_product_lsb, F128_product_guard, F128_product_sticky, F128_interm_guard_zero, F128_interm_sticky_zero; - B18_case_ii_b4_maxNorm_pm_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_maxNorm_pm_3ulp; - B18_case_ii_b4_gt_maxNorm_p_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_gt_maxNorm_p_3ulp; - B18_case_ii_b4_maxNorm_pm3_exp_range_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_maxNorm_pm3_exp_range; - - B18_case_iii_b5_subnorm_f128: cross F128_src_fmt, FMA_ops, F128_sign, FP_subnorm; - B18_case_iii_b5_minSubNorm_p_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_minSubNorm_p_3ulp; - B18_case_iii_b5_minSubNorm_m_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_minSubNorm_m_3ulp; - B18_case_iii_b5_minNorm_p_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_minNorm_p_3ulp; - B18_case_iii_b5_minNorm_m_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_minNorm_m_3ulp; - B18_case_iii_b5_btw_minSubNorm_zero_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_btw_minSubNorm_zero; - B18_case_iii_b5_minNorm_p5_exp_range_f128: cross F128_src_fmt, FMA_ops, FP_minNorm_p5_exp_range; // No Sign in Aharoni et al + B18_case_ii_b4_maxNorm_p_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_maxNorm_p_3ulp, FP_no_overflow; + B18_case_ii_b4_maxNorm_m_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_maxNorm_m_3ulp, FP_no_overflow; + B18_case_ii_b4_gt_maxNorm_p_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_gt_maxNorm_p_3ulp, FP_no_overflow; + B18_case_ii_b4_maxNorm_pm3_exp_range_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_maxNorm_pm3_exp_range, FP_no_overflow; + + B18_case_iii_b5_subnorm_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_subnorm, FP_no_underflow; + B18_case_iii_b5_minSubNorm_p_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_minSubNorm_p_3ulp, FP_no_underflow; + B18_case_iii_b5_minSubNorm_m_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_minSubNorm_m_3ulp, FP_no_underflow; + B18_case_iii_b5_minNorm_p_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_minNorm_p_3ulp, FP_no_underflow; + B18_case_iii_b5_minNorm_m_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_minNorm_m_3ulp, FP_no_underflow; + B18_case_iii_b5_btw_minSubNorm_zero_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_btw_minSubNorm_zero, FP_no_underflow; + B18_case_iii_b5_minNorm_p5_exp_range_f128: cross F128_src_fmt, FMA_ops, F128_minNorm_p5_exp_range, FP_no_underflow; // No Sign in Aharoni et al `endif `ifdef COVER_F16 B18_case_i_f16: cross F16_src_fmt, FMA_ops, F16_product_lsb, F16_product_guard, F16_product_sticky, F16_interm_guard_zero, F16_interm_sticky_zero; - B18_case_ii_b4_maxNorm_pm_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_maxNorm_pm_3ulp; - B18_case_ii_b4_gt_maxNorm_p_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_gt_maxNorm_p_3ulp; - B18_case_ii_b4_maxNorm_pm3_exp_range_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_maxNorm_pm3_exp_range; - - B18_case_iii_b5_subnorm_f16: cross F16_src_fmt, FMA_ops, F16_sign, FP_subnorm; - B18_case_iii_b5_minSubNorm_p_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_minSubNorm_p_3ulp; - B18_case_iii_b5_minSubNorm_m_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_minSubNorm_m_3ulp; - B18_case_iii_b5_minNorm_p_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_minNorm_p_3ulp; - B18_case_iii_b5_minNorm_m_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_minNorm_m_3ulp; - B18_case_iii_b5_btw_minSubNorm_zero_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_btw_minSubNorm_zero; - B18_case_iii_b5_minNorm_p5_exp_range_f16: cross F16_src_fmt, FMA_ops, FP_minNorm_p5_exp_range; // No Sign in Aharoni et al + B18_case_ii_b4_maxNorm_p_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_maxNorm_p_3ulp, FP_no_overflow; + B18_case_ii_b4_maxNorm_m_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_maxNorm_m_3ulp, FP_no_overflow; + B18_case_ii_b4_gt_maxNorm_p_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_gt_maxNorm_p_3ulp, FP_no_overflow; + B18_case_ii_b4_maxNorm_pm3_exp_range_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_maxNorm_pm3_exp_range, FP_no_overflow; + + B18_case_iii_b5_subnorm_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_subnorm, FP_no_underflow; + B18_case_iii_b5_minSubNorm_p_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_minSubNorm_p_3ulp, FP_no_underflow; + B18_case_iii_b5_minSubNorm_m_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_minSubNorm_m_3ulp, FP_no_underflow; + B18_case_iii_b5_minNorm_p_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_minNorm_p_3ulp, FP_no_underflow; + B18_case_iii_b5_minNorm_m_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_minNorm_m_3ulp, FP_no_underflow; + B18_case_iii_b5_btw_minSubNorm_zero_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_btw_minSubNorm_zero, FP_no_underflow; + B18_case_iii_b5_minNorm_p5_exp_range_f16: cross F16_src_fmt, FMA_ops, F16_minNorm_p5_exp_range, FP_no_underflow; // No Sign in Aharoni et al `endif `ifdef COVER_BF16 B18_case_i_bf16: cross BF16_src_fmt, FMA_ops, BF16_product_lsb, BF16_product_guard, BF16_product_sticky, BF16_interm_guard_zero, BF16_interm_sticky_zero; - B18_case_ii_b4_maxNorm_pm_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_maxNorm_pm_3ulp; - B18_case_ii_b4_gt_maxNorm_p_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_gt_maxNorm_p_3ulp; - B18_case_ii_b4_maxNorm_pm3_exp_range_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_maxNorm_pm3_exp_range; - - B18_case_iii_b5_subnorm_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, FP_subnorm; - B18_case_iii_b5_minSubNorm_p_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_minSubNorm_p_3ulp; - B18_case_iii_b5_minSubNorm_m_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_minSubNorm_m_3ulp; - B18_case_iii_b5_minNorm_p_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_minNorm_p_3ulp; - B18_case_iii_b5_minNorm_m_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_minNorm_m_3ulp; - B18_case_iii_b5_btw_minSubNorm_zero_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_btw_minSubNorm_zero; - B18_case_iii_b5_minNorm_p5_exp_range_bf16: cross BF16_src_fmt, FMA_ops, FP_minNorm_p5_exp_range; // No Sign in Aharoni et al + B18_case_ii_b4_maxNorm_p_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_maxNorm_p_3ulp, FP_no_overflow; + B18_case_ii_b4_maxNorm_m_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_maxNorm_m_3ulp, FP_no_overflow; + B18_case_ii_b4_gt_maxNorm_p_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_gt_maxNorm_p_3ulp, FP_no_overflow; + B18_case_ii_b4_maxNorm_pm3_exp_range_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_maxNorm_pm3_exp_range, FP_no_overflow; + + B18_case_iii_b5_subnorm_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_subnorm, FP_no_underflow; + B18_case_iii_b5_minSubNorm_p_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_minSubNorm_p_3ulp, FP_no_underflow; + B18_case_iii_b5_minSubNorm_m_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_minSubNorm_m_3ulp, FP_no_underflow; + B18_case_iii_b5_minNorm_p_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_minNorm_p_3ulp, FP_no_underflow; + B18_case_iii_b5_minNorm_m_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_minNorm_m_3ulp, FP_no_underflow; + B18_case_iii_b5_btw_minSubNorm_zero_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_btw_minSubNorm_zero, FP_no_underflow; + B18_case_iii_b5_minNorm_p5_exp_range_bf16: cross BF16_src_fmt, FMA_ops, BF16_minNorm_p5_exp_range, FP_no_underflow; // No Sign in Aharoni et al `endif endgroup From ed5772e59ff886ad83ee7e9719781103ed7d9f42 Mon Sep 17 00:00:00 2001 From: Ryan Wolk Date: Tue, 5 May 2026 17:15:01 -0700 Subject: [PATCH 3/7] Correct no underflow coverpoint --- coverage/covergroups/B18.svh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coverage/covergroups/B18.svh b/coverage/covergroups/B18.svh index fcc07ed..b2f56a5 100644 --- a/coverage/covergroups/B18.svh +++ b/coverage/covergroups/B18.svh @@ -636,7 +636,7 @@ covergroup B18_cg (virtual coverfloat_interface CFI); bins no_overflow = { 0 }; } - FP_no_underflow: coverpoint (CFI.exceptionBits & FLAG_OVERFLOW_MASK) { + FP_no_underflow: coverpoint (CFI.exceptionBits & FLAG_UNDERFLOW_MASK) { type_option.weight = 0; bins no_overflow = { 0 }; From e4d453cf9f5d8caa4b6783204ff68a67733e21c6 Mon Sep 17 00:00:00 2001 From: Ryan Wolk Date: Tue, 5 May 2026 19:42:10 -0700 Subject: [PATCH 4/7] Correct Coverage for B5 Cases --- coverage/coverfloat_pkg.sv | 35 ++- coverage/covergroups/B18.svh | 431 +++++++++++++++++++++-------------- 2 files changed, 284 insertions(+), 182 deletions(-) diff --git a/coverage/coverfloat_pkg.sv b/coverage/coverfloat_pkg.sv index e705925..860ed97 100644 --- a/coverage/coverfloat_pkg.sv +++ b/coverage/coverfloat_pkg.sv @@ -448,12 +448,15 @@ package coverfloat_pkg; logic [F16_E_BITS-1:0] exp_a = a[14:10]; logic [F16_E_BITS-1:0] exp_b = b[14:10]; + logic [F16_M_BITS-1:0] sig_a = a[F16_M_UPPER:0]; + logic [F16_M_BITS-1:0] sig_b = b[F16_M_UPPER:0]; + E_a = (exp_a == 0) ? - (1 - F16_EXP_BIAS) : + (0 - F16_EXP_BIAS - count_leading_zeros(sig_a, F16_M_BITS)) : (int'(exp_a) - F16_EXP_BIAS); E_b = (exp_b == 0) ? - (1 - F16_EXP_BIAS) : + (0 - F16_EXP_BIAS - count_leading_zeros(sig_b, F16_M_BITS)) : (int'(exp_b) - F16_EXP_BIAS); bias = F16_EXP_BIAS; @@ -467,12 +470,15 @@ package coverfloat_pkg; logic [BF16_E_BITS-1:0] exp_a = a[14:7]; logic [BF16_E_BITS-1:0] exp_b = b[14:7]; + logic [BF16_M_BITS-1:0] sig_a = a[BF16_M_UPPER:0]; + logic [BF16_M_BITS-1:0] sig_b = b[BF16_M_UPPER:0]; + E_a = (exp_a == 0) ? - (1 - BF16_EXP_BIAS) : + (0 - BF16_EXP_BIAS - count_leading_zeros(sig_a, BF16_M_BITS)) : (int'(exp_a) - BF16_EXP_BIAS); E_b = (exp_b == 0) ? - (1 - BF16_EXP_BIAS) : + (0 - BF16_EXP_BIAS - count_leading_zeros(sig_b, BF16_M_BITS)) : (int'(exp_b) - BF16_EXP_BIAS); bias = BF16_EXP_BIAS; @@ -486,12 +492,15 @@ package coverfloat_pkg; logic [F32_E_BITS-1:0] exp_a = a[30:23]; logic [F32_E_BITS-1:0] exp_b = b[30:23]; + logic [F32_M_BITS-1:0] sig_a = a[F32_M_UPPER:0]; + logic [F32_M_BITS-1:0] sig_b = b[F32_M_UPPER:0]; + E_a = (exp_a == 0) ? - (1 - F32_EXP_BIAS) : + (0 - F32_EXP_BIAS - count_leading_zeros(sig_a, F32_M_BITS)) : (int'(exp_a) - F32_EXP_BIAS); E_b = (exp_b == 0) ? - (1 - F32_EXP_BIAS) : + (0 - F32_EXP_BIAS - count_leading_zeros(sig_b, F32_M_BITS)) : (int'(exp_b) - F32_EXP_BIAS); bias = F32_EXP_BIAS; @@ -505,12 +514,15 @@ package coverfloat_pkg; logic [F64_E_BITS-1:0] exp_a = a[62:52]; logic [F64_E_BITS-1:0] exp_b = b[62:52]; + logic [F64_M_BITS-1:0] sig_a = a[F64_M_UPPER:0]; + logic [F64_M_BITS-1:0] sig_b = b[F64_M_UPPER:0]; + E_a = (exp_a == 0) ? - (1 - F64_EXP_BIAS) : + (0 - F64_EXP_BIAS - count_leading_zeros(sig_a, F64_M_BITS)) : (int'(exp_a) - F64_EXP_BIAS); E_b = (exp_b == 0) ? - (1 - F64_EXP_BIAS) : + (0 - F64_EXP_BIAS - count_leading_zeros(sig_b, F64_M_BITS)) : (int'(exp_b) - F64_EXP_BIAS); bias = F64_EXP_BIAS; @@ -524,12 +536,15 @@ package coverfloat_pkg; logic [F128_E_BITS-1:0] exp_a = a[126:112]; logic [F128_E_BITS-1:0] exp_b = b[126:112]; + logic [F128_M_BITS-1:0] sig_a = a[F128_M_UPPER:0]; + logic [F128_M_BITS-1:0] sig_b = b[F128_M_UPPER:0]; + E_a = (exp_a == 0) ? - (1 - F128_EXP_BIAS) : + (0 - F128_EXP_BIAS - count_leading_zeros(sig_a, F128_M_BITS)) : (int'(exp_a) - F128_EXP_BIAS); E_b = (exp_b == 0) ? - (1 - F128_EXP_BIAS) : + (0 - F128_EXP_BIAS - count_leading_zeros(sig_b, F128_M_BITS)) : (int'(exp_b) - F128_EXP_BIAS); bias = F128_EXP_BIAS; diff --git a/coverage/covergroups/B18.svh b/coverage/covergroups/B18.svh index b2f56a5..0c5dd56 100644 --- a/coverage/covergroups/B18.svh +++ b/coverage/covergroups/B18.svh @@ -222,7 +222,7 @@ covergroup B18_cg (virtual coverfloat_interface CFI); iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) == F32_MAXNORM_EXP && CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - 1) -: F32_M_BITS - 1] == '1) { type_option.weight = 0; - bins maxNorm_pm_3ulp[] = {[2'b01 : 2'b11]}; + bins maxNorm_pm_3ulp[] = {[2'b00 : 2'b11]}; } F32_maxNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS)], |CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 1) : 0]} // Minus one to the exponent means the ulp was shifted 1 to the left iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) == (F32_MAXNORM_EXP - 1) && CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - 1) -: F32_M_BITS] == '1) { @@ -235,7 +235,7 @@ covergroup B18_cg (virtual coverfloat_interface CFI); iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) == F64_MAXNORM_EXP && CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - 1) -: F64_M_BITS - 1] == '1) { type_option.weight = 0; - bins maxNorm_pm_3ulp[] = {[2'b01 : 2'b11]}; + bins maxNorm_pm_3ulp[] = {[2'b00 : 2'b11]}; } F64_maxNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 1)], |CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 2) : 0]} // Minus one to the exponent means the ulp was shifted 1 to the left iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) == (F64_MAXNORM_EXP - 1) && CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - 1) -: F64_M_BITS] == '1) { @@ -248,7 +248,7 @@ covergroup B18_cg (virtual coverfloat_interface CFI); iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) == F128_MAXNORM_EXP && CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - 1) -: F128_M_BITS - 1] == '1) { type_option.weight = 0; - bins maxNorm_pm_3ulp[] = {[2'b01 : 2'b11]}; + bins maxNorm_pm_3ulp[] = {[2'b00 : 2'b11]}; } F128_maxNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS)], |CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 1) : 0]} // Minus one to the exponent means the ulp was shifted 1 to the left iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) == (F128_MAXNORM_EXP - 1) && CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - 1) -: F128_M_BITS] == '1) { @@ -261,7 +261,7 @@ covergroup B18_cg (virtual coverfloat_interface CFI); iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) == F16_MAXNORM_EXP && CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - 1) -: F16_M_BITS - 1] == '1) { type_option.weight = 0; - bins maxNorm_pm_3ulp[] = {[2'b01 : 2'b11]}; + bins maxNorm_pm_3ulp[] = {[2'b00 : 2'b11]}; } F16_maxNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS)], |CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 1) : 0]} // Minus one to the exponent means the ulp was shifted 1 to the left iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) == (F16_MAXNORM_EXP - 1) && CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - 1) -: F16_M_BITS] == '1) { @@ -274,7 +274,7 @@ covergroup B18_cg (virtual coverfloat_interface CFI); iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) == BF16_MAXNORM_EXP && CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - 1) -: BF16_M_BITS - 1] == '1) { type_option.weight = 0; - bins maxNorm_pm_3ulp[] = {[2'b01 : 2'b11]}; + bins maxNorm_pm_3ulp[] = {[2'b00 : 2'b11]}; } BF16_maxNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS)], |CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 1) : 0]} // Minus one to the exponent means the ulp was shifted 1 to the left iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) == (BF16_MAXNORM_EXP - 1) && CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - 1) -: BF16_M_BITS] == '1) { @@ -375,223 +375,309 @@ covergroup B18_cg (virtual coverfloat_interface CFI); // cases iii & iv - // Guard bit sticky bit - F32_minSubNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 1)], |CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 2) : 0]} - // implicit leading 0 (subnorm) single 1 in LSB (except for Guard and sticky) - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) <= 0 && CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF -: F32_M_BITS +1] == 1) { - type_option.weight = 0; + F32_minSubNorm_p_3ulp: coverpoint ( + CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF + 1)] == 1 + ? { CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF+1 -: 2], |CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF-1:0] } + : { CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF -: 2], |CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF-2:0] } + ) iff ($signed(get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE)) == -(F32_M_BITS-1)) { + type_option.weight = 0; - bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; + // Factors in the lsb which must be one + bins minSubNorm_p_3ulp[] = {[3'b100 : 3'b111]}; } + F32_minSubNorm_m_1_2ulp: coverpoint ( + CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF + 1)] == 1 + ? { CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF+1], |CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF:0] } + : { CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF], |CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF-1:0] } + ) iff ($signed(get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE)) == -F32_M_BITS) { + type_option.weight = 0; - // Guard bit sticky bit - F32_minSubNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 1)], |CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 2) : 0]} - // implicit leading 0 (subnorm) all zeros fraction (except for Guard and sticky) - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) <= 0 && CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF -: F32_M_BITS +1] == 0) { - type_option.weight = 0; + bins minSubNorm_m_1ulp = { 2'b11 }; + bins minSubNorm_m_2ulp = { 2'b10 }; + } + F32_minSubNorm_m_3ulp: coverpoint ( + CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF + 1)] == 1 + ? |CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF+1:0] + : |CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF:0] + ) iff ($signed(get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE)) <= -(F32_M_BITS+1)) { + type_option.weight = 0; - bins minSubNorm_m_3ulp[] = {[2'b01 : 2'b11]}; + bins minSubNorm_m_3ulp = { '1 }; } - // Guard bit sticky bit - F64_minSubNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 1)], |CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 2) : 0]} - // implicit leading 0 (subnorm) single 1 in LSB (except for Guard and sticky) - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) <= 0 && CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF -: F64_M_BITS +1] == 1) { - type_option.weight = 0; + F64_minSubNorm_p_3ulp: coverpoint ( + CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF + 1)] == 1 + ? { CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF+1 -: 2], |CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF-1:0] } + : { CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF -: 2], |CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF-2:0] } + ) iff ($signed(get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE)) == -(F64_M_BITS-1)) { + type_option.weight = 0; - bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; + // Factors in the lsb which must be one + bins minSubNorm_p_3ulp[] = {[3'b100 : 3'b111]}; } + F64_minSubNorm_m_1_2ulp: coverpoint ( + CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF + 1)] == 1 + ? { CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF+1], |CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF:0] } + : { CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF], |CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF-1:0] } + ) iff ($signed(get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE)) == -F64_M_BITS) { + type_option.weight = 0; - // Guard bit sticky bit - F64_minSubNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 1)], |CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 2) : 0]} - // implicit leading 0 (subnorm) all zeros fraction (except for Guard and sticky) - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) <= 0 && CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF -: F64_M_BITS +1] == 0) { - type_option.weight = 0; + bins minSubNorm_m_1ulp = { 2'b11 }; + bins minSubNorm_m_2ulp = { 2'b10 }; + } + F64_minSubNorm_m_3ulp: coverpoint ( + CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF + 1)] == 1 + ? |CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF+1:0] + : |CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF:0] + ) iff ($signed(get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE)) <= -(F64_M_BITS+1)) { + type_option.weight = 0; - bins minSubNorm_m_3ulp[] = {[2'b01 : 2'b11]}; + bins minSubNorm_m_3ulp = { '1 }; } - // Guard bit sticky bit - F128_minSubNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 1)], |CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 2) : 0]} - // implicit leading 0 (subnorm) single 1 in LSB (except for Guard and sticky) - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) <= 0 && CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF -: F128_M_BITS +1] == 1) { - type_option.weight = 0; + F128_minSubNorm_p_3ulp: coverpoint ( + CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF + 1)] == 1 + ? { CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF+1 -: 2], |CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF-1:0] } + : { CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF -: 2], |CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF-2:0] } + ) iff ($signed(get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD)) == -(F128_M_BITS-1)) { + type_option.weight = 0; - bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; + // Factors in the lsb which must be one + bins minSubNorm_p_3ulp[] = {[3'b100 : 3'b111]}; } + F128_minSubNorm_m_1_2ulp: coverpoint ( + CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF + 1)] == 1 + ? { CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF+1], |CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF:0] } + : { CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF], |CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF-1:0] } + ) iff ($signed(get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD)) == -F128_M_BITS) { + type_option.weight = 0; - // Guard bit sticky bit - F128_minSubNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 1)], |CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 2) : 0]} - // implicit leading 0 (subnorm) all zeros fraction (except for Guard and sticky) - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) <= 0 && CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF -: F128_M_BITS +1] == 0) { - type_option.weight = 0; + bins minSubNorm_m_1ulp = { 2'b11 }; + bins minSubNorm_m_2ulp = { 2'b10 }; + } + F128_minSubNorm_m_3ulp: coverpoint ( + CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF + 1)] == 1 + ? |CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF+1:0] + : |CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF:0] + ) iff ($signed(get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD)) <= -(F128_M_BITS+1)) { + type_option.weight = 0; - bins minSubNorm_m_3ulp[] = {[2'b01 : 2'b11]}; + bins minSubNorm_m_3ulp = { '1 }; } - // Guard bit sticky bit - F16_minSubNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 1)], |CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 2) : 0]} - // implicit leading 0 (subnorm) single 1 in LSB (except for Guard and sticky) - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) <= 0 && CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF -: F16_M_BITS +1] == 1) { - type_option.weight = 0; + F16_minSubNorm_p_3ulp: coverpoint ( + CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF + 1)] == 1 + ? { CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF+1 -: 2], |CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF-1:0] } + : { CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF -: 2], |CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF-2:0] } + ) iff ($signed(get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF)) == -(F16_M_BITS-1)) { + type_option.weight = 0; - bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; + // Factors in the lsb which must be one + bins minSubNorm_p_3ulp[] = {[3'b100 : 3'b111]}; } + F16_minSubNorm_m_1_2ulp: coverpoint ( + CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF + 1)] == 1 + ? { CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF+1], |CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF:0] } + : { CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF], |CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF-1:0] } + ) iff ($signed(get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF)) == -F16_M_BITS) { + type_option.weight = 0; - // Guard bit sticky bit - F16_minSubNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 1)], |CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 2) : 0]} - // implicit leading 0 (subnorm) all zeros fraction (except for Guard and sticky) - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) <= 0 && CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF -: F16_M_BITS +1] == 0) { - type_option.weight = 0; + bins minSubNorm_m_1ulp = { 2'b11 }; + bins minSubNorm_m_2ulp = { 2'b10 }; + } + F16_minSubNorm_m_3ulp: coverpoint ( + CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF + 1)] == 1 + ? |CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF+1:0] + : |CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF:0] + ) iff ($signed(get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF)) <= -(F16_M_BITS+1)) { + type_option.weight = 0; - bins minSubNorm_m_3ulp[] = {[2'b01 : 2'b11]}; + bins minSubNorm_m_3ulp = { '1 }; } - // Guard bit sticky bit - BF16_minSubNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 1)], |CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 2) : 0]} - // implicit leading 0 (subnorm) single 1 in LSB (except for Guard and sticky) - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) <= 0 && CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF -: BF16_M_BITS +1] == 1) { - type_option.weight = 0; + BF16_minSubNorm_p_3ulp: coverpoint ( + CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF + 1)] == 1 + ? { CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF+1 -: 2], |CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF-1:0] } + : { CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF -: 2], |CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF-2:0] } + ) iff ($signed(get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16)) == -(BF16_M_BITS-1)) { + type_option.weight = 0; - bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; + // Factors in the lsb which must be one + bins minSubNorm_p_3ulp[] = {[3'b100 : 3'b111]}; } + BF16_minSubNorm_m_1_2ulp: coverpoint ( + CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF + 1)] == 1 + ? { CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF+1], |CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF:0] } + : { CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF], |CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF-1:0] } + ) iff ($signed(get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16)) == -BF16_M_BITS) { + type_option.weight = 0; - // Guard bit sticky bit - BF16_minSubNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 1)], |CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 2) : 0]} - // implicit leading 0 (subnorm) all zeros fraction (except for Guard and sticky) - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) <= 0 && CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF -: BF16_M_BITS +1] == 0) { - type_option.weight = 0; + bins minSubNorm_m_1ulp = { 2'b11 }; + bins minSubNorm_m_2ulp = { 2'b10 }; + } + BF16_minSubNorm_m_3ulp: coverpoint ( + CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF + 1)] == 1 + ? |CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF+1:0] + : |CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF:0] + ) iff ($signed(get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16)) <= -(BF16_M_BITS+1)) { + type_option.weight = 0; - bins minSubNorm_m_3ulp[] = {[2'b01 : 2'b11]}; + bins minSubNorm_m_3ulp = { '1 }; } + // cases v & vi - // Guard bit sticky bit - F32_minNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 1)], |CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 2) : 0]} - // implicit leading 1 (norm) all zero fraction (except for Guard and sticky) - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) != 0 && CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF -1 -: F32_M_BITS] == 0) { + F32_minNorm_p_3ulp: coverpoint ( + CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF + 1)] == 1 + // leading zeros guard sticky + ? { |CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF -: F32_M_BITS], CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF + 1) - F32_M_BITS - 1], |CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF + 1) - F32_M_BITS - 2 : 0] } + : { |CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - 1) -: F32_M_BITS], CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF) - F32_M_BITS - 1], |CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF) - F32_M_BITS - 2 : 0] } + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) == 1) { type_option.weight = 0; - bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; + // Zero for an all zero fraction + bins minNorm_p_3ulp[] = {[3'b000 : 3'b011]}; } - - // Guard bit sticky bit - F32_minNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 1)], |CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 2) : 0]} - // implicit leading 0 (subnorm) all ones fraction (except for Guard and sticky) - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) <= 0 && CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF -1 -: F32_M_BITS] == '1) { + F32_minNorm_m_3ulp: coverpoint ( + CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF + 1)] == 1 + // leading ones guard sticky + ? { &CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF -: F32_M_BITS-1], CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF + 1) - F32_M_BITS], |CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF + 1) - F32_M_BITS - 1 : 0] } + : { &CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF -: F32_M_BITS-1], CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF) - F32_M_BITS], |CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF) - F32_M_BITS - 1 : 0] } + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) == 0) { type_option.weight = 0; - bins minNorm_m_3ulp[] = {[2'b01 : 2'b11]}; + // One for an all ones fraction + bins minNorm_m_3ulp[] = {[3'b101 : 3'b111]}; } - // Guard bit sticky bit - F64_minNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 1)], |CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 2) : 0]} - // implicit leading 1 (norm) all zero fraction (except for Guard and sticky) - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) != 0 && CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF -1 -: F64_M_BITS] == 0) { + F64_minNorm_p_3ulp: coverpoint ( + CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF + 1)] == 1 + // leading zeros guard sticky + ? { |CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF -: F64_M_BITS], CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF + 1) - F64_M_BITS - 1], |CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF + 1) - F64_M_BITS - 2 : 0] } + : { |CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - 1) -: F64_M_BITS], CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF) - F64_M_BITS - 1], |CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF) - F64_M_BITS - 2 : 0] } + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) == 1) { type_option.weight = 0; - bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; + // Zero for an all zero fraction + bins minNorm_p_3ulp[] = {[3'b000 : 3'b011]}; } - - // Guard bit sticky bit - F64_minNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 1)], |CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 2) : 0]} - // implicit leading 0 (subnorm) all ones fraction (except for Guard and sticky) - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) <= 0 && CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF -1 -: F64_M_BITS] == '1) { + F64_minNorm_m_3ulp: coverpoint ( + CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF + 1)] == 1 + // leading ones guard sticky + ? { &CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF -: F64_M_BITS-1], CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF + 1) - F64_M_BITS], |CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF + 1) - F64_M_BITS - 1 : 0] } + : { &CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF -: F64_M_BITS-1], CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF) - F64_M_BITS], |CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF) - F64_M_BITS - 1 : 0] } + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) == 0) { type_option.weight = 0; - bins minNorm_m_3ulp[] = {[2'b01 : 2'b11]}; + // One for an all ones fraction + bins minNorm_m_3ulp[] = {[3'b101 : 3'b111]}; } - // Guard bit sticky bit - F128_minNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 1)], |CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 2) : 0]} - // implicit leading 1 (norm) all zero fraction (except for Guard and sticky) - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) != 0 && CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF -1 -: F128_M_BITS] == 0) { + F128_minNorm_p_3ulp: coverpoint ( + CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF + 1)] == 1 + // leading zeros guard sticky + ? { |CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF -: F128_M_BITS], CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF + 1) - F128_M_BITS - 1], |CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF + 1) - F128_M_BITS - 2 : 0] } + : { |CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - 1) -: F128_M_BITS], CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF) - F128_M_BITS - 1], |CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF) - F128_M_BITS - 2 : 0] } + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) == 1) { type_option.weight = 0; - bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; + // Zero for an all zero fraction + bins minNorm_p_3ulp[] = {[3'b000 : 3'b011]}; } - - // Guard bit sticky bit - F128_minNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 1)], |CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 2) : 0]} - // implicit leading 0 (subnorm) all ones fraction (except for Guard and sticky) - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) <= 0 && CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF -1 -: F128_M_BITS] == '1) { + F128_minNorm_m_3ulp: coverpoint ( + CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF + 1)] == 1 + // leading ones guard sticky + ? { &CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF -: F128_M_BITS-1], CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF + 1) - F128_M_BITS], |CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF + 1) - F128_M_BITS - 1 : 0] } + : { &CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF -: F128_M_BITS-1], CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF) - F128_M_BITS], |CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF) - F128_M_BITS - 1 : 0] } + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) == 0) { type_option.weight = 0; - bins minNorm_m_3ulp[] = {[2'b01 : 2'b11]}; + // One for an all ones fraction + bins minNorm_m_3ulp[] = {[3'b101 : 3'b111]}; } - // Guard bit sticky bit - F16_minNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 1)], |CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 2) : 0]} - // implicit leading 1 (norm) all zero fraction (except for Guard and sticky) - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) != 0 && CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF -1 -: F16_M_BITS] == 0) { + F16_minNorm_p_3ulp: coverpoint ( + CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF + 1)] == 1 + // leading zeros guard sticky + ? { |CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF -: F16_M_BITS], CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF + 1) - F16_M_BITS - 1], |CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF + 1) - F16_M_BITS - 2 : 0] } + : { |CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - 1) -: F16_M_BITS], CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF) - F16_M_BITS - 1], |CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF) - F16_M_BITS - 2 : 0] } + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) == 1) { type_option.weight = 0; - bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; + // Zero for an all zero fraction + bins minNorm_p_3ulp[] = {[3'b000 : 3'b011]}; } - - // Guard bit sticky bit - F16_minNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 1)], |CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 2) : 0]} - // implicit leading 0 (subnorm) all ones fraction (except for Guard and sticky) - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) <= 0 && CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF -1 -: F16_M_BITS] == '1) { + F16_minNorm_m_3ulp: coverpoint ( + CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF + 1)] == 1 + // leading ones guard sticky + ? { &CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF -: F16_M_BITS-1], CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF + 1) - F16_M_BITS], |CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF + 1) - F16_M_BITS - 1 : 0] } + : { &CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF -: F16_M_BITS-1], CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF) - F16_M_BITS], |CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF) - F16_M_BITS - 1 : 0] } + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) == 0) { type_option.weight = 0; - bins minNorm_m_3ulp[] = {[2'b01 : 2'b11]}; + // One for an all ones fraction + bins minNorm_m_3ulp[] = {[3'b101 : 3'b111]}; } - // Guard bit sticky bit - BF16_minNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 1)], |CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 2) : 0]} - // implicit leading 1 (norm) all zero fraction (except for Guard and sticky) - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) != 0 && CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF -1 -: BF16_M_BITS] == 0) { + BF16_minNorm_p_3ulp: coverpoint ( + CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF + 1)] == 1 + // leading zeros guard sticky + ? { |CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF -: BF16_M_BITS], CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF + 1) - BF16_M_BITS - 1], |CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF + 1) - BF16_M_BITS - 2 : 0] } + : { |CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - 1) -: BF16_M_BITS], CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF) - BF16_M_BITS - 1], |CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF) - BF16_M_BITS - 2 : 0] } + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) == 1) { type_option.weight = 0; - bins minNorm_p_3ulp[] = {[2'b00 : 2'b11]}; + // Zero for an all zero fraction + bins minNorm_p_3ulp[] = {[3'b000 : 3'b011]}; } - - // Guard bit sticky bit - BF16_minNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 1)], |CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 2) : 0]} - // implicit leading 0 (subnorm) all ones fraction (except for Guard and sticky) - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) <= 0 && CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF -1 -: BF16_M_BITS] == '1) { + BF16_minNorm_m_3ulp: coverpoint ( + CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF + 1)] == 1 + // leading ones guard sticky + ? { &CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF -: BF16_M_BITS-1], CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF + 1) - BF16_M_BITS], |CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF + 1) - BF16_M_BITS - 1 : 0] } + : { &CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF -: BF16_M_BITS-1], CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF) - BF16_M_BITS], |CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF) - BF16_M_BITS - 1 : 0] } + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) == 0) { type_option.weight = 0; - bins minNorm_m_3ulp[] = {[2'b01 : 2'b11]}; + // One for an all ones fraction + bins minNorm_m_3ulp[] = {[3'b101 : 3'b111]}; } - // cases vii & viii - F32_btw_minSubNorm_zero: coverpoint CFI.fmaPreAddition iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) <= 0) { - type_option.weight = 0; + F32_btw_minSubNorm_zero: coverpoint ($signed(get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE))) + iff (CFI.fmaPreAddition != 0) { + type_option.weight = 0; - // shift 1 into the ULP position, subtract one to be in the exclusive range (0 , minSubNorm) - bins btw_minSubNorm_zero = {[1 : ((F32_FMA_PRE_ADDITION_NF'(1) << (F32_FMA_PRE_ADDITION_NF - F32_M_BITS)) - 1)]}; + // shift 1 into the ULP position, subtract one to be in the exclusive range (0 , minSubNorm) + bins btw_minSubNorm_zero = {[$:-F32_M_BITS]}; } + F64_btw_minSubNorm_zero: coverpoint ($signed(get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE))) + iff (CFI.fmaPreAddition != 0) { + type_option.weight = 0; - F64_btw_minSubNorm_zero: coverpoint CFI.fmaPreAddition iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) <= 0) { - type_option.weight = 0; - - // shift 1 into the ULP position, subtract one to be in the exclusive range (0 , minSubNorm) - bins btw_minSubNorm_zero = {[1 : ((F64_FMA_PRE_ADDITION_NF'(1) << (F64_FMA_PRE_ADDITION_NF - F64_M_BITS)) - 1)]}; + // shift 1 into the ULP position, subtract one to be in the exclusive range (0 , minSubNorm) + bins btw_minSubNorm_zero = {[$:-F64_M_BITS]}; } + F128_btw_minSubNorm_zero: coverpoint ($signed(get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD))) + iff (CFI.fmaPreAddition != 0) { + type_option.weight = 0; - F128_btw_minSubNorm_zero: coverpoint CFI.fmaPreAddition iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) <= 0) { - type_option.weight = 0; - - // shift 1 into the ULP position, subtract one to be in the exclusive range (0 , minSubNorm) - bins btw_minSubNorm_zero = {[1 : ((F128_FMA_PRE_ADDITION_NF'(1) << (F128_FMA_PRE_ADDITION_NF - F128_M_BITS)) - 1)]}; + // shift 1 into the ULP position, subtract one to be in the exclusive range (0 , minSubNorm) + bins btw_minSubNorm_zero = {[$:-F128_M_BITS]}; } + F16_btw_minSubNorm_zero: coverpoint ($signed(get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF))) + iff (CFI.fmaPreAddition != 0) { + type_option.weight = 0; - F16_btw_minSubNorm_zero: coverpoint CFI.fmaPreAddition iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) <= 0) { - type_option.weight = 0; - - // shift 1 into the ULP position, subtract one to be in the exclusive range (0 , minSubNorm) - bins btw_minSubNorm_zero = {[1 : ((F16_FMA_PRE_ADDITION_NF'(1) << (F16_FMA_PRE_ADDITION_NF - F16_M_BITS)) - 1)]}; + // shift 1 into the ULP position, subtract one to be in the exclusive range (0 , minSubNorm) + bins btw_minSubNorm_zero = {[$:-F16_M_BITS]}; } + BF16_btw_minSubNorm_zero: coverpoint ($signed(get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16))) + iff (CFI.fmaPreAddition != 0) { + type_option.weight = 0; - BF16_btw_minSubNorm_zero: coverpoint CFI.fmaPreAddition iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) <= 0) { - type_option.weight = 0; - - // shift 1 into the ULP position, subtract one to be in the exclusive range (0 , minSubNorm) - bins btw_minSubNorm_zero = {[1 : ((BF16_FMA_PRE_ADDITION_NF'(1) << (BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS)) - 1)]}; + // shift 1 into the ULP position, subtract one to be in the exclusive range (0 , minSubNorm) + bins btw_minSubNorm_zero = {[$:-BF16_M_BITS]}; } // case ix @@ -636,23 +722,24 @@ covergroup B18_cg (virtual coverfloat_interface CFI); bins no_overflow = { 0 }; } - FP_no_underflow: coverpoint (CFI.exceptionBits & FLAG_UNDERFLOW_MASK) { + FP_no_underflow: coverpoint (CFI.exceptionBits & FLAG_UNDERFLOW_MASK != 0) { type_option.weight = 0; - bins no_overflow = { 0 }; + bins no_underflow = { [0:1] }; } `ifdef COVER_F32 - B18_case_i_f32: cross F32_src_fmt, FMA_ops, F32_product_lsb, F32_product_guard, F32_product_sticky, F32_interm_guard_zero, F32_interm_sticky_zero; + // B18_case_i_f32: cross F32_src_fmt, FMA_ops, F32_product_lsb, F32_product_guard, F32_product_sticky, F32_interm_guard_zero, F32_interm_sticky_zero; - B18_case_ii_b4_maxNorm_p_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_maxNorm_p_3ulp, FP_no_overflow; - B18_case_ii_b4_maxNorm_m_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_maxNorm_m_3ulp, FP_no_overflow; - B18_case_ii_b4_gt_maxNorm_p_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_gt_maxNorm_p_3ulp, FP_no_overflow; - B18_case_ii_b4_maxNorm_pm3_exp_range_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_maxNorm_pm3_exp_range, FP_no_overflow; + // B18_case_ii_b4_maxNorm_p_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_maxNorm_p_3ulp, FP_no_overflow; + // B18_case_ii_b4_maxNorm_m_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_maxNorm_m_3ulp, FP_no_overflow; + // B18_case_ii_b4_gt_maxNorm_p_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_gt_maxNorm_p_3ulp, FP_no_overflow; + // B18_case_ii_b4_maxNorm_pm3_exp_range_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_maxNorm_pm3_exp_range, FP_no_overflow; B18_case_iii_b5_subnorm_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_subnorm, FP_no_underflow; B18_case_iii_b5_minSubNorm_p_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_minSubNorm_p_3ulp, FP_no_underflow; + B18_case_iii_b5_minSubNorm_m_1_2ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_minSubNorm_m_1_2ulp, FP_no_underflow; B18_case_iii_b5_minSubNorm_m_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_minSubNorm_m_3ulp, FP_no_underflow; B18_case_iii_b5_minNorm_p_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_minNorm_p_3ulp, FP_no_underflow; B18_case_iii_b5_minNorm_m_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_minNorm_m_3ulp, FP_no_underflow; @@ -661,12 +748,12 @@ covergroup B18_cg (virtual coverfloat_interface CFI); `endif `ifdef COVER_F64 - B18_case_i_f64: cross F64_src_fmt, FMA_ops, F64_product_lsb, F64_product_guard, F64_product_sticky, F64_interm_guard_zero, F64_interm_sticky_zero; + // B18_case_i_f64: cross F64_src_fmt, FMA_ops, F64_product_lsb, F64_product_guard, F64_product_sticky, F64_interm_guard_zero, F64_interm_sticky_zero; - B18_case_ii_b4_maxNorm_p_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_maxNorm_p_3ulp, FP_no_overflow; - B18_case_ii_b4_maxNorm_m_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_maxNorm_m_3ulp, FP_no_overflow; - B18_case_ii_b4_gt_maxNorm_p_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_gt_maxNorm_p_3ulp, FP_no_overflow; - B18_case_ii_b4_maxNorm_pm3_exp_range_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_maxNorm_pm3_exp_range, FP_no_overflow; + // B18_case_ii_b4_maxNorm_p_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_maxNorm_p_3ulp, FP_no_overflow; + // B18_case_ii_b4_maxNorm_m_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_maxNorm_m_3ulp, FP_no_overflow; + // B18_case_ii_b4_gt_maxNorm_p_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_gt_maxNorm_p_3ulp, FP_no_overflow; + // B18_case_ii_b4_maxNorm_pm3_exp_range_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_maxNorm_pm3_exp_range, FP_no_overflow; B18_case_iii_b5_subnorm_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_subnorm, FP_no_underflow; B18_case_iii_b5_minSubNorm_p_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_minSubNorm_p_3ulp, FP_no_underflow; @@ -678,12 +765,12 @@ covergroup B18_cg (virtual coverfloat_interface CFI); `endif `ifdef COVER_F128 - B18_case_i_f128: cross F128_src_fmt, FMA_ops, F128_product_lsb, F128_product_guard, F128_product_sticky, F128_interm_guard_zero, F128_interm_sticky_zero; + // B18_case_i_f128: cross F128_src_fmt, FMA_ops, F128_product_lsb, F128_product_guard, F128_product_sticky, F128_interm_guard_zero, F128_interm_sticky_zero; - B18_case_ii_b4_maxNorm_p_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_maxNorm_p_3ulp, FP_no_overflow; - B18_case_ii_b4_maxNorm_m_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_maxNorm_m_3ulp, FP_no_overflow; - B18_case_ii_b4_gt_maxNorm_p_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_gt_maxNorm_p_3ulp, FP_no_overflow; - B18_case_ii_b4_maxNorm_pm3_exp_range_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_maxNorm_pm3_exp_range, FP_no_overflow; + // B18_case_ii_b4_maxNorm_p_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_maxNorm_p_3ulp, FP_no_overflow; + // B18_case_ii_b4_maxNorm_m_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_maxNorm_m_3ulp, FP_no_overflow; + // B18_case_ii_b4_gt_maxNorm_p_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_gt_maxNorm_p_3ulp, FP_no_overflow; + // B18_case_ii_b4_maxNorm_pm3_exp_range_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_maxNorm_pm3_exp_range, FP_no_overflow; B18_case_iii_b5_subnorm_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_subnorm, FP_no_underflow; B18_case_iii_b5_minSubNorm_p_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_minSubNorm_p_3ulp, FP_no_underflow; @@ -695,12 +782,12 @@ covergroup B18_cg (virtual coverfloat_interface CFI); `endif `ifdef COVER_F16 - B18_case_i_f16: cross F16_src_fmt, FMA_ops, F16_product_lsb, F16_product_guard, F16_product_sticky, F16_interm_guard_zero, F16_interm_sticky_zero; + // B18_case_i_f16: cross F16_src_fmt, FMA_ops, F16_product_lsb, F16_product_guard, F16_product_sticky, F16_interm_guard_zero, F16_interm_sticky_zero; - B18_case_ii_b4_maxNorm_p_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_maxNorm_p_3ulp, FP_no_overflow; - B18_case_ii_b4_maxNorm_m_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_maxNorm_m_3ulp, FP_no_overflow; - B18_case_ii_b4_gt_maxNorm_p_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_gt_maxNorm_p_3ulp, FP_no_overflow; - B18_case_ii_b4_maxNorm_pm3_exp_range_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_maxNorm_pm3_exp_range, FP_no_overflow; + // B18_case_ii_b4_maxNorm_p_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_maxNorm_p_3ulp, FP_no_overflow; + // B18_case_ii_b4_maxNorm_m_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_maxNorm_m_3ulp, FP_no_overflow; + // B18_case_ii_b4_gt_maxNorm_p_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_gt_maxNorm_p_3ulp, FP_no_overflow; + // B18_case_ii_b4_maxNorm_pm3_exp_range_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_maxNorm_pm3_exp_range, FP_no_overflow; B18_case_iii_b5_subnorm_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_subnorm, FP_no_underflow; B18_case_iii_b5_minSubNorm_p_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_minSubNorm_p_3ulp, FP_no_underflow; @@ -712,12 +799,12 @@ covergroup B18_cg (virtual coverfloat_interface CFI); `endif `ifdef COVER_BF16 - B18_case_i_bf16: cross BF16_src_fmt, FMA_ops, BF16_product_lsb, BF16_product_guard, BF16_product_sticky, BF16_interm_guard_zero, BF16_interm_sticky_zero; + // B18_case_i_bf16: cross BF16_src_fmt, FMA_ops, BF16_product_lsb, BF16_product_guard, BF16_product_sticky, BF16_interm_guard_zero, BF16_interm_sticky_zero; - B18_case_ii_b4_maxNorm_p_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_maxNorm_p_3ulp, FP_no_overflow; - B18_case_ii_b4_maxNorm_m_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_maxNorm_m_3ulp, FP_no_overflow; - B18_case_ii_b4_gt_maxNorm_p_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_gt_maxNorm_p_3ulp, FP_no_overflow; - B18_case_ii_b4_maxNorm_pm3_exp_range_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_maxNorm_pm3_exp_range, FP_no_overflow; + // B18_case_ii_b4_maxNorm_p_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_maxNorm_p_3ulp, FP_no_overflow; + // B18_case_ii_b4_maxNorm_m_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_maxNorm_m_3ulp, FP_no_overflow; + // B18_case_ii_b4_gt_maxNorm_p_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_gt_maxNorm_p_3ulp, FP_no_overflow; + // B18_case_ii_b4_maxNorm_pm3_exp_range_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_maxNorm_pm3_exp_range, FP_no_overflow; B18_case_iii_b5_subnorm_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_subnorm, FP_no_underflow; B18_case_iii_b5_minSubNorm_p_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_minSubNorm_p_3ulp, FP_no_underflow; From 00bb2b02172ba851b3a029aefb5c322900e23c9f Mon Sep 17 00:00:00 2001 From: Ryan Wolk Date: Tue, 5 May 2026 19:49:41 -0700 Subject: [PATCH 5/7] Redo Case i of B18 to correctly handle all fma Pre Addition Values Currently, we constrain case i to take on only normalized values because extracting subnormal rounding bits from fmaPreAddition is a task I am not sure is possible to do in coverage, considering that we take a range for the sticky bit, and the subnormal rounding bits are dynamic. --- coverage/covergroups/B18.svh | 129 +++++++++++++++++++++++++++++------ 1 file changed, 109 insertions(+), 20 deletions(-) diff --git a/coverage/covergroups/B18.svh b/coverage/covergroups/B18.svh index 0c5dd56..c7fdcbb 100644 --- a/coverage/covergroups/B18.svh +++ b/coverage/covergroups/B18.svh @@ -62,17 +62,29 @@ covergroup B18_cg (virtual coverfloat_interface CFI); // The FMA Pre-Addition Result is of the form 2.2nf, so here there are // 2.(23 bits of mantissa) (guard: nf-1) (sticky: nf-2 --> 0) - F32_product_lsb: coverpoint |CFI.fmaPreAddition[F32_M_BITS] { + F32_product_lsb: coverpoint ( + CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF+1] == 1 + ? CFI.fmaPreAddition[F32_M_BITS+1] + : CFI.fmaPreAddition[F32_M_BITS] + ) { type_option.weight = 0; bins lsb0 = { 0 }; bins lsb1 = { 1 }; } - F32_product_guard: coverpoint CFI.fmaPreAddition[F32_M_BITS-1] { + F32_product_guard: coverpoint ( + CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF+1] == 1 + ? CFI.fmaPreAddition[F32_M_BITS] + : CFI.fmaPreAddition[F32_M_BITS-1] + ) { type_option.weight = 0; bins guard0 = { 0 }; bins guard1 = { 1 }; } - F32_product_sticky: coverpoint |CFI.fmaPreAddition[F32_M_BITS-2:0] { + F32_product_sticky: coverpoint ( + CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF+1] == 1 + ? |CFI.fmaPreAddition[F32_M_BITS-1:0] + : |CFI.fmaPreAddition[F32_M_BITS-2:0] + ) { type_option.weight = 0; bins sticky0 = { 0 }; bins sticky1 = { 1 }; @@ -86,17 +98,29 @@ covergroup B18_cg (virtual coverfloat_interface CFI); bins zero = { 0 }; } - F64_product_lsb: coverpoint |CFI.fmaPreAddition[F64_M_BITS] { + F64_product_lsb: coverpoint ( + CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF+1] == 1 + ? CFI.fmaPreAddition[F64_M_BITS+1] + : CFI.fmaPreAddition[F64_M_BITS] + ) { type_option.weight = 0; bins lsb0 = { 0 }; bins lsb1 = { 1 }; } - F64_product_guard: coverpoint CFI.fmaPreAddition[F64_M_BITS-1] { + F64_product_guard: coverpoint ( + CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF+1] == 1 + ? CFI.fmaPreAddition[F64_M_BITS] + : CFI.fmaPreAddition[F64_M_BITS-1] + ) { type_option.weight = 0; bins guard0 = { 0 }; bins guard1 = { 1 }; } - F64_product_sticky: coverpoint |CFI.fmaPreAddition[F64_M_BITS-2:0] { + F64_product_sticky: coverpoint ( + CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF+1] == 1 + ? |CFI.fmaPreAddition[F64_M_BITS-1:0] + : |CFI.fmaPreAddition[F64_M_BITS-2:0] + ) { type_option.weight = 0; bins sticky0 = { 0 }; bins sticky1 = { 1 }; @@ -110,17 +134,29 @@ covergroup B18_cg (virtual coverfloat_interface CFI); bins zero = { 0 }; } - F128_product_lsb: coverpoint |CFI.fmaPreAddition[F128_M_BITS] { + F128_product_lsb: coverpoint ( + CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF+1] == 1 + ? CFI.fmaPreAddition[F128_M_BITS+1] + : CFI.fmaPreAddition[F128_M_BITS] + ) { type_option.weight = 0; bins lsb0 = { 0 }; bins lsb1 = { 1 }; } - F128_product_guard: coverpoint CFI.fmaPreAddition[F128_M_BITS-1] { + F128_product_guard: coverpoint ( + CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF+1] == 1 + ? CFI.fmaPreAddition[F128_M_BITS] + : CFI.fmaPreAddition[F128_M_BITS-1] + ) { type_option.weight = 0; bins guard0 = { 0 }; bins guard1 = { 1 }; } - F128_product_sticky: coverpoint |CFI.fmaPreAddition[F128_M_BITS-2:0] { + F128_product_sticky: coverpoint ( + CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF+1] == 1 + ? |CFI.fmaPreAddition[F128_M_BITS-1:0] + : |CFI.fmaPreAddition[F128_M_BITS-2:0] + ) { type_option.weight = 0; bins sticky0 = { 0 }; bins sticky1 = { 1 }; @@ -134,17 +170,29 @@ covergroup B18_cg (virtual coverfloat_interface CFI); bins zero = { 0 }; } - F16_product_lsb: coverpoint |CFI.fmaPreAddition[F16_M_BITS] { + F16_product_lsb: coverpoint ( + CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF+1] == 1 + ? CFI.fmaPreAddition[F16_M_BITS+1] + : CFI.fmaPreAddition[F16_M_BITS] + ) { type_option.weight = 0; bins lsb0 = { 0 }; bins lsb1 = { 1 }; } - F16_product_guard: coverpoint CFI.fmaPreAddition[F16_M_BITS-1] { + F16_product_guard: coverpoint ( + CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF+1] == 1 + ? CFI.fmaPreAddition[F16_M_BITS] + : CFI.fmaPreAddition[F16_M_BITS-1] + ) { type_option.weight = 0; bins guard0 = { 0 }; bins guard1 = { 1 }; } - F16_product_sticky: coverpoint |CFI.fmaPreAddition[F16_M_BITS-2:0] { + F16_product_sticky: coverpoint ( + CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF+1] == 1 + ? |CFI.fmaPreAddition[F16_M_BITS-1:0] + : |CFI.fmaPreAddition[F16_M_BITS-2:0] + ) { type_option.weight = 0; bins sticky0 = { 0 }; bins sticky1 = { 1 }; @@ -158,17 +206,29 @@ covergroup B18_cg (virtual coverfloat_interface CFI); bins zero = { 0 }; } - BF16_product_lsb: coverpoint |CFI.fmaPreAddition[BF16_M_BITS] { + BF16_product_lsb: coverpoint ( + CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF+1] == 1 + ? CFI.fmaPreAddition[BF16_M_BITS+1] + : CFI.fmaPreAddition[BF16_M_BITS] + ) { type_option.weight = 0; bins lsb0 = { 0 }; bins lsb1 = { 1 }; } - BF16_product_guard: coverpoint CFI.fmaPreAddition[BF16_M_BITS-1] { + BF16_product_guard: coverpoint ( + CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF+1] == 1 + ? CFI.fmaPreAddition[BF16_M_BITS] + : CFI.fmaPreAddition[BF16_M_BITS-1] + ) { type_option.weight = 0; bins guard0 = { 0 }; bins guard1 = { 1 }; } - BF16_product_sticky: coverpoint |CFI.fmaPreAddition[BF16_M_BITS-2:0] { + BF16_product_sticky: coverpoint ( + CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF+1] == 1 + ? |CFI.fmaPreAddition[BF16_M_BITS-1:0] + : |CFI.fmaPreAddition[BF16_M_BITS-2:0] + ) { type_option.weight = 0; bins sticky0 = { 0 }; bins sticky1 = { 1 }; @@ -182,6 +242,35 @@ covergroup B18_cg (virtual coverfloat_interface CFI); bins zero = { 0 }; } + // We will constrain these cases to only take on normal numbers in the fma phase, because coverage + // does not seem possible to write for both normal and subnormal cases with SystemVerilog as it + // requires a dynamic access of the fmaPreAddition bits + F32_normal_multiplication: coverpoint (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) > 0 && CFI.fmaPreAddition != 0) { + type_option.weight = 0; + + bins normal_multiplication = {1}; + } + F64_normal_multiplication: coverpoint (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) > 0 && CFI.fmaPreAddition != 0) { + type_option.weight = 0; + + bins normal_multiplication = {1}; + } + F128_normal_multiplication: coverpoint (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) > 0 && CFI.fmaPreAddition != 0) { + type_option.weight = 0; + + bins normal_multiplication = {1}; + } + F16_normal_multiplication: coverpoint (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) > 0 && CFI.fmaPreAddition != 0) { + type_option.weight = 0; + + bins normal_multiplication = {1}; + } + BF16_normal_multiplication: coverpoint (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) > 0 && CFI.fmaPreAddition != 0) { + type_option.weight = 0; + + bins normal_multiplication = {1}; + } + // Useful coverpoint for both case ii and case iii F32_sign: coverpoint CFI.result[31] { type_option.weight = 0; @@ -730,7 +819,7 @@ covergroup B18_cg (virtual coverfloat_interface CFI); `ifdef COVER_F32 - // B18_case_i_f32: cross F32_src_fmt, FMA_ops, F32_product_lsb, F32_product_guard, F32_product_sticky, F32_interm_guard_zero, F32_interm_sticky_zero; + B18_case_i_f32: cross F32_src_fmt, FMA_ops, F32_product_lsb, F32_product_guard, F32_product_sticky, F32_interm_guard_zero, F32_interm_sticky_zero, F32_normal_multiplication; // B18_case_ii_b4_maxNorm_p_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_maxNorm_p_3ulp, FP_no_overflow; // B18_case_ii_b4_maxNorm_m_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_maxNorm_m_3ulp, FP_no_overflow; @@ -748,7 +837,7 @@ covergroup B18_cg (virtual coverfloat_interface CFI); `endif `ifdef COVER_F64 - // B18_case_i_f64: cross F64_src_fmt, FMA_ops, F64_product_lsb, F64_product_guard, F64_product_sticky, F64_interm_guard_zero, F64_interm_sticky_zero; + B18_case_i_f64: cross F64_src_fmt, FMA_ops, F64_product_lsb, F64_product_guard, F64_product_sticky, F64_interm_guard_zero, F64_interm_sticky_zero, F64_normal_multiplication; // B18_case_ii_b4_maxNorm_p_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_maxNorm_p_3ulp, FP_no_overflow; // B18_case_ii_b4_maxNorm_m_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_maxNorm_m_3ulp, FP_no_overflow; @@ -765,7 +854,7 @@ covergroup B18_cg (virtual coverfloat_interface CFI); `endif `ifdef COVER_F128 - // B18_case_i_f128: cross F128_src_fmt, FMA_ops, F128_product_lsb, F128_product_guard, F128_product_sticky, F128_interm_guard_zero, F128_interm_sticky_zero; + B18_case_i_f128: cross F128_src_fmt, FMA_ops, F128_product_lsb, F128_product_guard, F128_product_sticky, F128_interm_guard_zero, F128_interm_sticky_zero, F128_normal_multiplication; // B18_case_ii_b4_maxNorm_p_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_maxNorm_p_3ulp, FP_no_overflow; // B18_case_ii_b4_maxNorm_m_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_maxNorm_m_3ulp, FP_no_overflow; @@ -782,7 +871,7 @@ covergroup B18_cg (virtual coverfloat_interface CFI); `endif `ifdef COVER_F16 - // B18_case_i_f16: cross F16_src_fmt, FMA_ops, F16_product_lsb, F16_product_guard, F16_product_sticky, F16_interm_guard_zero, F16_interm_sticky_zero; + B18_case_i_f16: cross F16_src_fmt, FMA_ops, F16_product_lsb, F16_product_guard, F16_product_sticky, F16_interm_guard_zero, F16_interm_sticky_zero, F16_normal_multiplication; // B18_case_ii_b4_maxNorm_p_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_maxNorm_p_3ulp, FP_no_overflow; // B18_case_ii_b4_maxNorm_m_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_maxNorm_m_3ulp, FP_no_overflow; @@ -799,7 +888,7 @@ covergroup B18_cg (virtual coverfloat_interface CFI); `endif `ifdef COVER_BF16 - // B18_case_i_bf16: cross BF16_src_fmt, FMA_ops, BF16_product_lsb, BF16_product_guard, BF16_product_sticky, BF16_interm_guard_zero, BF16_interm_sticky_zero; + B18_case_i_bf16: cross BF16_src_fmt, FMA_ops, BF16_product_lsb, BF16_product_guard, BF16_product_sticky, BF16_interm_guard_zero, BF16_interm_sticky_zero, BF16_normal_multiplication; // B18_case_ii_b4_maxNorm_p_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_maxNorm_p_3ulp, FP_no_overflow; // B18_case_ii_b4_maxNorm_m_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_maxNorm_m_3ulp, FP_no_overflow; From 0e948a888615bd53b6423b8d349161b53795e65b Mon Sep 17 00:00:00 2001 From: Ryan Wolk Date: Tue, 5 May 2026 20:20:42 -0700 Subject: [PATCH 6/7] Fix up the B4 cases of B18 coverage --- coverage/covergroups/B18.svh | 194 +++++++++++++++++++++++++---------- 1 file changed, 138 insertions(+), 56 deletions(-) diff --git a/coverage/covergroups/B18.svh b/coverage/covergroups/B18.svh index c7fdcbb..a2c24b0 100644 --- a/coverage/covergroups/B18.svh +++ b/coverage/covergroups/B18.svh @@ -303,104 +303,186 @@ covergroup B18_cg (virtual coverfloat_interface CFI); } /************************************************************************ - * Overflow Boundary Helper Coverpoints (from B4, written by Corey Hickson) + * Overflow Boundary Helper Coverpoints (inspired by B4, written by Corey Hickson) ************************************************************************/ // cases i & ii - F32_maxNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 1)], |CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 2) : 0]} - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) == F32_MAXNORM_EXP && CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - 1) -: F32_M_BITS - 1] == '1) { + F32_maxNorm_p_3ulp: coverpoint ( + CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF + 1)] == 1 + // leading zeros guard sticky + ? { |CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF -: F32_M_BITS], CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF + 1) - F32_M_BITS - 1], |CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF + 1) - F32_M_BITS - 2 : 0] } + : { |CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - 1) -: F32_M_BITS], CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF) - F32_M_BITS - 1], |CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF) - F32_M_BITS - 2 : 0] } + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) == F32_MAXNORM_EXP) { type_option.weight = 0; - bins maxNorm_pm_3ulp[] = {[2'b00 : 2'b11]}; + // Account for the leading zeros + bins maxNorm_p_3ulp[] = {[3'b000 : 3'b011]}; } - F32_maxNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS)], |CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 1) : 0]} // Minus one to the exponent means the ulp was shifted 1 to the left - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) == (F32_MAXNORM_EXP - 1) && CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - 1) -: F32_M_BITS] == '1) { + F32_maxNorm_m_3ulp: coverpoint ( + CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF + 1)] == 1 + // leading ones guard sticky + ? { &CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF -: F32_M_BITS-1], CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF + 1) - F32_M_BITS], |CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF + 1) - F32_M_BITS - 1 : 0] } + : { &CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF - 1) -: F32_M_BITS-1], CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF) - F32_M_BITS], |CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF) - F32_M_BITS - 1 : 0] } + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) == (F32_MAXNORM_EXP-1)) { type_option.weight = 0; - bins maxNorm_pm_3ulp[] = {[2'b01 : 2'b11]}; + // Account for the leading ones + bins maxNorm_p_3ulp[] = {[3'b100 : 3'b111]}; } - F64_maxNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 1)], |CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 2) : 0]} - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) == F64_MAXNORM_EXP && CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - 1) -: F64_M_BITS - 1] == '1) { + F64_maxNorm_p_3ulp: coverpoint ( + CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF + 1)] == 1 + // leading zeros guard sticky + ? { |CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF -: F64_M_BITS], CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF + 1) - F64_M_BITS - 1], |CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF + 1) - F64_M_BITS - 2 : 0] } + : { |CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - 1) -: F64_M_BITS], CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF) - F64_M_BITS - 1], |CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF) - F64_M_BITS - 2 : 0] } + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) == F64_MAXNORM_EXP) { type_option.weight = 0; - bins maxNorm_pm_3ulp[] = {[2'b00 : 2'b11]}; + // Account for the leading zeros + bins maxNorm_p_3ulp[] = {[3'b000 : 3'b011]}; } - F64_maxNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 1)], |CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 2) : 0]} // Minus one to the exponent means the ulp was shifted 1 to the left - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) == (F64_MAXNORM_EXP - 1) && CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - 1) -: F64_M_BITS] == '1) { + F64_maxNorm_m_3ulp: coverpoint ( + CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF + 1)] == 1 + // leading ones guard sticky + ? { &CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF -: F64_M_BITS-1], CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF + 1) - F64_M_BITS], |CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF + 1) - F64_M_BITS - 1 : 0] } + : { &CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF - 1) -: F64_M_BITS-1], CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF) - F64_M_BITS], |CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF) - F64_M_BITS - 1 : 0] } + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) == (F64_MAXNORM_EXP-1)) { type_option.weight = 0; - bins maxNorm_pm_3ulp[] = {[2'b01 : 2'b11]}; + // Account for the leading ones + bins maxNorm_p_3ulp[] = {[3'b100 : 3'b111]}; } - F128_maxNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 1)], |CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 2) : 0]} - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) == F128_MAXNORM_EXP && CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - 1) -: F128_M_BITS - 1] == '1) { + F128_maxNorm_p_3ulp: coverpoint ( + CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF + 1)] == 1 + // leading zeros guard sticky + ? { |CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF -: F128_M_BITS], CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF + 1) - F128_M_BITS - 1], |CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF + 1) - F128_M_BITS - 2 : 0] } + : { |CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - 1) -: F128_M_BITS], CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF) - F128_M_BITS - 1], |CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF) - F128_M_BITS - 2 : 0] } + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) == F128_MAXNORM_EXP) { type_option.weight = 0; - bins maxNorm_pm_3ulp[] = {[2'b00 : 2'b11]}; + // Account for the leading zeros + bins maxNorm_p_3ulp[] = {[3'b000 : 3'b011]}; } - F128_maxNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS)], |CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 1) : 0]} // Minus one to the exponent means the ulp was shifted 1 to the left - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) == (F128_MAXNORM_EXP - 1) && CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - 1) -: F128_M_BITS] == '1) { + F128_maxNorm_m_3ulp: coverpoint ( + CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF + 1)] == 1 + // leading ones guard sticky + ? { &CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF -: F128_M_BITS-1], CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF + 1) - F128_M_BITS], |CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF + 1) - F128_M_BITS - 1 : 0] } + : { &CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF - 1) -: F128_M_BITS-1], CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF) - F128_M_BITS], |CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF) - F128_M_BITS - 1 : 0] } + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) == (F128_MAXNORM_EXP-1)) { type_option.weight = 0; - bins maxNorm_pm_3ulp[] = {[2'b01 : 2'b11]}; + // Account for the leading ones + bins maxNorm_p_3ulp[] = {[3'b100 : 3'b111]}; } - F16_maxNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 1)], |CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 2) : 0]} - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) == F16_MAXNORM_EXP && CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - 1) -: F16_M_BITS - 1] == '1) { + F16_maxNorm_p_3ulp: coverpoint ( + CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF + 1)] == 1 + // leading zeros guard sticky + ? { |CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF -: F16_M_BITS], CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF + 1) - F16_M_BITS - 1], |CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF + 1) - F16_M_BITS - 2 : 0] } + : { |CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - 1) -: F16_M_BITS], CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF) - F16_M_BITS - 1], |CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF) - F16_M_BITS - 2 : 0] } + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) == F16_MAXNORM_EXP) { type_option.weight = 0; - bins maxNorm_pm_3ulp[] = {[2'b00 : 2'b11]}; + // Account for the leading zeros + bins maxNorm_p_3ulp[] = {[3'b000 : 3'b011]}; } - F16_maxNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS)], |CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 1) : 0]} // Minus one to the exponent means the ulp was shifted 1 to the left - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) == (F16_MAXNORM_EXP - 1) && CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - 1) -: F16_M_BITS] == '1) { + F16_maxNorm_m_3ulp: coverpoint ( + CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF + 1)] == 1 + // leading ones guard sticky + ? { &CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF -: F16_M_BITS-1], CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF + 1) - F16_M_BITS], |CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF + 1) - F16_M_BITS - 1 : 0] } + : { &CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF - 1) -: F16_M_BITS-1], CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF) - F16_M_BITS], |CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF) - F16_M_BITS - 1 : 0] } + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) == (F16_MAXNORM_EXP-1)) { type_option.weight = 0; - bins maxNorm_pm_3ulp[] = {[2'b01 : 2'b11]}; + // Account for the leading ones + bins maxNorm_p_3ulp[] = {[3'b100 : 3'b111]}; } - BF16_maxNorm_p_3ulp: coverpoint {CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 1)], |CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 2) : 0]} - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) == BF16_MAXNORM_EXP && CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - 1) -: BF16_M_BITS - 1] == '1) { + BF16_maxNorm_p_3ulp: coverpoint ( + CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF + 1)] == 1 + // leading zeros guard sticky + ? { |CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF -: BF16_M_BITS], CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF + 1) - BF16_M_BITS - 1], |CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF + 1) - BF16_M_BITS - 2 : 0] } + : { |CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - 1) -: BF16_M_BITS], CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF) - BF16_M_BITS - 1], |CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF) - BF16_M_BITS - 2 : 0] } + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) == BF16_MAXNORM_EXP) { type_option.weight = 0; - bins maxNorm_pm_3ulp[] = {[2'b00 : 2'b11]}; + // Account for the leading zeros + bins maxNorm_p_3ulp[] = {[3'b000 : 3'b011]}; } - BF16_maxNorm_m_3ulp: coverpoint {CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS)], |CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 1) : 0]} // Minus one to the exponent means the ulp was shifted 1 to the left - iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) == (BF16_MAXNORM_EXP - 1) && CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - 1) -: BF16_M_BITS] == '1) { + BF16_maxNorm_m_3ulp: coverpoint ( + CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF + 1)] == 1 + // leading ones guard sticky + ? { &CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF -: BF16_M_BITS-1], CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF + 1) - BF16_M_BITS], |CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF + 1) - BF16_M_BITS - 1 : 0] } + : { &CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF - 1) -: BF16_M_BITS-1], CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF) - BF16_M_BITS], |CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF) - BF16_M_BITS - 1 : 0] } + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) == (BF16_MAXNORM_EXP-1)) { type_option.weight = 0; - bins maxNorm_pm_3ulp[] = {[2'b01 : 2'b11]}; + // Account for the leading ones + bins maxNorm_p_3ulp[] = {[3'b100 : 3'b111]}; } // cases iii & iv - F32_gt_maxNorm_p_3ulp: coverpoint CFI.fmaPreAddition iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) == F32_MAXNORM_EXP) { + + // If we are greater than p_3 ulp, something is in the first M_BITS fractional bits + F32_gt_maxNorm_p_3ulp: coverpoint ( + (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) == F32_MAXNORM_EXP) + ? (CFI.fmaPreAddition[(F32_FMA_PRE_ADDITION_NF + 1)] == 1 + ? |CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF -: F32_M_BITS] + : |CFI.fmaPreAddition[F32_FMA_PRE_ADDITION_NF - 1 -: F32_M_BITS]) + : '1 + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_SINGLE) >= F32_MAXNORM_EXP) { type_option.weight = 0; - bins gt_maxNorm = {[ ('1 << (F32_FMA_PRE_ADDITION_NF - F32_M_BITS - 2)) : $]}; + bins gt_maxNorm_p_3ulp = { 1 }; } - F64_gt_maxNorm_p_3ulp: coverpoint CFI.fmaPreAddition iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) == F64_MAXNORM_EXP) { + F64_gt_maxNorm_p_3ulp: coverpoint ( + (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) == F64_MAXNORM_EXP) + ? (CFI.fmaPreAddition[(F64_FMA_PRE_ADDITION_NF + 1)] == 1 + ? |CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF -: F64_M_BITS] + : |CFI.fmaPreAddition[F64_FMA_PRE_ADDITION_NF - 1 -: F64_M_BITS]) + : '1 + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_DOUBLE) >= F64_MAXNORM_EXP) { type_option.weight = 0; - bins gt_maxNorm = {[ ('1 << (F64_FMA_PRE_ADDITION_NF - F64_M_BITS - 2)) : $]}; + bins gt_maxNorm_p_3ulp = { 1 }; } - F128_gt_maxNorm_p_3ulp: coverpoint CFI.fmaPreAddition iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) == F128_MAXNORM_EXP) { + F128_gt_maxNorm_p_3ulp: coverpoint ( + (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) == F128_MAXNORM_EXP) + ? (CFI.fmaPreAddition[(F128_FMA_PRE_ADDITION_NF + 1)] == 1 + ? |CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF -: F128_M_BITS] + : |CFI.fmaPreAddition[F128_FMA_PRE_ADDITION_NF - 1 -: F128_M_BITS]) + : '1 + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_QUAD) >= F128_MAXNORM_EXP) { type_option.weight = 0; - bins gt_maxNorm = {[ ('1 << (F128_FMA_PRE_ADDITION_NF - F128_M_BITS - 2)) : $]}; + bins gt_maxNorm_p_3ulp = { 1 }; } - F16_gt_maxNorm_p_3ulp: coverpoint CFI.fmaPreAddition iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) == F16_MAXNORM_EXP) { + F16_gt_maxNorm_p_3ulp: coverpoint ( + (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) == F16_MAXNORM_EXP) + ? (CFI.fmaPreAddition[(F16_FMA_PRE_ADDITION_NF + 1)] == 1 + ? |CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF -: F16_M_BITS] + : |CFI.fmaPreAddition[F16_FMA_PRE_ADDITION_NF - 1 -: F16_M_BITS]) + : '1 + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_HALF) >= F16_MAXNORM_EXP) { type_option.weight = 0; - bins gt_maxNorm = {[ ('1 << (F16_FMA_PRE_ADDITION_NF - F16_M_BITS - 2)) : $]}; + bins gt_maxNorm_p_3ulp = { 1 }; } - BF16_gt_maxNorm_p_3ulp: coverpoint CFI.fmaPreAddition iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) == BF16_MAXNORM_EXP) { + BF16_gt_maxNorm_p_3ulp: coverpoint ( + (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) == BF16_MAXNORM_EXP) + ? (CFI.fmaPreAddition[(BF16_FMA_PRE_ADDITION_NF + 1)] == 1 + ? |CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF -: BF16_M_BITS] + : |CFI.fmaPreAddition[BF16_FMA_PRE_ADDITION_NF - 1 -: BF16_M_BITS]) + : '1 + ) iff (get_effective_product_exponent(CFI.a, CFI.b, CFI.fmaPreAddition, FMT_BF16) >= BF16_MAXNORM_EXP) { type_option.weight = 0; - bins gt_maxNorm = {[ ('1 << (BF16_FMA_PRE_ADDITION_NF - BF16_M_BITS - 2)) : $]}; + bins gt_maxNorm_p_3ulp = { 1 }; } // case v @@ -432,7 +514,7 @@ covergroup B18_cg (virtual coverfloat_interface CFI); /************************************************************************ - Underflow Boundary Helper Coverpoints (from B5, commit: f5a2369 by Corey Hickson) + Underflow Boundary Helper Coverpoints (inspired by B5, commit: f5a2369 by Corey Hickson) ************************************************************************/ // cases i & ii @@ -811,20 +893,20 @@ covergroup B18_cg (virtual coverfloat_interface CFI); bins no_overflow = { 0 }; } - FP_no_underflow: coverpoint (CFI.exceptionBits & FLAG_UNDERFLOW_MASK != 0) { + FP_no_underflow: coverpoint (CFI.exceptionBits & FLAG_UNDERFLOW_MASK) { type_option.weight = 0; - bins no_underflow = { [0:1] }; + bins no_underflow = { 0 }; } `ifdef COVER_F32 B18_case_i_f32: cross F32_src_fmt, FMA_ops, F32_product_lsb, F32_product_guard, F32_product_sticky, F32_interm_guard_zero, F32_interm_sticky_zero, F32_normal_multiplication; - // B18_case_ii_b4_maxNorm_p_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_maxNorm_p_3ulp, FP_no_overflow; - // B18_case_ii_b4_maxNorm_m_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_maxNorm_m_3ulp, FP_no_overflow; - // B18_case_ii_b4_gt_maxNorm_p_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_gt_maxNorm_p_3ulp, FP_no_overflow; - // B18_case_ii_b4_maxNorm_pm3_exp_range_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_maxNorm_pm3_exp_range, FP_no_overflow; + B18_case_ii_b4_maxNorm_p_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_maxNorm_p_3ulp, FP_no_overflow; + B18_case_ii_b4_maxNorm_m_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_maxNorm_m_3ulp, FP_no_overflow; + B18_case_ii_b4_gt_maxNorm_p_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_gt_maxNorm_p_3ulp, FP_no_overflow; + B18_case_ii_b4_maxNorm_pm3_exp_range_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_maxNorm_pm3_exp_range, FP_no_overflow; B18_case_iii_b5_subnorm_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_subnorm, FP_no_underflow; B18_case_iii_b5_minSubNorm_p_3ulp_f32: cross F32_src_fmt, FMA_ops, F32_sign, F32_minSubNorm_p_3ulp, FP_no_underflow; @@ -839,10 +921,10 @@ covergroup B18_cg (virtual coverfloat_interface CFI); `ifdef COVER_F64 B18_case_i_f64: cross F64_src_fmt, FMA_ops, F64_product_lsb, F64_product_guard, F64_product_sticky, F64_interm_guard_zero, F64_interm_sticky_zero, F64_normal_multiplication; - // B18_case_ii_b4_maxNorm_p_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_maxNorm_p_3ulp, FP_no_overflow; - // B18_case_ii_b4_maxNorm_m_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_maxNorm_m_3ulp, FP_no_overflow; - // B18_case_ii_b4_gt_maxNorm_p_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_gt_maxNorm_p_3ulp, FP_no_overflow; - // B18_case_ii_b4_maxNorm_pm3_exp_range_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_maxNorm_pm3_exp_range, FP_no_overflow; + B18_case_ii_b4_maxNorm_p_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_maxNorm_p_3ulp, FP_no_overflow; + B18_case_ii_b4_maxNorm_m_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_maxNorm_m_3ulp, FP_no_overflow; + B18_case_ii_b4_gt_maxNorm_p_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_gt_maxNorm_p_3ulp, FP_no_overflow; + B18_case_ii_b4_maxNorm_pm3_exp_range_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_maxNorm_pm3_exp_range, FP_no_overflow; B18_case_iii_b5_subnorm_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_subnorm, FP_no_underflow; B18_case_iii_b5_minSubNorm_p_3ulp_f64: cross F64_src_fmt, FMA_ops, F64_sign, F64_minSubNorm_p_3ulp, FP_no_underflow; @@ -856,10 +938,10 @@ covergroup B18_cg (virtual coverfloat_interface CFI); `ifdef COVER_F128 B18_case_i_f128: cross F128_src_fmt, FMA_ops, F128_product_lsb, F128_product_guard, F128_product_sticky, F128_interm_guard_zero, F128_interm_sticky_zero, F128_normal_multiplication; - // B18_case_ii_b4_maxNorm_p_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_maxNorm_p_3ulp, FP_no_overflow; - // B18_case_ii_b4_maxNorm_m_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_maxNorm_m_3ulp, FP_no_overflow; - // B18_case_ii_b4_gt_maxNorm_p_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_gt_maxNorm_p_3ulp, FP_no_overflow; - // B18_case_ii_b4_maxNorm_pm3_exp_range_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_maxNorm_pm3_exp_range, FP_no_overflow; + B18_case_ii_b4_maxNorm_p_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_maxNorm_p_3ulp, FP_no_overflow; + B18_case_ii_b4_maxNorm_m_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_maxNorm_m_3ulp, FP_no_overflow; + B18_case_ii_b4_gt_maxNorm_p_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_gt_maxNorm_p_3ulp, FP_no_overflow; + B18_case_ii_b4_maxNorm_pm3_exp_range_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_maxNorm_pm3_exp_range, FP_no_overflow; B18_case_iii_b5_subnorm_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_subnorm, FP_no_underflow; B18_case_iii_b5_minSubNorm_p_3ulp_f128: cross F128_src_fmt, FMA_ops, F128_sign, F128_minSubNorm_p_3ulp, FP_no_underflow; From 04f00ed87556f757b9f853436add72b1eed96f4e Mon Sep 17 00:00:00 2001 From: Ryan Wolk Date: Wed, 6 May 2026 22:27:41 -0700 Subject: [PATCH 7/7] Actually enable all of the covergroups --- coverage/covergroups/B18.svh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/coverage/covergroups/B18.svh b/coverage/covergroups/B18.svh index a2c24b0..5e8c233 100644 --- a/coverage/covergroups/B18.svh +++ b/coverage/covergroups/B18.svh @@ -955,10 +955,10 @@ covergroup B18_cg (virtual coverfloat_interface CFI); `ifdef COVER_F16 B18_case_i_f16: cross F16_src_fmt, FMA_ops, F16_product_lsb, F16_product_guard, F16_product_sticky, F16_interm_guard_zero, F16_interm_sticky_zero, F16_normal_multiplication; - // B18_case_ii_b4_maxNorm_p_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_maxNorm_p_3ulp, FP_no_overflow; - // B18_case_ii_b4_maxNorm_m_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_maxNorm_m_3ulp, FP_no_overflow; - // B18_case_ii_b4_gt_maxNorm_p_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_gt_maxNorm_p_3ulp, FP_no_overflow; - // B18_case_ii_b4_maxNorm_pm3_exp_range_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_maxNorm_pm3_exp_range, FP_no_overflow; + B18_case_ii_b4_maxNorm_p_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_maxNorm_p_3ulp, FP_no_overflow; + B18_case_ii_b4_maxNorm_m_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_maxNorm_m_3ulp, FP_no_overflow; + B18_case_ii_b4_gt_maxNorm_p_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_gt_maxNorm_p_3ulp, FP_no_overflow; + B18_case_ii_b4_maxNorm_pm3_exp_range_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_maxNorm_pm3_exp_range, FP_no_overflow; B18_case_iii_b5_subnorm_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_subnorm, FP_no_underflow; B18_case_iii_b5_minSubNorm_p_3ulp_f16: cross F16_src_fmt, FMA_ops, F16_sign, F16_minSubNorm_p_3ulp, FP_no_underflow; @@ -972,10 +972,10 @@ covergroup B18_cg (virtual coverfloat_interface CFI); `ifdef COVER_BF16 B18_case_i_bf16: cross BF16_src_fmt, FMA_ops, BF16_product_lsb, BF16_product_guard, BF16_product_sticky, BF16_interm_guard_zero, BF16_interm_sticky_zero, BF16_normal_multiplication; - // B18_case_ii_b4_maxNorm_p_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_maxNorm_p_3ulp, FP_no_overflow; - // B18_case_ii_b4_maxNorm_m_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_maxNorm_m_3ulp, FP_no_overflow; - // B18_case_ii_b4_gt_maxNorm_p_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_gt_maxNorm_p_3ulp, FP_no_overflow; - // B18_case_ii_b4_maxNorm_pm3_exp_range_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_maxNorm_pm3_exp_range, FP_no_overflow; + B18_case_ii_b4_maxNorm_p_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_maxNorm_p_3ulp, FP_no_overflow; + B18_case_ii_b4_maxNorm_m_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_maxNorm_m_3ulp, FP_no_overflow; + B18_case_ii_b4_gt_maxNorm_p_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_gt_maxNorm_p_3ulp, FP_no_overflow; + B18_case_ii_b4_maxNorm_pm3_exp_range_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_maxNorm_pm3_exp_range, FP_no_overflow; B18_case_iii_b5_subnorm_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_subnorm, FP_no_underflow; B18_case_iii_b5_minSubNorm_p_3ulp_bf16: cross BF16_src_fmt, FMA_ops, BF16_sign, BF16_minSubNorm_p_3ulp, FP_no_underflow;