Internals: Minor cleanups preparing for initialization fixes. No functional change.

This commit is contained in:
Wilson Snyder 2026-02-08 17:54:04 -05:00
parent 8700617fae
commit 9ba625225d
7 changed files with 250 additions and 244 deletions

View File

@ -5495,6 +5495,16 @@ class WidthVisitor final : public VNVisitor {
}
}
bool firstNewStatementOkRecurse(AstNode* nodep) {
if (AstVar* const varp = VN_CAST(nodep, Var)) {
if (!varp->valuep() || VN_CAST(varp->valuep(), Const) || varp->isIO()) return true;
}
if (AstAssign* const aitemp = VN_CAST(nodep, Assign)) {
if (VN_IS(aitemp->rhsp(), Const) || VN_IS(aitemp->rhsp(), CReset)) return true;
}
return false;
}
//--------------------
// Top levels
@ -6510,13 +6520,7 @@ class WidthVisitor final : public VNVisitor {
}
continue;
}
if (AstVar* const varp = VN_CAST(itemp, Var)) {
if (!varp->valuep() || VN_CAST(varp->valuep(), Const) || varp->isIO())
continue;
}
if (AstAssign* const aitemp = VN_CAST(itemp, Assign)) {
if (VN_IS(aitemp->rhsp(), Const)) continue;
}
if (firstNewStatementOkRecurse(itemp)) continue;
firstp = itemp;
}
}

View File

