Non-symmetric behaviour of raise/drop_objection and uvm_objection::get_objection_total

I tried the following code, and the last assertion is producing an error. I would expect the total count of objections to be zero, but it seems that uvm_objection.m_drop does not propagate the objection to the parent class properly. Any ideas if this is the intended behaviour or a bug in the UVM code.

You can also find the example here: Edit code - EDA Playground


import uvm_pkg::*;

class Child extends uvm_component;

  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction: new

endclass

class Parent extends uvm_component;

  Child child;
  
  function new(string name, uvm_component parent);
    super.new(name, parent);
    child = new("child", this);
  endfunction: new

endclass



module tb_top();
  
  Parent parent;
  uvm_objection my_obj;
  
  initial begin
    my_obj = new("obj2");
    parent = new("parent", null);
    assert(my_obj.get_objection_total(parent) == 0);
    my_obj.raise_objection(parent.child);
    assert(my_obj.get_objection_total(parent) == 1);
    my_obj.drop_objection(parent.child);
    assert(my_obj.get_objection_total(parent) == 0);
  end
endmodule

In reply to tpoikela:

If you refer to the UVM reference for uvm_objection, you will find the following for drop_objection():

If the total objection count reaches zero, propagation up the hierarchy is deferred until a configurable drain-time has passed and the uvm_component::all_dropped callback for the current hierarchy level has returned.

This means that there is a forked process which waits for the drain-time to complete, and then the objection drop is propagated up the hierarchy. This forked task requires you to block until completion.

You can modify your code to wait for this:


module tb_top();
 
  Parent parent;
  uvm_objection my_obj;
 
  initial begin
    my_obj = new("obj2");
    parent = new("parent", null);
    assert(my_obj.get_objection_total(parent) == 0);
    my_obj.raise_objection(parent.child);
    assert(my_obj.get_objection_total(parent) == 1);
    my_obj.drop_objection(parent.child);
    wait (my_obj.get_objection_total(parent) == 0);  // Blocking until objection dropped
    assert(my_obj.get_objection_total(parent) == 0);
  end
endmodule