Add warning that timing controls in DPI exports are unsupported (#4238)

Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
This commit is contained in:
Krzysztof Bieganski 2023-05-30 15:00:10 +02:00 committed by GitHub
parent ba82d43ca1
commit 77502aeb97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 51 additions and 44 deletions

View File

@ -568,17 +568,25 @@ private:
}
void visit(AstCFunc* nodep) override {
iterateChildren(nodep);
if (nodep->user2()) {
nodep->rtnType("VlCoroutine");
// If in a class, create a shared pointer to 'this'
if (m_classp) nodep->addInitsp(new AstCStmt{nodep->fileline(), "VL_KEEP_THIS;\n"});
if (!nodep->exists([](AstCAwait*) { return true; })) {
// It's a coroutine but has no awaits (a class method that overrides/is
// overridden by a suspendable, but doesn't have any awaits itself). Add a
// 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"});
}
if (!nodep->user2()) return;
nodep->rtnType("VlCoroutine");
// If in a class, create a shared pointer to 'this'
if (m_classp) nodep->addInitsp(new AstCStmt{nodep->fileline(), "VL_KEEP_THIS;\n"});
AstNode* firstCoStmtp = nullptr; // First co_* statement in the function
nodep->exists([&](AstCAwait* const awaitp) -> bool { return (firstCoStmtp = awaitp); });
if (!firstCoStmtp) {
// It's a coroutine but has no awaits (a class method that overrides/is
// overridden by a suspendable, but doesn't have any awaits itself). Add a
// co_return at the end (either that or a co_await is required in a
// coroutine)
firstCoStmtp = new AstCStmt{nodep->fileline(), "co_return;\n"};
nodep->addStmtsp(firstCoStmtp);
}
if (nodep->dpiExportImpl()) {
// A DPI-exported coroutine won't be able to block the calling code
// Error on the await node; fall back to the function node
firstCoStmtp->v3warn(E_UNSUPPORTED,
"Unsupported: Timing controls inside DPI-exported tasks");
}
}
void visit(AstNodeCCall* nodep) override {

View File

@ -1,28 +0,0 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# This file ONLY is placed under the Creative Commons Public Domain, for
# any use, without warranty, 2023 by Toru Niina.
# SPDX-License-Identifier: CC0-1.0
scenarios(vlt => 1);
if (!$Self->have_coroutines) {
skip("No coroutine support")
}
else {
compile(
v_flags2 => ["t/t_timing_dpi.cpp"],
verilator_flags2 => ["--exe --main --timing"],
make_main => 0,
);
execute(
check_finished => 1,
);
}
ok(1);
1

View File

@ -0,0 +1,5 @@
%Error-UNSUPPORTED: t/t_timing_dpi_unsup.v:28:19: Unsupported: Timing controls inside DPI-exported tasks
28 | repeat(n) @(negedge clk);
| ^
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error: Exiting due to

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 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(linter => 1);
top_filename("t/t_timing_dpi_unsup.v");
lint(
verilator_flags2 => ["--timing"],
fails => 1,
expect_filename => $Self->{golden_filename},
);
ok(1);
1;

View File

@ -24,19 +24,19 @@ module t;
export "DPI-C" task tb_sv_wait;
task automatic tb_sv_wait(input int n);
`WRITE_VERBOSE("tb_sv_wait start...");
`WRITE_VERBOSE("tb_sv_wait start...\n");
repeat(n) @(negedge clk);
`WRITE_VERBOSE("tb_sv_wait done!");
`WRITE_VERBOSE("tb_sv_wait done!\n");
endtask
always #halfcycle clk = ~clk;
initial begin
`WRITE_VERBOSE("test start");
`WRITE_VERBOSE("test start\n");
repeat(10) @(posedge clk);
`WRITE_VERBOSE("calling tb_c_wait...");
`WRITE_VERBOSE("calling tb_c_wait...\n");
tb_c_wait();
`WRITE_VERBOSE("tb_c_wait finish");
`WRITE_VERBOSE("tb_c_wait finish\n");
repeat(10) @(posedge clk);
$write("*-* All Finished *-*\n");
$finish;