UVM Randomized Problem of Scoreboard

i ask you someting weird this is my code → apb uvm testbench(1) - EDA Playground

My code just is verifying simple memory. It’s just a test code for studying UVM.
My sequence is writing 8 times && reading 8 times. So, i should have to store the writing data in my uvm_scoreboard named “scoreboard”, so i will able to compare with reading data. But, it doesn’t work.
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. Changed Values seem like randomized value which already tranmitted by monitor. But, as you see, i use push_back method, so Not-Targetted value is not contained to the queue. I suggest that the queue type is apb_transmission which has ‘rand’ type values, so it the queue in scoreborad was randomized when other apb_transmission type in other uvm_component was randomized.


class exp_obj extends uvm_object;
  apb_transaction exp_queue[$];
  function new(string name = "exp_obj");

class apb_scoreboard extends uvm_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 = exp_obj::type_id::create("exp_queue", this);
    //exp_queue = new();
  function void build_phase(uvm_phase phase);
    //exp_queue = apb_transaction::type_id::create("exp_queue", this);

  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();
        if(tr.prdata == expdata.pwdata)begin
          `uvm_info("",$sformatf("MATCHED, %8h", expdata.pwdata),UVM_LOW)
        else begin
          `uvm_info("",$sformatf("MISMATCHED, tr: %8h, expdata: %8h", tr.prdata, expdata.pwdata),UVM_LOW)
  function write_expdata(input apb_transaction tr);
    if (tr.pwrite == 1 && tr.penable == 1) begin
      `uvm_info(get_type_name(), "get_write_data", UVM_LOW)
      `uvm_info(get_type_name(), $psprintf("queue[0]: \n%s", obj.exp_queue[0].sprint()), UVM_LOW)
    foreach(obj.exp_queue[i]) `uvm_info(get_type_name(), $psprintf("pwdata[%d]: %8h", i, obj.exp_queue[i].pwdata), UVM_LOW)

i want to store some write data in this queue, but when i get it, it is replaced with Randomized data. how can i fix it?

In reply to choicelee:

Your problem 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

In reply to choicelee:

Your problem is more complex. The generation of your control signals for RD and WR is not consistent with the design implementation. You do not really get back the RD values.

Thank you for your help! :)

In reply to choicelee:

I have developped a more smart solution for your testbench. It has more flexibility and uses less resources. This results in a higher verification quality and makes the simulation faster.
Find the solution here

I’m doinng the compare in the sequence. As reference model I use an associative array in the sequence. I’m randomizing the address and the data. And you can set the numbers of sequence_items to be generated from the test.