Question on use_response_handler() and response_handler functions

Hello,
the UVM reference 1.1 states following :
“By default, responses from the driver are retrieved in the sequence by calling
get_response.
An alternative method is for the sequencer to call the response_handler function with
each response.”

Assuming we want to use the response_handler function, which is a virtual method, how can it be used. Assuming that it needs to be extended to perform some additional functionality, how can we call the part of the method which actually reads the response item from response fifo. The signature of response_handler is :
virtual function void response_handler(uvm_sequence_item response)
Manual says method is called every time there is a response in response fifo, to keep the response fifo empty. If I need to extend this to say, count the total number of response items received and also get the response items for comparison with some members of request item class, how will the code look like? Do we need to call the original response_handler (of the base class) using super.response_handler() and retrieve the response items from the response fifo in extended method?
Can someone clarify please.
thanks,
-sunil puranik

In reply to puranik.sunil@tcs.com:
Look here to see details of the response handler usage:
https://verificationacademy.com/cookbook/driver/pipelined

Hello,
thanks for the reply and the link. My question was in fact referring to the same section from Cookbook given in the link.
The extended response_handler given there just increments the count and waits for count to go to 20 to ensure that sequence does not exit before 20 responses are collected in fifo. My question is if I need to read the response items also, how can I do it in the extended response_handler function? Do I need to call the version in base class, which will read the response items?
regards,
-sunil

In reply to puranik.sunil@tcs.com:

You have 2 options to handle responses from the driver to the sequence:
(1) Sending back the response from the driver to the sequence using put or item_done: In the sequencer you have to execute get_response explicitly. This works perfectly with non-pipelined protocols.
(2) Using the response handler sends automatically a response to the sequence. You have to enable the response_handeler by calling

use_response_handler(1);

in the sequence (body task). And you have to override the function

response_handler

.
The implementation in the base class is doing nothing. One very simple implementation is to count the responses. This look like this:

function void response_handler(uvm_sequence_item response);
     count++;
endfunction: response_handler

It keeps also the reponse FIFO empty. Additionally you can add more functionality to this function. Using the response handler works with pipelined/out-of-order protocols.

In reply to chr_sue:

[i]
The implementation in the base class is doing nothing. One very simple implementation is to count the responses. This look like this:

function void response_handler(uvm_sequence_item response);
count++;
endfunction: response_handler

It keeps also the reponse FIFO empty. Additionally you can add more functionality to this function. Using the response handler works with pipelined/out-of-order protocols.

Hello,
thanks for the reply and information. If the implementation in base class is doing nothing as said above, how does one read the response items from the response fifo. The extended method you have given is only counting the response items. Can you please clarify. How are the response item read out of the response fifo by response_handler() method.
rgs,
-sunil puranik

In reply to puranik.sunil@tcs.com:

If you do not know what to do insert simply a diagnostic message like this:

function void response_handler(uvm_sequence_item response);
     count++;
     `uvm_info(get_type_name(), $sformatf("count = %0d, response = %p", count, response), UVM_MEDIUM)
endfunction: response_handler

Hello,
my question is different:
If you are saying that "Using the response handler sends automatically a response to the sequence. You have to enable the response_handeler by calling use_response_handler(1)"

uvm_Reference manual says “By default, responses from the driver are retrieved in the sequence by calling get_response”.
An alternative method is for the sequencer to call the response_handler function with
each response.

Now if the implementation of response_handler in base class is doing nothing as said above, how are the response items read out of the response fifo if response_handler() is used instead of get_Response(). I mean if resonse_handler() in base class is not doing anything, reading of the response items from response fifo needs to be performed in extended response_handler() method. But the response_handler() extended method above is just maintaining the count. Which portion of the code of the response_handler() is actually reading the response items from the response fifo.
rgs,
-sunil

In reply to puranik.sunil@tcs.com:

I have to precise my statement:
It is doing nothing with the response. But it is receiving the response, when enabled.
And the most simple action in the function is to print the response as I have proposed in my last post.

function void response_handler(uvm_sequence_item response);
     count++;
     `uvm_info(get_type_name(), $sformatf("count = %0d, response = %p", count, response), UVM_MEDIUM)
