diff --git a/src/V3Coverage.cpp b/src/V3Coverage.cpp index 3ec67eb85..68e98835c 100644 --- a/src/V3Coverage.cpp +++ b/src/V3Coverage.cpp @@ -39,17 +39,28 @@ class ExprCoverageEligibleVisitor final : public VNVisitor { // STATE bool m_eligible = true; + static bool elemDTypeEligible(const AstNodeDType* dtypep) { + dtypep = dtypep->skipRefp(); + if (AstNodeDType* const dtp = dtypep->virtRefDTypep()) { + if (!elemDTypeEligible(dtp)) return false; + } + if (AstNodeDType* const dtp = dtypep->virtRefDType2p()) { + if (!elemDTypeEligible(dtp)) return false; + } + return !VN_IS(dtypep, ClassRefDType); + } + void visit(AstNodeVarRef* nodep) override { AstNodeDType* dtypep = nodep->varp()->dtypep(); - // Class objecs and references not supported for expression coverage + // Class objects and references not supported for expression coverage // because the object may not persist until the point at which // coverage data is gathered // This could be resolved in the future by protecting against dereferrencing // null pointers when cloning the expression for expression coverage - if (VN_CAST(dtypep, ClassRefDType)) { - m_eligible = false; - } else { + if (dtypep && elemDTypeEligible(dtypep)) { iterateChildren(nodep); + } else { + m_eligible = false; } } @@ -858,7 +869,6 @@ class CoverageVisitor final : public VNVisitor { != strs[!term.m_objective].end()) impossible = true; } - if (!redundant) expr.push_back(term); } if (!impossible) m_exprs.push_back(std::move(expr)); diff --git a/test_regress/t/t_cover_expr_array_class.py b/test_regress/t/t_cover_expr_array_class.py new file mode 100755 index 000000000..27aec629f --- /dev/null +++ b/test_regress/t/t_cover_expr_array_class.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile(verilator_flags2=['--coverage-expr']) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_cover_expr_array_class.v b/test_regress/t/t_cover_expr_array_class.v new file mode 100644 index 000000000..1c82e6a45 --- /dev/null +++ b/test_regress/t/t_cover_expr_array_class.v @@ -0,0 +1,26 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +class Class1; + int value0 = 7; +endclass + +module t; + initial begin + int i = 0; + Class1 q[15]; + for (int j = 0; j < 15; j = j + 1) begin + Class1 x = new; + q[j] = x; + end + while (i < 15) begin + if ((q[i].value0 > 8) || (q[i].value0 < 5)) $stop; + i += 1; + end + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_cover_expr_associative_array_class.py b/test_regress/t/t_cover_expr_associative_array_class.py new file mode 100755 index 000000000..27aec629f --- /dev/null +++ b/test_regress/t/t_cover_expr_associative_array_class.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile(verilator_flags2=['--coverage-expr']) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_cover_expr_associative_array_class.v b/test_regress/t/t_cover_expr_associative_array_class.v new file mode 100644 index 000000000..2c1057a3b --- /dev/null +++ b/test_regress/t/t_cover_expr_associative_array_class.v @@ -0,0 +1,26 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +class Class1; + int value0 = 7; +endclass + +module t; + initial begin + int i = 0; + Class1 q[int] = '{}; + for (int j = 0; j < 15; j = j + 1) begin + Class1 x = new; + q[j] = x; + end + while (i < 15) begin + if ((q[i].value0 > 8) || (q[i].value0 < 5)) $stop; + i += 1; + end + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_cover_expr_dyn_array_class.py b/test_regress/t/t_cover_expr_dyn_array_class.py new file mode 100755 index 000000000..27aec629f --- /dev/null +++ b/test_regress/t/t_cover_expr_dyn_array_class.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile(verilator_flags2=['--coverage-expr']) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_cover_expr_dyn_array_class.v b/test_regress/t/t_cover_expr_dyn_array_class.v new file mode 100644 index 000000000..5cd5ab1cc --- /dev/null +++ b/test_regress/t/t_cover_expr_dyn_array_class.v @@ -0,0 +1,26 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +class Class1; + int value0 = 7; +endclass + +module t; + initial begin + int i = 0; + Class1 q[] = new [15]; + for (int j = 0; j < 15; j = j + 1) begin + Class1 x = new; + q[j] = x; + end + while (i < 15) begin + if ((q[i].value0 > 8) || (q[i].value0 < 5)) $stop; + i += 1; + end + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_cover_expr_queue_class.py b/test_regress/t/t_cover_expr_queue_class.py new file mode 100755 index 000000000..27aec629f --- /dev/null +++ b/test_regress/t/t_cover_expr_queue_class.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile(verilator_flags2=['--coverage-expr']) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_cover_expr_queue_class.v b/test_regress/t/t_cover_expr_queue_class.v new file mode 100644 index 000000000..fefcb0f36 --- /dev/null +++ b/test_regress/t/t_cover_expr_queue_class.v @@ -0,0 +1,26 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +class Class1; + int value0 = 7; +endclass + +module t; + initial begin + int i = 0; + Class1 q[$]; + repeat(15) begin + Class1 x = new; + q = { q, x }; + end + while (i < q.size()) begin + if ((q[i].value0 > 8) || (q[i].value0 < 5)) $stop; + i += 1; + end + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule