diff --git a/src/V3Begin.cpp b/src/V3Begin.cpp index b936e33bb..c2a06df4b 100644 --- a/src/V3Begin.cpp +++ b/src/V3Begin.cpp @@ -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(""); } diff --git a/test_regress/t/t_timing_debug2.out b/test_regress/t/t_timing_debug2.out index bbb0b3fe2..3a4ac0ecb 100644 --- a/test_regress/t/t_timing_debug2.out +++ b/test_regress/t/t_timing_debug2.out @@ -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 diff --git a/test_regress/t/t_timing_fork_taskcall.pl b/test_regress/t/t_timing_fork_taskcall.pl new file mode 100755 index 000000000..439181d0a --- /dev/null +++ b/test_regress/t/t_timing_fork_taskcall.pl @@ -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; diff --git a/test_regress/t/t_timing_fork_taskcall.v b/test_regress/t/t_timing_fork_taskcall.v new file mode 100644 index 000000000..f2b45b66b --- /dev/null +++ b/test_regress/t/t_timing_fork_taskcall.v @@ -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