Getting last transaction in consumer repetitively even though producer is sending all transaction

Hi,

I am sending 5 transactions from producer, in consumer i am getting only last transaction from consumer repetitively. Can some help what can i do to get all transaction in consumer?

This is code below i tried:

`include “uvm_macros.svh”
import uvm_pkg::*;

class my_txn extends uvm_object;
rand int addr;
rand int txn_id;

`uvm_object_utils_begin(my_txn)     `uvm_field_int(addr, UVM_DEFAULT)
`uvm_field_int(txn_id, UVM_DEFAULT)   `uvm_object_utils_end

function new(string name=“my_txn”);
super.new(name);
endfunction

endclass: my_txn

class my_producer extends uvm_component;
`uvm_component_utils(my_producer)

uvm_analysis_port #(my_txn) analysis_port;

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

virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
analysis_port = new(“analysis_port”, this);
endfunction : build_phase

virtual task run_phase(uvm_phase phase);
my_txn txn;
int tx_cnt;
phase.raise_objection(this);
txn = my_txn::type_id::create(“txn”, this);
repeat(5) begin
void’(txn.randomize());
`uvm_info(get_type_name(), $sformatf(“txn #%0d\n%s”, tx_cnt, txn.sprint()), 	UVM_LOW);
analysis_port.write(txn);
tx_cnt += 1;
end
phase.drop_objection(this);
endtask:run_phase
endclass

class my_consumer extends uvm_component;
`uvm_component_utils(my_consumer)

uvm_analysis_port #(my_txn) analysis_export;
local uvm_tlm_analysis_fifo #(my_txn) analysis_fifo;

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

virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
analysis_export = new(“analysis_export”, this);
analysis_fifo = new(“analysis_fifo”, this);
endfunction : build_phase

virtual function void connect_phase(uvm_phase phase);
analysis_export.connect(analysis_fifo.analysis_export);
endfunction

