I have the following scoreboarding logic for an asynchronous FIFO. Basically, I am getting read and write txn from the monitor separately, and I use a fork join in run_phase to get both transactions and read them in two analysis FIFOs.
Next, I process the write transaction and check if the data matches with read txn.
Can someone comment if this logic seems fine.
class async_fifo_scoreboard extends uvm_component;
`uvm_component_utils(async_fifo_scoreboard)
uvm_analysis_export #(async_fifo_txn) write_export;
uvm_analysis_export #(async_fifo_txn) read_export;
uvm_tlm_analysis_fifo #(async_fifo_txn) write_fifo,
read_fifo;
int m_matches,
m_mismatches;
async_fifo_txn pkt_q[$];
function new( string name , uvm_component parent) ;
super.new( name , parent );
m_matches = 0;
m_mismatches = 0;
endfunction
function void build_phase( uvm_phase phase );
write_fifo = new("before_fifo", this);
read_fifo = new("after_fifo", this);
write_export = new("before_export", this);
read_export = new("after_export", this);
endfunction
// FIFO implements the write by providing analysis imps, so connect the imp port to FIFO analysis exports.
function void connect_phase( uvm_phase phase );
write_export.connect(write_fifo.analysis_export);
read_export.connect(read_fifo.analysis_export);
endfunction
task run_phase( uvm_phase phase );
async_fifo_txn write_txn, read_txn;
forever begin
fork
begin
write_fifo.get(write_txn);
pkt_q.push_back(write_txn);
end
begin
read_fifo.get(read_txn);
end
join
async_fifo_txn exp_read_txn = pkt_q.pop_back();
if(exp_read_txn.data!=rd_txn.data)
`uvm_error("Comparator Mismatch",
$sformatf("%s does not match %s", before_txn.convert2string(), after_txn.convert2string()))
endtask
endclass