endfunction: response_handler

And don’t forget to declare the count variable in your sequence.

In reply to chr_sue:

In reply to puranik.sunil@tcs.com:
I have to precise my statement:
It is doing nothing with the response. But it is receiving the response, when enabled.
And the most simple action in the function is to print the response as I have proposed in my last post.

Hi Thanks for the reply. If the response_handler() is a virtual function and function in base is receiving actual response, when we override response_handler() in extended sequence, we need to call the function in base IN ADDITION to the code which prints the response as given above. So it is necessary to add the statement super.response_handler() to call base implementation IN ADDITION to the code in extended sequence which overrides the base version.
I am not clear how this is done. Can you please clarify.
rgs,
-sunil

In reply to puranik.sunil@tcs.com:

The response handler is a function without any functionality inside. It looks like this:

function void response_handler(uvm_sequence_item response);
endfunction: response_handler

If you want to use the response handler explicitly you have to write in your functionality, depending on your needs. It could look like this:

 class my_seq extends uvm_sequence  #(my_seq_item);
 `uvm_object_utils(my_seq)
 
   int my_addr = 0; // To save addresses
   int count; // To count the responses
 
 // Constructor
 function new (string name);
   super.new(name);
 endfunction: new
 
 // Task body()
 task body;
 
   my_seq_item req;
   my_seq_item rsp;
   req = my_seq_item::type_id::create("req", this);
   rsp = my_seq_item::type_id::create("rsp", this);
   use_response_handler(1); // Enable Response Handler
   count = 0;
 
   for(int i=0; i<10; i++) begin
     start_item(req);
     assert(req.randomize() with {addr == my_addr+2;});  
     finish_item(req);
   end
 
 // Wait till last seq item is over
   wait(count == 20);
 endtask: body
 
 /// This response_handler function is enabled to keep the sequence response FIFO empty
   function void response_handler(uvm_sequence_item response);
     $cast(rsp, response);
     `uvm_info(get_type_name(), $sformatf("count = %0d, rsp = %p", count, rsp), UVM_MEDIUM)
     my_addr = rsp.addr;
     count++;
   endfunction: response_handler
 
 endclass: my_seq

Hello,
my question here is slightly different.
UVM reference states following :
"function void use_response_handler(bit enable)
When called with enable set to 1, responses will be sent to the response handler.
Otherwise, responses must be retrieved using get_response".

By default, responses from the driver are retrieved in the sequence by calling
get_response.
An alternative method is for the sequencer to call the response_handler function with
each response.

Now responses are retrieved from resonse_queue by calling get_response. However, when we are not using get_response() and use the response_handler() by enabling it (by calling use_response_handler(1)), how are the responses read from response_queue. I mean which part of code of response_handler() is doing this. As you have said, implementation in base is doing nothing and extended response_handler() function is simply dispolaying some paratmeters of response. So my question is WHICH PART OF CODE IS ACTUALLY RETRIEIVING THE RESPONSE FROM RESONSE QUEUE IF THE GET_RESPONSE() IS NOT USED AND RESPONSE_HANDLER() IS USED INSTEAD.

regards,
-sunil puranik

In reply to puranik.sunil@tcs.com:

This is a theretical question you are asking. Look to the file uvm_sequence_base.svh in the UVM Class Library.

In reply to puranik.sunil@tcs.com:
Hi puranik,
As mentioned by chr_sue,

function void use_response_handler(bit enable);
  m_use_response_handler = enable;
endfunction

set the variable inside the sequence_base and when the put_responses gets called from driver(we have to call it if want to return response), it calls

virtual function void response_handler(uvm_sequence_item response);
  return;
endfunction

if we set the use_response_handler(1). Hope this is helpful.