diff --git a/include/verilated_std_waiver.vlt b/include/verilated_std_waiver.vlt index 9d4e1534a..09ab4bd06 100644 --- a/include/verilated_std_waiver.vlt +++ b/include/verilated_std_waiver.vlt @@ -53,6 +53,7 @@ lint_off -rule MISINDENT `VLT_UVM_FILES -match "* rw_access.data=*" lint_off -rule MISINDENT `VLT_UVM_FILES -match "* uvm_cmdline_proc =*" lint_off -rule REALCVT `VLT_UVM_FILES -match "* m_time *" lint_off -rule REALCVT `VLT_UVM_FILES -match "*$realtime*" +lint_off -rule SIDEEFFECT `VLT_UVM_FILES -match "*foreach (blks[blk_].reg_files[blk_rf])*" lint_off -rule SYMRSVDWORD `VLT_UVM_FILES -match "*'delete'*" lint_off -rule SYMRSVDWORD `VLT_UVM_FILES -match "*'list'*" lint_off -rule SYMRSVDWORD `VLT_UVM_FILES -match "*'map'*" diff --git a/test_regress/t/t_foreach_sideeff_uvm.py b/test_regress/t/t_foreach_sideeff_uvm.py new file mode 100755 index 000000000..563b6fc6f --- /dev/null +++ b/test_regress/t/t_foreach_sideeff_uvm.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_st') + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_foreach_sideeff_uvm.v b/test_regress/t/t_foreach_sideeff_uvm.v new file mode 100644 index 000000000..c67b8e85c --- /dev/null +++ b/test_regress/t/t_foreach_sideeff_uvm.v @@ -0,0 +1,54 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +// verilog_format: off +`define stop $stop +`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); +// verilog_format: on + +typedef struct {int reg_files[int unsigned];} uvm_reg_t; + +module t; + uvm_reg_t blks[int unsigned]; + + initial begin + int sum; + int inner1_i; + int inner2_j; + + blks[1].reg_files[10] = 101; + blks[1].reg_files[11] = 102; + blks[3].reg_files[20] = 308; + blks[3].reg_files[21] = 309; + + foreach (blks[i]) begin + // $display("blks[%d]", i); + ++inner1_i; + // This isn't a 2D foreach, but rather a dotted reference using above loop + + // Vlt considers below blks[i]. a side effect because the AstAssocSel can + // create elements, and threw SIDEEFFECT + // As this code occurs in UVM, we special case a SIDEEFFECT suppress in + // verilated_std_waiver.vlt + // Future alternative is to auto-waiver an ArraySel under another ArraySel + // with same index in outer loop + + // verilator lint_off SIDEEFFECT + foreach (blks[i].reg_files[j]) begin + // verilator lint_on SIDEEFFECT + + ++inner2_j; + sum += blks[i].reg_files[j]; + // $display("blks[%d].reg_files[%d]", i, j); + end + end + `checkd(inner1_i, 2); + `checkd(inner2_j, 4); + `checkd(sum, 820); + $finish; + end + +endmodule