Support writing to inout in fork after timing (#7345)
This commit is contained in:
parent
f85641e40d
commit
5820d2936c
|
|
@ -298,12 +298,39 @@ class BeginVisitor final : public VNVisitor {
|
|||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
void visit(AstVar* nodep) override {
|
||||
if (nodep->user1SetOnce()) { return; }
|
||||
// If static variable, move it outside a function.
|
||||
if (nodep->lifetime().isStatic() && m_ftaskp) {
|
||||
const std::string newName
|
||||
= m_ftaskp->name() + "__Vstatic__" + dot(m_unnamedScope, nodep->name());
|
||||
if (nodep->isIO()) {
|
||||
if (nodep->direction().isRef()) {
|
||||
nodep->v3error(
|
||||
"It is illegal to use argument passing by reference for subroutines with "
|
||||
"a lifetime of static (IEEE 1800-2023 13.5.2)");
|
||||
}
|
||||
// Create a port that is used for passing value between argument and static
|
||||
// variable
|
||||
AstVar* const portp = nodep->cloneTreePure(false);
|
||||
nodep->replaceWith(portp);
|
||||
|
||||
if (nodep->isInput() || nodep->isInout()) {
|
||||
AstAssign* const initAssignp = new AstAssign{
|
||||
nodep->fileline(), new AstVarRef{nodep->fileline(), nodep, VAccess::WRITE},
|
||||
new AstVarRef{portp->fileline(), portp, VAccess::READ}};
|
||||
portp->addNextHere(initAssignp);
|
||||
}
|
||||
|
||||
if (nodep->isWritable()) {
|
||||
AstAssign* const endAssignp = new AstAssign{
|
||||
nodep->fileline(), new AstVarRef{portp->fileline(), portp, VAccess::WRITE},
|
||||
new AstVarRef{nodep->fileline(), nodep, VAccess::READ}};
|
||||
m_ftaskp->addStmtsp(endAssignp);
|
||||
}
|
||||
} else {
|
||||
nodep->unlinkFrBack();
|
||||
}
|
||||
nodep->name(newName);
|
||||
nodep->unlinkFrBack();
|
||||
m_ftaskp->addHereThisAsNext(nodep);
|
||||
nodep->funcLocal(false);
|
||||
} else if (m_unnamedScope != "") {
|
||||
|
|
|
|||
|
|
@ -443,20 +443,11 @@ class DynScopeVisitor final : public VNVisitor {
|
|||
if (!isEvent && m_afterTimingControl && nodep->varp()->isWritable()
|
||||
&& nodep->access().isWriteOrRW()) {
|
||||
// The output variable may not exist after a delay, so we can't just write to it
|
||||
if (m_inFunc) {
|
||||
nodep->v3error(
|
||||
"Writing to an "
|
||||
<< nodep->varp()->verilogKwd()
|
||||
<< " variable of a function after a timing control is not allowed");
|
||||
} else {
|
||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: Writing to a captured "
|
||||
<< nodep->varp()->verilogKwd()
|
||||
<< " variable in a "
|
||||
<< (VN_IS(nodep->backp(), AssignDly)
|
||||
? "non-blocking assignment"
|
||||
: "fork")
|
||||
<< " after a timing control");
|
||||
}
|
||||
nodep->v3error(
|
||||
"Writing to an "
|
||||
<< nodep->varp()->verilogKwd() << " automatic variable of a "
|
||||
<< (m_inFunc ? "function" : "task")
|
||||
<< " after a timing control is not allowed (IEEE 1800-2023 13.2.2)");
|
||||
}
|
||||
if (!framep->instance().initialized()) framep->createInstancePrototype();
|
||||
framep->captureVarInsert(nodep->varp());
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ class LinkParseVisitor final : public VNVisitor {
|
|||
int m_randSequenceNum = 0; // RandSequence uniqify number
|
||||
VLifetime m_lifetime = VLifetime::STATIC_IMPLICIT; // Propagating lifetime
|
||||
bool m_lifetimeAllowed = false; // True to allow lifetime settings
|
||||
bool m_hasTimingControl = false; // If current task has timing control
|
||||
bool m_moduleWithGenericIface = false; // If current module contains generic interface
|
||||
std::set<AstVar*> m_portDups; // Non-ANSI port datatype duplicating input/output decls
|
||||
|
||||
|
|
@ -249,6 +250,9 @@ class LinkParseVisitor final : public VNVisitor {
|
|||
VL_RESTORER(m_lifetime);
|
||||
VL_RESTORER(m_lifetimeAllowed);
|
||||
m_lifetimeAllowed = true;
|
||||
VL_RESTORER(m_hasTimingControl);
|
||||
m_hasTimingControl
|
||||
= nodep->exists([](const AstNode* const nodep) { return nodep->isTimingControl(); });
|
||||
if (!nodep->lifetime().isNone()) {
|
||||
m_lifetime = nodep->lifetime().makeImplicit();
|
||||
} else {
|
||||
|
|
@ -383,7 +387,13 @@ class LinkParseVisitor final : public VNVisitor {
|
|||
}
|
||||
}
|
||||
} else if (m_ftaskp) {
|
||||
if (!nodep->lifetime().isAutomatic()) nodep->lifetime(VLifetime::AUTOMATIC_IMPLICIT);
|
||||
// Variables in static tasks with timing control can be used after the task has ended
|
||||
// with use of join..fork_none, so they need to be static
|
||||
if (m_ftaskp->lifetime().isStatic() && m_hasTimingControl) {
|
||||
nodep->lifetime(VLifetime::STATIC_IMPLICIT);
|
||||
} else {
|
||||
nodep->lifetime(VLifetime::AUTOMATIC_IMPLICIT);
|
||||
}
|
||||
} else if (nodep->lifetime().isNone()) {
|
||||
// lifetime shouldn't be unknown, set static if none
|
||||
nodep->lifetime(VLifetime::STATIC_IMPLICIT);
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
%Error-UNSUPPORTED: t/t_fork_dynscope_unsup.v:17:7: Unsupported: Writing to a captured inout variable in a fork after a timing control
|
||||
: ... note: In instance 't'
|
||||
17 | p = #1 1;
|
||||
| ^
|
||||
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
||||
%Error-UNSUPPORTED: t/t_fork_dynscope_unsup.v:22:5: Unsupported: Writing to a captured output variable in a non-blocking assignment after a timing control
|
||||
: ... note: In instance 't'
|
||||
22 | q <= #1 1;
|
||||
| ^
|
||||
%Error: Exiting due to
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# 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-FileCopyrightText: 2024 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('simulator')
|
||||
|
||||
test.compile(verilator_flags2=["--binary"])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// verilog_format: off
|
||||
`define stop $stop
|
||||
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
|
||||
// verilog_format: on
|
||||
|
||||
module t;
|
||||
int x1, x2, x3, x4, x5, x6, x7;
|
||||
|
||||
initial begin
|
||||
x1 = -1;
|
||||
x2 = -1;
|
||||
x3 = -1;
|
||||
x4 = -1;
|
||||
|
||||
#1;
|
||||
t1(x1);
|
||||
t2(x2);
|
||||
t3(x3);
|
||||
t4(x4);
|
||||
`checkd(x1, 0)
|
||||
`checkd(x2, -1)
|
||||
`checkd(x3, 1)
|
||||
`checkd(x4, 2)
|
||||
|
||||
#10 t1(x1);
|
||||
t2(x2);
|
||||
t3(x3);
|
||||
t4(x4);
|
||||
`checkd(x1, 1)
|
||||
`checkd(x2, -1)
|
||||
`checkd(x3, 1)
|
||||
`checkd(x4, 2)
|
||||
|
||||
`checkd(x5, 3)
|
||||
`checkd(x6, 0)
|
||||
`checkd(x7, 4)
|
||||
|
||||
#5;
|
||||
`checkd(x1, 1)
|
||||
`checkd(x2, -1)
|
||||
`checkd(x3, 1)
|
||||
`checkd(x4, 2)
|
||||
`checkd(x5, 3)
|
||||
`checkd(x6, 0)
|
||||
`checkd(x7, 4)
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
always #1 t5(x5);
|
||||
always #1 t6(x6);
|
||||
always #1 t7(x7);
|
||||
|
||||
task t1(output int x);
|
||||
fork
|
||||
x = #1 1;
|
||||
join_none
|
||||
if ($time < 10) begin
|
||||
`checkd(x, 0)
|
||||
end
|
||||
else begin
|
||||
`checkd(x, 1)
|
||||
end
|
||||
endtask
|
||||
|
||||
task t2(inout int x);
|
||||
fork
|
||||
x = #1 2;
|
||||
join_none
|
||||
`checkd(x, -1)
|
||||
endtask
|
||||
|
||||
task t3(output int x);
|
||||
if ($time < 10) begin
|
||||
`checkd(x, 0)
|
||||
end
|
||||
else begin
|
||||
`checkd(x, 1)
|
||||
end
|
||||
fork
|
||||
x = #1 1;
|
||||
join_none
|
||||
#2 `checkd(x, 1);
|
||||
endtask
|
||||
|
||||
task t4(inout int x);
|
||||
if ($time < 10) begin
|
||||
`checkd(x, -1)
|
||||
end
|
||||
else begin
|
||||
`checkd(x, 2)
|
||||
end
|
||||
fork
|
||||
x = #1 2;
|
||||
join_none
|
||||
#2 `checkd(x, 2);
|
||||
endtask
|
||||
|
||||
task t5(output int x);
|
||||
x <= #1 3;
|
||||
endtask
|
||||
|
||||
task t6(inout int x);
|
||||
x <= #1 4;
|
||||
endtask
|
||||
|
||||
task static t7(inout int x);
|
||||
int y = 0;
|
||||
x <= #1 4;
|
||||
#2 y = x;
|
||||
`checkd(x, 4)
|
||||
endtask
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
%Error: t/t_fork_write_after_timing_bad.v:12:19: It is illegal to use argument passing by reference for subroutines with a lifetime of static (IEEE 1800-2023 13.5.2)
|
||||
: ... note: In instance 't'
|
||||
12 | task t1(ref int x);
|
||||
| ^
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: Exiting due to
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# 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-FileCopyrightText: 2024 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('simulator')
|
||||
|
||||
test.lint(verilator_flags2=["--timing"], fails=True, expect_filename=test.golden_filename)
|
||||
|
||||
test.passes()
|
||||
|
|
@ -1,24 +1,17 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain
|
||||
// SPDX-FileCopyrightText: 2024 Antmicro
|
||||
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t;
|
||||
bit p = 0, q = 0;
|
||||
|
||||
int x1;
|
||||
initial begin
|
||||
t1(p);
|
||||
t2(q);
|
||||
t1(x1);
|
||||
$finish;
|
||||
end
|
||||
|
||||
task t1(inout p);
|
||||
task t1(ref int x);
|
||||
fork
|
||||
p = #1 1;
|
||||
x = #1 2;
|
||||
join_none
|
||||
endtask
|
||||
|
||||
task t2(output q);
|
||||
q <= #1 1;
|
||||
endtask
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# 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-FileCopyrightText: 2026 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('simulator')
|
||||
|
||||
test.compile(verilator_flags2=["--binary"])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// verilog_format: off
|
||||
`define stop $stop
|
||||
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
|
||||
// verilog_format: on
|
||||
|
||||
module t;
|
||||
// test static argument
|
||||
task t1(output int x);
|
||||
x = #1 x + 1;
|
||||
endtask
|
||||
|
||||
// test concurrent executions of static tasks
|
||||
int expected;
|
||||
task t2(inout int x);
|
||||
#5 `checkd(x, expected);
|
||||
endtask
|
||||
|
||||
task factorial1 (input [31:0] x, output [31:0] out);
|
||||
if (x >= 2) begin
|
||||
factorial1 (x - 1, out);
|
||||
out = out * x;
|
||||
end
|
||||
else
|
||||
out = 1;
|
||||
endtask
|
||||
|
||||
function int factorial2 (input int x);
|
||||
if (x >= 2)
|
||||
factorial2 = factorial2(x - 1) * x;
|
||||
else
|
||||
factorial2 = 1;
|
||||
endfunction
|
||||
|
||||
int result;
|
||||
initial begin
|
||||
// t1
|
||||
result = 0;
|
||||
t1(result);
|
||||
`checkd(result, 1);
|
||||
t1(result);
|
||||
`checkd(result, 2);
|
||||
t1(result);
|
||||
`checkd(result, 3);
|
||||
t1(result);
|
||||
`checkd(result, 4);
|
||||
|
||||
factorial1(1, result);
|
||||
`checkd(result, 1);
|
||||
factorial1(3, result);
|
||||
`checkd(result, 6);
|
||||
factorial1(5, result);
|
||||
`checkd(result, 120);
|
||||
|
||||
`checkd(factorial2(1), 1);
|
||||
`checkd(factorial2(3), 6);
|
||||
`checkd(factorial2(5), 120);
|
||||
|
||||
// t2
|
||||
expected = 3;
|
||||
fork
|
||||
begin
|
||||
static int x1 = 1;
|
||||
t2(x1);
|
||||
`checkd(x1, 3);
|
||||
end
|
||||
join_none
|
||||
#2
|
||||
fork
|
||||
begin
|
||||
static int x2 = 3;
|
||||
t2(x2);
|
||||
`checkd(x2, 3);
|
||||
end
|
||||
join_none
|
||||
|
||||
#10
|
||||
expected = 10;
|
||||
fork
|
||||
begin
|
||||
static int x3 = 99;
|
||||
t2(x3);
|
||||
`checkd(x3, 10);
|
||||
end
|
||||
join_none
|
||||
#1
|
||||
fork
|
||||
begin
|
||||
static int x4 = 123;
|
||||
t2(x4);
|
||||
`checkd(x4, 10);
|
||||
end
|
||||
join_none
|
||||
#1
|
||||
fork
|
||||
begin
|
||||
static int x5 = 10;
|
||||
t2(x5);
|
||||
`checkd(x5, 10);
|
||||
end
|
||||
join_none
|
||||
|
||||
|
||||
#10
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
%Error: t/t_static_task_args_bad.v:12:19: It is illegal to use argument passing by reference for subroutines with a lifetime of static (IEEE 1800-2023 13.5.2)
|
||||
: ... note: In instance 't'
|
||||
12 | task t1(ref int x);
|
||||
| ^
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: Exiting due to
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t;
|
||||
int x1;
|
||||
initial begin
|
||||
t1(x1);
|
||||
$finish;
|
||||
end
|
||||
task t1(ref int x);
|
||||
x = #1 1;
|
||||
endtask
|
||||
endmodule
|
||||
|
|
@ -1,42 +1,46 @@
|
|||
%Error: t/t_timing_func_fork_bad.v:13:9: Writing to an output variable of a function after a timing control is not allowed
|
||||
%Error: t/t_timing_func_fork_bad.v:13:9: Writing to an output automatic variable of a function after a timing control is not allowed (IEEE 1800-2023 13.2.2)
|
||||
: ... note: In instance 't'
|
||||
13 | f1 = 0;
|
||||
| ^~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: t/t_timing_func_fork_bad.v:14:9: Writing to an output variable of a function after a timing control is not allowed
|
||||
%Error: t/t_timing_func_fork_bad.v:14:9: Writing to an output automatic variable of a function after a timing control is not allowed (IEEE 1800-2023 13.2.2)
|
||||
: ... note: In instance 't'
|
||||
14 | o1 = 0;
|
||||
| ^~
|
||||
%Error: t/t_timing_func_fork_bad.v:22:9: Writing to an output variable of a function after a timing control is not allowed
|
||||
%Error: t/t_timing_func_fork_bad.v:22:7: Writing to an output automatic variable of a task after a timing control is not allowed (IEEE 1800-2023 13.2.2)
|
||||
: ... note: In instance 't'
|
||||
22 | f2 = #5 0;
|
||||
22 | o1 = 0;
|
||||
| ^~
|
||||
%Error: t/t_timing_func_fork_bad.v:29:9: Writing to an output automatic variable of a function after a timing control is not allowed (IEEE 1800-2023 13.2.2)
|
||||
: ... note: In instance 't'
|
||||
29 | f2 = #5 0;
|
||||
| ^~
|
||||
%Error: t/t_timing_func_fork_bad.v:24:9: Writing to an inout variable of a function after a timing control is not allowed
|
||||
%Error: t/t_timing_func_fork_bad.v:31:9: Writing to an inout automatic variable of a function after a timing control is not allowed (IEEE 1800-2023 13.2.2)
|
||||
: ... note: In instance 't'
|
||||
24 | io2 = 0;
|
||||
31 | io2 = 0;
|
||||
| ^~~
|
||||
%Error: t/t_timing_func_fork_bad.v:34:9: Writing to an output variable of a function after a timing control is not allowed
|
||||
%Error: t/t_timing_func_fork_bad.v:41:9: Writing to an output automatic variable of a function after a timing control is not allowed (IEEE 1800-2023 13.2.2)
|
||||
: ... note: In instance 't'
|
||||
34 | f3 = 0;
|
||||
41 | f3 = 0;
|
||||
| ^~
|
||||
%Error: t/t_timing_func_fork_bad.v:35:9: Writing to an output variable of a function after a timing control is not allowed
|
||||
%Error: t/t_timing_func_fork_bad.v:42:9: Writing to an output automatic variable of a function after a timing control is not allowed (IEEE 1800-2023 13.2.2)
|
||||
: ... note: In instance 't'
|
||||
35 | o3 = 0;
|
||||
42 | o3 = 0;
|
||||
| ^~
|
||||
%Error: t/t_timing_func_fork_bad.v:43:9: Writing to an output variable of a function after a timing control is not allowed
|
||||
%Error: t/t_timing_func_fork_bad.v:50:9: Writing to an output automatic variable of a function after a timing control is not allowed (IEEE 1800-2023 13.2.2)
|
||||
: ... note: In instance 't'
|
||||
43 | f4 = @e 0;
|
||||
50 | f4 = @e 0;
|
||||
| ^~
|
||||
%Error: t/t_timing_func_fork_bad.v:45:9: Writing to an inout variable of a function after a timing control is not allowed
|
||||
%Error: t/t_timing_func_fork_bad.v:52:9: Writing to an inout automatic variable of a function after a timing control is not allowed (IEEE 1800-2023 13.2.2)
|
||||
: ... note: In instance 't'
|
||||
45 | io4 = 0;
|
||||
52 | io4 = 0;
|
||||
| ^~~
|
||||
%Error: t/t_timing_func_fork_bad.v:56:9: Writing to an output variable of a function after a timing control is not allowed
|
||||
%Error: t/t_timing_func_fork_bad.v:63:9: Writing to an output automatic variable of a function after a timing control is not allowed (IEEE 1800-2023 13.2.2)
|
||||
: ... note: In instance 't'
|
||||
56 | f5 = 0;
|
||||
63 | f5 = 0;
|
||||
| ^~
|
||||
%Error: t/t_timing_func_fork_bad.v:57:9: Writing to an output variable of a function after a timing control is not allowed
|
||||
%Error: t/t_timing_func_fork_bad.v:64:9: Writing to an output automatic variable of a function after a timing control is not allowed (IEEE 1800-2023 13.2.2)
|
||||
: ... note: In instance 't'
|
||||
57 | o5 = 0;
|
||||
64 | o5 = 0;
|
||||
| ^~
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
module t;
|
||||
|
||||
function int f1(output int o1);
|
||||
function automatic int f1(output int o1);
|
||||
fork
|
||||
begin
|
||||
#1 $stop;
|
||||
|
|
@ -16,7 +16,14 @@ module t;
|
|||
join_none
|
||||
endfunction
|
||||
|
||||
function int f2(inout io2);
|
||||
task automatic t1(output int o1);
|
||||
fork begin
|
||||
#1 $stop;
|
||||
o1 = 0;
|
||||
end join_none
|
||||
endtask
|
||||
|
||||
function automatic int f2(inout io2);
|
||||
fork
|
||||
begin
|
||||
f2 = #5 0;
|
||||
|
|
@ -27,7 +34,7 @@ module t;
|
|||
endfunction
|
||||
|
||||
event e;
|
||||
function int f3(output int o3);
|
||||
function automatic int f3(output int o3);
|
||||
fork
|
||||
begin
|
||||
@e $stop;
|
||||
|
|
@ -37,7 +44,7 @@ module t;
|
|||
join_none
|
||||
endfunction
|
||||
|
||||
function int f4(inout int io4);
|
||||
function automatic int f4(inout int io4);
|
||||
fork
|
||||
begin
|
||||
f4 = @e 0;
|
||||
|
|
@ -49,7 +56,7 @@ module t;
|
|||
|
||||
int i;
|
||||
|
||||
function int f5(output int o5);
|
||||
function automatic int f5(output int o5);
|
||||
fork
|
||||
begin
|
||||
wait (i == 0) $stop;
|
||||
|
|
|
|||
Loading…
Reference in New Issue