Response Handling

Driving is only half the job. How to get data BACK from the DUT to the Sequence (e.g., Read Data).

The Bidirectional Bridge

While most UVM communication is one-way (stimulus down), many protocols require a Bidirectional Handshake. Whether it's returning read data, a status code, or a completion interrupt, the Driver must be able to push information back "up" to the Sequence.

Response Methods:

  • In-Place Update: Modifying the req object directly.
  • Separate Response: Creating a new rsp object and sending it.
  • Layered Transport: Passing responses through multiple translation sequences.

The ID Matching Secret

In a multi-sequence environment, the Sequencer might be handling dozens of items. If the Driver just sends a random response back, how does the Sequencer know which Sequence it belongs to?

The set_id_info() Method:

Every uvm_sequence_item has internal metadata (Sequence ID and Transaction ID). When a Driver creates a new response object, it MUST call rsp.set_id_info(req). This copies the IDs from the request to the response, allowing UVM's internal routing to deliver the data to the correct get_response() call.

Implementation Flow

Driver: Read Data Return

task drive_read(my_item req);
    my_item rsp;
    // 1. Perform physical read
    wait(vif.rvalid);
    // 2. Create Response & Link IDs
    rsp = my_item::type_id::create("rsp");
    rsp.set_id_info(req); 
    rsp.data = vif.rdata;
    // 3. Send back
    seq_item_port.put_response(rsp);
endtask
                            
Sequence: Retrieval

task body();
    `uvm_do(req)
    // Blocks here until Driver calls put_response()
    get_response(rsp); 
    `uvm_info("READ", $sformatf("Data: %h", rsp.data), UVM_LOW)
endtask
                            

Advanced: The Response Handler

For asynchronous protocols where responses might come out-of-order or at unpredictable times, the blocking get_response() can be problematic. UVM offers a non-blocking alternative: the response_handler.

By calling use_response_handler(1), you tell UVM to execute a specific callback function (response_handler()) immediately whenever a response arrives at the sequencer. This allows the main sequence body() to continue running uninterrupted.