Is it necessary for comparison of data in scoreboard we should use check_phase?

Actually I have some problem in comparing data in run_phase of scoreboard. When I am comparing in run phase of scoreboard the data’s are not matching although when I am printing both data they are coming as same. But when I moved my comparing logic to check_phase then their is no mismatch. All data matched . What is the reason behind these mismatch in scoreboard’s run phase ?

In reply to Subhra Bera:
Impossible to answer without knowing the timing of the data you are trying to compare, but most likely a race condition.

The purpose of the check_phase is to do comparisons after the test has finished executing, so it might be more appropriate to do the check there.

In reply to dave_59:

Did you try the case equality? There might be x or z in your data. Or the format is wrong.
There can be more reasons. Do you apply the compare data as a transaction?

In reply to chr_sue:
Yes I tried case equality but they did not work. Actually I am writing scoreboard logic for SPI. I have taken a queue of apb(master) sequence item in scoreboard. And another queue of SPI sequence item. I have taken an associative array in scoreboard for mimicking the DUT model.
I am poping out data from apb_queue and based on address(apb sequence item) I am storing the the data in the associative array. Then when spi_queue is getting its first data. Then I am comparing based on the character length.
SPI DUT has Tx0,Tx1,Tx2,Tx3,Rx0,Rx1,Rx2,Rx3,ctrl,divider,ss register. All are 32bit in size. There address are 00,04,08,0c,10,14,18 in hexadecimal(Tx and Rx registers address are same).ctrl[6:0] is the length of the character to be send and received.
when I am taking logic[31:0] char_len variable in scoreboard. In this variable I am storing associative_array[ctrl_addr]. And based on char_len[6:0](character length) I am comparing.
I have taken logic[127:0]Total_tx variable. And storing like Total_tx={Tx3,Tx2,Tx1,Tx0}; and then based on char_len[6:0] I am comparing. like

 for(int i=0;i<char_len;i++) begin
                           if(Total_tx[i]==MOSI[i]) (Mosi is the spi slave sequence item 
                          k++;                            data of 128 bit length logic type 
                       else                                                         variable)
                        break; 
                   end  

and then if k==char_lenth then data matches.
But Tx_Total=10203040102030401020304010203040;
MOSI= XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX40(30 X, 2 DIGIT)
CHAR_LEN =8 BUT data is not matching.

In reply to Subhra Bera:

You should show how you are extracting your transactions. This help might hrlp to resolve the issue.

In reply to chr_sue:

//Macros to create the uvm_analysis_imp ports (just an export + write function)
  `uvm_analysis_imp_decl(_apb_port) 
  `uvm_analysis_imp_decl(_spi_port)
 
class spi_scoreboard extends uvm_scoreboard;
  `uvm_component_utils(spi_scoreboard)
string m_name;
virtual irq_if irq_if_1;
///golden reference model
logic [31:0] dut_model_w[*];//for mimicing the  writing into the dut reg
logic [31:0] dut_model_r[*];//for mimicing the reading from the dut reg
logic[31:0] ctrl_reg_value;// to know the ctrl register value
logic[127:0] Tx_reg_value,Rx_reg_value;
logic[6:0] char_len;
// for checking purpose
int k,l;

apb_seq_item apb_item,apb_item_2;
spi_seq_item spi_item,spi_item_2;

uvm_analysis_imp_apb_port#(apb_seq_item,spi_scoreboard)apb_imp;
uvm_analysis_imp_spi_port#(spi_seq_item,spi_scoreboard)spi_imp;

//queue to store data which will come from apb and spi side
apb_seq_item apb_dataQ[$];
spi_seq_item spi_dataQ[$];
logic[127:0] MOSIDATA,MISODATA;

extern function new(string name="spi_scoreboard",uvm_component parent =null);
extern function void build_phase(uvm_phase phase);
extern task run_phase( uvm_phase phase );
extern function void write_apb_port(apb_seq_item apb_item_1);
extern function void write_spi_port(spi_seq_item spi_item_1);
extern function void extract_phase( uvm_phase phase );
extern function void check_phase(uvm_phase phase);
extern function void report_phase( uvm_phase phase );


endclass:spi_scoreboard


 function spi_scoreboard::new (string name="spi_scoreboard", uvm_component parent=null);
    super.new(name, parent);
     m_name=name;
  endfunction : new

function void spi_scoreboard:: build_phase(uvm_phase phase);
 super.build_phase(phase);
 if(!uvm_config_db#(virtual irq_if)::get(this,"","irq_if",irq_if_1))
  `uvm_fatal("NO IRQ IF",{"virtual interface of IRQ must be set for:",get_full_name(),".irq_if"});
 spi_imp=new("spi_imp",this);
 apb_imp=new("apb_imp",this);
endfunction:build_phase


function void spi_scoreboard:: write_apb_port(apb_seq_item apb_item_1);
       $cast(apb_item,apb_item_1.clone());
      `uvm_info(get_type_name(),$sformatf("writing in the apb write method \n %s",apb_item.sprint()), UVM_LOW)
      apb_dataQ.push_back(apb_item);


endfunction


function void spi_scoreboard:: write_spi_port(spi_seq_item spi_item_1);
    $cast(spi_item,spi_item_1.clone());
    `uvm_info(get_type_name(),$sformatf("writing in spi write method \n %s",spi_item.sprint()),UVM_LOW)
    spi_dataQ.push_back(spi_item);
