Tuesday, 2 February 2016

Process class in SystemVerilog


A process is a built-in class that allows one process to access and control another process once it has started. Users can declare variables of type process and safely pass them through tasks or incorporate them into other objects. The prototype for the process class is:


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.

Objects of type process are unique; they become available for reuse once the underlying process terminates and all references to the object are discarded.

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).

kill
The kill() task terminates the given process and all its sub-processes, that is, processes spawned using fork statements by the process being killed. If the process to be terminated is not blocked waiting on some other condition, such as an event, wait expression, or a delay then the process shall be terminated at some unspecified time in the current time step.

await
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. 

suspend
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. Calling this method more than once, on the same (suspended) process, has no effect. 

resume
The resume() task restarts a previously suspended process. Calling resume on a process that was suspended while blocked on another condition shall re-sensitize the process to the event expression, or wait for the wait condition to become true, or for the delay to expire. If the wait condition is now true or the original delay has transpired, the process is scheduled onto the Active or Reactive region, so as to continue its execution in the current time step. Calling resume on a process that suspends itself causes the process to continue to execute at the statement following the call to suspend.

The example below starts an arbitrary number of processes, as specified by the task argument N. Next, the task waits for the last process to start executing, and then waits for the first process to terminate. At that point the parent process forcibly terminates all forked processes that have not completed yet.

USE-CASE:
Consider a case where you have already written a transactor which sends packets according to your requirements. Now you need to change your code to make it work in the low-power-world where you need to stop sending packets whenever the system enters low-power state and resume sending packet once you are out of it. You have coded “HOW” to send your packet, and now you need to incorporate “WHEN” to send it, which itself can be far more complex that the simple “HOW”.

You can directly go and modify the transactor code to incorporate “WHEN” aspect of the packet transmission. There are quite a few reasons why you would rather not touch the code and do the same in another way.

Fine grain process control can be very nicely used in such scenario. You can have a handle of the process of sending packet. Now using this handle, we can stop/resume execution of the process (thereby stopping/resuming sending of packet) by calling suspend/resume method. We can have another piece of code where we can code the logic which will have the logic that shall control “WHEN” to send the packet.

4 comments:

  1. How do I use a process::state Pstate; variable to get the status?
    i.e.
    task body()
    process::state Pstate; <-- This gives me an error "expecting an identifier"

    Pstate = process_object.status();

    ReplyDelete
    Replies


    1. Hi,
      task body()
      string p_status;
      process P_1;
      p_status = P_1.status();

      Delete
  2. task dut();
    process A , B , C ;
    fork
    {
    A = process::self()
    process 1
    }
    {
    B = process::self()
    process 2
    }
    {
    C = process::self()
    process 3
    }
    join_none
    if (B.status != FINISHED)
    B.kill();
    // process 2 will be executed or not ??

    ReplyDelete