Wait not working for uvm_tlm_analysis_fifo

Hi,

I have uvm_tlm_analysis_fifo in my comparator and i have a condition in the compare function which waits till the fifo size is non-zero.

      wait ((m_before_fifo.size() != 0) && (m_after_fifo.size() != 0)) ;

I can see this wait statement keeps on waiting throughout the simulation.

If i replace this statement by #1, i can see the comparator behaving correctly and get matches and mismatches correctly.
But if the wait statement above is there, it hangs there itself.

Can anybody throw light on this?

Thanks,
verif_buff

The full code of my comparator looks like -

class mbu_in_order_comparator
  #( type T = int,
     type comp_type = uvm_built_in_comp #(T),
     type convert = uvm_built_in_converter #(T),
     type pair_type = uvm_built_in_pair #(T))
    extends uvm_component;

  typedef mbu_in_order_comparator #(T, comp_type, convert, pair_type) this_type;
  `uvm_component_param_utils(this_type)

  const static string type_name = "mbu_in_order_comparator #(T, comp_type, convert, pair_type)";

  uvm_analysis_export #(T) before_export;
  uvm_analysis_export #(T) after_export;

  uvm_analysis_port #(pair_type) pair_ap;

  // TLM Analysis FIFO's
  uvm_tlm_analysis_fifo #(T) m_before_fifo;
  uvm_tlm_analysis_fifo #(T) m_after_fifo;

  int m_matches;
  int m_mismatches;

  function new(string name, uvm_component parent);
    super.new(name, parent);
    before_export = new("before_export", this);
    after_export  = new("after_export", this);
    pair_ap       = new("pair_ap", this);
    m_before_fifo = new("before", this);
    m_after_fifo  = new("after", this);
    m_matches     = 0;
    m_mismatches  = 0;
  endfunction

  virtual function string get_type_name();
    return type_name;
  endfunction

  virtual function void connect_phase(uvm_phase phase);
    before_export.connect(m_before_fifo.analysis_export);
    after_export.connect(m_after_fifo.analysis_export);
  endfunction

  virtual task run_phase(uvm_phase phase);
    pair_type pair;
    T b;
    T a;
    string s;
    super.run_phase(phase);

    forever begin

      if ((!m_before_fifo.is_empty()) && (!m_after_fifo.is_empty())) begin
        m_before_fifo.get(b);
        m_after_fifo.get(a);

        if (!comp_type::comp(b, a)) begin
          $sformat(s, "%s differs from %s", convert::convert2string(a), convert::convert2string(b));
          `uvm_error("Comparator Mismatch",$psprintf("Mismatching transaction - %s", s))
          m_mismatches++;
        end
        else begin
          s = convert::convert2string(b);
          uvm_report_info("Comparator Match", s);
          m_matches++;
        end

        // we make the assumption here that a transaction "sent for
        // analysis" is safe from being edited by another process.
        // Hence, it is safe not to clone a and b.
        pair = new("after/before");
        pair.first  = a;
        pair.second = b;
        pair_ap.write(pair);
      end
      else begin
       //#1;
       wait ((m_before_fifo.size() != 0) && (m_after_fifo.size() != 0)) ;
      end

    end
  endtask

  // Function: flush
  //
  // This method sets m_matches and m_mismatches back to zero. The
  // <uvm_tlm_fifo#(T)::flush> takes care of flushing the FIFOs.

  virtual function void flush();
    string s;
    m_matches    = 0;
    m_mismatches = 0;
    m_before_fifo.flush();
    m_after_fifo.flush();
    $sformat(s, "Size of\nm_before_fifo = %d\n m_after_fifo = %d", m_before_fifo.used(), m_after_fifo.used());
    `uvm_info(get_type_name(), $psprintf("%s",s), UVM_NONE)
  endfunction

  function void report_phase(uvm_phase phase);

    if ((m_before_fifo.size() != 0) && (m_after_fifo.size() != 0)) begin
      `uvm_error(this.get_name(), $psprintf("[ERROR] BOTH Comparator FIFO's not empty at the end of test"))
    end
    else if ((m_before_fifo.size() != 0) && (m_after_fifo.size() == 0)) begin
      `uvm_error(this.get_name(), $psprintf("[ERROR] m_before_fifo Comparator FIFO not empty at the end of test"))
    end
    else if ((m_before_fifo.size() == 0) && (m_after_fifo.size() != 0)) begin
      `uvm_error(this.get_name(), $psprintf("[ERROR] m_after_fifo Comparator FIFO not empty at the end of test"))
    end

    `uvm_info(get_type_name(), $psprintf("MATCHES = %d   MISMATCHES= %d",m_matches,m_mismatches), UVM_NONE)

  endfunction : report_phase

endclass

In reply to verif_buff:

I do not understand what you want to do with this statement:

wait ((m_before_fifo.size() != 0) && (m_after_fifo.size() != 0)) ;

. The get methods are always blocking until a transaction is available. In my eyes it does not make any sense to work with the wait statement.

In reply to chr_sue:

I get issues when i get a random reset. So i added this.

But if syntactically its ok, why dosent it work, that what i am not getting.

Thanks,
verif_buff

In reply to verif_buff:

I have to correct me.
The size function of a uvm_tlm_fifo indicates an infinite size if the size = 0!
Instead of the size method you should use is_empty. For more Details see the UVM Reference Manual.

In reply to chr_sue:
Thanks a lot for the pointer chr_sue.

Its working now perfectly with is_empty function call instead of size() call.

Thanks a lot again.
verif_buff