Jump to content

seq_item_port.put_response(rsp);


Recommended Posts

There are conflicting recommendations about which method to use to return a pipelined response back to the sequencer. The 1.1 User Guide states that the response can be returned via a call to seq_item_port.put_response() (section 3.5.4), however, the 1.1RC5 code flags that as an internal method:

  // Function- put_response
  //           
  // Internal method.

  virtual function void put_response(uvm_sequence_item response_item);
    RSP response;
    if (!$cast(response, response_item)) begin
      uvm_report_fatal("PUTRSP", "Failure to cast response in put_response", UVM_NONE);
    end
    put_base_response(response_item);
  endfunction

Is this an internal method?

Link to comment
Share on other sites

Use item_done() to return a response to a sequencer. From the spec:-

virtual function void item_done( input  T2  	t =  null )

If a response item is provided, then it will be sent back to the requesting sequence. The response item must have it’s sequence ID and transaction ID set correctly, using the uvm_sequence_item::set_id_info method:

rsp.set_id_info(req);
Link to comment
Share on other sites

item_done() can be used to return the response if the sequencer/driver communication model is an atomic in-order execution model. However, we cannot return the response in the call to item_done() if we are using a pipelined response or an out of order response. In that case we need to call item_done() without returning a response, and then we need to send the response back only when the request is completed.

I think that I have an answer to my original query however. I believe that the put_response() method is currently documented incorrectly and is intended to be a public method. See the following:

http://www.eda.org/svdb/view.php?id=3590

Link to comment
Share on other sites

item_done() may not be suitable for your application, but item_done() does actually call put_response() and can deal with out-of-order responses..

In the driver, when you send a response via item_done(), you can set the transaction id of the response to match the request:

  task run();
    forever begin
      seq_item_port.get_next_item(req);
      send_to_dut(req, rsp);
      seq_item_port.item_done(rsp);
    end
  endtask : run

  task send_to_dut(input packet reqp, output packet rspp);
    rspp = packet::type_id::create("rspp",this);
    rspp.set_id_info(reqp);
   ...

Then in the sequence, you can get the response based on the transaction id:

virtual task body();
    `uvm_do_with(req, {req.data_in == 2'b00;})
    get_response(rsp, req.get_transaction_id());
    ...

There's a response queue (default length 8) between the sequence and driver to store responses. Writing responses to a full queue loses the response and generates an error.

Note if you call get_response() without a response id, it returns the next response in the queue. Get_response is blocking, so if there is no response with a matching id or the response queue is empty, the get_response will block until a response is received.

Link to comment
Share on other sites

Bart -

You are correct that item_done() can be used to return the response to the sequence if the response is returned back to the sequence before the original request is completed.

This is one way to design the request/response process, but this isn't how the response is normally used from what I've seen. In the User Guide, and in the public examples that are shipping with UVM the response is not returned to the sequence until the request is completed. Granted, the UVM examples that ship with the UVM BCL are very basic, and don't demonstrate pipelined requests. However, the User Guide seems to back this up as well Section 3.5.3 Fetching Consecutive Randomized Items talks about pipelined protocols and suggests that item_done() should be called without providing a response.

Waiting until the request is completed before returning the response seems to convey more information as well. For example, sequences can use the get_response() call to synchronize to the completion of the original request if desired. If sequences don't care to synchronize to the end of the request then they can wait for the response in a thread or else just ignore it by calling set_response_queue_depth(-1).

Link to comment
Share on other sites

Hi Pratta

Like I said, returning a response via item_done() may not be suitable for your application.

Section 4.5.4 of UVM1.0.1 User Guide - Sending Processed Data back to the Sequencer - actually identifies 3 options for passing a response to the sequencer:

1) Argument to item_done()

2) Explicit put_response() call

3) Using the built-in analysis port of the driver

We use option 1 for simple transfers where the response is obtained in the same transaction as the request. For responses outside the original request transaction, we've always used a fourth option:

4) Connect the sequencer to the analysis port of the UVC monitor.

Of course this has the disadvantage of not having access to the transaction id of the request for matching, but our applications don't have non-deterministic out-of-order responses. Your Mileage May Vary :D

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...