Unexpected Queue Randomization with UVM environment

91 Views Asked by At

This is my code -> eda playground

When the code below activate, class "trasn packet queue" in uvm_scoreboard is changed when "monitor" send value as anlaysis_port. i just give a write data to packet queue "push_back" method. but all data in the queue has changed.

`uvm_analysis_imp_decl(_expdata)
`uvm_analysis_imp_decl(_actdata)

class exp_obj extends uvm_object;
  `uvm_object_utils(exp_obj)
  apb_transaction exp_queue[$];
  
  function new(string name = "exp_obj");
    super.new(name);
  endfunction
endclass

class apb_scoreboard extends uvm_scoreboard;
  `uvm_component_utils(apb_scoreboard)
  
  uvm_analysis_imp_expdata#(apb_transaction, apb_scoreboard) mon_export;
  uvm_analysis_imp_actdata#(apb_transaction, apb_scoreboard) sb_export;
  exp_obj obj;
  
  
  function new(string name, uvm_component parent);
    super.new(name, parent);
    mon_export = new("mon_export", this);
    sb_export = new("sb_export", this);
    obj = new("obj");
    obj.rand_mode(0);
    //obj = exp_obj::type_id::create("exp_queue", this);
    //exp_queue = new();
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    //exp_queue = apb_transaction::type_id::create("exp_queue", this);
  endfunction

  function write_actdata(input apb_transaction tr);
    apb_transaction expdata;
    if (tr.pwrite == 0 && tr.penable == 0) begin
      if(obj.exp_queue.size()) begin
        `uvm_info(get_type_name(), $psprintf("queue[0]: \n%s", obj.exp_queue[0].sprint()), UVM_LOW)
        //expdata = apb_transaction::type_id::create($psprintf("exp_queue%d", exp_queue.size()), this);
        expdata = obj.exp_queue.pop_front();
        tr.compare(expdata);
        if(tr.prdata == expdata.pwdata)begin
          `uvm_info("",$sformatf("MATCHED, %8h", expdata.pwdata),UVM_LOW)
        end
        else begin
          `uvm_info("",$sformatf("MISMATCHED, tr: %8h, expdata: %8h", tr.prdata, expdata.pwdata),UVM_LOW)
        end
      end
    end
  endfunction
  
  function write_expdata(input apb_transaction tr);
    if (tr.pwrite == 1 && tr.penable == 1) begin
      obj.exp_queue.push_back(tr);
      `uvm_info(get_type_name(), "get_write_data", UVM_LOW)
      tr.print();
      `uvm_info(get_type_name(), $psprintf("queue[0]: \n%s", obj.exp_queue[0].sprint()), UVM_LOW)
    end
    
    foreach(obj.exp_queue[i]) `uvm_info(get_type_name(), $psprintf("pwdata[%d]: %8h", i, obj.exp_queue[i].pwdata), UVM_LOW)
  endfunction
                            
endclass

The goal is to store write data in the queue, however it gets, replaced with Randomized data.
How can obtain the desired behavior?

1

There are 1 best solutions below

1
dave_59 On

Your problem (at least one of them) is you only construct one transaction object. What you need to do is construct a new object for each transaction that goes into the queue. Put this into the forever loop of your monitors that does the write to the scoreboard.