Proper use of while(1) inside fork/join , when while(1) is in initial block and module also has final block

I have some checks in while(1) that would like run throughout the simulation. And final block run towards the end of simulation.
The second block in fork, needs to run once in the simulation.
When having join_none, I see zero-loop delay which is expected. What is the right option to use here, so the above holds good as well there is no zero loop delay. What would be the difference between join_any vs join here.
if having join_any, will the while(1) skip and test go to final block directly after the second fork-join code is complete ?


module abc();
int total_checks = 0;

initial begin
  logic valid;
  int count;  
  assign valid = `RTL_PATH.valid;

  fork 
    while(1) begin
      count = 0;
      @ (posedge valid); 
      total_checks++;  // no of times valid is asserted
      while(valid == 1 || count <6) begin // while loop needs to loop for cycle for some checking after valid is asserted
         count++;
      end 
    end // while(1)

    begin
      wait(signal_x);
    end
    join_none
end // initial block

final begin
// some checks 
end
endmodule











In reply to roopa7:

A final block executes when there is a $finish, or nothing left to schedule. You need a way to exit the while(1) loop. You can use a break statement, or some other construct to terminate the process. You haven’t described it well enough to know if this is the right behavior your want. And the inner while() loop makes no sense with a 0-delay loop. perhaps you have a clock somewhere?

The difference between join/join_any/join_none only matters if there are statements that follow it. Most people will have join_any followed by disable fork. That means as soon as one of the processes you fork off terminates, then terminate all of the remaining processes.

In reply to dave_59:

Thank you, Dave.

Yes, I missed the clock inside the inner while loop. We have @(negedge clk) before the count++.

Most people will have join_any followed by disable fork. That means as soon as one of the processes you fork off terminates, then terminate all of the remaining processes.

In my case, I don’t want the while(1) to terminate yet, so cannot use join_any and disable fork option for the original code.

You need a way to exit the while(1) loop.

Thanks for this, as I wasn’t sure if the test would hang because of this while(1) loop. I understand I have to find a way to exit this loop for test to finish gracefully.

Can I add a big delay in the second begin-end statement of fork and then have join_any and disable fork to exit the while :

 
fork 
    while(1) begin
      count = 0;
      @ (posedge valid); 
      total_checks++;  // no of times valid is asserted
      while(valid == 1 || count <6) begin // while loop needs to loop for cycle for some checking after valid is asserted
         count++;
      end 
    end // while(1)
 
    begin
      wait(signal_x);
      #x; //x is big enough to finish all the transactions in while(1) loop
    end
 join_any
 disable fork


In reply to roopa7:

Yes, that could work. But I would try to figure out a way to know when all the transactions are finished so you don’t waste a lot of unnecessary simulation cycles.