Multiple get_response in a sequence

Hi There,

In a sequence I have the following code.

body()

fork
   begin
     trans req, rsp;
     req = trans::type_id::create("req");
     start _item(req);
     finish_item(req);
     get_response(rsp);
   end
   begin
     trans req, rsp;
     req = trans::type_id::create("req");
     start _item(req);
     finish_item(req);
     get_response(rsp);
   end
join


In the driver I do

seq_item_port.get(req);
rsp = trans::type_id::create("rsp");
rsp.set_id_info(req);
seq_item_port.put(rsp);

I am observing that when seq_item_port.put(rsp) is executed both the get_response(rsp) in the sequence returns.
I was expecting only 1 of them to return.
However when I checked the uvm code uvm-1.2/seq/uvm_sequence_base.svh
I see the following.


  virtual task get_base_response(output uvm_sequence_item response, input int transaction_id = -1);

    int queue_size, i;

    if (response_queue.size() == 0)
      wait (response_queue.size() != 0);

    if (transaction_id == -1) begin
      response = response_queue.pop_front();
      return;
    end

    forever begin
      queue_size = response_queue.size();
      for (i = 0; i < queue_size; i++) begin
        if (response_queue[i].get_transaction_id() == transaction_id) 
          begin
            $cast(response,response_queue[i]);
            response_queue.delete(i);
            return;
          end
      end
      wait (response_queue.size() != queue_size);
    end
  endtask

so both the get_response wait till the response_queue size is nonzero.
As soon as the size is non zero the transaction_id is checked and the item is poped.
One of the get_response gets a valid response and the other gets a value of 0.
So, is the way I use the sequence incorrect? Or should there be more tight check in uvm code around response_queue (e.g. using semaphore to check the queue size before poing)?

Thanks,
Sunil.

In reply to KumarSunilB:

What do you mean with ‘both the get_response(rsp) in the sequence returns’. I do not see 2 methods returning.
The pu in the driver is blocking until get_response is executed. If you do not the get_response you will face response queue overflow.

In reply to chr_sue:

By returns, I mean get_response call gets unblocked.
My issue is both the get_response unblocks and my expectation was only on of the get_response gets unblocked.

In reply to KumarSunilB:
What do you mean with ‘both the get_response(rsp) in the sequence returns’. I do not see 2 methods returning.
The pu in the driver is blocking until get_response is executed. If you do not the get_response you will face response queue overflow.

In reply to KumarSunilB:

Looking to your code I try to understand what are you doing with fork/join in your sequence, i.e. you are running 2 processes in parallel generating seq_items. But you have to have a one-to-one connection between your sequencer and your driver, i.e only 1 seq_item can be processed at a time.
In my eyes it does not make really sense what you are doing here.

In each fork thread you have to call get_response() using the transaction_id that corresponds to each request:

get_response(rsp, req.get_transaction_id());