forked from github/verilator
Fix task calls as fork statements (#4055)
Before this patch, calling tasks directly under forks would result in each statement of these tasks being executed concurrently. This was due to Verilator inlining tasks most of the time. Such inlined tasks' statements would simply replace the original call, and there would be no indication that these used to be grouped together. Ultimately resulting in `V3Timing` treating each statement as a separate process. The solution is simply to wrap each fork sub-statement in a begin in `V3Begin` (except for the ones that are begins, as that would be pointless). `V3Begin` is already aware of forks, and is supposed to avoid issues like this one, so it seems like a natural fit. This also protects us from similar bugs, i.e. if some statement gets replaced or expanded into multiple statements. Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
This commit is contained in:
parent
577e0700ba
commit
5de8ccbf32
@ -144,9 +144,20 @@ private:
|
||||
|
||||
// VISITORS
|
||||
void visit(AstFork* nodep) override {
|
||||
// Keep this begin to group its statements together
|
||||
// Keep begins in forks to group their statements together
|
||||
VL_RESTORER(m_keepBegins);
|
||||
m_keepBegins = true;
|
||||
// If a statement is not a begin, wrap it in a begin. This fixes an issue when the
|
||||
// statement is a task call that gets inlined later (or any other statement that gets
|
||||
// replaced with multiple statements)
|
||||
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (!VN_IS(stmtp, Begin)) {
|
||||
AstBegin* const beginp = new AstBegin{stmtp->fileline(), "", nullptr};
|
||||
stmtp->replaceWith(beginp);
|
||||
beginp->addStmtsp(stmtp);
|
||||
stmtp = beginp;
|
||||
}
|
||||
}
|
||||
dotNames(nodep, "__FORK__");
|
||||
nodep->name("");
|
||||
}
|
||||
|
@ -526,7 +526,7 @@
|
||||
-V{t#,#} Resuming delayed processes
|
||||
-V{t#,#} Resuming: Process waiting at t/t_timing_class.v:91
|
||||
-V{t#,#} Resuming: Process waiting at t/t_timing_class.v:89
|
||||
-V{t#,#}+ Vt_timing_debug2_t____Vfork_h########__0__1
|
||||
-V{t#,#}+ Vt_timing_debug2_t____Vfork_h########__0__0
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aAssignDelayClass::__VnoInFunc_do_assign
|
||||
-V{t#,#}+ Vt_timing_debug2___024root___eval_act
|
||||
-V{t#,#}+ Vt_timing_debug2___024root___eval_triggers__act
|
||||
|
28
test_regress/t/t_timing_fork_taskcall.pl
Executable file
28
test_regress/t/t_timing_fork_taskcall.pl
Executable file
@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2023 by Antmicro Ltd. 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(simulator => 1);
|
||||
|
||||
if (!$Self->have_coroutines) {
|
||||
skip("No coroutine support");
|
||||
}
|
||||
else {
|
||||
compile(
|
||||
verilator_flags2 => ["--exe --main --timing"],
|
||||
make_main => 0,
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
}
|
||||
|
||||
ok(1);
|
||||
1;
|
23
test_regress/t/t_timing_fork_taskcall.v
Normal file
23
test_regress/t/t_timing_fork_taskcall.v
Normal file
@ -0,0 +1,23 @@
|
||||
// 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;
|
||||
task foo;
|
||||
#1 if ($time != 1) $stop;
|
||||
#1 if ($time != 2) $stop;
|
||||
#1 if ($time != 3) $stop;
|
||||
endtask
|
||||
|
||||
initial fork
|
||||
foo;
|
||||
foo;
|
||||
foo;
|
||||
#4 begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
join
|
||||
endmodule
|
Loading…
Reference in New Issue
Block a user