-1

I am executing a piece of code written by someone else, and it works, but I don't understand what is going on!

    initial begin: running_test

        fork
            task1();
            task2();
        join
        task3();

end: running_test

When, I follow by the debugger in the simulation, I see that when task1() hits a clock statement, then the debugger jumps to task2(), and once task2() similarly hits a clock statement, then the debugger jumps to task3() !!!!!

And this is where I get confused, because task2() is a long task, so why does it moves (joins) to task3() before finishing it.

And when I keep running the debugger, I constantly see that the debugger keeps jumping between task1(), task2() and task3()!!!!

This completely goes against my understanding of Fork/Join. I was expecting to see that the debugger will not move to task3(), unless it is done with task1() and task2(), but apparently every time it hits a clock statement (inside either one of the tasks), it goes to a different task!!!

Can someone explain what is going on?

Rudy01
  • 1,027
  • 5
  • 18
  • 32
  • 1
    include a snippet of task1 and task2 – H.Modh Feb 17 '16 at 03:40
  • 1
    Do you have any `fork..join_none` or something like that in `task1()` and `task2()`? Since task1 and task are concurrent, the simulator will jump back-and-forth between them. Please include task1 and task2 in the code. – sharvil111 Feb 17 '16 at 03:47
  • Pay attention to the `join`. make sure it is not `join_any` or `join_none` And the only way task3 could be executed repeatedly is if there is a loop you are not showing or there are multiple instances of the module containing the initial block. – dave_59 Feb 17 '16 at 04:37

2 Answers2

1

I have seen your question for one scenario for that above case which is explained by you is possible. According to me in a case where task2 or task1 internally called task1 then it is possible. I also provide code for same.

class A;

  task task1;
    #10 $display("@ time = %t Here is first task\n",$realtime);
  endtask

  task task2;
    #15 $display("@ time = %t  Here is second task\n",$realtime);
    task3;
    #10 $display("@ time = %t  Here is second task\n",$realtime);
  endtask

  task task3;
     #5 $display("@ time = %t  Here is third task\n",$realtime);
  endtask

endclass


program mailbox;
  mailbox m1;
  A a1;

  initial
    begin
      a1 = new;
      m1 = new;


      fork
        a1.task1;
        a1.task2;
  join
  a1.task3;


end

endprogram

Ashutosh Rawal
  • 301
  • 1
  • 4
  • 16
0

There must be some kind of fork...join_none or fork...join_any in the task2 & task3

If there are any join_none or join_any in the task2 & task3, then simulator will spawn the thread from both tasks, and exit the task. So that, in turn, will exit from fork...join and will evaluate task3 first.

This is a sample code, which will help you to understand my explanation:

// Code your testbench here // or browse Examples

module top();
  bit clk;

  always #5 clk = ~clk;

  initial
    begin
      fork 
        task1();
        task2();
      join
      task3();
    end

  task task1();
    fork
      begin
        @(posedge clk);
        $display("@%0t : In Task1", $time);
      end
    join_none
  endtask

  task task2();
    fork
      begin
        @(negedge clk);
        $display("@%0t : In Task2", $time);
      end
    join_none
  endtask

  task task3();
    $display("@%0t : In Task3", $time);
  endtask
endmodule

And output of the above code is written below. Note that in this output, task3 display statement has printed before task1, task2 gets completed.

// Output
@0 : In Task3
@5 : In Task1
@10 : In Task2
Karan Shah
  • 1,912
  • 1
  • 29
  • 42