Question regarding sv process::suspend


  5     class my_class;                                                             
  6         process m,n;                                                            
  7         task run();                                                             
  8             fork                                                                
  9                 begin : first_thread                                            
 10                     m = process::self();                                        
 11                     #10;                                                        
 12                     $display("first thread %0t",  $time);                       
 13                 end                                                             
 14                                                                                 
 15                 begin : second_thread                                           
 16                     n = process::self();                                        
 17                     #10;                                                        
 18                     #10;                                                        
 19                     $display("second thread %0t", $time);                       
 20                 end                                                             
 21                                                                                 
 22             join_none                                                           
 23                                                                                 
 24             wait(m!=null);                                                      
 25             m.await();                                                          
 26                                                                                 
 27             $display("time before suspend %0t", $time);                         
 28                                                                                 
 29             // wait for first thread to finish using await, then suspend second thread for 10ns
 30             n.suspend();                                                        
 31             #10;                                                                
 32             n.resume();                                                         
 33             // resume second thread , expecting to display 30?                  
 34             $display("time after resume   %0t", $time);                         
 35         endtask                                                                 
 36     endclass                                              

output:
first thread 10
time before suspend 10
second thread 20
time after resume 20

Hello there,

My question is that why second thread seems not suspended for 10?
My intent is to wait for first thread to finish ,and suspend sencond thread for 10 , and then resume second thread, then the second thread display should be happening @time 30, but it showed 20 instead, can anyone explain to me where I was wrong or what’s going under the hood?
Thanks

In reply to Jeff_Li_90:

There are two issues.

First is you have a race condition. At the point when you suspend the second_thread, you don’t know if the 2nd #10 has been scheduled or not. If it has not, then you would get your expected results. But if it had been scheduled, the second issue is a Delay does not work like a timer. A Delay suspends the current process and schedules it to wake up at the appropriate time. The process will remain suspended if you have explicitly suspended it. It does not add time to the scheduled delay.

In reply to dave_59:

The process will remain suspended if you have explicitly suspended it. It does not add time to the scheduled delay. So calling process::suspend to Delay is like to call multiple times process::suspend to same thread, which will only be honored once. This is something new to me.

Thanks Dave for the explanation.

as Dave pointed out, there’s a race condition between when <second #10> and <n.suspend> scheduled. and clearly original output showed <second #10> scheduled first. I tried adding #0 to delay one to NBA region and it worked.

 
 15                 begin : second_thread                                           
 16                     int nba, next_nba;                                          
 17                                                                                 
 18                     n = process::self();                                        
 19                     //repeat(20) begin                                          
 20                     //    #1;                                                   
 21                     //end                                                       
 22                     #10;                                                        
 23                                                                                 
 24                     //next_nba++;                                               
 25                     //nba <= next_nba;                                          
 26                     //@(nba);                                                   
 27                     #0;    // delay to NBA region                                                        
 28                     #10;                                                        
 29                     $display("second thread %0t", $time);                       
 30                 end