Async FIFO Scoreboarding Logic

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

You do not need pkt_q.