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?