Fix coroutines without awaits to have a co_return (#4208) (#5175)

After the V3Timing refactoring the V3SchedTiming phase could apparently
move away all awaits from a coroutine without adding a co_return
statement.

Signed-off-by: Arkadiusz Kozdra <akozdra@antmicro.com>
This commit is contained in:
Arkadiusz Kozdra 2024-06-12 21:13:52 +02:00 committed by GitHub
parent bc853e260b
commit 3203019408
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 93 additions and 0 deletions

View File

@ -283,6 +283,7 @@ void transformForks(AstNetlist* const netlistp) {
// STATE
bool m_inClass = false; // Are we in a class?
bool m_beginHasAwaits = false; // Does the current begin have awaits?
bool m_awaitMoved = false; // Has the current function lost awaits?
AstFork* m_forkp = nullptr; // Current fork
AstCFunc* m_funcp = nullptr; // Current function
@ -344,7 +345,13 @@ void transformForks(AstNetlist* const netlistp) {
}
void visit(AstCFunc* nodep) override {
m_funcp = nodep;
m_awaitMoved = false;
iterateChildren(nodep);
if (nodep->isCoroutine() && m_awaitMoved
&& !nodep->stmtsp()->exists([](AstCAwait*) { return true; })) {
// co_return at the end (either that or a co_await is required in a coroutine
nodep->addStmtsp(new AstCStmt{nodep->fileline(), "co_return;\n"});
}
m_funcp = nullptr;
}
void visit(AstVar* nodep) override {
@ -399,6 +406,8 @@ void transformForks(AstNetlist* const netlistp) {
if (!m_beginHasAwaits) {
// co_return at the end (either that or a co_await is required in a coroutine
newfuncp->addStmtsp(new AstCStmt{nodep->fileline(), "co_return;\n"});
} else {
m_awaitMoved = true;
}
remapLocals(newfuncp, callp);
} else {

View File

@ -0,0 +1,22 @@
#!/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 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(simulator => 1);
compile(
verilator_flags2 => ["--exe --main --timing"],
);
execute(
check_finished => 1,
);
ok(1);
1;

View File

@ -0,0 +1,62 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2024 by Antmicro Ltd.
// SPDX-License-Identifier: CC0-1.0
event evt1;
typedef enum {ENUM_VALUE} enum_t;
class Foo;
int m_member;
enum_t m_en;
virtual task do_something();
fork
#20 begin
m_member++;
$display("this's m_member: %0d m_en: %s", m_member, m_en.name());
if (m_member != 3)
$stop;
->evt1;
end
#10 begin
m_member++;
bar(this);
end
join_none
endtask
static task bar(Foo foo);
fork
begin
foo.m_member++;
$display("foo's m_member: %0d m_en: %s", foo.m_member, foo.m_en.name());
if (foo.m_member != 2)
$stop;
end
join_none
endtask
endclass
class Subfoo extends Foo;
virtual task do_something();#5;endtask
endclass
module t();
initial begin
Subfoo subfoo;
Foo foo;
subfoo = new;
subfoo.do_something();
foo = new;
foo.m_member = 0;
foo.do_something();
end
always @(evt1) begin
$write("*-* All Finished *-*\n");
$finish;
end
endmodule