Fix reordering of function body inlined on RHS of <= NBA (#6780)

This commit is contained in:
Geza Lore 2025-12-08 18:42:52 +00:00 committed by GitHub
parent 9a23711ff9
commit 1baa832efc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 84 additions and 2 deletions

View File

@ -340,11 +340,17 @@ protected:
// We don't do AstLoop, due to the standard question of what is before vs. after
void visit(AstExprStmt* nodep) override {
VL_RESTORER(m_inDly);
m_inDly = false;
iterateChildren(nodep);
}
void visit(AstAssignDly* nodep) override {
UINFO(4, " ASSIGNDLY " << nodep);
iterate(nodep->rhsp());
VL_RESTORER(m_inDly);
m_inDly = true;
UINFO(4, " ASSIGNDLY " << nodep);
iterateChildren(nodep);
iterate(nodep->lhsp());
}
void visit(AstVarRef* nodep) override {
if (!m_stmtStackps.empty()) {

View File

@ -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('vlt_all')
test.compile(verilator_flags2=["--binary"])
test.execute()
test.passes()

View File

@ -0,0 +1,58 @@
// 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
`define stop $stop
`define check(got ,exp) do if ((got) !== (exp)) begin $write("%%Error: %s:%0d: $time=%0t got='h%x exp='h%x\n", `__FILE__,`__LINE__, $time, (got), (exp)); `stop; end while(0)
module t;
logic clk = 0;
always #5 clk = ~clk;
int cyc = 0;
always @(posedge clk) cyc <= cyc + 1;
// Constant 1 set in initial block, but not known at compile time
logic enable = 1'b0;
int array [32];
function automatic int get(logic en, logic [4:0] idx);
if (en) begin // Always taken, but need the 'if' to show bug
int tmp;
idx = ~idx;
tmp = array[~idx];
return tmp;
end else begin
return 0;
end
endfunction
int q;
always @(posedge clk) begin
// Function inlined on RHS or NBA used to have its body reordered as if
// assignments in the body were NBAs themselves.
q <= cyc == 0 ? 0 : get(enable, 5'(cyc));
end
initial begin
enable = 1'b1;
for (int n = 0; n < 32; ++n) begin
array[n] = 100 + n;
end
repeat (100) begin
@(posedge clk);
#1;
$display("$08t %3d %3d", $time, cyc - 1, q);
`check(q, cyc == 1 ? 0 : 100 + (cyc - 1) % 32);
end
$write("*-* All Finished *-*\n");
$finish;
end
endmodule