Facing issue while sending Dynamic array transaction items through UVM analysis port

Hi All,
I am facing issue, when I was trying to send i2c_transaction items (Here, i2c_data & i2c_addr are dynamic arrays) from monitor to reg predictor for write/read transaction. But the transaction items especially i2c_data & i2c_addr are not reaching to reg predictor.
I am using the following lines of code to send transaction items from monitor to reg predictor.

uvm_analysis_port #(REQ) i2c_data_to_export;

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

virtual function void send_transaction_to_analysis_export(REQ send_tran);
i2c_data_to_export.write(send_tran);
`uvm_info(this.get_name(),$psprintf(“Transaction Sent \n%s”,send_tran.sprint()), m_drv_verb_imp_msg_e)
endfunction : send_transaction_to_analysis_export

if (rsp.m_i2c_trans_type == READ || rsp.m_i2c_trans_type == RD_WITH_RE_START) begin
for (int idx = 0; idx < (m_i2c_data.size()); idx++) begin
{rsp.m_i2c_data[idx],rsp.m_i2c_data[idx+1]} = {m_i2c_data[idx],m_i2c_data[idx+1]};
end
end

`uvm_info(this.get_name(),$psprintf(“Transaction before Sent_gen \n%s”,rsp.sprint()), m_drv_verb_imp_msg_e) //1st display statement

  //Send transaction out on analysis port.
  send_transaction_to_analysis_export(rsp);

`uvm_info(this.get_name(),$psprintf(“Transaction Sent_gen \n%s”,rsp.sprint()), m_drv_verb_imp_msg_e) //2nd display statement

As shown in the above code, I have put two display statements, one is before sending the transaction items to analysis port and other one is after sending the transaction items.
In the 1st display statement, it displays all the transaction items. But in the second display statement, the values of transaction items are zero.

1st display statement ouput:

UVM_INFO /accts/smopidev/projects/fomax_branch_apr13_r219/dv/verif/common/uvc/i2c/i2c_driver.sv(915) @ 125.625000us: uvm_test_top.TB.env.walleye_i2c_agent.m_driver [m_driver] Transaction before Sent_gen

--------------------------------------------------------

Name Type Size Value

--------------------------------------------------------

req i2c_transaction - @4186

m_i2c_addr da(integral) 1 -

[0] integral 8 'h2

m_i2c_data da(integral) 4 -

[0] integral 8 'h43

[1] integral 8 'h50

m_trans_data_len integral 32 'h2

m_i2c_trans_type i2c_trans_type_e 3 READ

m_i2c_err_type i2c_err_config_e 4 NO_ERROR

m_no_of_acks integral 32 'h4

m_no_of_nacks integral 32 'h1

m_trans_start_time integral 64 'h33f38f8

m_trans_end_time integral 64 'h77ce2a8

m_i2c_tr_verb_e uvm_verbosity 32 UVM_DEBUG

begin_time time 64 1.500000us

2nd display statement output:

UVM_INFO /accts/smopidev/projects/fomax_branch_apr13_r219/dv/verif/common/uvc/i2c/i2c_driver.sv(919) @ 125.625000us: uvm_test_top.TB.env.walleye_i2c_agent.m_driver [m_driver] Transaction Sent_gen

--------------------------------------------------------

Name Type Size Value

--------------------------------------------------------

req i2c_transaction - @4186

m_i2c_addr da(integral) 1 -

[0] integral 8 'h0

m_i2c_data da(integral) 2 -

[0] integral 8 'h0

[1] integral 8 'h0

m_trans_data_len integral 32 'h2

m_i2c_trans_type i2c_trans_type_e 3 READ

m_i2c_err_type i2c_err_config_e 4 NO_ERROR

m_no_of_acks integral 32 'h4

m_no_of_nacks integral 32 'h1

m_trans_start_time integral 64 'h33f38f8

m_trans_end_time integral 64 'h77ce2a8

m_i2c_tr_verb_e uvm_verbosity 32 UVM_DEBUG

begin_time time 64 1.500000us

Would you please help me to fix this issue.

In reply to Sivajim:

You should always clone an item before sending it out an analysis port. This ensures that the item won’t be overwritten by the next transaction.

In reply to cgales:

Could you please soem more Code. Without seeing the Code it is near impossibel to give you and advice.
What I’m guessing is you do not construct your dynamic arrays. There are 2 ways to do this: the explicit call of the constructor new or the implicit construction by using an assignment pattern.
What is REQ? This should be your transaction.

Hi,

Please find the code that I am using to read the data from DUT and send the i2c data & addr to predictor through uvm analysis port.

virtual protected task i2c_data_transmition(REQ trans);

if(m_i2c_trans_type == READ) begin
m_i2c_data = new [m_trans_data_len];
//Receive Data Buffer
for(int i2c_trans_data_idx=0; i2c_trans_data_idx < m_trans_data_len;
i2c_trans_data_idx++)
begin : RCV_READ_BYTE

      i2c_byte_read((i2c_trans_data_idx+1 == m_trans_data_len), 
                    m_i2c_data[i2c_trans_data_idx]); 
    end
  end

endtask

virtual protected task i2c_byte_read(bit ack, output bit[7:0] dataOut);

for(int i2c_data_idx=7; i2c_data_idx >=0; i2c_data_idx--) 
begin : RCV_READ_BIT
  @(negedge m_i2c_if.filtered_scl)
  m_i2c_if.io_sda_l <= 1'bz;

  @(posedge m_i2c_if.filtered_scl)
  dataOut          = {dataOut[6:0], m_i2c_if.io_sda};
end

//for debug purpose
m_i2c_if.read_bytes_debug <= dataOut; 

uvm_info(this.get_name(),"=============================================", UVM_LOW); uvm_info(this.get_name(), $psprintf(“Data Read from Slave :0x%0h”, dataOut), UVM_LOW);
`uvm_info(this.get_name(),“=============================================”, UVM_LOW);

