2. Systemverilog has a built in class named Process that
allows one process to access and control other
processes/threads.
When we fork off any thread, a new object of
process class is created at that time. This object
contains status information about that thread.
An attempt to create a user defined object of
process class will result in error.
3. Process class includes the following
class process;
typedef enum { FINISHED, RUNNING, WAITING,
SUSPENDED, KILLED } state;
static function process self();
function state status();
function void kill();
task await();
function void suspend();
function void resume();
function void srandom( int seed );
function string get_randstate();
function void set_randstate( string state );
endclass
4. Practical ex.
Let’s say a protocol that sends five packets
concurrently to the RTL on five similar but distinct
interfaces. RTL triggers an event/signal when it has
accepted a packet.
But, when the RTL accepts fourth numbered
packet (this can be any random numbered packet
also), the second numbered packet (this can also
be some random numbered packet) must be
dropped off and not be sent to RTL.
But the rest of packets (1st, 3rd and 5th packet)
must be sent.
5. So, I will fork off five processes
(named fork_all_processes in code below)
in my testbench which invokes same task
(named run_task in the code below).
Take a handle of each process that gets forked
off.
6. Now, in the thread for the process that is to be
killed (2nd process over here),wait for the other
process completion (4th process here).
In the process 4, I will look for whether process
2 thread is running or not.
If it is still running, when the trigger event
for process 4 is triggered, then kill the process
2.
If process 2 is already completed before process
4, then we have to kill nothing.
In this way, we can have a fine grain control over
different threads executing concurrently.
7. example
module top();
class process_ex; // class that forks all processes
process p[]; // number of processes
event ev[]; // events triggered by RTL for each process
int wait_process,kill_process; // process number which is
to be awaited and killed
function new(int num_process); // constructor
p = new[num_process]; // handle of processes
ev = new[num_process];
endfunction
8. function void fork_all_processes(int num_process); // fork all
the processes
for(int i=0; i<num_process;i++)
fork
automatic int j=i;
begin
p[j] = process::self(); // get object of current processs
run_task(j); // send some stimulus to RTL
end
join_none
endfunction
9. function void assign_wait_kill_process(int wait_process,int kill_process);
this.wait_process = wait_process; // number of process that is to be awaited
this.kill_process = kill_process; // number of process that is to be killed
endfunction
task automatic run_task(int i);
process::state pstat;
wait(p[kill_process] != null); // wait till the killing process starts (Process-2)
pstat = p[kill_process].status(); // get status for killing process (Process-2)
$display($time,"tWaiting for trigger of %0d event",i);
wait(ev[i].triggered); // wait for current process event tirgger
if(i==wait_process) begin // if the current process is the process which was
to be awaited (Process-4)
10. $display($time,"tProcess %0d found that p[%0d] is
%0s",wait_process,kill_process,pstat.name);
if(pstat == process::RUNNING || pstat == process::WAITING) begin // check
the status of killing process (Process-2)
$display($time,"tProcess %0d found running/waiting",kill_process);
p[kill_process].kill(); // kill the process (Process-2)
$display($time,"tProcess %0d killed",kill_process);
end
end
$display($time,"tWait completed for trigger of %0d event",i); // current
process completed successfully
endtask
endclass
11. process_ex proc = new(5);
initial begin
proc.assign_wait_kill_process(4,2); // Some random number.
When process 4 completes, kill process 2 also
proc.fork_all_processes(5);
for(int i=0;i proc.ev[j]; // assume this is triggered by RTL
$display($time,"tTriggered %0d event",j);
end
join_none
end
end
initial begin
#1000 $finish;
end
endmodule
12. OUTPUT:
0 Waiting for trigger of 2 event
0 Waiting for trigger of 3 event
0 Waiting for trigger of 4 event
0 Waiting for trigger of 0 event
0 Waiting for trigger of 1 event
5 Triggered 4 event
5 Process 4 found that p[2] is WAITING
5 Process 2 found running/waiting
5 Process 2 killed
5 Wait completed for trigger of 4 event
8 Triggered 1 event
8 Triggered 2 event
8 Wait completed for trigger of 1 event
9 Triggered 0 event
9 Triggered 3 event
9 Wait completed for trigger of 0 event
9 Wait completed for trigger of 3 event