Tutorials

Learn More

The process or thread is a common concept of an operating system. In an operating system (OS), a process is a program (a piece of code) that is under execution. 

Similarly in SystemVerilog, process or thread is also a piece of code that executes independently. The process or thread is enclosed in begin..end. If begin..end is not used, each statement acts as a separate process.

SystemVerilog provides three different ways to start/control processes.

SystemVerilog fork join

In fork-join, all processes start simultaneously, and join will wait for all processes to be completed.

fork join

Example of fork join

In the below example, there are three processes A, B, and C. All started at the same time.

Execution time for process A: 10ns

Execution time for process B: 15ns

Execution time for process C: 20ns

Fork-join will be completed when all three process execution is completed.

module fork_join_example;

  initial begin
    fork
      begin // process A
        $display("Process A started at time = %0t", $time);
        #10;
        $display("Process A completed at time = %0t", $time);
      end
      begin // process B
        $display("Process B started at time = %0t", $time);
        #15;
        $display("Process B completed at time = %0t", $time);
      end
      begin // process C
        $display("Process C started at time = %0t", $time);
        #20;
        $display("Process C completed at time = %0t", $time);
      end
    join
    $display("fork-join completed at time = %0t", $time);
  end
endmodule

Output:

Process A started at time = 0
Process B started at time = 0
Process C started at time = 0
Process A completed at time = 10
Process B completed at time = 15
Process C completed at time = 20
fork-join completed at time = 20

SystemVerilog fork join_any

In fork-join_any, all processes start simultaneously and join_any will wait for any one process to be completed.

fork join_any

Example of fork join_any

In the below example, there are three processes A, B, and C. All started at the same time.

Execution time for process A: 10ns

Execution time for process B: 15ns

Execution time for process C: 20ns

Fork-join_any will be completed when any one of the three process execution is completed.

module fork_join_any_example;

  initial begin
    fork
      begin // process A
        $display("Process A started at time = %0t", $time);
        #10;
        $display("Process A completed at time = %0t", $time);
      end
      begin // process B
        $display("Process B started at time = %0t", $time);
        #15;
        $display("Process B completed at time = %0t", $time);
      end
      begin // process C
        $display("Process C started at time = %0t", $time);
        #20;
        $display("Process C completed at time = %0t", $time);
      end
    join_any
    $display("fork-join_any completed at time = %0t", $time);
  end
endmodule

Output:

Process A started at time = 0
Process B started at time = 0
Process C started at time = 0
Process A completed at time = 10
fork-join_any completed at time = 10
Process B completed at time = 15
Process C completed at time = 20

SystemVerilog fork join_none

In fork-join_none, all processes start simultaneously and join_none will not wait for any process to be completed.

So, we can say that fork-join and fork-join_any is blocked due to process execution time, whereas fork-join_none is not blocked due to any process.

fork join_none

Example of fork join_none

In the below example, there are three processes A, B, and C. All started at the same time.

Execution time for process A: 10ns

Execution time for process B: 15ns

Execution time for process C: 20ns

Fork-join_none will be completed without waiting for any process completion.

module fork_join_none_example;
  initial begin
    fork
      begin // process A
        $display("Process A started at time = %0t", $time);
        #10;
        $display("Process A completed at time = %0t", $time);
      end
      begin // process B
        $display("Process B started at time = %0t", $time);
        #15;
        $display("Process B completed at time = %0t", $time);
      end
      begin // process C
        $display("Process C started at time = %0t", $time);
        #20;
        $display("Process C completed at time = %0t", $time);
      end
    join_none
    $display("fork-join_none completed at time = %0t", $time);
  end
endmodule

Output:

fork-join_none completed at time = 0
Process A started at time = 0
Process B started at time = 0
Process C started at time = 0
Process A completed at time = 10
Process B completed at time = 15
Process C completed at time = 20

disable fork

The ‘disable fork’ statement terminates all outstanding or active processes.

Without disable fork

In the below example, fork-join_any is used without a wait fork statement. So, once process A is finished, immediately join_any is unblocked without waiting for process B and C to be completed and further statements are executed.

module fork_join_any_example;
  initial begin
    fork
      begin // process A
        $display("Process A started at time = %0t", $time);
        #10;
        $display("Process A completed at time = %0t", $time);
      end
      begin // process B
        $display("Process B started at time = %0t", $time);
        #15;
        $display("Process B completed at time = %0t", $time);
      end
      begin // process C
        $display("Process C started at time = %0t", $time);
        #20;
        $display("Process C completed at time = %0t", $time);
      end
    join_any
    $display("fork-join_any completed at time = %0t", $time);
  end
endmodule

Output:

Process A started at time = 0
Process B started at time = 0
Process C started at time = 0
Process A completed at time = 10
fork-join_any completed at time = 10
Process B completed at time = 15
Process C completed at time = 20

With disable fork

After the addition of the ‘disable fork’ statement, processes B and C will get terminated immediately.

module disable_fork_example;
  initial begin
    fork
      begin // process A
        $display("Process A started at time = %0t", $time);
        #10;
        $display("Process A completed at time = %0t", $time);
      end
      begin // process B
        $display("Process B started at time = %0t", $time);
        #15;
        $display("Process B completed at time = %0t", $time);
      end
      begin // process C
        $display("Process C started at time = %0t", $time);
        #20;
        $display("Process C completed at time = %0t", $time);
      end
    join_any
    disable fork;
    $display("fork-join_any completed at time = %0t", $time);
  end
endmodule

Output:

Process A started at time = 0
Process B started at time = 0
Process C started at time = 0
Process A completed at time = 10
fork-join_any completed at time = 10

wait fork

The ‘wait fork’ statement is used to wait for all forked processes to be completed.

Without wait fork

In the below example, fork-join_any is used without a wait fork statement. So, once process A is finished, immediately join_any is unblocked without waiting for process B and C to be completed and further statements are executed.

module fork_join_any_example;
  initial begin
    fork
      begin // process A
        $display("Process A started at time = %0t", $time);
        #10;
        $display("Process A completed at time = %0t", $time);
      end
      begin // process B
        $display("Process B started at time = %0t", $time);
        #15;
        $display("Process B completed at time = %0t", $time);
      end
      begin // process C
        $display("Process C started at time = %0t", $time);
        #20;
        $display("Process C completed at time = %0t", $time);
      end
    join_any
    $display("fork-join_any completed at time = %0t", $time);
  end
endmodule

Output:

Process A started at time = 0
Process B started at time = 0
Process C started at time = 0
Process A completed at time = 10
fork-join_any completed at time = 10
Process B completed at time = 15
Process C completed at time = 20

With wait fork

After the addition of the wait fork statement,  statements after the ‘wait fork’ will be executed only after all forked process completion.

module wait_fork_example;
  initial begin
    fork
      begin // process A
        $display("Process A started at time = %0t", $time);
        #10;
        $display("Process A completed at time = %0t", $time);
      end
      begin // process B
        $display("Process B started at time = %0t", $time);
        #15;
        $display("Process B completed at time = %0t", $time);
      end
      begin // process C
        $display("Process C started at time = %0t", $time);
        #20;
        $display("Process C completed at time = %0t", $time);
      end
    join_any
    wait fork;
    $display("fork-join_any completed at time = %0t", $time);
  end
endmodule

Output:

Process A started at time = 0
Process B started at time = 0
Process C started at time = 0
Process A completed at time = 10
Process B completed at time = 15
Process C completed at time = 20
fork-join_any completed at time = 20

System Verilog Tutorials