endfunction

task spi_scoreboard:: run_phase( uvm_phase phase );
      forever begin


         foreach(apb_dataQ[i]) begin
           apb_item_2=apb_dataQ.pop_front();
          `uvm_info(m_name,$sformatf("Scoreboard \n %s",apb_item_2.sprint()),UVM_LOW)
              if(apb_item_2.we) begin
                    dut_model_w[apb_item_2.addr]=apb_item_2.data;
                   // $display("dut_model_w=%p",dut_model_w);
                end
          
             else begin
               dut_model_r[apb_item_2.addr]=apb_item_2.data;
                //$display("dut_model_r=%p",dut_model_r);
              end


          end

           Tx_reg_value={dut_model_w[32'h0c],dut_model_w[32'h08],dut_model_w[32'h04],dut_model_w[32'h00]};
           Rx_reg_value={dut_model_r[32'h0c],dut_model_r[32'h08],dut_model_r[32'h04],dut_model_r[32'h00]};

           ctrl_reg_value = dut_model_w[32'h10];
           char_len=ctrl_reg_value[6:0];
                  wait(spi_dataQ.size())begin
                      spi_item_2= spi_dataQ.pop_front();
                      MOSIDATA=spi_item_2.MOSIDATA;
                      MISODATA=spi_item_2.MISODATA;
                      $display($time,"MOSIDATA[127:0]::%b\n MISODATA[127:0]::%b",MOSIDATA[127:0],MISODATA[127:0]);

                  end
            end
 
endtask




function void spi_scoreboard::  extract_phase(uvm_phase phase);
super.extract_phase(phase);

  foreach(apb_dataQ[i]) begin
           apb_item_2=apb_dataQ.pop_front();
          `uvm_info(m_name,$sformatf("Scoreboard \n %s",apb_item_2.sprint()),UVM_LOW)
              if(apb_item_2.we) begin
                    dut_model_w[apb_item_2.addr]=apb_item_2.data;
                   // $display("dut_model_w=%p",dut_model_w);
                end
          
             else begin
               dut_model_r[apb_item_2.addr]=apb_item_2.data;
                //$display("dut_model_r=%p",dut_model_r);
              end
          end
     Rx_reg_value={dut_model_r[32'h0c],dut_model_r[32'h08],dut_model_r[32'h04],dut_model_r[32'h00]};
endfunction

function void spi_scoreboard::  check_phase(uvm_phase phase);
super.check_phase(phase);

//compare logic
    begin
      for(int j=0;j<char_len;j++) begin
          if(MOSIDATA[j]===Tx_reg_value[j])
             k++;
          else 
            break;
       end

      for(int m=0;m<char_len;m++) begin
          if(MISODATA[m]===Rx_reg_value[m])
             l++;
          else
            break;
       end
   end
       apb_dataQ.delete();
       spi_dataQ.delete();

endfunction




function void spi_scoreboard:: report_phase( uvm_phase phase );
//report
 super.report_phase(phase);
    `uvm_info(get_type_name(), "============================", UVM_NONE)
    `uvm_info(get_type_name(), "Scoreboard Results", UVM_NONE)
     if(char_len==k&&char_len==l)begin
                   `uvm_info(get_type_name(), "TEST PASSED", UVM_NONE)
                   `uvm_info(m_name,$sformatf("CONSIDERED CHARACTER LENGTH::%d",char_len),UVM_LOW)
                   `uvm_info(m_name,$sformatf("DATA SENT FROM APB MASTER IS MATCHED WITH DATA IN MOSI LINE::\n\n\n       MOSI DATA SENT FROM APB MASTER::%b\n MOSI DATA COLLECTED FROM SPI MONITOR::%b\n\n",Tx_reg_value[127:0],  MOSIDATA[127:0] ),UVM_LOW)
                   `uvm_info(m_name,$sformatf("DATA SENT FROM SPI SLAVE IS MATCHED WITH DATA IN MISO LINE::\n\n\n        MISO DATA SENT FROM SPI SLAVE::%b\n MISO DATA COLLECTED FROM APB MONITOR::%b\n\n",MISODATA[127:0],Rx_reg_value[127:0]),UVM_LOW)

          end
        else begin 
                 `uvm_info(get_type_name(), "TEST FAILED", UVM_NONE)
     
    `uvm_info(get_type_name(), "============================", UVM_NONE)
          end
endfunction








Here actually I have written 12 sequence item through apb_driver within which 8 of which are writing operation and 4 are reading operation. All of the sequence item are coming to queue of type apb_seq_item. But the first 8(write seq item) are stored in the queue first and the scoreboard run_phase is taking out those 8 item from the queue and after that it completes run_phase. But the apb_seq_item which come some time after to the queue, scoreboard is not considering them in run_phase. If I use extract phase then only it able to extract the remaining sequence item . Otherwise it is not happening . Why this problem is coming?