Add error on module automatic variables.
This commit is contained in:
parent
2a498cb670
commit
4e866fd710
|
|
@ -300,6 +300,12 @@ class LinkParseVisitor final : public VNVisitor {
|
|||
nodep->v3warn(STATICVAR, "Static variable with assignment declaration declared in a "
|
||||
"loop converted to automatic");
|
||||
}
|
||||
if (!m_lifetimeAllowed && nodep->lifetime().isAutomatic()) {
|
||||
nodep->v3error(
|
||||
"Module variables cannot have automatic lifetime (IEEE 1800-2023 6.21): "
|
||||
<< nodep->prettyNameQ());
|
||||
nodep->lifetime(VLifetime::STATIC);
|
||||
}
|
||||
if (!nodep->direction().isAny()) { // Not a port
|
||||
if (nodep->lifetime().isNone()) {
|
||||
if (m_lifetimeAllowed) {
|
||||
|
|
|
|||
|
|
@ -1,42 +1,34 @@
|
|||
%Error: t/t_assign_automatic_bad.v:37:10: Automatic lifetime variable not allowed in continuous assignment (IEEE 1800-2023 6.21): 'bad_auto3'
|
||||
%Error: t/t_assign_automatic_bad.v:35:10: Dynamically-sized variable not allowed in continuous assignment (IEEE 1800-2023 6.21): 'bad_dyn5'
|
||||
: ... note: In instance 't'
|
||||
37 | assign bad_auto3 = 2;
|
||||
| ^~~~~~~~~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: t/t_assign_automatic_bad.v:38:10: Dynamically-sized variable not allowed in continuous assignment (IEEE 1800-2023 6.21): 'bad_dyn5'
|
||||
: ... note: In instance 't'
|
||||
38 | assign bad_dyn5[0] = empty_dyn;
|
||||
35 | assign bad_dyn5[0] = empty_dyn;
|
||||
| ^~~~~~~~
|
||||
%Error: t/t_assign_automatic_bad.v:40:12: Automatic lifetime variable not allowed in continuous assignment (IEEE 1800-2023 6.21): 'm_bad1'
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: t/t_assign_automatic_bad.v:37:12: Automatic lifetime variable not allowed in continuous assignment (IEEE 1800-2023 6.21): 'm_bad1'
|
||||
: ... note: In instance 't'
|
||||
40 | assign c.m_bad1 = 2;
|
||||
37 | assign c.m_bad1 = 2;
|
||||
| ^~~~~~
|
||||
%Error: t/t_assign_automatic_bad.v:50:5: Automatic lifetime variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 'bad_auto4'
|
||||
%Error: t/t_assign_automatic_bad.v:47:5: Dynamically-sized variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 'bad_dyn6'
|
||||
: ... note: In instance 't'
|
||||
50 | bad_auto4 <= 2;
|
||||
| ^~~~~~~~~
|
||||
%Error: t/t_assign_automatic_bad.v:51:5: Dynamically-sized variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 'bad_dyn6'
|
||||
: ... note: In instance 't'
|
||||
51 | bad_dyn6[0] <= 2;
|
||||
47 | bad_dyn6[0] <= 2;
|
||||
| ^~~~~~~~
|
||||
%Error: t/t_assign_automatic_bad.v:53:5: Dynamically-sized variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 'bad_queue'
|
||||
%Error: t/t_assign_automatic_bad.v:49:5: Dynamically-sized variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 'bad_queue'
|
||||
: ... note: In instance 't'
|
||||
53 | bad_queue[0] <= 2;
|
||||
49 | bad_queue[0] <= 2;
|
||||
| ^~~~~~~~~
|
||||
%Error: t/t_assign_automatic_bad.v:55:5: Dynamically-sized variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 'bad_assoc'
|
||||
%Error: t/t_assign_automatic_bad.v:51:5: Dynamically-sized variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 'bad_assoc'
|
||||
: ... note: In instance 't'
|
||||
55 | bad_assoc[0] <= 2;
|
||||
51 | bad_assoc[0] <= 2;
|
||||
| ^~~~~~~~~
|
||||
%Error: t/t_assign_automatic_bad.v:58:7: Automatic lifetime variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 'm_bad2'
|
||||
%Error: t/t_assign_automatic_bad.v:54:7: Automatic lifetime variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 'm_bad2'
|
||||
: ... note: In instance 't'
|
||||
58 | c.m_bad2 <= 2;
|
||||
54 | c.m_bad2 <= 2;
|
||||
| ^~~~~~
|
||||
%Error: t/t_assign_automatic_bad.v:60:10: Dynamically-sized variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 's_dyn'
|
||||
%Error: t/t_assign_automatic_bad.v:56:10: Dynamically-sized variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 's_dyn'
|
||||
: ... note: In instance 't'
|
||||
60 | Cls::s_dyn[0] <= 2;
|
||||
56 | Cls::s_dyn[0] <= 2;
|
||||
| ^~~~~
|
||||
%Error: t/t_assign_automatic_bad.v:62:26: Dynamically-sized variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 's_dyn'
|
||||
%Error: t/t_assign_automatic_bad.v:58:26: Dynamically-sized variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 's_dyn'
|
||||
: ... note: In instance 't'
|
||||
62 | clist[bad_dyn6[0]++].s_dyn[0] <= '1;
|
||||
58 | clist[bad_dyn6[0]++].s_dyn[0] <= '1;
|
||||
| ^~~~~
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -23,8 +23,6 @@ module t(clk);
|
|||
|
||||
Cls c;
|
||||
|
||||
automatic int bad_auto3;
|
||||
automatic int bad_auto4;
|
||||
int bad_dyn5[];
|
||||
int bad_dyn6[];
|
||||
int empty_dyn[];
|
||||
|
|
@ -34,7 +32,6 @@ module t(clk);
|
|||
int bad_assoc[int];
|
||||
Cls clist[1];
|
||||
|
||||
assign bad_auto3 = 2; // <--- Error: continuous automatic
|
||||
assign bad_dyn5[0] = empty_dyn; // <--- Error: continuous dynarray element
|
||||
assign bad_dyn5 = empty_dyn; // <--- OK: continuous dynarray assignment, not to its element
|
||||
assign c.m_bad1 = 2; // <--- Error: continuous class non-static
|
||||
|
|
@ -47,7 +44,6 @@ module t(clk);
|
|||
endtask
|
||||
|
||||
always @(posedge clk) begin
|
||||
bad_auto4 <= 2; // <--- Error: nonblocking automatic
|
||||
bad_dyn6[0] <= 2; // <--- Error: nonblocking dynarray element
|
||||
bad_dyn6 <= empty_dyn; // <--- OK: nonblocking dynarray assignment, not to its element
|
||||
bad_queue[0] <= 2; // Error: nonblocking queue element assignment
|
||||
|
|
|
|||
|
|
@ -34,9 +34,6 @@ endclass
|
|||
|
||||
module t;
|
||||
|
||||
automatic int rand_result, v1, v2;
|
||||
automatic string s;
|
||||
|
||||
initial begin
|
||||
Cls c;
|
||||
c = new;
|
||||
|
|
|
|||
|
|
@ -5,35 +5,35 @@
|
|||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
class Cls;
|
||||
rand int length;
|
||||
rand int length;
|
||||
endclass
|
||||
|
||||
module t;
|
||||
|
||||
automatic int rand_result, v1, v2;
|
||||
automatic string s;
|
||||
int rand_result, v1, v2;
|
||||
string s;
|
||||
|
||||
initial begin
|
||||
Cls c;
|
||||
c = new;
|
||||
initial begin
|
||||
Cls c;
|
||||
c = new;
|
||||
|
||||
s = c.get_randstate();
|
||||
s = c.get_randstate();
|
||||
|
||||
rand_result = c.randomize();
|
||||
if (rand_result != 1) $stop;
|
||||
v1 = c.length;
|
||||
rand_result = c.randomize();
|
||||
if (rand_result != 1) $stop;
|
||||
v1 = c.length;
|
||||
|
||||
c.set_randstate(s);
|
||||
c.set_randstate(s);
|
||||
|
||||
rand_result = c.randomize();
|
||||
if (rand_result != 1) $stop;
|
||||
v2 = c.length;
|
||||
rand_result = c.randomize();
|
||||
if (rand_result != 1) $stop;
|
||||
v2 = c.length;
|
||||
|
||||
`ifdef VERILATOR // About half of the other simulators fail at this
|
||||
if (v1 != v2) $stop;
|
||||
if (v1 != v2) $stop;
|
||||
`endif
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -4,21 +4,10 @@
|
|||
// any use, without warranty, 2025 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// verilog_format: off
|
||||
`define stop $stop
|
||||
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
|
||||
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
|
||||
`define checks(gotv,expv) do if ((gotv) != (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
|
||||
`define checkp(gotv,expv_s) do begin string gotv_s; gotv_s = $sformatf("%p", gotv); if ((gotv_s) != (expv_s)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv_s), (expv_s)); `stop; end end while(0);
|
||||
// verilog_format: on
|
||||
|
||||
module t;
|
||||
const static int a1;
|
||||
const static int a2 = 0;
|
||||
|
||||
const automatic int b1;
|
||||
const automatic int b2 = 0;
|
||||
|
||||
initial begin
|
||||
const static int c1;
|
||||
const static int c2 = 0;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
%Error: t/t_var_lifetime_module_bad.v:8:17: Module variables cannot have automatic lifetime (IEEE 1800-2023 6.21): 'i'
|
||||
8 | automatic int i;
|
||||
| ^
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: Exiting due to
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#!/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('linter')
|
||||
|
||||
test.lint(fails=True, expect_filename=test.golden_filename)
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
// 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
|
||||
|
||||
module t;
|
||||
automatic int i;
|
||||
endmodule
|
||||
Loading…
Reference in New Issue