process

SystemVerilogには、processというクラスがあります。

今週は、このprocessについて、4連続でアップしていきます。

IEEE 1800-2005では、このprocessクラスは、つぎのように宣言されています(実装は別です)。

class process;

enum state { FINISHED, RUNNING, WAITING, SUSPENDED, KILLED };

static function process self();

function state status();

function void kill();

task await();

function void suspend();

task resume();

endclass

各プロセスに対するアクセスをする前に、かならずプロセスのハンドルを'''self'''関数で獲得する必要があります。

process pid;

pid = process::self();

self 関数は、宣言の最初に static がついているのでクラス関数になります。

なので、process::self() のようにクラス名( process )の後に :: を付け、

その後に関数名( self() )が続きます。

各プロセスは、状態を持ちます。この状態を state で表現しています。

プロセスの状態を知りたいときは、 status 関数を呼びます。

各状態は、次のようになります。

FINISHED :プロセスが正常終了した

RUNNING :プロセスが現在、動作中である(ブロッキングされていない)

WAITING :プロセスがブロッキング文で待ち状態である

SUSPENDED :プロセスが停止中である(復帰を待っている状態)

KILLED :プロセスが強制的に終了した(強制終了、あるいは、disableが実行された)

各プロセスに対して、次の4つの関数あるいはタスクが用意されています。

kill() : プロセス(このプロセス内で生成した子プロセスも)を終了する。

await() : 他のプロセスが終了するのを待ちます

(自分自身に対してこのawait()を実行することはできません)

suspend() : 自分あるいは他のプロセスを一時的に停止します。

resume() : 停止しているプロセスを復帰させます

processの例として、IEEE 1800-2005から引用です。

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

fork/join_none 部でプロセスがN個生成されます。

生成されたプロセスのハンドルは、 job に格納します。

wait 文で各プロセスが起動したかどうか確認します。

プロセスが起動できれば、 job[j] には process のハンドラが代入されるので

null ではありません。ここでハンドラが null でないことを確認しないと、

それ以降、ハンドラにアクセスした場合、null である可能性があり、そうなると

null に対するアクセスになり、エラーになるので注意してください。

次の job[1].await() では、 job[1] が終了するまで待ちます。

最後の for 文では、各プロセスが正常終了していないときに job[k].kill() で

プロセスを強制的に終了しています。

このように process を使うことで、 fork/join で生成したプロセスの制御ができます。

============================================================

OVM 2.1の中でも使われている場所については、こちら

VMM 1.2の中でも使われている場所については、こちら