Sunday, 13 March 2016

How to kill a process in SystemVerilog


In this blog, we will see a couple of issues in the simulation while using "disable fork" and "disable LABEL" statements. Most of us, have faced these kind of issues at least one time in our system verilog programming and I just want to sum up them on a single page.


(1) Issue while using "disable fork;" statement in the code

Below is the pseudo code to understand:

task multiple_process();
    fork
        forever begin
            #10; // Task-A
            $display("Process-1");
        end
    join_none
    fork
    begin
        dly1=$urandom_range(1,10);
        #dly1; // Task-B
        $display("Process-2");
    end
    begin
        dly1=$urandom_range(1,20);
        #dly1; / Task-C
        $display("Process-3");
    end
    join_any
    disable fork;
    $display("Process-4");
endtask : multiple_process

As shown in above task, "Task-A" process is running continuously. Two different processes, "Task-B" and "Task-C" should run in parallel and any of two processes is completed, other process shall stop its execution due to join_any statement.

While simulating above code, you may face that when the disable fork is executed, "Task-A" process also stop it's execution. So, to avoid this kind of situation, it's better to use "disable LABEL" statement.

(2) Issue while using "disable LABEL" statement:

task multiple_process();
    fork
        forever begin
            #10; // Task-A
            $display("Process-1");
        end
    join_none

    fork : LABEL_B_C

    begin
        dly1=$urandom_range(1,10);
        #dly1; // Task-B
        $display("Process-2");
    end
    begin
        dly1=$urandom_range(1,20);
        #dly1; / Task-C
        $display("Process-3");
    end
    join_any
    disable LABEL_B_C;
    $display("Process-4");
endtask : multiple_process


Above code works fine with a single instance of that class. It disables only "Task-B" and/or "Task-C" process when "disable LABEL_B_C" is executed. But when there are multiple instances of the same class in the testbench and all the instances are executing their threads simultaneously then the simulation will stop after executing "disable LABEL_B_C" statement of any instance.


To handle these kind of situations, it's better to use "process" class in the system verilog to kill any process.

task multiple_process();
    process b_process, c_process;

    fork

        forever begin
            #10; // Task-A
            $display("Process-1");
        end
    join_none

    fork : LABEL_B_C

    begin 
        b_process = process::self();
        dly1=$urandom_range(1,10);
        #dly1; // Task-B
        $display("Process-2");
    end
    begin
        c_process = process::self();
        dly1=$urandom_range(1,20);
        #dly1; / Task-C
        $display("Process-3");
    end
    join_any
    if(b_process.status != process::FINISHED)
        b_process.kill();
    if(c_process.status != process::FINISHED)
        c_process.kill();

    $display(“Process-4”);
endtask : multiple_process

Here, we are defining each process using process class and after join_any, we are checking that whether any of “b_process” or “c_process” is finished or not.If it is  not finished, then kill that process.

Reference:
(1) IEEE Standard for SystemVerilog (IEEE Std 1800™-2012)
(2) https://verificationacademy.com/forums/systemverilog/fork-within-loop-join-all

4 comments:

  1. "But when there are multiple instances of the same class in the testbench and all the instances are executing their threads simultaneously then the simulation will stop after executing "disable LABEL_B_C" statement of any instance".
    My understanding on this statement is,if a thread is disabled in one instance will disable the same threads running in other instances as well. While if thread is disabled thru "process" in one instance will not impact the same thread running in other instances.Is my understanding correct?

    ReplyDelete
    Replies
    1. Yes. However, this blog intends to avoid such situation. I don't know, but you may find different behavior with different simulators.

      Delete