Out-of-Order Scoreboarding

Handling complex protocols like AXI where responses do not match the request order.

The Pipelined Matching Challenge

In simple protocols like APB, transactions appear on the bus in the exact order they were requested. Verifying this is easy: you use a uvm_tlm_analysis_fifo and compare items as they arrive.

However, advanced SoC protocols like AXI or PCIe support Out-of-Order (OoO) completions. A read request with ID=5 might finish after a read request with ID=10 because of interconnect latency or memory controller arbitration.

The FIFO Trap:

If you use a standard FIFO queue for an OoO protocol, the first transaction that returns out of sequence will trigger a mismatch error, even though the data might be perfectly correct. You need a Searchable Buffer instead.

Strategy: Associative Array Matching

The most robust way to build an OoO scoreboard is to use a SystemVerilog Associative Array (Hash Map) as your internal "expectation memory." You index this memory using a unique Transaction ID or Tag.

The Algorithm:

  1. Predict: When a request is observed at the Master side, clone it and store it in the array: expected_mem[tr.id] = tr;
  2. Observe: When a response arrives at the Slave side, retrieve the original request: tr_exp = expected_mem[tr_actual.id];
  3. Compare: Perform the data check and then delete the entry from the array to free memory.

Implementation Flow

OoO Scoreboard Logic

class axi_scoreboard extends uvm_scoreboard;
    // Expectation Buffer: Key = Transaction ID
    axi_item exp_buffer[int];
    // Input from Master Monitor (Request)
    virtual function void write_request(axi_item tr);
        axi_item tr_clone;
        $cast(tr_clone, tr.clone());
        exp_buffer[tr_clone.id] = tr_clone;
    endfunction
    // Input from Slave Monitor (Response)
    virtual function void write_response(axi_item tr_actual);
        if (exp_buffer.exists(tr_actual.id)) begin
            axi_item tr_exp = exp_buffer[tr_actual.id];
            if (!tr_actual.compare(tr_exp))
                `uvm_error("SCB", "Data Mismatch!")
            // Clean up to prevent memory leak
            exp_buffer.delete(tr_actual.id);
        end else begin
            `uvm_error("SCB", "Unexpected Response ID!")
        end
    endfunction
endclass
                            

Best Practices for OoO Checkers

  • ID Reuse: Ensure your scoreboarding logic handles ID reuse. If the DUT reuses an ID before the previous transaction finished, your code should flag an error or use a more complex key (e.g., ID + Address).
  • Memory Leak Check: Always use the check_phase to verify the associative array is empty. Any remaining items represent "dropped" transactions that the DUT never completed.
  • Clone Everything: Transaction objects are passed by reference. If you don't clone() the request before storing it, future updates to the object in the monitor will corrupt your scoreboard memory.