Support NBAs in initial blocks with delay/event controls (#7566) (#7600)

Fixes #7566.
This commit is contained in:
Muzaffer Kal 2026-05-17 04:34:29 -07:00 committed by GitHub
parent c1ab369da2
commit 9fe058677b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 64 additions and 2 deletions

View File

@ -320,3 +320,4 @@ emmettifelts
Yogish Sekhar
24bit-xjkp
Zubin Jain
Muzaffer Kal

View File

@ -1179,7 +1179,10 @@ List Of Warnings
Warns that the code has a delayed assignment inside of an ``initial`` or
``final`` block. If this message is suppressed, Verilator will convert
this to a non-delayed assignment. See also :option:`COMBDLY`.
this to a non-delayed assignment. With :vlopt:`--timing`, delayed
assignments in ``initial`` blocks that also contain a `#` delay
control, or `@` even control statement are scheduled as
non-blocking assignments. See also :option:`COMBDLY`.
Ignoring this warning may make Verilator simulations differ from other
simulators.

View File

@ -509,7 +509,13 @@ class ActiveVisitor final : public VNVisitor {
void visit(AstInitialStatic* nodep) override { moveUnderSpecial<AstSenItem::Static>(nodep); }
void visit(AstInitial* nodep) override {
const ActiveDlyVisitor dlyvisitor{nodep, ActiveDlyVisitor::CT_INITIAL};
const bool timedInitial
= v3Global.opt.timing().isSetTrue()
&& nodep->exists([](const AstNode* const subp) {
return VN_IS(subp, Delay) || VN_IS(subp, EventControl);
});
const ActiveDlyVisitor dlyvisitor{nodep, timedInitial ? ActiveDlyVisitor::CT_SUSPENDABLE
: ActiveDlyVisitor::CT_INITIAL};
visitSenItems(nodep);
moveUnderSpecial<AstSenItem::Initial>(nodep);
}

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'])
test.execute()
test.passes()

View File

@ -0,0 +1,34 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 Wilson Snyder
// SPDX-License-Identifier: CC0-1.0
module t;
bit clk = 0;
int cnt = 0;
bit fire = 0;
always #1 clk = ~clk;
always_ff @(posedge clk) begin
if (fire) cnt <= cnt + 1;
end
assert property (@(posedge clk) fire |-> (cnt == 0))
$write("Assertion fired and passed: cnt=%0d\n", cnt);
else begin
$write("%%Error: sampled fire=1 cnt=%0d, expected preponed cnt 0\n", cnt);
$stop;
end
initial begin
@(posedge clk);
fire <= 1;
@(posedge clk);
fire <= 0;
repeat (2) @(posedge clk);
$write("*-* All Finished *-*\n");
$finish;
end
endmodule