10.タスク とファンクション

 タスクとファンクションの違いについて

10.1タスク


定義
<task>
::= task <name_of_task> ;
<tf_declaration>*
<statement_or_null>
endtask

タスクの呼び出し
<task_enable>
::= <name_of_task>
||= <name_of_task> ( <expression> <,<expression>>* ) ;

タスクは、テストベンチを書くときに重宝します。タスクの呼び出しは、パラメータを入、出力を引数にすることができます。このとき、引数は、値渡しでコピーされるので、引数をタスク内で変数として使っても上位呼び出し側変数には影響しません。これは、module 引数と決定的に違います。基本的にmodule引数は、物理的接続なのでNET型ですが、task/functionは、variable型(reg,integer,time,real,realtime)です。これは、記憶のある型です。

<例 >

module task_test;
        parameter data_array_size=10;
        integer i;
        reg [31:0] data;
        reg [31:0] data_array [0:data_array_size-1];


        initial begin
                init_data_array;//配列を初期化、ランダムデータ作成するタスク
                disp_data_array(13);//表示するタスク
                
        end


        task make_rand_data;
                input [31:0] i;
                output [31:0] data;

                begin
                        $display("making rand data. ");
                        #10;
                        data=$random(i);//$randomは、Verilogシステムタスク
                        $display("Complete rand data i=%h %h",i,data);
                end
        endtask

        task init_data_array;
                reg [31:0] local_data;
                begin
                        local_data=32'h0000_0000;
                        for (i=0; i<data_array_size;i=i+1)      data_array[i]=local_data;
                        for (i=0; i<data_array_size;i=i+1)      make_rand_data(i,data_array[i]);
                end
        endtask

        task disp_data_array;
                input [31:0] number_of_items;
        
                begin
                        if (number_of_items >data_array_size) begin
                                number_of_items=data_array_size;
                                $display("Warning: truncated...");
                        end
                        for (i=0; i<number_of_items;i=i+1) $display("data array[%d]=%h",i,data_array[i]);
                end
        endtask 


endmodule


10.2 ファンクション

<function>
::= function <range_or_type>? <name_of_function> ;
<tf_declaration>+
<statement>
endfunction


ファンクションのルールは以下の通りです。

10.3 verilog2001スタイルのファンクション、タスクの例

モジュールポートでは不可能ですが、taskやfunctionのポートでは、以下のようにvariable typeを入力、出力として定義できます。


function は符号付で返すことができます。
次の結果を説明できる人は、verilog2001上級者といっていいでしょう。(筆者も怪しいので、心配する必要はありません。)

結果

F:\regression_test\signed_test6.v(2)::signed_test6
Verilogのシミュレーションの準備が完了しました。スタートは,Goボタンを押してください。
------------- シミュレーションを開始します。--------------------

display should be 1 1 65025 -511 1:      1      1 65025   -511     1
display should be -1 -1 255 255 65535:    -1     -1   255    255 65535


---------- シミュレーションを終了します。time=0----------

ソースはこれです。


次の例は、const functionの例です。

メモリのビット幅は、次のようになります。パラメータのオーバライド後の値で、const functionが計算されていることがわかります。

このように、コンパイル時ビット幅(const値)を計算するのにパラメータの計算では非力のときに使います。ただし、階層表現が使えませんので使うモジュール毎に定義しないといけません。この他に以下の制限があります。