Exiting a sequence that has a forever loop

I have a reactive sequence that waits for an event for it to send a transaction. Once the transaction is sent it again has to wait for the event to occur. So basically I have this logic inside a forever loop of my sequence. This results in the simulation never ending since the forever-loop is never exited. What are the ways in which I can exit such a sequence?

Here is my code -


task body ();
  forever begin
    wait (p_sequencer.event_que.size() > 0); //This is the event for which it waits. This queue is populated by the sequencer
    p_sequencer.event_que.pop_front(); //Clearing it to make sure the size of the queue is 0 so as to 'wait' again
    
    trans.randomize(); //randomize fields of transaction

    start_item(trans);
    finish_item(trans);
  end
endtask

This sequence itself is started from the run_phase of the test under fork-join (there are sequences running on other interfaces too)

In reply to tpan:

you need to drop the objections to stop the simulation.


  virtual task main_phase(uvm_phase phase);
    super.main_phase(phase);   
    phase.raise_objection(this, "raise objection");  //raise objection
   
    fork
        begin
              /* //infinite sequence
              seq1 = my_sequence_1::type_id::create("seq1");
              seq1.randomize();
              seq1.start(env.agt.sequencer);
              */
        end
    join_none
    
    //wait for the event/end of other sequence after that you want to stop the simulation 
    /* .... */

    phase.drop_objection(this, "drop objection");  //drop objection
  endtask : main_phase


//example 2, if you want to stop the simulation after any one of the sequence is finished 
  virtual task main_phase(uvm_phase phase);
    super.main_phase(phase);   
    phase.raise_objection(this, "raise objection");  //raise objection
   
    fork
        begin //T1
              /*
              seq1 = my_sequence_1::type_id::create("seq1");
              seq1.randomize();
              seq1.start(env.agt.sequencer);
              */
        end
        begin //T2
              /* seq2 */
        end
        begin //T3
              /* seq3 */
        end
        ......
        ......
        begin //Tn
              /* seqn */
        end
    join_any
 
    phase.drop_objection(this, "drop objection");  //drop objection
  endtask : main_phase

In reply to tpan:

I have a reactive sequence that waits for an event for it to send a transaction. Once the transaction is sent it again has to wait for the event to occur. So basically I have this logic inside a forever loop of my sequence. This results in the simulation never ending since the forever-loop is never exited. What are the ways in which I can exit such a sequence?
Here is my code -


task body ();
forever begin
wait (p_sequencer.event_que.size() > 0); //This is the event for which it waits. This queue is populated by the sequencer
p_sequencer.event_que.pop_front(); //Clearing it to make sure the size of the queue is 0 so as to 'wait' again
trans.randomize(); //randomize fields of transaction
start_item(trans);
finish_item(trans);
end
endtask

This sequence itself is started from the run_phase of the test under fork-join (there are sequences running on other interfaces too)

What you are doing is a bad coding style. The only way to stop this sequence is to kill it and this also bad for the execution.
The body task of a sequence does never contain a forever loop!

In reply to Rahulkumar:

Thanks Rahulkumar. I will try with fork-join_any. I think that might work

In reply to chr_sue:

Thanks chr_sue. What is the recommended way to handle such sequences? How can I be in the sequence waiting for an event without a forever loop?

In reply to tpan:

In reply to Rahulkumar:
Thanks Rahulkumar. I will try with fork-join_any. I think that might work

The fork/join_any will not stop the executung unless you have at least 1 sequence without a forever loop. What Rahulkumar is recommending is useless if you do not need such a sequence execution structure.

In reply to tpan:

In reply to chr_sue:
Thanks chr_sue. What is the recommended way to handle such sequences? How can I be in the sequence waiting for an event without a forever loop?

It is recommended to recode your body tasks and replace all forever loops with loops running a well defined number of loops. The number of the loops can be controlled from the test by setting test-specific numbers of loops.

In reply to chr_sue:

In reply to tpan:
The fork/join_any will not stop the executung unless you have at least 1 sequence without a forever loop. What Rahulkumar is recommending is useless if you do not need such a sequence execution structure.

I have recommended two different use cases. Which one to use depended on requirement and constraint.
I have clearly mentioned to use fork/join_any “if you want to stop the simulation after any one of the sequence is finished”

In reply to Rahulkumar:

But, if your sequences have all forever loops no one will stop!

In reply to chr_sue:

In reply to Rahulkumar:
But, if your sequences have all forever loops no one will stop!

Yes, i agree with you at least one sequence should finish.