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.