Question regarding the scheduling order after an event is triggered

module tb;
    event e1;
    int   a = 1;
    initial begin : x
       #1ns;
       ->e1;
       a = 2;
    end
    initial begin : y
        @e1; 
        $display("%0d", a);
    end
endmodule

Hi All,

I have a few questions. After reading SystemVerilog LRM, I have some personal insights. For events within the same process (begin…end), they enter the Active queue in the order they occur; for events from different processes, they enter the Active queue in a random order.

So, in the example above, at 1 ns, the e1 is triggered. Theoretically, for the subsequent events in the initial blocks of x and y (a = 2; / $display(“%0d”, a);), the order in which they enter the Active queue is undetermined. Consequently, the value of a displayed at the end could be the default value 1 or 2. Is that correct?

This issue arose while I was examining the trigger() and wait_trigger_data() methods of uvm_event;
The trigger method of uvm_event executes as follows:

virtual function void trigger (T data=null);
  …
  ->m_event;
  trigger_data = data;
endfunction

virtual task wait_trigger_data (output T data);
  wait_trigger();
  data = get_trigger_data();
endtask

This seems similar to the example I gave. If the implementation actually works as I understand it, could there be a potential risk (returning a null handle)?

BR

Your understanding is correct—there’s a potential race condition. While it’s challenging to recreate, it could become an issue as people try to execute the code on multiple cores.

This problem has been corrected in the IEEE version of the standard. See 04934: uvm_event::trigger_data assigned too late - Accellera Mantis

2 Likes

Thanks for your reply!