It most important to kill some particular processes when we have System reset or at such type of event when test bench required to kill some threads and restart the same. It is easy to start any thread as you just need to call it. Main effort of BFM developer is to kill running thread especially when task written is blocking. Blocking means it is taking too many clock cycles before checking arrival of Reset signal.
There are many ways to kill running processes in System Verilog. Some of them are disable fork, disable LABLE or you can create some flags that will break all consequent process and achieve your goal.
disable fork is able to kill the process only if the condition to kill the process and fork-join_x block is in same scope.
disable LABLE is brutal way to kill your process as LABLE is static for class and it you kill one process using LABLE than all processes created under that particular gets killed. It will kill your other processes that is running in other objects of the class. You can see the example
What if you can specify to kill process whenever you want just like push some button and there is a blast that kill tasks that is running right now !!
System Verilog provides such facility. It has inbuilt class named process. This class can not be extended.
Objects of class process internally created by simulation when processed spawned.
Process class contains following members.
typedef enum {FINISHED , RUNNING, WAITTING, SUSPENDED, KILLED} state;
This enum is mainly used to indicate current state of process.
static function process self ()
Function returns handle to the current process , that is, a handle to the process making the call.
function state status()
This function return current status of the process.
If it returns FINISHDE than it indicates that process has terminated normally.
If it returns RUNNIG than it indicates that process is running durring current time stamp.
If it returns WAITTING than it indicates that waiting in blocking statement.
If it returns SUSPENDEN than it indicates that process has been stopped and waiting for getting resume.
If it returns KILLED than it indicates that process has been successfully killed via kill or disable.
function void kill();
This function terminated the given process and all its subsequent processes that is processes spawned using fork statements by the process being killed.
task await();
This task waits for the process to be finished successfully. This can be called from another process which is waiting for some process to be finished.
function void suspend();
This function suspends either its own execution or execution or that of another process.
function void resume();
This function resumes previously suspended process.
The methods kill(), await(), suspend() and resume() shall be restricted to a process created by initial, always or fork blocks only.
To understand how to use the process class to kill any task please consider the following example. you can understand from this example use of the process class and apply your understanding to your specific requirement.
class main_class;
bit a = 0;
task main_run(string name = "not assigned");
$display($realtime,$psprintf("Task from %s class called",name));
#1000;
$display($realtime,$psprintf("Class %s end of the main_run task",name));
endtask : main_run
endclass : main_class
module disable_lable();
main_class m1;
main_class m2;
main_class m3;
process p1;
process p2;
process p3;
initial begin
m1 = new ();
m2 = new ();
m3 = new ();
fork
begin
p1 = process :: self();
m1.main_run("m1");
$display($realtime,"m1 main_run finished");
end
begin
p2 = process :: self();
m2.main_run("m2");
$display($realtime,"m2 main_run finished");
end
begin
p3 = process :: self();
m3.main_run("m3");
$display($realtime,"m3 main_run finished");
end
join_none
#20;
$display($realtime,"Before killing p1 process");
p1.kill;
end
initial begin
#100000;
end
endmodule : disable_labl
Output
# 0Task from m1 class called
# 0Task from m2 class called
# 0Task from m3 class called
# 20Before killing p1 process
# 1000Class m2 end of the main_run task
# 1000m2 main_run finished
# 1000Class m3 end of the main_run task
# 1000m3 main_run finished
From above example you can see that main_run task is called in fork join_x from three different classes. Now for each begin end block contains one call of task and one process handle created. From the above example you can see that we can kill the task whenever we want to kill by just calling process obj.kill(); method of class process. Output of the above code is shown above.
There are many ways to kill running processes in System Verilog. Some of them are disable fork, disable LABLE or you can create some flags that will break all consequent process and achieve your goal.
disable fork is able to kill the process only if the condition to kill the process and fork-join_x block is in same scope.
disable LABLE is brutal way to kill your process as LABLE is static for class and it you kill one process using LABLE than all processes created under that particular gets killed. It will kill your other processes that is running in other objects of the class. You can see the example
What if you can specify to kill process whenever you want just like push some button and there is a blast that kill tasks that is running right now !!
System Verilog provides such facility. It has inbuilt class named process. This class can not be extended.
Process Class
A process is a built in class in System Verilog. This class allows one process to control another process once it has started. You can declare object of the process class, pass it to other class or task or take instance in another objects or in other words you can use instance of process class same as object of normal class. But there are some restriction while using process class which are as follows.- You can not extend process class.
- You can not call new function of process class to create memory.
Objects of class process internally created by simulation when processed spawned.
Process class contains following members.
typedef enum {FINISHED , RUNNING, WAITTING, SUSPENDED, KILLED} state;
This enum is mainly used to indicate current state of process.
static function process self ()
Function returns handle to the current process , that is, a handle to the process making the call.
function state status()
This function return current status of the process.
If it returns FINISHDE than it indicates that process has terminated normally.
If it returns RUNNIG than it indicates that process is running durring current time stamp.
If it returns WAITTING than it indicates that waiting in blocking statement.
If it returns SUSPENDEN than it indicates that process has been stopped and waiting for getting resume.
If it returns KILLED than it indicates that process has been successfully killed via kill or disable.
function void kill();
This function terminated the given process and all its subsequent processes that is processes spawned using fork statements by the process being killed.
task await();
This task waits for the process to be finished successfully. This can be called from another process which is waiting for some process to be finished.
function void suspend();
This function suspends either its own execution or execution or that of another process.
function void resume();
This function resumes previously suspended process.
The methods kill(), await(), suspend() and resume() shall be restricted to a process created by initial, always or fork blocks only.
To understand how to use the process class to kill any task please consider the following example. you can understand from this example use of the process class and apply your understanding to your specific requirement.
Example
// Example to kill the processes in system Verilog.class main_class;
bit a = 0;
task main_run(string name = "not assigned");
$display($realtime,$psprintf("Task from %s class called",name));
#1000;
$display($realtime,$psprintf("Class %s end of the main_run task",name));
endtask : main_run
endclass : main_class
module disable_lable();
main_class m1;
main_class m2;
main_class m3;
process p1;
process p2;
process p3;
initial begin
m1 = new ();
m2 = new ();
m3 = new ();
fork
begin
p1 = process :: self();
m1.main_run("m1");
$display($realtime,"m1 main_run finished");
end
begin
p2 = process :: self();
m2.main_run("m2");
$display($realtime,"m2 main_run finished");
end
begin
p3 = process :: self();
m3.main_run("m3");
$display($realtime,"m3 main_run finished");
end
join_none
#20;
$display($realtime,"Before killing p1 process");
p1.kill;
end
initial begin
#100000;
end
endmodule : disable_labl
Output
# 0Task from m1 class called
# 0Task from m2 class called
# 0Task from m3 class called
# 20Before killing p1 process
# 1000Class m2 end of the main_run task
# 1000m2 main_run finished
# 1000Class m3 end of the main_run task
# 1000m3 main_run finished
From above example you can see that main_run task is called in fork join_x from three different classes. Now for each begin end block contains one call of task and one process handle created. From the above example you can see that we can kill the task whenever we want to kill by just calling process obj.kill(); method of class process. Output of the above code is shown above.
No comments:
Post a Comment