From 55958efbe1f938dcf46b3dd8c7c353dabde5700e Mon Sep 17 00:00:00 2001 From: Artur Bieniek Date: Mon, 30 Mar 2026 10:42:51 +0200 Subject: [PATCH] Fix false sensitivity of signals to unrelated interface members --- src/V3Sched.cpp | 6 ++- ...t_virtual_interface_unused_task_trigger.py | 18 ++++++++ .../t_virtual_interface_unused_task_trigger.v | 46 +++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100755 test_regress/t/t_virtual_interface_unused_task_trigger.py create mode 100644 test_regress/t/t_virtual_interface_unused_task_trigger.v diff --git a/src/V3Sched.cpp b/src/V3Sched.cpp index 6f713cce0..c2f7e24e2 100644 --- a/src/V3Sched.cpp +++ b/src/V3Sched.cpp @@ -109,9 +109,13 @@ findTriggeredIface(const AstVarScope* vscp, UASSERT_OBJ(ifacep, vscp, "Variable is not sensitive for any interface"); std::vector result; for (const auto& memberIt : vifMemberTriggered) { + // Interface member variables already identify the exact member that can + // change externally. Sensitizing them to every triggered member of the interface causes + // false feedback paths, e.g. a block reading one signal becoming spuriously sensitive to + // another signal just because both belong to the same interface. + if (memberIt.first.m_memberp != vscp->varp()) continue; if (memberIt.first.m_ifacep == ifacep) result.push_back(memberIt.second); } - UASSERT_OBJ(!result.empty(), vscp, "Did not find virtual interface trigger"); return result; } diff --git a/test_regress/t/t_virtual_interface_unused_task_trigger.py b/test_regress/t/t_virtual_interface_unused_task_trigger.py new file mode 100755 index 000000000..f2d7f08fa --- /dev/null +++ b/test_regress/t/t_virtual_interface_unused_task_trigger.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# 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-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile(verilator_flags2=['--binary', '--timing']) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_virtual_interface_unused_task_trigger.v b/test_regress/t/t_virtual_interface_unused_task_trigger.v new file mode 100644 index 000000000..9ae26cb61 --- /dev/null +++ b/test_regress/t/t_virtual_interface_unused_task_trigger.v @@ -0,0 +1,46 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain. +// SPDX-FileCopyrightText: 2026 Antmicro +// SPDX-License-Identifier: CC0-1.0 + +module leaf( + input sel, + output logic ready +); + always @(sel) + if ((sel == 1)) + ready = 1; +endmodule + +interface iface(input clk); + logic sel; + logic ready; +endinterface + +class C_noinst; + virtual iface v; + int idx = 0; + + task t_noinst(); + forever begin + @(posedge v.clk); + if (v.ready && v.sel) begin + end + end + endtask +endclass + +module t; + logic clk; + iface i(.clk(clk)); + + leaf d( + .sel(i.sel), + .ready(i.ready) + ); + + initial #1 clk = ~clk; + + initial #10 $finish; +endmodule