Fix detection of mixed blocking and nonblocking assignment in nested assignments (#4404)

This commit is contained in:
Ryszard Rozak 2023-08-07 11:35:44 +02:00 committed by GitHub
parent b1c1aa53a9
commit b0942ed8c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 75 additions and 0 deletions

View File

@ -623,6 +623,12 @@ private:
m_inLoop = true;
iterateChildren(nodep);
}
void visit(AstNodeAssign* nodep) override {
VL_RESTORER(m_inDly);
// Restoring is needed in nested assignments, like a <= (x = y);
m_inDly = false;
iterateChildren(nodep);
}
//--------------------
void visit(AstNode* nodep) override { iterateChildren(nodep); }

View File

@ -0,0 +1,11 @@
%Error-BLKANDNBLK: t/t_assign_on_rhs_of_nonblocking_unsup.v:15:8: Unsupported: Blocked and non-blocking assignments to same variable: 't.x'
15 | int x;
| ^
t/t_assign_on_rhs_of_nonblocking_unsup.v:24:18: ... Location of blocking assignment
24 | y <= (x = 2);
| ^
t/t_assign_on_rhs_of_nonblocking_unsup.v:21:10: ... Location of nonblocking assignment
21 | x <= 1;
| ^
... For error description see https://verilator.org/warn/BLKANDNBLK?v=latest
%Error: Exiting due to

View File

@ -0,0 +1,19 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2009 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
scenarios(linter => 1);
lint(
fails => 1,
expect_filename => $Self->{golden_filename},
);
ok(1);
1;

View File

@ -0,0 +1,33 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2023 by Antmicro Ltd.
// SPDX-License-Identifier: CC0-1.0
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
integer cyc = 0;
int x;
int y;
always @ (posedge clk) begin
cyc <= cyc + 1;
if (cyc == 0) begin
x <= 1;
end
else if (cyc == 1) begin
y <= (x = 2);
end else begin
if (x != 2) $stop;
if (y != 2) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule

View File

@ -48,15 +48,21 @@ module t (/*AUTOARG*/
end
//
else if (cyc == 10) begin
/* verilator lint_off BLKANDNBLK */
i_cast <= $cast(e, 60'h1234);
/* verilator lint_on BLKANDNBLK */
end
else if (cyc == 11) begin
`checkh(i_cast, 0);
/* verilator lint_off BLKANDNBLK */
i_cast <= $cast(e, 60'h1);
/* verilator lint_on BLKANDNBLK */
end
else if (cyc == 12) begin
`checkh(i_cast, 1);
/* verilator lint_off BLKANDNBLK */
i_cast <= $cast(e, 60'h1234_4567_abcd);
/* verilator lint_on BLKANDNBLK */
end
else if (cyc == 13) begin
`checkh(i_cast, 1);