Saturday, February 7, 2009

Fine-grain process control -- System Verilog

In Vera/NTB the user has very limited control to the threads/process spawned by fork ..join construct . We have constructs like wait_child() to wait for all the threads to complete. terminate() to kill all threads spawned. What was missing in VERA/NTB was the fine-grain process control which will allow the user to selectively suspend,resume,wait and kill the spawned threads.

System Verilog has a build in process class which can be used for fine-grain process control.This process class is a good addition in system verilog and provides fine-grain process control which was not available in VERA/NTB. The prototype of the process class is as follows.



class process;
enum state { FINISHED, RUNNING, WAITING, SUSPENDED, KILLED };
static function process self();
function state status();
task kill();
task await();
task suspend();
task resume();
endclass

Objects of type process are created internally when processes are spawned. Users cannot create objects of type process; attempts to call new shall not create a new process, and instead result in an error. The process class cannot be extended. Attempts to extend it shall result in a compilation error.

The self() function returns a handle to the current process, that is, a handle to the process making the call. The status() function returns the process status, as defined by the state enumeration:



  • FINISHED Process terminated normally.

  • RUNNING Process is currently running (not in a blocking statement).

  • WAITING Process is waiting in a blocking statement.

  • SUSPENDED Process is stopped awaiting a resume.

  • KILLED Process was forcibly killed (via kill or disable).

The await() task allows one process to wait for the completion of another process. It shall be an error to call this task on the current process, i.e., a process cannot wait for its own completion.


The suspend() task allows a process to suspend either its own execution or that of another process. If the process to be suspended is not blocked waiting on some other condition, such as an event, wait expression, or a delay then the process shall be suspended at some unspecified time in the current time step.

The resume() task restarts a previously suspended process.


The kill() task terminates the given process and all its sub-processes, that is, processes spawned using fork statements by the process being killed.


Usage example for the process class


task do_n_way( int N );
process job[1:N];
for ( int j = 1; j <= N; j++ )
fork
automatic int k = j;
begin job[j] = process::self(); ... ; end
join_none
for( int j = 1; j <= N; j++ ) // wait for all processes to start
wait( job[j] != null );
job[1].await(); // wait for first process to finish
for ( int k = 1; k <= N; k++ ) begin
if ( job[k].status != process::FINISHED )
job[k].kill();
end
endtask


No comments: