Fix false sensitivity of signals to unrelated interface members

This commit is contained in:
Artur Bieniek 2026-03-30 10:42:51 +02:00 committed by GitHub
parent be6780e44b
commit 55958efbe1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 69 additions and 1 deletions

View File

@ -109,9 +109,13 @@ findTriggeredIface(const AstVarScope* vscp,
UASSERT_OBJ(ifacep, vscp, "Variable is not sensitive for any interface");
std::vector<AstSenTree*> 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;
}

View File

@ -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()

View File

@ -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