Forever loop break

How the forever loop breaks in the following code snippet? My assumption is the execution should remain inside forever loop indefinitely as there is no break condition. But the execution exits the loop to my surprise.



task evsock_alarm_center::run_phase(uvm_phase phase);
     phase.raise_objection(this);	
	fork    
	  forever begin		     
	      int_fifo.get(gpio_item);	     
              parse_interrupt(gpio_item,interrupt_vector);  //interrupt_vector_parsing
              irq_out=interrupt_vector[0]|| interrupt_vector[1]; //merge the irq_out 
        
              if(irq_out) begin       
                if(interrupt_vector[2]) begin
                  `uvm_info("!INTERRUPT TRIGGERED!", "Interrupt Source is EM Classifier", UVM_LOW)
                end
                if(interrupt_vector[3]) begin
                  `uvm_info("!INTERRUPT TRIGGERED!", "Interrupt Source is EM Queue Manager", UVM_LOW)
                end
                if(interrupt_vector[4]) begin 
                 `uvm_info("!INTERRUPT TRIGGERED!", "Interrupt Source is EM Scheduler", UVM_LOW)
                end
                if(interrupt_vector[5]) begin
                 `uvm_info("!INTERRUPT TRIGGERED!", "Interrupt Source is BM", UVM_LOW)
                end              
	  end
	join_none
    phase.drop_objection(this);
	
endtask


In reply to rbasnet:

It does never break and the objection will never drop, i.e. your simulation is running forever.

In reply to chr_sue:

In reply to rbasnet:
It does never break and the objection will never drop, i.e. your simulation is running forever.

could you explain why the objection will never drop? I think in run phase, he uses the fork/join_none then the phase.drop_objection will be executed in main thread right?
I believe, the objection will raise and drop immediatly after fork. The fork will be terminated when all other phases parallel running with run phase are finished.

Correct me if Im wrong.

In reply to cuonghl:

Oh sorry, I have to correct myself. It is a fork/join_none. The objection is dropping immediately after the join_none and leaving the run_phase task.

In reply to rbasnet:

You are spawning the forever loop in a fork/join_none process, so the that runs in the background while you immediately drop the objection. Why are you raising/dropping an objection?

In reply to dave_59:

A following-up question. Let us assume Rbasent’s code is correct. When the fork/join_none kick off ? According the LRM, fork/join_none is started at the first blocking statement in main thread after join_none.

In reply to VE:

As the LRMs says, the parent thread has to block or terminate before the fork/join_none process starts executing the forked process. Since each component’s run_phase is started as a separate thread, this fork/join_none gets scheduled upon returning from the task vsock_alarm_center::run_phase. But there may be other component run_phases ahead in the queue to execute before getting to the fork thread.

In reply to dave_59:

In reply to rbasnet:
You are spawning the forever loop in a fork/join_none process, so the that runs in the background while you immediately drop the objection. Why are you raising/dropping an objection?

The objection raising/dropping is redundant. That was my bad. Now I got rid of the objection but still the execution comes out of the forever loop. I tried with the fork_join and fork_join_any to see if that makes any difference but no. I also completely got rid of the fork and tried with the forever loop only and i could see that the execution still exits the forever loop. What is going on here? Seems like I am missing something here.

In reply to rbasnet:

In reply to dave_59:
The objection raising/dropping is redundant. That was my bad. Now I got rid of the objection but still the execution comes out of the forever loop. I tried with the fork_join and fork_join_any to see if that makes any difference but no. I also completely got rid of the fork and tried with the forever loop only and i could see that the execution still exits the forever loop. What is going on here? Seems like I am missing something here.

From the simulation it seems that the loop executes as many times as I have items in the fifo. If there are no items in the fifo, regardless of the call to get method, the loop exits. My understanding is the execution should stuck in the call to get method as it is a blocking call even if there are no items in the fifo. What is that I am missing here?

In reply to rbasnet:

The your loop is located in run_phase, when the run_phase complete, simulation will terminate your fork/join_none and the loop as well. I think, the loop exists because your run_phase is completed (when all other phases such as reset, configure, main, shutdown, etc… parallel running with run_phase are finished). Please check again.

In reply to dave_59:

In reply to VE:
As the LRMs says, the parent thread has to block or terminate before the fork/join_none process. Since each component’s run_phase is started as a separate thread, this fork/join_none gets scheduled upon returning from the task vsock_alarm_center::run_phase. But there may be other component run_phases ahead in the queue to execute before getting to the fork thread.

Thanks Dave. Would you elaborate " As the LRMs says, the parent thread has to block or terminate before the fork/join_none process."? On IEEE1800-2012, P175. it says :
join_none :: The parent process continues to execute concurrently with all the processes spawned by the fork. The spawned processes do not start executing until the parent thread executes a blocking statement or terminates.

Just want to make sure i understand it correctly.
Thanks

In reply to VE:

Help me with what you are having trouble understanding. Do you know

  • “process” and “thread” are interchangeable words
  • what a parent thread is?
  • what a spawned or forked thread is? ( a child of the parent thread )
  • what it means to encounter a blocking statement?
  • the conditions that terminate a process?

In reply to cuonghl:

Hi Cuonghl

Are you trying to say that regardless of the implementation in the run phase, the run phase should terminate at some point of time during the simulation and the execution proceeds to extract phase? Please consider the code below. What makes the forever loop break? My understanding is, the execution should get stuck forever inside the loop as get method is blocking. It should not return unless the item is available in the fifo and hence the execution should get stuck forever. If i remove the int_fifo.get(), then the execution remains inside the forever loop indefinitely. Any pointers will be appreciated!!!

uvm_tlm_analysis_fifo #(gpio_sequence_item) 	 int_fifo;
...
task evsock_alarm_center::run_phase(uvm_phase phase);	   
   forever begin		     
     int_fifo.get(gpio_item);	              
   end
endtask

In reply to rbasnet:

The run_phase will be terminated by following reasons:

  • The post_shutdown_phase is finished (all objection are dropped)
  • Timeout 9200s.

In your example, the forever loop in run_phase will be terminated if all objections (from pre_reset to post_shutdown phase) are dropped. Let’s see the following example:


  class phase_test extends uvm_test;
    `uvm_component_utils(phase_test)
    function new(string name, uvm_component parent);
      super.new(name, parent);
    endfunction : new
    
    task main_phase(uvm_phase phase);
      phase.raise_objection(this);
      #5;
      phase.drop_objection(this);
    endtask
    
    task run_phase(uvm_phase phase);
      forever begin
        #1;
        `uvm_info("PHASE_TEST", "Printed forever loop", UVM_NONE)
      end
    endtask
  endclass 

Can you guess, how many line “Printed forever loop” will be displayed in forever loop of run_phase? It will never stuck forever because in main_phase, the objection is dropped after 5ns delay.

In reply to cuonghl:
Now I see that the simulation time advances when executing the instructions inside the forever loop and ultimately the run phase proceeds to the extract phase. Had there been no instructions to execute inside the forever loop (I tried this to check), the simulation time never advances and the forever loop is never exited. Thanks for the replies…:)

In reply to rbasnet:

You can’t execute a task with zero timing in forever loop of run_phase, it will stuck forever.

In reply to cuonghle:

Hi Cuonghle, could you please explain why a task with zero timing in forever loop of run_phase will be stuck forever? I get that a forever loop goes forever but what different does a task with zero timing make? Also, isn’t that technically a function?

In reply to vk7715:

A forever loop in the run_phase will run forever if there is no break statement. It will not stuck, but override any previous values.