//Send Acknowledgement to Slave once Read Data is received.
@(negedge m_i2c_if.filtered_scl)
m_i2c_if.io_sda_l <= ack;

endtask

virtual protected task gen_stop_condition(REQ rsp);

if(cfg.send_tr_at_stop == 1’b1 && send_tr_at_stop == 1) begin
//Copying Read Data into Transaction, to send it to Scoreboard
if (rsp.m_i2c_trans_type == READ || rsp.m_i2c_trans_type == RD_WITH_RE_START) begin
for (int idx = 0; idx < (m_i2c_data.size()); idx++) begin
//rsp.m_i2c_data[idx] = {m_i2c_data[idx],m_i2c_data[idx+1]};
{rsp.m_i2c_data[idx],rsp.m_i2c_data[idx+1]} = {m_i2c_data[idx],m_i2c_data[idx+1]};
end
end

  //Adding information about number of ACKs and NACKs in the transaction.
  rsp.m_no_of_acks  = m_no_of_acks;
  rsp.m_no_of_nacks = m_no_of_nacks;

  //Record transaction Start and End times
  rsp.m_trans_start_time = m_trans_start_time;
  rsp.m_trans_end_time   = m_trans_end_time;

  `uvm_info(this.get_name(),$psprintf("Transaction before Sent_gen \n%s",rsp.sprint()), UVM_LOW)  -- 1St Display Statement

  //Send transaction out on analysis port.
  send_transaction_to_analysis_export(rsp);

  `uvm_info(this.get_name(),$psprintf("Transaction Sent_gen \n%s",rsp.sprint()), UVM_LOW)    --2nd display statement
end

endtask

In reply to Sivajim:

I will repeat: You should always clone an item before sending it out an analysis port. This ensures that the item won’t be overwritten by the next transaction.

You aren’t creating a clone of rsp prior to sending it out the analysis port.

In reply to cgales:

Your Code Looks quite confusing to me. Let me ask again what REQ is? In task i2c_data_transmition(REQ trans) I do not see what are you doing with the transaction trans.
And it is unclear to me where all the variables starting with m_ are coming from.
And of Course what Chuck is saying is also important.

I did clone of seq items before sending them to analysis port, but still i2c data & addr shows zero values.

`uvm_info(this.get_name(),$psprintf(“Transaction before Sent_gen \n%s”,rsp.sprint()), UVM_LOW) – 1St Display Statement

$cast(rsp, req.clone());

//Send transaction out on analysis port.
send_transaction_to_analysis_export(rsp);

`uvm_info(this.get_name(),$psprintf(“Transaction Sent_gen \n%s”,rsp.sprint()), UVM_LOW) --2nd display statement

In reply to Sivajim:

Have you implemented the do_clone() method in your sequence_item?

Review this article to ensure that you are doing it correctly.

Hi,
Thank you All,
Issue resolved.

In reply to Sivajim:

Hi Sivajim,
Could you please tell what was the issue?

Thanks

In reply to cgales:

hey cgales, im facing the same issue, could u tell me how to clone my item becuase its gets overwritten

In reply to abdelaali_21:

My response above provides a link describing all the transaction methods you need to implement in your sequence_item. Have you implemented those?

Do you clone() your item as described above prior to sending it?

In reply to cgales:

thnak you cgales ! i did it differently and it worked.