Item_done() during async reset

I have a question regarding when to call item_done() in uvm_driver when handling async reset.



txn item;
task process_thread();
  forever begin
    item = null;
    seq_item_port.try_next_item(item);
      if(item == null) begin
        wait_cycle();
        continue;
      end
    seq_item_port.item_done();
  end 
endtask

task clean_up_after_reset();
  if (item != null) 
    seq_item_port.item_done();
endtask

According to SV LRM, it is possible thread get switched right after calling item_done() and before setting item to null. And this would result in calling item_done() twice, which would make uvm complain with uvm_error.

I feel to completely solve this issue I need an atomic operation that groups “calling item_done() + setting some kind of flag” together, so that I could clean up this mess after an async reset. Otherwise there seems no good way to tell if I need to call item_done() or not after async reset.

Any help is appreciated.

In reply to Jianfeng_0:

It is unclear to me what do you want to achieve. You are showing definitions, but you do not show how you are calling these methods.

In reply to chr_sue:

this is what I wanna achieve, basically a driver that could handle async reset. But I found it difficult to handle the seq_item_port.get_next_item() and seq_item_port.item_done() handshake, because reset could be coming any time and killing the calling of “seq_item_port.item_done()” .

task run_phase();             
    forever begin                                                                                                                                 
        fork                                                                                                                       
            detect_reset();                                                     
            process_thread();                                
        join_any 
                                                               
        // Handle an async reset here                                           
        clean_up_after_reset();                                                  
        disable fork;                                                                                                               
endtask

In reply to Jianfeng_0:

And what is detect_reset? Plase show the code.

In reply to chr_sue:

task detect_reset;
  @(negedge vif.reset_n);
endtask

In reply to Jianfeng_0:

See On the Fly Reset | Verification Horizons | Verification Academy