How to finish the forever until other component done?

I read that Multiple Transaction Streams With Synchronization
https://verificationacademy.com/cookbook/analysisconnections


 task run_phase( uvm_phase phase );
   alu_txn before_txn, after_txn;
   forever begin
     before_fifo.get(before_txn);
     after_fifo.get(after_txn);
     if (!before_txn.compare(after_txn)) begin
       `uvm_error("Comparator Mismatch",
                  $sformatf("%s does not match %s", before_txn.convert2string(), after_txn.convert2string()))
       m_mismatches++;
     end else begin
       m_matches++;
     end
   end
 endtask

and I made one simple example as reference code.


class component_a extends uvm_component;

  transaction trans;

  uvm_analysis_port#(transaction) analysis_port;

  `uvm_component_utils(component_a)

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

  virtual task run_phase(uvm_phase phase);
    phase.raise_objection(this);

 for(int a=0; a<10; a++) begin
      trans = transaction::type_id::create("trans");
      if (!trans.randomize())
        `uvm_fatal("RNDERR", "Randomization of trans failed");
      analysis_port.write(trans);
        `uvm_info(get_type_name(), "Trans Sending....",UVM_LOW)
    end

    phase.drop_objection(this);
  endtask

endclass


class component_b extends uvm_component;

  `uvm_component_utils(component_b)
  transaction trans;
  uvm_tlm_analysis_fifo#(transaction) analy_fifo;


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

  virtual task run_phase(uvm_phase phase);
    phase.raise_objection(this);

  forever begin
      `uvm_info(get_type_name(), $sformatf(" FIFO used: %0d", analy_fifo.used()), UVM_LOW)   
      if(analy_fifo.is_empty()) begin
        `uvm_info(get_type_name(), "FIFO is Empty!!!!!",UVM_LOW)
      end
      else begin
        analy_fifo.get(trans);
      `uvm_info(get_type_name(),$sformatf(" Printing receive trans, \n ",trans.sprint()),UVM_LOW)
      end
  end
    phase.drop_objection(this);
  endtask

endclass

This test never finished when I ran the test.

UVM_INFO component_b.sv(49) @ 0: uvm_test_top.env.comp_b [component_b] FIFO is Empty!!!!!
UVM_INFO component_b.sv(46) @ 0: uvm_test_top.env.comp_b [component_b]  FIFO used: 0
UVM_INFO component_b.sv(49) @ 0: uvm_test_top.env.comp_b [component_b] FIFO is Empty!!!!!
UVM_INFO component_b.sv(46) @ 0: uvm_test_top.env.comp_b [component_b]  FIFO used: 0
...

How do I finish the forever loop until component_a done?

In reply to UVM_LOVE:

If these are the only two components, do not call raise_objection() in component_b::run_phase.

In reply to dave_59:

Thank you Dave, I removed objections, still never stop. So I add delay #1;
I’m not sure whether adding delay is correct or not.
Now I’m referencing AnalysisConnections | Verification Academy
there is no Delay implemented in.

 task run_phase( uvm_phase phase );
   alu_txn before_txn, after_txn;
   forever begin
     before_fifo.get(before_txn);
     after_fifo.get(after_txn);
     if (!before_txn.compare(after_txn)) begin
       `uvm_error("Comparator Mismatch",
                  $sformatf("%s does not match %s", before_txn.convert2string(), after_txn.convert2string()))
       m_mismatches++;
     end else begin
       m_matches++;
     end
   end
 endtask

If I add delay, analy_fifo.get(trans); is working as my expectation.
But why do I need to add the # dealy ? even the referencing code does not implemented # delay code.
If I get rid of Delay then it never stop.


//component_b
///...

forever begin
  #1; //<== ???
      `uvm_info(get_type_name(), $sformatf(" FIFO used: %0d", analy_fifo.used()), UVM_LOW)   
      if(analy_fifo.is_empty()) begin
        `uvm_info(get_type_name(), "FIFO is Empty!!!!!",UVM_LOW)
      end
      else begin
        analy_fifo.get(trans);
      `uvm_info(get_type_name(),$sformatf(" Printing receive trans, \n ",trans.sprint()),UVM_LOW)
      end
  end

In reply to UVM_LOVE:

Because in the case analy_fifo.is_empty, you are in a zero-delay infinite loop and there is no way to break out go it. There is no need for this if statement.