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
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.
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.
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.
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.
/* 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.
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.