How do I get all transferred data by uvm_analysis_port?

I generated and send 10 randomized transaction by “uvm_tlm_analysis_fifo” in uvm_component_a, I expected that I can get 10 transferred randomized transaction from component_b.

But I can’t get 10 transferred randomized transactions from component_b.

case 1.


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);                                                             
    trans = transaction::type_id::create("trans", this);                                     
                                                                                             
    for(int a=0; a<10; a++) begin                                                            
      void'(trans.randomize());                                                              
      analysis_port.write(trans);                                                            
    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);

    for(int i=0; i< 10; i++) begin                                                           
    #100;
      analy_fifo.get(trans);
      `uvm_info(get_type_name(),$sformatf(" Printing trans, \n %s",trans.sprint()),UVM_LOW)  
    end

    phase.drop_objection(this);                                                              
  endtask                                                                                    

endclass

I got the result as the below,

UVM_INFO component_b.sv(20) @ 100: uvm_test_top.env.comp_b [component_b]  Printing trans, 
 ---------------------------------
Name     Type         Size  Value
---------------------------------
trans    transaction  -     @3131
  addr   integral     4     'h9  
  wr_rd  integral     1     'h1  
  wdata  integral     8     'he7 
---------------------------------

UVM_INFO component_b.sv(20) @ 200: uvm_test_top.env.comp_b [component_b]  Printing trans, 
 ---------------------------------
Name     Type         Size  Value
---------------------------------
trans    transaction  -     @3131
  addr   integral     4     'h9  
  wr_rd  integral     1     'h1  
  wdata  integral     8     'he7 
---------------------------------

UVM_INFO component_b.sv(20) @ 300: uvm_test_top.env.comp_b [component_b]  Printing trans, 
 ---------------------------------
Name     Type         Size  Value
---------------------------------
trans    transaction  -     @3131
  addr   integral     4     'h9  
  wr_rd  integral     1     'h1  
  wdata  integral     8     'he7 
---------------------------------

UVM_INFO component_b.sv(20) @ 400: uvm_test_top.env.comp_b [component_b]  Printing trans, 
 ---------------------------------
Name     Type         Size  Value
---------------------------------
trans    transaction  -     @3131
  addr   integral     4     'h9  
  wr_rd  integral     1     'h1  
  wdata  integral     8     'he7 
---------------------------------

UVM_INFO component_b.sv(20) @ 500: uvm_test_top.env.comp_b [component_b]  Printing trans, 
 ---------------------------------
Name     Type         Size  Value
---------------------------------
trans    transaction  -     @3131
  addr   integral     4     'h9  
  wr_rd  integral     1     'h1  
  wdata  integral     8     'he7 
---------------------------------

UVM_INFO component_b.sv(20) @ 600: uvm_test_top.env.comp_b [component_b]  Printing trans, 
 ---------------------------------
Name     Type         Size  Value
---------------------------------
trans    transaction  -     @3131
  addr   integral     4     'h9  
  wr_rd  integral     1     'h1  
  wdata  integral     8     'he7 
---------------------------------

UVM_INFO component_b.sv(20) @ 700: uvm_test_top.env.comp_b [component_b]  Printing trans, 
 ---------------------------------
Name     Type         Size  Value
---------------------------------
trans    transaction  -     @3131
  addr   integral     4     'h9  
  wr_rd  integral     1     'h1  
  wdata  integral     8     'he7 
---------------------------------

UVM_INFO component_b.sv(20) @ 800: uvm_test_top.env.comp_b [component_b]  Printing trans, 
 ---------------------------------
Name     Type         Size  Value
---------------------------------
trans    transaction  -     @3131
  addr   integral     4     'h9  
  wr_rd  integral     1     'h1  
  wdata  integral     8     'he7 
---------------------------------

UVM_INFO component_b.sv(20) @ 900: uvm_test_top.env.comp_b [component_b]  Printing trans, 
 ---------------------------------
Name     Type         Size  Value
---------------------------------
trans    transaction  -     @3131
  addr   integral     4     'h9  
  wr_rd  integral     1     'h1  
  wdata  integral     8     'he7 
---------------------------------

UVM_INFO component_b.sv(20) @ 1000: uvm_test_top.env.comp_b [component_b]  Printing trans, 
 ---------------------------------
Name     Type         Size  Value
---------------------------------
trans    transaction  -     @3131
  addr   integral     4     'h9  
  wr_rd  integral     1     'h1  
  wdata  integral     8     'he7 
---------------------------------


So If I change with write() method instead of run_phase(),
Case2


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);
    #100;
    phase.drop_objection(this);                                                              
  endtask                                                                                    


  virtual function write(transaction trans);
      `uvm_info(get_type_name(),$sformatf(" Printing trans, \n %s",trans.sprint()),UVM_LOW)
  endfunction
  

There is no print out from write() method.

How do I get all transferred data by uvm_analysis_port in case1 and case2?

In reply to UVM_LOVE:

I don’t understand your question.

The uvm_tlm_analysis_fifo is a class with a fifo and an internal write() method. When the connected analysis_port calls write(), the analysis_fifo will take the written item and push it to the fifo. You can then get() the transactions from the fifo as required.

Since the write() method is internal to the analysis_fifo, there is no requirement for you to implement a write() function.

What is not working in your first implementation?

In reply to cgales:

In reply to UVM_LOVE:
I don’t understand your question.
The uvm_tlm_analysis_fifo is a class with a fifo and an internal write() method. When the connected analysis_port calls write(), the analysis_fifo will take the written item and push it to the fifo. You can then get() the transactions from the fifo as required.
Since the write() method is internal to the analysis_fifo, there is no requirement for you to implement a write() function.
What is not working in your first implementation?

My first implementation is

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);                                                             
    trans = transaction::type_id::create("trans", this);                                     
 
    for(int a=0; a<10; a++) begin                                                            
      void'(trans.randomize());                                                              
      analysis_port.write(trans);                                                            
    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);
 
    for(int i=0; i< 10; i++) begin                                                           
    #100;
      analy_fifo.get(trans);
      `uvm_info(get_type_name(),$sformatf(" Printing trans, \n %s",trans.sprint()),UVM_LOW)  
    end
 
    phase.drop_objection(this);                                                              
  endtask                                                                                    
 
endclass

As you can see, I send 10 transactions in component_a then I get the transactions from component_b.

Since the write() method is internal to the analysis_fifo, there is no requirement for you to implement a write() function.

Yes I understood like your comment, I thought that If I send 10 transactions then I can get 10 transactions.
But I get the same date.

This is the uvm_tlm_analysis_fifo even this is unbounded then all transactions supposed to be stored in the FIFO.

UVM_INFO component_b.sv(20) @ 800: uvm_test_top.env.comp_b [component_b]  Printing trans, 
 ---------------------------------
Name     Type         Size  Value
---------------------------------
trans    transaction  -     @3131
  addr   integral     4     'h9  
  wr_rd  integral     1     'h1  
  wdata  integral     8     'he7 
---------------------------------
...

So this is not working first implemenation of my problem

In reply to UVM_LOVE:

The issue with the first implementation is that you use keep pushing the same handle, resulting in 10 copies of the same object.

You want:


  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);                                                            
    end                                                                                      
 
    phase.drop_objection(this);                                                              
  endtask