Verilog – Nested Parallel Blocks

verilog

I executed the following code on vcs:

module test;
  
reg v,y,a,b,p,m;

  initial

    begin

      v = 1'b0;

      #5 y = 1'b1;

      fork

        #20 a = v;

        #15 b = y;
join
      
#40 v = 1'b1;
      
fork
  
#10 p = v;
  
begin
  
#10 a = y;
  
#30 b = v;
  
end
  
#5 m = y;
  
join
      
end
  
initial
  
  $monitor($time, "\n v=%b y=%b a=%b b=%b m=%b  p=%b \n",v,y,a,b,m,p);

endmodule 

The console gives the following output:

Compiler version S-2021.09; Runtime version S-2021.09;  Oct 24 03:00 2022
                   0
 v=0 y=x a=x b=x m=x  p=x 

                   5
 v=0 y=1 a=x b=x m=x  p=x 

                  20
 v=0 y=1 a=x b=1 m=x  p=x 

                  25
 v=0 y=1 a=0 b=1 m=x  p=x 

                  65
 v=1 y=1 a=0 b=1 m=x  p=x 

                  70
 v=1 y=1 a=0 b=1 m=1  p=x 

                  75
 v=1 y=1 a=1 b=1 m=1  p=1 

What's the significance of using the 'begin and end' statements in the second fork block?

Best Answer

A fork block executes all statements within it in parallel.

A begin block executes all statements within it in sequence.

Here is the 2nd fork block with different whitespace layout:

fork
   #10 p = v;
   begin
      #10 a = y;
      #30 b = v;
   end
   #5 m = y;
join

In this fork block, 3 threads are run in parallel (all 3 start at the same time):

  1. The 1st statement: #10 p = v;
  2. The begin block
  3. The last statement: #5 m = y;

The 2 statements inside the begin block run in sequence. The 1st statement in that block delays simulation by 10. The 2nd statement delays by 30, for a total of 40. b is assigned to v 40 time units after the fork starts.

Without the begin/end block, 4 statement would run in parallel. b would be assigned to v 30 time units after the fork starts.