Using get_next_item and item_done methods in the driver With/Without RSP packet

Hi, I’m quite a bit confused about the using get_next_item and item_done methods in the driver With/Without RSP packet.
Basically, one of the approach in Sequence-Driver-Sequencer communication is the using get_next_item and item_done methods in the driver.
Especially, In Using get_next_item and item_done methods in the driver, I can get the response without rsp.

This is the example without get_response(req) and rsp packet.
But I can get the value of “req.rsp_b” well. why do I need get_response() approach?

//Driver
class driver extends uvm_driver#(seq_item);                          
  `uvm_component_utils(driver)                                       
                                                                 
  function new(string name = "driver", uvm_component parent = null);
    super.new(name, parent);                                         
  endfunction                                                        
                                                                     
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);      
  endfunction                      
                                   
  task run_phase (uvm_phase phase);
    forever begin                  
      seq_item req;                                                  
      seq_item rsp;                                                  
                                                                     
      seq_item_port.get_next_item(req);                              
      void'(req.randomize());                                        
      #50;                                                           
      req.rsp_b = 1;                                                 
      seq_item_port.item_done(req);                                  
                                                                     
    end                                                              
  endtask                                                            
endclass

class base_seq extends uvm_sequence #(seq_item);
  seq_item req;      
  `uvm_object_utils(base_seq)                                        
                     
  function new (string name = "base_seq");
    super.new(name); 
  endfunction                      
                     
  task body();       
                     
    req = seq_item::type_id::create("req");                          
    wait_for_grant();                                                
    assert(req.randomize());                                         
    send_request(req);
    wait_for_item_done();
//    get_response(req);                                             
    `uvm_info(get_type_name(), $sformatf("After get_response: rsp_b = %0d", req.rsp_b), UVM_LOW);
  endtask            
endclass


The below is a blocking example to check that the get_response() will block until a response is received.
So I commented out “rsp.rsp_b=1” in the driver to see the blocking.


class driver extends uvm_driver#(seq_item);                                      
  `uvm_component_utils(driver)                                                   
                           
  seq_item req;            
  seq_item rsp;            
  function new(string name = "driver", uvm_component parent = null);             
    super.new(name, parent);                                                     
  endfunction              
                           
  function void build_phase(uvm_phase phase);                                    
    super.build_phase(phase);                                                    
  endfunction              
                           
  task run_phase (uvm_phase phase);                                              
    forever begin          
      seq_item_port.get_next_item(req);                                          
      void'(req.randomize());                                                    
      #50;                 
      $cast(rsp, req.clone());                                                   
      rsp.set_id_info(req);                                                      
//      rsp.rsp_b = 1;     
      seq_item_port.item_done(rsp);                                              
                           
    end                    
  endtask                  
endclass


`include "uvm_macros.svh"
import uvm_pkg::*;
     
`include "seq_item.sv"
`include "sequencer.sv"
`include "driver.sv"
`include "agent.sv"
`include "env.sv"
     
class base_seq extends uvm_sequence #(seq_item);
  seq_item req;
  seq_item rsp;
  `uvm_object_utils(base_seq)
     
  function new (string name = "base_seq");
    super.new(name);
  endfunction
     
  task body();
     
    req = seq_item::type_id::create("req");
    wait_for_grant();
    assert(req.randomize());
    send_request(req);
    wait_for_item_done();
    get_response(rsp); // Block until a response is received
    `uvm_info(get_type_name(), $sformatf("After get_response: rsp_b = %0d", rsp.rsp_b), UVM_LOW);
  endtask
endclass

Unexpectedly, I don’t see it blocking as expected.

I’m confused that I think I don’t need a get_response() to get a response from slave.
Get_response() also doesn’t blocking work.

In reply to UVM_LOVE:

If your driver only processes one sequence_item at a time, you can use the req handle to pass information back to the sequence without using item_done(rsp) or get_response().

However, there are many protocols where the driver will accept multiple sequence_items and they may complete in a different order than received. In these cases, the driver will send the responses back to the sequence using item_done(rsp) and the sequence will get the results with get_response().