virtual task run_phase(uvm_phase phase);
int tx_cnt;
phase.raise_objection(this);
#100ns;
//forever begin
repeat(6) begin
my_txn txn;
analysis_fifo.get(txn);
`uvm_info(get_type_name(), $sformatf(“txn #%0d\n%s”, tx_cnt, txn.sprint()), 	UVM_LOW);
tx_cnt += 1;
end
phase.drop_objection(this);
endtask:run_phase
endclass: my_consumer

class my_env extends uvm_env;
\`uvm_component_utils(my_env)

my_producer m_producer;
my_consumer m_consumer;

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

virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
m_producer = my_producer::type_id::create(“m_producer”, this);
m_consumer = my_consumer::type_id::create(“m_consumer”, this);
endfunction : build_phase

virtual function void connect_phase(uvm_phase phase);
m_producer.analysis_port.connect(m_consumer.analysis_export);
endfunction : connect_phase

endclass : my_env

class my_test extends uvm_test;
\`uvm_component_utils(my_test)
my_env m_env;

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

virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
m_env = my_env::type_id::create(“m_env”, this);
endfunction : build_phase

task run_phase(uvm_phase phase);
phase.raise_objection(this);    
#100;
phase.drop_objection(this);


endtask
endclass

module tb_top;
initial begin
run_test(“my_test”);
end
endmodule

Result:

UVM_INFO @ 0: reporter \[RNTST\] Running test my_test...
UVM_INFO testbench.sv(40) @ 0: uvm_test_top.m_env.m_producer \[my_producer\] txn #0
------------------------------------
Name      Type      Size  Value     
------------------------------------
txn       my_txn    -     @463      
  addr    integral  32    'hdbbbe251
  txn_id  integral  32    'h3164924f
------------------------------------

UVM_INFO testbench.sv(40) @ 0: uvm_test_top.m_env.m_producer \[my_producer\] txn #1
------------------------------------
Name      Type      Size  Value     
------------------------------------
txn       my_txn    -     @463      
  addr    integral  32    'he66813cc
  txn_id  integral  32    'h4f69d2ba
------------------------------------

UVM_INFO testbench.sv(40) @ 0: uvm_test_top.m_env.m_producer \[my_producer\] txn #2
------------------------------------
Name      Type      Size  Value     
------------------------------------
txn       my_txn    -     @463      
  addr    integral  32    'h684cc6c1
  txn_id  integral  32    'hc1876609
------------------------------------

UVM_INFO testbench.sv(40) @ 0: uvm_test_top.m_env.m_producer \[my_producer\] txn #3
------------------------------------
Name      Type      Size  Value     
------------------------------------
txn       my_txn    -     @463      
  addr    integral  32    'h1532f254
  txn_id  integral  32    'h99d8cefb
------------------------------------

UVM_INFO testbench.sv(40) @ 0: uvm_test_top.m_env.m_producer \[my_producer\] txn #4
------------------------------------
Name      Type      Size  Value     
------------------------------------
txn       my_txn    -     @463      
  addr    integral  32    'h487120f6
  txn_id  integral  32    'h2df22641
------------------------------------

UVM_INFO testbench.sv(76) @ 100: uvm_test_top.m_env.m_consumer \[my_consumer\] txn #0
------------------------------------
Name      Type      Size  Value     
------------------------------------
txn       my_txn    -     @463      
  addr    integral  32    'h487120f6
  txn_id  integral  32    'h2df22641
------------------------------------

UVM_INFO testbench.sv(76) @ 100: uvm_test_top.m_env.m_consumer \[my_consumer\] txn #1
------------------------------------
Name      Type      Size  Value     
------------------------------------
txn       my_txn    -     @463      
  addr    integral  32    'h487120f6
  txn_id  integral  32    'h2df22641
------------------------------------

UVM_INFO testbench.sv(76) @ 100: uvm_test_top.m_env.m_consumer \[my_consumer\] txn #2
------------------------------------
Name      Type      Size  Value     
------------------------------------
txn       my_txn    -     @463      
  addr    integral  32    'h487120f6
  txn_id  integral  32    'h2df22641
------------------------------------

UVM_INFO testbench.sv(76) @ 100: uvm_test_top.m_env.m_consumer \[my_consumer\] txn #3
------------------------------------
Name      Type      Size  Value     
------------------------------------
txn       my_txn    -     @463      
  addr    integral  32    'h487120f6
  txn_id  integral  32    'h2df22641
------------------------------------

UVM_INFO testbench.sv(76) @ 100: uvm_test_top.m_env.m_consumer \[my_consumer\] txn #4
------------------------------------
Name      Type      Size  Value     
------------------------------------
txn       my_txn    -     @463      
  addr    integral  32    'h487120f6
  txn_id  integral  32    'h2df22641

Please format your code making your code easier for others to read. I have done that for you.

Place the construction of txn within the producer’s repeat loop. Otherwise, you’re placing the same handle into your analysis fifo, effectively overwriting the object it points to.

Thanks dave, it is working.

but i am still not understanding that before keeping txn within producer loop, if i use txn.sprint() we were getting different transactions in producer why it is putting only last transaction in analysis_port.write() method in producer?

You’re not getting different transactions in the producer. You were putting different values into the same transaction, effectively overwriting the previous ones.

This simpler example should demonstrate the concept by using a queue instead of an analysis port for the fifo. In the producer loop, whenever we push a new element onto the queue, we’re simply copying the handle to the object, not a copy of the object itself. Since there’s only one instance of our object, there’s only one place to store values for b.

module top;
  
  class A;
    rand bit [7:0] b;
  endclass
  
  A fifo[$];
  initial begin : producer
    A handle;
    handle =new();
    repeat (5) begin
      // handle =new();  // create a new object for each transaction
      assert(handle.randomize());
      fifo.push_back(handle);
      $write("producer--fifo size: %0d ",fifo.size());
      foreach(fifo[i]) $write(" fifo[%0d].b: $h ",i,fifo[i].b);
      $display; // newline
    end
  end
  initial begin : consumer
    A handle;
    forever begin
      wait(fifo.size>0)
      $write("consumer--fifo size: %0d ",fifo.size());
      foreach(fifo[i]) $write(" fifo[%0d].b: $h ",i,fifo[i].b);
      $display; // newline
      handle= fifo.pop_front();
    end
  end 
  
endmodule

When you put the constructor inside the producer loop, now there’s an object to hold each unique set of values.