Doing x.stop_sequences() is causing this UVM FATAL Item_done() called with no outstanding requests. Each call to item_done() must be paired with a previous call to get_next_item()

In order to avoid a deadlock situation, I recently added stop sequences to a block which is instantiated in the main sequence, it took care of the deadlock situation but it causes UVM FATAL error, what other way can I add this stop sequences to my code?

In reply to uvm_va_1:

I do not understand why you expect a deadlock situation.
But without showing your sequence (body task) it is impossible to help you.

In reply to chr_sue:

Sorry, I pasted the code it didn’t get through
Here’s what I’m trying to do, I have to create a stop_sequence for the parent_vseqr consisting of 3 different child seqr
When I am trying to stop these 3 processes, I get the uvm fatal error stated above
function void stop_sequences();
`uvm_info(get_report_id(“stop_sequences”), $sformatf(“calling stop_sequences”), UVM_LOW);
stop_parent_sequences();
endfunction: stop_sequences

function void stop_parent_sequences();
`uvm_info(get_report_id(“stop_parent_sequences”), $sformatf(“calling stop_sequences”), UVM_LOW);
parent_vseqr.stop_sequences();
parent_vseqr._process1_sqr.stop_sequences();
parent_vseqr._process2_sqr.stop_sequences();
parent_vseqr._process3_sqr.stop_sequences();
endfunction: stop_parent_sequences

In reply to uvm_va_1:

You shoule never stop a sequence. This might cause serious issues.
Any sequence comes to its end and that’s fine. If you are running in any deadlock your sequence execution has to be modified.

In reply to chr_sue:

I was running into a deadlock, that was one of the primary reasons to have to add the stop sequences.
What modification are you suggesting for that a scenario ?

In reply to uvm_va_1:

Could you please describe in some more detail what really happened.

In reply to chr_sue:

I was running into this error, sequence has been killed, to avoid a deadlock the sequence will be removed from the arbitration queues, because parent_sequncer was a newly added in to my top sequencer, when I added the stop-sequences function I started running into this error

In reply to uvm_va_1:

It is confusing what you are saying-- parent sequencer, top sequencer – and you run into this error after adding stop-sequences. You should not stop sequences because you’ll not know what the consequence is. Let your sequences running as you waant to have it.
Again, I do not understand your environment and I do not see how you are running your sequences. To see and understand this is necessary to give you an advice.

In reply to chr_sue:

If I keep it super simple can you explain to me with a code how can I use stop.sequences and to make it clear I have to stop these without using get or without using the suspend and resume.

I have to add stop_sequences for one of the newly added virtual seqr into the top virtual seqr and that’s why I’m doing this

In reply to uvm_va_1:

Never there is a reason to stop sequences manually if you architect the sequence execution in the right way.
Why you don’t show your sequencer and sequence architecture. This is the key information to solve your problem.

In reply to chr_sue:

Yes, they need to be stop manually, that’s how it’s been architected. I am afraid I can’t put my code here, so that’s why I showed you a general example. I will ask differently
how to make sure that the Driver is inactive before calling stop_sequences

In reply to uvm_va_1:

I do not ask for any secirity informatiuon.
I want to see how your sequencer architecture looks like and how you are architecting and starting your sequences. I’m not interested in any information abot the details of your body tasks. And I’m sure yopu do not have to stop/kill any sequence if you are doing the things right.

In reply to uvm_va_1:

In order to avoid a deadlock situation, I recently added stop sequences to a block which is instantiated in the main sequence, it took care of the deadlock situation but it causes UVM FATAL error, what other way can I add this stop sequences to my code?

Hi, I think the issue arise when driver tries to call the item_done() after we called the stop_sequences() method. So it will give the fatal which you mentioned. I think, driver should handle reset such a way that when reset occur, it stops driving and call item_done(if had fetched with get_next_tem) and then wait for reset to lift-up before fetching new transaction. But here i believe it’s not getting handled in driver.
One way to call the stop_sequence is after wait_for_item_done() inside sequence to make sure nothing put into sequencer and driver also must be ideal. Inside sequence, we can have a variable set after it seen txn finished and we can get it’s value in another component and call stop_sequence method only when reset is asserted. if no reset asserted, set that variable to 0 so when it again gets updated from sequence after finish, we can have an idea.
if we don’t have that deep access then from where we are starting sequence, we can get the current state of uvm_sequence which we can take for decision making. if it’s UVM_FINISH, we can then call stop_sequence() method.

In reply to tez:

Can you provide me a pseudo code for it as an example ?

In reply to uvm_va_1:


class base_seq_item extends uvm_seq_item;
  // variable, registrations and all..
endclass
class base_seq extends uvm_sequence#(base_seq_item);
  // pre_body, body, post_body, registration..
endclass
class base_test extends uvm_test;
  // registration and other stuff.
  base_seq m_seq;
  task run_phase (uvm_phase phase);
    // other stuff..
    m_seq = base_seq::type_id::create("m_seq");
    fork
      begin
	m_seq.start(m_sequencer); // assuming provided proper sequencer handle
      end
      begin
	m_seq.wait_for_sequence_state(UVM_FINISHED);
      	m_sequencer.stop_sequences();
      end
    join_any
  endtask
endclass

This is one way to do it. But i’m not encouraging to use the stop_sequences method as with the complex architecture, it will lead to issue in handling multiple threads.

Thanks & Regards,
Tejendra.

In reply to tez:

What yoiu are proposing is stopping the sequence at its end.
This is what the standard says:
UVM_FINISHED—The sequence is completely finished executing and was not forcibly ended.

It stops the sequence at its end, which is not the intention of the question.

In reply to chr_sue:
Hi chr_sue, I think i got your idea. if sequence itself hang then it will never reaches to finish state. So above mentioned solution won’t work straight away. I think in that case we can override the item_done() method and add changes as per our need. I have tried it and it’s working fine. Another way i can think of is to demote that fatal by accepting that thing for our own environment. But i’m not sure if it’s a good way or not. If you have any other idea then please let me know. Thanks.

In reply to tez:

What exactly do you mean by overriding item_done ?

In reply to uvm_va_1:

item_done() is a function belonging to the class uvm_sqr_if_base. You had to extend this class. I believe this is not a good idea.

In reply to uvm_va_1:

In order to avoid a deadlock situation, I recently added stop sequences to a block which is instantiated in the main sequence, it took care of the deadlock situation but it causes UVM FATAL error, what other way can I add this stop sequences to my code?

I had a closer look to your problem. A deadlock situation cannot be caused by the sequence execution, because the sequencer/sequence does not have any timing relationship. The behavior is defined by the order of the execution. If a sequence hangs this is never caused by the sequence itself. It comes always from the components which are processing the sequence and driving the pinlevel interface. Typically this is the driver. A driver can hang and will not continue with the execution of a sequence, i.e. indicating to the sequencer the next seq_item can be generated by sending item_done.
If you are facing a deadlock you should investigate/debug your driver behavior. This process can be complicated when you are using uvm_barriers or uvm_events.