In reply to puranik.sunil@tcs.com:
I believe what you are asking is this:
module top;
function automatic foo;
bit local_prm;
fork
begin : forked
tsk1(local_prm);
$display("local_prm %b exists till this process ends %t",local_prm, $time);
end
join_none
endfunction
task automatic tsk1(output bit prm_out); // ref bit prm_out also allowed
#10 prm_out = 1;
endtask
initial foo();
endmodule
This is allowed because:
The lifetime of a fork-join block (see 9.3.2) shall encompass the execution of all processes spawned by the
block. The lifetime of a scope enclosing any fork-join block includes the lifetime of the fork-join block.
Solocal_prm remains active while the process forked is active even after foo() returns. And it doesn’t matter if prm_out gets passed by reference or not. So it’s a little more complex than just a call stack determining the lifetime of an automatic.
But let’s go back to your original post and modify this example
module top;
function automatic foo;
bit prm;
fork
begin : forked
tsk1(prm);
$display("prm %b exists till this process ends %t",prm, $time);
end
join_none
endfunction
task automatic tsk1(ref bit prm_out);
#10 prm_out = 1;
fork
tsk2(prm_out);
join_none
endtask
task automatic tsk2(ref bit prm_out); // this is illegal
#10 prm_out = 0;
endtask
initial foo;
endmodule
For this to work, the compiler would need to know the lifetime of prm goes beyond the lifetime of the forked process. Generally, it’s not a good idea to have to look inside the task you are calling in determining the behavior of code outside the task call.