1

I have a very simple piece of code that is boggling my mind.

->ev1; //Trigger the event of interest


fork : main_fork
  begin : T1
    $display("T1 is RUNNING");
    fork
      begin
        $display("T1.B3 is RUNNING");
        $display("T1.B3 END");
      end
      begin
        $display("T1.B0 is RUNNING");
        $display("T1.B0 END");
      end
    join
    $display("T1 END");
  end : T1
  begin :T2
    $display("T2 is RUNNING");
    @ev1;
    $display("T2 END");
  end : T2
join_any : main_fork

disable main_fork;

So, the idea is when ev1 happens, I want T2 to end and thus effectively killing everything in T1. If ev1 never happens, then I want both the threads T1.B3 followed by T1.B0 to execute and and proceed to the code after disable main_fork.

Now, here is the funny/confusing part. When I grep for the above statements, I can see a set of RUNNING prints at timestamp:X ... but I never see any of the END prints and then again at timestamp:X+100, I once again see all the RUNNING prints.

I can see event ev1 has happened AFTER we start running T2 for the first time, I expected T2 to be killed at that point, END print of T2 to come. But, it looks like T2 never ends when ev1 happens and magically, all the threads start once again.

How can threads re-start when they do not end? Why wasn't the event recognized even when we started waiting for them before the event actually occurred?

Greg
  • 18,111
  • 5
  • 46
  • 68
  • Please provided us a run-able testcase and the output log. With the provided code, you will never see "T2 END". There are no time blocking statements in `T1`, it will always finish before `T2`. – Greg Aug 09 '15 at 21:38

2 Answers2

2

I isolated the problem after reading the LRM carefully..when you name your fork, main_fork, in this case...you have to use it in the join_any statement too which I did not. Thats one error that could be the reason.

Secondly, when you write disbale main_fork..its essentially a disable statement used in the verilog sense and does not kill what we think it would kill..disable fork is the system verilog version that I needed for this purpose. So, when I removed the name of the fork and replaced disable main_fork; with disable fork; and recompiled and re-ran the failing test, voila..I can see when the threads end and I could also see all the other threads ending as expected.

0

Looking at the example you gave, T1 will finish in 0 time, which will disable the fork, meaning T2 never gets a chance to wait for the event.

Threads don't re-start magically. You probably have a loop over there that's running this code again. It's impossible to say, though, from only the code you showed us.

Tudor Timi
  • 7,453
  • 1
  • 24
  • 53
  • But when a thread finishes, the "END" prints would have to be printed right? I put the prints in to see if the thread ever ends and I do not see the END prints...each of the threads have code in them that wait for various events etc but the main thing is ev1 which happens and which should kill T1 as a whole.. – user3662733 Aug 09 '15 at 20:18
  • It could be that you kill the parent thread using a `disable fork` statement somewhere, which leads to killing all of its child threads (including this one). – Tudor Timi Aug 09 '15 at 22:02
  • well...i named this thread main_fork so that nothing except the events that i want would kill it when it reaches disable main_fork line.. plus there arent any other disabe forks that come into the picture in this file. – user3662733 Aug 09 '15 at 22:24