@ -15,56 +15,56 @@
`endif
class nba_waiter;
// Task taken from UVM
task wait_for_nba_region;
static int nba;
int next_nba;
next_nba++;
nba <= `DELAY next_nba;
@(nba);
endtask
// Task taken from UVM
task wait_for_nba_region;
static int nba;
int next_nba;
next_nba++;
nba <= `DELAY next_nba;
@(nba);
endtask
endclass
class Foo;
task bar(logic a, logic b);
static int x;
static int y;
// bar's local vars and intravals could be overwritten by other locals
if (a) x <= `DELAY 'hDEAD;
if (b) y <= `DELAY 'hBEEF;
#2
if (x != 'hDEAD) $stop;
endtask
task bar(logic a, logic b);
static int x;
static int y;
// bar's local vars and intravals could be overwritten by other locals
if (a) x <= `DELAY 'hDEAD;
if (b) y <= `DELAY 'hBEEF;
#2;
if (x != 'hDEAD) $stop;
endtask
endclass
module t;
nba_waiter waiter = new;
Foo foo = new;
event e;
int cnt = 0;
nba_waiter waiter = new;
Foo foo = new;
event e;
int cnt = 0;
initial begin
#1 ->e;
if (cnt != 0) $stop;
cnt++;
waiter.wait_for_nba_region;
->e;
if (cnt != 2) $stop;
if ($time != `TIME_AFTER_FIRST_WAIT) $stop;
cnt++;
waiter.wait_for_nba_region;
if (cnt != 4) $stop;
if ($time != `TIME_AFTER_SECOND_WAIT) $stop;
foo.bar(1, 1);
#2
$write("*-* All Finished *-*\n");
$finish;
end
initial begin
#1 ->e;
if (cnt != 0) $stop;
cnt++;
waiter.wait_for_nba_region;
->e;
if (cnt != 2) $stop;
if ($time != `TIME_AFTER_FIRST_WAIT) $stop;
cnt++;
waiter.wait_for_nba_region;
if (cnt != 4) $stop;
if ($time != `TIME_AFTER_SECOND_WAIT) $stop;
foo.bar(1, 1);
#2;
$write("*-* All Finished *-*\n");
$finish;
end
initial begin
@e if (cnt != 1) $stop;
cnt++;
@e if (cnt != 3) $stop;
cnt++;
end
initial begin
@e if (cnt != 1) $stop;
cnt++;
@e if (cnt != 3) $stop;
cnt++;
end
endmodule

View File

@ -8,44 +8,44 @@ class Foo;
task do_something(int arg_v);
int dynscope_var;
int x;
dynscope_var = 0;
if (dynscope_var != 0) $stop;
dynscope_var = 10;
if (dynscope_var != 10) $stop;
fork
#10 begin
x = 0;
// Test capturing a variable that needs to be modified
$display("Incremented dynscope_var: %d", ++dynscope_var);
if (dynscope_var != 1)
$stop;
if (dynscope_var != 10) $stop;
$display("Incremented dynscope_var: %0d", ++dynscope_var);
if (dynscope_var != 11) $stop;
// Check nested access
fork
#10 begin
$display("Incremented x: %d", ++x);
$display("Incremented dynscope_var: %d", ++dynscope_var);
if (dynscope_var != 2)
$stop;
$display("Incremented x: %0d", ++x);
$display("Incremented dynscope_var: %0d", ++dynscope_var);
if (dynscope_var != 12) $stop;
end
join_none
end
#10 begin
// Same as the first check, but with an argument
// (so it needs to be copied to the dynamic scope instead of being moved there)
$display("Incremented arg_v: %d", ++arg_v);
if (arg_v != 2)
$stop;
if (arg_v != 1) $stop;
$display("Incremented arg_v: %0d", ++arg_v);
if (arg_v != 2) $stop;
end
join_none
// Check if regular access to arg_v has been substituted with access to its copy from
// a dynamic scope
$display("Incremented arg_v: %d", ++arg_v);
if (arg_v != 1)
$stop;
$display("Incremented arg_v: %0d", ++arg_v);
if (arg_v != 1) $stop;
endtask
endclass
module t();
module t;
initial begin
Foo foo;
foo = new;

View File

@ -5,22 +5,22 @@
// SPDX-License-Identifier: CC0-1.0
module t;
process job;
process job;
initial begin
process p1 = process::self();
fork
begin
wait(p1.status() != process::RUNNING);
$write("job started\n");
job = process::self();
end
join_none
wait (job);
$write("all jobs started\n");
job.await();
$write("all jobs finished\n");
$write("*-* All Finished *-*\n");
$finish;
end
initial begin
automatic process p1 = process::self();
fork
begin
wait (p1.status() != process::RUNNING);
$write("job started\n");
job = process::self();
end
join_none
wait (job);
$write("all jobs started\n");
job.await();
$write("all jobs finished\n");
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -5,152 +5,152 @@
// SPDX-License-Identifier: CC0-1.0
class Foo;
rand int zero;
int two;
rand int zero;
int two;
endclass
class Bar extends Foo;
rand int one;
static int three;
rand int one;
static int three;
function void test;
logic[1:0] ok = '0;
zero = 100;
one = 200;
two = 300;
three = 400;
for (int i = 0; i < 20; i++) begin
void'(randomize(one));
if (zero != 100) $stop;
if (one != 200) ok[0] = 1;
if (two != 300) $stop;
if (three != 400) $stop;
end
if (!ok[0]) $stop;
ok = '0;
function void test;
logic [1:0] ok = '0;
zero = 100;
one = 200;
two = 300;
three = 400;
for (int i = 0; i < 20; i++) begin
void'(randomize(one));
if (zero != 100) $stop;
if (one != 200) ok[0] = 1;
if (two != 300) $stop;
if (three != 400) $stop;
end
if (!ok[0]) $stop;
ok = '0;
if (zero.rand_mode() != 1) $stop;
if (one.rand_mode() != 1) $stop;
zero = 500;
one = 600;
two = 700;
three = 800;
one.rand_mode(0);
for (int i = 0; i < 20; i++) begin
void'(randomize(one, two));
if (zero != 500) $stop;
if (one != 600) ok[0] = 1;
if (two != 700) ok[1] = 1;
if (three != 800) $stop;
end
if (one.rand_mode() != 0) $stop;
one.rand_mode(1);
if (ok != 'b11) $stop;
endfunction
if (zero.rand_mode() != 1) $stop;
if (one.rand_mode() != 1) $stop;
zero = 500;
one = 600;
two = 700;
three = 800;
one.rand_mode(0);
for (int i = 0; i < 20; i++) begin
void'(randomize(one, two));
if (zero != 500) $stop;
if (one != 600) ok[0] = 1;
if (two != 700) ok[1] = 1;
if (three != 800) $stop;
end
if (one.rand_mode() != 0) $stop;
one.rand_mode(1);
if (ok != 'b11) $stop;
endfunction
endclass
class Baz;
int four;
Bar bar;
int four;
Bar bar;
function new;
bar = new;
endfunction
function new;
bar = new;
endfunction
endclass
class Qux;
Baz baz;
Baz baz;
function new;
baz = new;
endfunction
function new;
baz = new;
endfunction
endclass
class Boo extends Bar;
rand int five;
rand int five;
endclass
module t;
initial begin
Boo boo = new;
Bar bar = boo;
Qux qux = new;
logic[2:0] ok = '0;
initial begin
automatic Boo boo = new;
automatic Bar bar = boo;
automatic Qux qux = new;
automatic logic [2:0] ok = '0;
bar.test;
bar.test;
bar.zero = 1000;
bar.one = 2000;
bar.two = 3000;
bar.three = 4000;
boo.five = 999999;
for (int i = 0; i < 20; i++) begin
int res = bar.randomize(two);
if (boo.five != 999999) $stop;
end
bar.zero = 1000;
bar.one = 2000;
bar.two = 3000;
bar.three = 4000;
boo.five = 999999;
for (int i = 0; i < 20; i++) begin
automatic int res = bar.randomize(two);
if (boo.five != 999999) $stop;
end
bar.zero = 1000;
bar.one = 2000;
bar.two = 3000;
bar.three = 4000;
boo.five = 999999;
for (int i = 0; i < 20; i++) begin
int res = bar.randomize(two) with { two > 3000 && two < 4000; };
if (bar.zero != 1000) $stop;
if (bar.one != 2000) $stop;
if (!(bar.two > 3000 && bar.two < 4000)) $stop;
if (bar.three != 4000) $stop;
if (boo.five != 999999) $stop;
end
bar.zero = 1000;
bar.one = 2000;
bar.two = 3000;
bar.three = 4000;
boo.five = 999999;
for (int i = 0; i < 20; i++) begin
automatic int res = bar.randomize(two) with {two > 3000 && two < 4000;};
if (bar.zero != 1000) $stop;
if (bar.one != 2000) $stop;
if (!(bar.two > 3000 && bar.two < 4000)) $stop;
if (bar.three != 4000) $stop;
if (boo.five != 999999) $stop;
end
qux.baz.bar.zero = 5000;
qux.baz.bar.one = 6000;
qux.baz.bar.two = 7000;
qux.baz.bar.three = 8000;
qux.baz.four = 9000;
for (int i = 0; i < 20; i++) begin
void'(qux.randomize(baz));
if (qux.baz.bar.zero != 5000) $stop;
if (qux.baz.bar.one != 6000) $stop;
if (qux.baz.bar.two != 7000) $stop;
if (qux.baz.bar.three != 8000) $stop;
if (qux.baz.four != 9000) $stop;
end
for (int i = 0; i < 20; i++) begin
void'(qux.randomize(baz.bar));
if (qux.baz.bar.zero != 5000) ok[0] = 1;
if (qux.baz.bar.one != 6000) ok[1] = 1;
if (qux.baz.bar.two != 7000) $stop;
if (qux.baz.bar.three != 8000) $stop;
if (qux.baz.four != 9000) $stop;
end
if (!ok[0]) $stop;
if (!ok[1]) $stop;
ok = '0;
qux.baz.bar.zero = 10000;
qux.baz.bar.one = 20000;
for (int i = 0; i < 20; i++) begin
void'(qux.randomize(baz.four));
if (qux.baz.bar.zero != 10000) $stop;
if (qux.baz.bar.one != 20000) $stop;
if (qux.baz.bar.two != 7000) $stop;
if (qux.baz.bar.three != 8000) $stop;
if (qux.baz.four != 9000) ok[0] = 1;
end
if (!ok[0]) $stop;
ok = '0;
qux.baz.four = 30000;
for (int i = 0; i < 20; i++) begin
void'(qux.randomize(baz.bar, qux.baz.bar.one, baz.four));
if (qux.baz.bar.zero != 10000) ok[0] = 1;
if (qux.baz.bar.one != 20000) ok[1] = 1;
if (qux.baz.bar.two != 7000) $stop;
if (qux.baz.bar.three != 8000) $stop;
if (qux.baz.four != 30000) ok[2] = 1;
end
if (ok != 'b111) $stop;
qux.baz.bar.zero = 5000;
qux.baz.bar.one = 6000;
qux.baz.bar.two = 7000;
qux.baz.bar.three = 8000;
qux.baz.four = 9000;
for (int i = 0; i < 20; i++) begin
void'(qux.randomize(baz));
if (qux.baz.bar.zero != 5000) $stop;
if (qux.baz.bar.one != 6000) $stop;
if (qux.baz.bar.two != 7000) $stop;
if (qux.baz.bar.three != 8000) $stop;
if (qux.baz.four != 9000) $stop;
end
for (int i = 0; i < 20; i++) begin
void'(qux.randomize(baz.bar));
if (qux.baz.bar.zero != 5000) ok[0] = 1;
if (qux.baz.bar.one != 6000) ok[1] = 1;
if (qux.baz.bar.two != 7000) $stop;
if (qux.baz.bar.three != 8000) $stop;
if (qux.baz.four != 9000) $stop;
end
if (!ok[0]) $stop;
if (!ok[1]) $stop;
ok = '0;
qux.baz.bar.zero = 10000;
qux.baz.bar.one = 20000;
for (int i = 0; i < 20; i++) begin
void'(qux.randomize(baz.four));
if (qux.baz.bar.zero != 10000) $stop;
if (qux.baz.bar.one != 20000) $stop;
if (qux.baz.bar.two != 7000) $stop;
if (qux.baz.bar.three != 8000) $stop;
if (qux.baz.four != 9000) ok[0] = 1;
end
if (!ok[0]) $stop;
ok = '0;
qux.baz.four = 30000;
for (int i = 0; i < 20; i++) begin
void'(qux.randomize(baz.bar, qux.baz.bar.one, baz.four));
if (qux.baz.bar.zero != 10000) ok[0] = 1;
if (qux.baz.bar.one != 20000) ok[1] = 1;
if (qux.baz.bar.two != 7000) $stop;
if (qux.baz.bar.three != 8000) $stop;
if (qux.baz.four != 30000) ok[2] = 1;
end
if (ok != 'b111) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -1,71 +1,71 @@
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:101:17: Static variable initializer
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:103:17: Static variable initializer
: is dependent on function/task I/O variable
101 | logic tmp = in;
103 | logic tmp = in;
| ^~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:106:17: Static variable initializer
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:108:17: Static variable initializer
: is dependent on function/task I/O variable
106 | logic tmp = in;
108 | logic tmp = in;
| ^~
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:111:24: Static variable initializer
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:113:24: Static variable initializer
: is dependent on function/task I/O variable
111 | static logic tmp = in;
113 | static logic tmp = in;
| ^~
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:116:17: Static variable initializer
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:118:17: Static variable initializer
: is dependent on function/task I/O variable
116 | logic tmp = out;
118 | logic tmp = out;
| ^~~
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:121:20: Static variable initializer
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:123:20: Static variable initializer
: is dependent on function/task I/O variable
121 | logic tmp = in + 1;
123 | logic tmp = in + 1;
| ^
%Error: t/t_var_static_assign_decl_bad.v:126:26: Static variable initializer
%Error: t/t_var_static_assign_decl_bad.v:128:26: Static variable initializer
: is dependent on automatic variable
126 | static int foo = tmp + 1;
128 | static int foo = tmp + 1;
| ^
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: t/t_var_static_assign_decl_bad.v:132:26: Static variable initializer
%Error: t/t_var_static_assign_decl_bad.v:134:26: Static variable initializer
: is dependent on automatic variable
132 | static int foo = tmp + 1;
134 | static int foo = tmp + 1;
| ^
%Error: t/t_var_static_assign_decl_bad.v:138:29: Static variable initializer
%Error: t/t_var_static_assign_decl_bad.v:140:29: Static variable initializer
: is dependent on automatic variable
138 | static logic func_var = loc;
140 | static logic func_var = loc;
| ^~~
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:9:15: Static variable initializer
: is dependent on function/task I/O variable
9 | logic tmp = in;
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:11:15: Static variable initializer
: is dependent on function/task I/O variable
11 | logic tmp = in;
| ^~
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:14:15: Static variable initializer
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:16:15: Static variable initializer
: is dependent on function/task I/O variable
14 | logic tmp = in;
16 | logic tmp = in;
| ^~
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:20:17: Static variable initializer
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:22:17: Static variable initializer
: is dependent on function/task I/O variable
20 | logic tmp = in;
22 | logic tmp = in;
| ^~
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:25:17: Static variable initializer
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:27:17: Static variable initializer
: is dependent on function/task I/O variable
25 | logic tmp = in;
27 | logic tmp = in;
| ^~
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:32:17: Static variable initializer
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:34:17: Static variable initializer
: is dependent on function/task I/O variable
32 | logic tmp = in;
34 | logic tmp = in;
| ^~
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:37:17: Static variable initializer
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:39:17: Static variable initializer
: is dependent on function/task I/O variable
37 | logic tmp = in;
39 | logic tmp = in;
| ^~
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:44:17: Static variable initializer
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:46:17: Static variable initializer
: is dependent on function/task I/O variable
44 | logic tmp = in;
46 | logic tmp = in;
| ^~
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:49:17: Static variable initializer
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:51:17: Static variable initializer
: is dependent on function/task I/O variable
49 | logic tmp = in;
51 | logic tmp = in;
| ^~
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:72:17: Static variable initializer
%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:74:17: Static variable initializer
: is dependent on function/task I/O variable
72 | logic tmp = in;
74 | logic tmp = in;
| ^~
%Error: Exiting due to

View File

@ -4,6 +4,8 @@
// SPDX-FileCopyrightText: 2024 Antmicro
// SPDX-License-Identifier: CC0-1.0
// verilator lint_off NORETURN
function static func_stat;
input logic in;
logic tmp = in;
@ -63,8 +65,8 @@ module no_warn#(PARAM = 1)(input in, input clk);
// Do not warn on constant assignments.
function static func_param;
static logic func_var = PARAM;
static logic func_enum = A;
static bit func_var = PARAM != 0;
static bit func_enum = A != B;
endfunction
// Do not warn on assignment referencing module I/O.