Can I use "wait fork" to wait for threads spawned inside a task?

137 views Asked by At

I'm experimenting with SystemVerilog threads, and I wrote the following example that works fine. The goal is simply to spawn 2 tasks that print a number and wait for both of them using "wait fork" and not simply "join".

program automatic tb_wait_fork();

task wait_and_print_int(int data);
    #5;
    $display(">> task got data %d @ %t", data, $time);
endtask

initial begin

    fork
        wait_and_print_int(10);
        wait_and_print_int(20);
    join_none

    $display(">> fork completed...");

    wait fork;

    $display(">> wait fork completed. exiting...");

end

endprogram

The output of this using Vivado v2023.2 is:

>> fork completed...
>> task got data          10 @                 5000
>> task got data          20 @                 5000
>> wait fork completed. exiting...
$finish called at time : 5 ns : File "C:/Users/HP/repos/sv_tb_test/tb_wait_fork.sv" Line 8

Now I want to spawn threads from inside a task instead of the main initial block, but I still want to wait for them in the initial block.

program automatic tb_wait_task();

task wait_and_print_int(int data);
    #5;
    $display(">> task got data %d @ %t", data, $time);
endtask

task spawn_threads();
    fork
        wait_and_print_int(10);
        wait_and_print_int(20);
    join_none

    $display(">> fork completed...");
endtask

initial begin

    spawn_threads();
    
    wait fork;

    $display(">> wait fork completed. exiting...");

end

endprogram

This doesn't seem to work as the display statements are not executed:

>> fork completed...
>> wait fork completed. exiting...
$finish called at time : 0 fs : File "C:/Users/HP/repos/sv_tb_test/tb_wait_task.sv" Line 17

I was expecting the 2 versions to behave in the same way. Why does it happen? How do we solve this problem? What if we need to spawn threads from inside tasks and wait for them?

2

There are 2 answers

1
toolic On

It could be a Vivado bug.

I get a different output when I run your code on EDA Playground. For example, with VCS:

>> fork completed...
>> task got data          10 @                    5
>> task got data          20 @                    5
>> wait fork completed. exiting...
$finish at simulation time                    5

Other simulators produce a similar output.

1
dave_59 On

The behavior you are seeing is not correct according to the LRM. This is a tool bug. Section 9.6.1 of the IEEE 1800-2023 LRM says:

The wait fork statement blocks process execution flow until all immediate child subprocesses (processes created by the current process, excluding their descendants) have terminated.

Calling a task or function does not create a new process in itself. The processes created by the fork/join_none construct inside the task are created by the same parent process that called the task.