Problem with wait_ptrigger_data being issued twice on same time-slice/tick

Hi Verification Academy,

I have a task, which spans forever begin…end.
Inside it, there is a fork…join_any which waits to 2 events from monitor of PHY interface.

First branch of the fork should capture the SOF(start of frame) event, create an element with the $time of the event, and push it to the list.
Second branch of the fork should capture the EOF(end of frame) event, and update the $time in the last element of the list.
*Assumption: SOF should arrive before EOF.


virtual task performance_measure_per_vc();
        uvm_object                      source_cast_rx_data;
        mipi_csi2_short_packet          dst_cast_mipi_csi2_short_pkt;
        phy_frame_events_info_s         frame_info;
        
        `uvm_info(get_name(), $sformatf("[PERF_CHECKER][MEASURE_PER_VC_ID] START"), UVM_MEDIUM)
        
        forever begin
            
            fork 
                begin
                    dphy_start_of_frame_e[0].wait_ptrigger_data(source_cast_rx_data);
                    dphy_start_of_frame_e[0].reset();
                    
                    if ( !$cast(dst_cast_mipi_csi2_short_pkt, source_cast_rx_data) )
                        `uvm_fatal(get_name(), "DPHY SOF triggered object casting failed.")
                    
                    frame_info.pkt_id = dst_cast_mipi_csi2_short_pkt.pkt_id;
                    frame_info.start_of_frame_event_time = $time;
                    phy_per_vc_id_frames_info_arr[dst_cast_mipi_csi2_short_pkt.vc_id].push_back(frame_info);
                    `uvm_info(get_name(), $sformatf("[PERF_CHECKER][MEASURE_PER_VC_ID] Received SOF event for: vc_id=%0d, pkt_id=0x%0x", dst_cast_mipi_csi2_short_pkt.vc_id, frame_info.pkt_id), UVM_MEDIUM)
                end
                begin
                    dphy_end_of_frame_e[0].wait_ptrigger_data(source_cast_rx_data);
                    dphy_end_of_frame_e[0].reset();
                    
                    if ( !$cast(dst_cast_mipi_csi2_short_pkt, source_cast_rx_data) )
                        `uvm_fatal(get_name(), "DPHY EOF triggered object casting failed.")
                    
                    phy_per_vc_id_frames_info_arr[dst_cast_mipi_csi2_short_pkt.vc_id][$].end_of_frame_event_time = $time;
                    
                    `uvm_info(get_name(), $sformatf("[PERF_CHECKER][MEASURE_PER_VC_ID] Received EOF event for: vc_id=%0d, pkt_id=0x%0x", dst_cast_mipi_csi2_short_pkt.vc_id, dst_cast_mipi_csi2_short_pkt.pkt_id), UVM_MEDIUM)
                end
                begin : WATCHDOG_BRANCH
                    #1500us;
                    `uvm_fatal(get_name(), $sformatf("[PERF_CHECKER][MEASURE_PER_VC_ID] Timeout reached. Please check")) 
                end
            join_any
            
            #0; // to prevent same event triggering on same time-slice (???? is it really working ????) 
            
        end
        
        `uvm_info(get_name(), $sformatf("[PERF_CHECKER: MEASURE_PER_VC_ID] START"), UVM_MEDIUM)
    endtask

Test has only 3 frames.

But from some reason the task attached prints to log twice for each EOF and SOF after the first event on same simulation clock cycle (though used reset of event after trigger).
See below in bold.

From the log:
UVM_INFO |@ 278081000 ps | uvm_test_top.env.m_chkr | [PERF_CHECKER][MEASURE_PER_VC_ID] Received SOF event for: vc_id=0, pkt_id=0x0
UVM_INFO |@ 326863000 ps | uvm_test_top.env.m_chkr | [PERF_CHECKER][MEASURE_PER_VC_ID] Received EOF event for: vc_id=0, pkt_id=0x0
UVM_INFO |@ 326863000 ps | uvm_test_top.env.m_chkr | [PERF_CHECKER][MEASURE_PER_VC_ID] Received EOF event for: vc_id=0, pkt_id=0x0

UVM_INFO |@ 327491000 ps | uvm_test_top.env.m_chkr | [PERF_CHECKER][MEASURE_PER_VC_ID] Received SOF event for: vc_id=0, pkt_id=0x0
UVM_INFO |@ 327491000 ps | uvm_test_top.env.m_chkr | [PERF_CHECKER][MEASURE_PER_VC_ID] Received SOF event for: vc_id=0, pkt_id=0x0
UVM_INFO |@ 424423000 ps | uvm_test_top.env.m_chkr | [PERF_CHECKER][MEASURE_PER_VC_ID] Received EOF event for: vc_id=0, pkt_id=0x0
UVM_INFO |@ 424423000 ps | uvm_test_top.env.m_chkr | [PERF_CHECKER][MEASURE_PER_VC_ID] Received EOF event for: vc_id=0, pkt_id=0x0

UVM_INFO |@ 425051000 ps | uvm_test_top.env.m_chkr | [PERF_CHECKER][MEASURE_PER_VC_ID] Received SOF event for: vc_id=0, pkt_id=0x0
UVM_INFO |@ 425051000 ps | uvm_test_top.env.m_chkr | [PERF_CHECKER][MEASURE_PER_VC_ID] Received SOF event for: vc_id=0, pkt_id=0x0
UVM_INFO |@ 473843000 ps | uvm_test_top.env.m_chkr | [PERF_CHECKER][MEASURE_PER_VC_ID] Received EOF event for: vc_id=0, pkt_id=0x0
UVM_INFO |@ 473843000 ps | uvm_test_top.env.m_chkr | [PERF_CHECKER][MEASURE_PER_VC_ID] Received EOF event for: vc_id=0, pkt_id=0x0

Any ideas what is wrong in my code?
I guess it is related to the fork…join_any code…

Thanks.

In reply to Michael54:

Your issue is that when the SOF block occurs in the fork/join_any, the forever block will loop and fork another SOF and EOF process. This results in two EOF processes existing at the same time, resulting in the double message (as both EOF processes handle the trigger).

You also still have your timeout processes running and will eventually hit that as well.

In reply to cgales:

Thank you for the replay,
I understand the problems…
Any suggestion what modification to do in order it to work?

In reply to Michael54:

After the join_any, you can kill all of the remaining forked processes. The forever loop would then re-fork all three processes again.

In reply to cgales:

In the end used some posts from the VA, for example:

And blog post by Hardik Modh:

Thanks VA!