Uvm_send is blocked even after driver executes item_done

Hi All,

I have a sequence sending a created and randomized item using `uvm_send.

The driver receives an item using try_next_item. Upon receiving, it drives the item and calls item_done.
Using debug message after item_done, I can clearly see that item_done is called and returned but `uvm_send in sequence is still blocked and not doing forward to send next item (it implements a loop).

Can anyone help me with possible reasons why `uvm_send would not return even when driver has called item_done and come out of item_done.

Thanks in advance!
Ninad

— Update: Posting pseudo code —

  • sequence

my_trans_item item;
for (n_trans = 0; n_trans < 4; n_trans++) begin
uvm_create_on(item, p_sequencer.sequencer_for_item); dp.randomize(); uvm_send(item);
/* Also tried replacing `uvm_send with following:
start_item(item);
finish_item(item);
*/
end

  • driver

forever begin
seq_item_port.try_next_item(item);
if (item == null) begin
// Drive junk without valid
end else begin
fork
reset_detect();
begin
uvm_test_done.raise_objection(this, tID);
send_to_dut(item);
seq_item_port.item_done();
uvm_test_done.drop_objection(this, tID);
end
join_any
disable fork;
end
end

In reply to ninadpachpute:

Instead of using `uvm_send, you should use start_item() followed by finish_item(). At the very least, this will give you more information about where the hang happens.

In reply to tfitz:

Thanks for quick response.

finish_item() does not go through, start_item() does go through. I also see transaction completely driven on DUT interface after which driver calls item_done() but somehow finish_item() is blocked.

finish_item() call only one task - that is sequencer.wait_for_item_done(). So this is the one which is blocked.

I am looking into UVM source if I can find anything. Meanwhile, if you have anything off the top of your head, please share.

In reply to ninadpachpute:

Can you post the source code for both your sequence and your driver? There are several reasons why things might be going wrong and trying to figure it out without seeing your code is very difficult.

In reply to cgales:

Hi tfitz, cgales, I updated original post to add pseudo code. Please take a look.
tfitz, I also tried with start_item and finish_item. I see that finish_item is getting blocked.

In reply to ninadpachpute:

hi ninadpachpute,
i hope it is helpfull!!!

sequence

Quote:
my_trans_item item;

for (n_trans = 0; n_trans < 4; n_trans++) begin
uvm_create_on(item, p_sequencer.sequencer_for_item); dp.randomize(); uvm_send(item);

//…
// use uvm_do(item) (or) define uvm_do(item)
`uvm_create_on();
start_item(item)
item.randomize();
finish_item(item);

//…

/* Also tried replacing `uvm_send with following:
start_item(item);
finish_item(item);
*/
end

  • driver

Quote:
forever begin
seq_item_port.try_next_item(item);
if (item == null) begin
// Drive junk without valid
end else begin
fork
reset_detect();
begin
uvm_test_done.raise_objection(this, tID);
send_to_dut(item);

                                     //......................................................................................
                                                    // use non-blocking method it will work,seq_item_port.get_next_item(item) 
                                                                                send(item);
                                                                            seq_item_port.item_done();
                                   //......................................................................................

seq_item_port.item_done();
uvm_test_done.drop_objection(this, tID);
end
join_any
disable fork;
end
end

I think the issue has to do with the fork/join_any/disable fork statements in your driver. Why are you using this in your driver? It seems like it’s possible that part of the driver task is disabled prior to completing. I would recommend not using a fork/join when handling sequence items.

Also, you should not raise/drop objections in your driver. This should only be done at the test level.

In reply to cgales:

Also, you should not be using the uvm_test_done objection.

In reply to tfitz:

  1. Commented out fork-join and reset_detect function
  2. Commented out raise/drop objections
  3. Commented out both fork-join and raise/drop objections

In all 3 cases, result is same.

In reply to ninadpachpute:

New finding:

After item.randomize(), I am corrupting a dw data in dw array inside item (flipping 2 bits to inject un-correctable error).
The issue is seen only when I flip the dw bits. Otherwise the pseudo code above works just fine. Really strage!
(I did not post that as a part of pseudo code as it is logically irrelevant with this issue).

I moved ucorrectable error insertion logic inside item’s class. In this case, the code works absolutely fine :)

Again really strange - havn’t found root cause but at least I somehow got it working.

Thanks tfitz, cgales and praveen. I will updated thread if I am able to find root cause.