Verilog関数のマスター:効率的なRTL設計のために
RTL内で特定のコード片が繰り返し呼び出されることがよくあります。これらは主にシミュレーション時間を消費せず、異なるデータ値で実行する必要がある複雑な計算を含む場合があります。このような場合、functionを宣言し、繰り返しコードを関数内に配置して結果を返すようにできます。これにより、計算を実行するデータを渡して関数呼び出しを行うだけでよくなるため、RTLの行数を大幅に削減できます。これはC言語の関数と非常に似ています。
関数の目的は、式で使用される値を返すことです。関数定義は常にキーワードfunctionで始まり、続いて戻り値の型、名前、括弧で囲まれたポートリストが続きます。Verilogはendfunctionキーワードを見つけると関数定義が終了したと認識します。関数には少なくとも1つの入力宣言が必要で、何も返さない場合の戻り値の型はvoidになります。
構文
function [automatic] [return_type] name ([port_list]);
[statements]
endfunction
キーワードautomaticを指定すると、関数が再入可能になり、タスク内で宣言されたアイテムが静的に共有されるのではなく、動的に割り当てられます。これは再帰関数や、同じ関数がforkされてN個のプロセスによって同時に実行される場合に有用です。
関数宣言
関数への入力を宣言するには2つの方法があります:
// スタイル1
function [7:0] sum;
input [7:0] a, b;
begin
sum = a + b;
end
endfunction
// スタイル2(ANSIスタイル)
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
関数のルール
- 時間制御文(#、@、wait、posedge、negedge)を含めることはできない
- タスクを開始できない(シミュレーション時間を消費する可能性があるため)が、他の関数を呼び出すことはできる
- 少なくとも1つの入力を持たなければならない
- ノンブロッキング代入、
force-release、assign-deassignを含めることはできない - トリガーを含めることはできない
- outputやinoutを持つことはできない
再帰関数
自分自身を呼び出す関数を再帰関数と呼びます。以下の例では、与えられた数の階乗を計算する再帰関数を記述しています。
module tb;
initial begin
integer result = factorial(4);
$display("factorial(4) = %0d", result);
end
function automatic integer factorial(integer i);
integer result = i;
// この関数は、異なる引数でこの関数の本体内で呼び出される
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
- Stratasys FDM造形を最適化するInsight必須機能10選
- C++関数を実例で徹底解説:基本から応用まで
- C言語の関数マスター:構造、宣言、ベストプラクティス
- Verilogマスター:デジタル回路設計のための完全チュートリアル
- Verilog連結マスター:実践ガイド
- Verilog代入文の理解:種類、構文、ベストプラクティス
- Verilogブロッキング代入とノンブロッキング代入:違いを徹底解説
- Verilog数学関数のマスター:効率的なハードウェア設計のために
- MATLAB関数:定義、ワークスペース、入出力
- Pythonラムダ関数をマスターする:実例とベストプラクティス
- Python 関数完全ガイド:再利用可能なコードモジュールの構築