How to use UVM try_next_item ?

get_next_item(); 
This method blocks until a REQ sequence_item is available in the sequencer.

    seq_item_port.get_next_item(req);
    req.print();
    drive(req); //drive logic
    seq_item_port.item_done();


try_next_item(); 
This is a non-blocking variant of the get_next_item() method. It will return a null pointer if there is no REQ sequence_item available in the sequencer.

Porting the above code to use try_next_item():

    seq_item_port.try_next_item(req);
    req.print();
    drive(req); //drive logic
    seq_item_port.item_done();


   If seq_item is not available on the exection of try_next_item, it returns null; So on execution of req.print(); simulator will give a NULL pointer dereference error.

Best practice to use try_next_item();

    seq_item_port.try_next_item(req);
    if(req != null) begin
      req.print();
      drive(req); //drive logic
      seq_item_port.item_done();
    end   


Example on Using try_next_item();

Below is one of the scenario where i come acroos the real use case of try_next_item();
In this Sequence item consists of multiple pkt's to be driven,

  class pkt_type;
    rand int pkt_id;
    ...
    ...
  endclass



  class seq_item extends uvm_seq_item;
    ...
    rand pkt_type pkt[];
    ...
    ...
  endclass



Here pkt is dynamic array, it can be 1 to 'n' number. On every randomization all the 1 to n pkt's will get same pkt_id;

As per the design implementation (DUT), the next pkt of same pkt_id can be driven only after getting the completion for previously driven pkt with same pkt_id. and its allowed to drive the pkt with different pkt_id. (Getting the completion for the pkt may take some time, so it is allowed to drive other pkt's)

Below is one of the way to implement the same,
 
  while(1) begin  
    if(comp_q.size()>0) begin   //comp_q => completions are sampled and corresponding pkt_id is pushed to comp_q
      tmp = comp_q.pop_front();   
      drive_pkt(tmp_pkt[tmp]);  //next pkt with the pkt_id will be driven
      ...
      ...
    end
    else begin
      seq_item_port.try_next_item(req);
      if(req!=null) begin
        drive_pkt(req);
        if(req.pkt.size()>1) tmp_pkt[req.pkt.pkt_id] = req; //req with multiple pkt's are stored for further processing
        seq_item_port.item_done();
      end
    end
    end