Verilog 関数
多くの場合、特定のコードが反復的であり、RTL 内で複数回呼び出されていることがわかります。ほとんどの場合、シミュレーション時間は消費されず、さまざまなデータ値で実行する必要がある複雑な計算が含まれる場合があります。そのような場合、 function
を宣言できます 繰り返しコードを関数内に配置し、結果を返せるようにします。 関数呼び出しを実行するだけなので、これにより RTL の行数が大幅に削減されます。 計算を実行する必要があるデータを渡します。実際、これは C の関数と非常によく似ています。
関数の目的は、式で使用される値を返すことです。関数定義は常にキーワード function
で始まります その後に、戻り値の型、名前、および括弧で囲まれたポート リストが続きます。 Verilog は、endfunction
を見つけると、関数定義が終了したことを認識します。 キーワード。関数には少なくとも 1 つの入力が宣言され、戻り値の型は void
になることに注意してください。 関数が何も返さない場合。
構文
function [automatic] [return_type] name ([port_list]);
[statements]
endfunction
キーワード automatic
関数を再入可能にします タスク内で宣言されたアイテムは、タスクの異なる呼び出し間で共有されるのではなく、動的に割り当てられます。これは、再帰関数や、同じ関数が fork されたときに N 個のプロセスによって同時に実行される場合に役立ちます。
関数宣言
関数への入力を宣言するには、次の 2 つの方法があります。
function [7:0] sum;
input [7:0] a, b;
begin
sum = a + b;
end
endfunction
function [7:0] sum (input [7:0] a, b);
begin
sum = a + b;
end
endfunction
関数から値を返す
関数定義は、関数と同じ名前の内部変数を暗黙的に作成します。したがって、関数のスコープ内で同じ名前の別の変数を宣言することは違法です。戻り値は、関数の結果を内部変数に代入することによって初期化されます。
sum = a + b;
関数の呼び出し
関数呼び出し は式を伴うオペランドであり、以下に示す構文を持ちます。
reg [7:0] result;
reg [7:0] a, b;
initial begin
a = 4;
b = 5;
#10 result = sum (a, b);
end
関数のルール
- # のような時間制御ステートメントを関数に含めることはできません , @ 、待って 、ポージング 、否定
- シミュレーション時間を消費する可能性があるため、関数はタスクを開始できませんが、他の関数を呼び出すことはできます
- 関数には少なくとも 1 つの入力が必要です
- 関数にノンブロッキング割り当てまたは
force-release
を指定することはできません またはassign-deassign
- 関数にトリガーを含めることはできません
- 関数に出力または入出力を含めることはできません
再帰関数
自分自身を呼び出す関数は、再帰関数と呼ばれます。以下に示す例では、指定された数値の階乗を計算する再帰関数が記述されています。
module tb;
initial begin
integer result = factorial(4);
$display("factorial(4) = %0d", result);
end
function automatic integer factorial(integer i);
integer result = i;
// This function is called within the body of this
// function with a different argument
if (i) begin
result = i * factorial(i-1);
$display("i=%0d result=%0d", i, result);
end else
result = 1;
return result;
endfunction
endmodule
シミュレーションログ xcelium> run i=1 result=1 i=2 result=2 i=3 result=6 i=4 result=24 factorial(4) = 24 xmsim: *W,RNQUIE: Simulation is complete
Verilog