Question on background processes spawned by function calls

Hello! Can anyone please tell me what’s the problem for the statement commented ‘illegal’?

class IntClass;
int a;
endclass
IntClass address=new(), stack=new();
function automatic bit watch_for_zero( IntClass p );
fork
forever @p.a begin
if ( p.a == 0 ) $display (“Unexpected zero”);
end
join_none
return ( p.a == 0 );
endfunction
function bit start_check();
return ( watch_for_zero( address ) | watch_for_zero( stack ) );
endfunction
bit y = watch_for_zero( stack ); // illegal
initial if ( start_check() ) $display ( “OK”); // legal
initial fork
if (start_check() ) $display( “OK too”); // legal
join_none

In reply to WeitingSwish:

You are only allow to fork threads from an initial or always block. Static variable initializations are not necessarily handled as an exiting thread that can be forked. Same issue with continuous assignments.

In reply to dave_59:
Can I understand as: The watch_for_zero function contains fork…join_none. However, there is not any initial or always block for assignment “bit y = watch_for_zero( stack );”. Thus make this assignment illegal? Thank you.

In reply to fzl1029:

Correct.

In reply to dave_59:
Thanks, Dave.

  1. If a function doesn’t contain any fork thread, Can we call this function without initial or always block?
  2. Besides, where does this “only allow to fork threads from an initial or always block” rule come from? Is it from “IEEE Standard for SystemVerilog—Unified Hardware Design, Specification, and Verification Language”? If yes, would you please show me the section number?
    Appreciate your help!

In reply to fzl1029:

  1. Yes. It is the combination of features that has to exist to make it illegal. This is a semantic error, not a syntax error.
  2. The second paragraph of Section 13.4.4 Background processes spawned by function calls explains the restrictions