Fix wide non-blocking assignment mis-optimization (#6150) (#6152)

This commit is contained in:
Todd Strader 2025-07-02 18:43:10 -04:00 committed by GitHub
parent 73ca2ab997
commit ae0f29ed37
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 148 additions and 2 deletions

View File

@ -2107,8 +2107,9 @@ class ConstVisitor final : public VNVisitor {
AstVar* const tempPurep = new AstVar{rhsp->fileline(), VVarType::BLOCKTEMP,
m_concswapNames.get(rhsp), rhsp->dtypep()};
m_modp->addStmtsp(tempPurep);
AstNodeAssign* const asnp = nodep->cloneType(
new AstVarRef{rhsp->fileline(), tempPurep, VAccess::WRITE}, rhsp);
AstAssign* const asnp = new AstAssign(
nodep->fileline(), new AstVarRef{rhsp->fileline(), tempPurep, VAccess::WRITE},
rhsp);
nodep->addHereThisAsNext(asnp);
nodep->rhsp(new AstVarRef{rhsp->fileline(), tempPurep, VAccess::READ});
} else if (need_temp) {

View File

@ -0,0 +1,67 @@
// // verilator_coverage annotation
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2024 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
interface intf();
logic foo;
logic [31:0] bar;
logic [127:0] baz;
endinterface
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
integer cyc;
%000001 initial cyc=1;
-000001 point: comment=block hier=top.t
intf intfs [2] ();
intf intf_sel();
%000001 always_comb begin
-000001 point: comment=block hier=top.t
%000001 intfs[0].bar = 123;
-000001 point: comment=block hier=top.t
%000001 intfs[1].bar = 456;
-000001 point: comment=block hier=top.t
end
%000009 always @ (posedge clk) begin
-000009 point: comment=block hier=top.t
%000009 {intf_sel.foo, intf_sel.bar, intf_sel.baz} <=
-000009 point: comment=block hier=top.t
%000009 cyc[0] ?
-000009 point: comment=cond_then hier=top.t
-000009 point: comment=cond_else hier=top.t
%000009 {intfs[1].foo, intfs[1].bar, intfs[1].baz} :
-000009 point: comment=cond_then hier=top.t
%000009 {intfs[0].foo, intfs[0].bar, intfs[0].baz};
-000009 point: comment=cond_else hier=top.t
end
%000009 always @ (posedge clk) begin
-000009 point: comment=block hier=top.t
%000009 cyc <= cyc + 1;
-000009 point: comment=block hier=top.t
%000008 if (cyc==9) begin
-000008 point: comment=else hier=top.t
-000001 point: comment=if hier=top.t
%000001 $display("bar = %0d", intf_sel.bar);
-000001 point: comment=if hier=top.t
%000001 if (intf_sel.bar != 123) $stop();
-000001 point: comment=else hier=top.t
%000001 $write("*-* All Finished *-*\n");
-000001 point: comment=if hier=top.t
%000001 $finish;
-000001 point: comment=if hier=top.t
end
end
endmodule

View File

@ -0,0 +1,31 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2024 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
from pathlib import Path
test.scenarios('simulator')
test.compile(verilator_flags2=['--cc', '--coverage-line'])
test.execute()
test.run(cmd=[
os.environ["VERILATOR_ROOT"] + "/bin/verilator_coverage",
"--annotate-points",
"--annotate",
test.obj_dir + "/annotated",
test.obj_dir + "/coverage.dat",
],
verilator_run=True)
top = Path(test.top_filename)
test.files_identical(test.obj_dir + f"/annotated/{top.name}", test.golden_filename)
test.passes()

View File

@ -0,0 +1,47 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2024 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
interface intf();
logic foo;
logic [31:0] bar;
logic [127:0] baz;
endinterface
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
integer cyc;
initial cyc=1;
intf intfs [2] ();
intf intf_sel();
always_comb begin
intfs[0].bar = 123;
intfs[1].bar = 456;
end
always @ (posedge clk) begin
{intf_sel.foo, intf_sel.bar, intf_sel.baz} <=
cyc[0] ?
{intfs[1].foo, intfs[1].bar, intfs[1].baz} :
{intfs[0].foo, intfs[0].bar, intfs[0].baz};
end
always @ (posedge clk) begin
cyc <= cyc + 1;
if (cyc==9) begin
$display("bar = %0d", intf_sel.bar);
if (intf_sel.bar != 123) $stop();
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule