10.3 Functions と function呼び出し ~ Functions and function calling
functionの目的は,式中で使用するための値を返すことです.この節では,functionの定義の仕方と使い方について解説します.
syntax
function_declaration ::= (From Annex A - A.2.6)
function [ automatic ] [ signed ] [ range_or_type ]
function_identifier ;
function_item_declaration { function_item_declaration }
function_statement
endfunction
|
function [ automatic ] [ signed ] [ range_or_type ]
function_identifier ( function_port_list ) ;
block_item_declaration { block_item_declaration }
function_statement
endfunction
function_item_declaration ::=
block_item_declaration
| tf_input_declaration ;
function_port_list ::=
{ attribute_instance } tf_input_declaration
{ , { attribute_instance }tf_input_declaration }
tf_input_declaration ::=
input [ reg ] [ signed ] [ range ] list_of_port_identifiers
| input [ task_port_type ] list_of_port_identifiers
range_or_type ::=
range | integer | real | realtime | time
block_item_declaration ::= (From Annex A - A.2.8)
{ attribute_instance } block_reg_declaration
| { attribute_instance } event_declaration
| { attribute_instance } integer_declaration
| { attribute_instance } local_parameter_declaration
| { attribute_instance } parameter_declaration
| { attribute_instance } real_declaration
| { attribute_instance } realtime_declaration
| { attribute_instance } time_declaration
block_reg_declaration ::=
reg [ signed ] [ range ]
list_of_block_variable_identifiers ;
list_of_block_variable_identifiers ::=
block_variable_type { , block_variable_type }
block_variable_type ::=
variable_identifier
| variable_identifier dimension { dimension }
function定義は,'function'キーワードで始まり,オプショナルで'automatic'が続き,符号('signed')指定,rangeや関数の戻り値の型,function名と続いてから,セミコロン,または親で閉じたfunction port listにセミコロンとなり,'endfunction'で終わります.
'range_or_type shall'の使用はオプションです.'range'や'type'なしで定義されたfunctionは,戻り値はデフォルトで1bit reg型になります.もし使われたならば,'range_or_type'は,real型,integer型,time型,realtime型,[n:m] bit幅指定の値となるfunctionの戻り値を与えます.
A function shall have at least one input declared.
functionは,たった一つの入力宣言を持ちます.keyworf 'automatic'は,各再帰呼び出しのために動的に確保される再帰可能なfunctionを宣言します.
- automatic functionのitemは,階層参照('hierarchical references')によるアクセスができません.
- automatic functionは,階層名('hierarchical name')を使うことで,起動することができます.
function入力は,2つの方法のうちの1つで宣言されます.
1つ目の方法は,セミコロンに続いてfunction名を持ちます.セミコロンのあと,1つ以上のオプション的な入力は,後述するblock item宣言と混ざって宣言します.function item宣言のあと,ビヘイビア文とendfunction keywordがあります.
2つ目の方法は,function名のあと,開き丸括弧と1つ以上の入力宣言をコンマ区切りで持ちます.全ての入力宣言のあと,閉じ丸括弧とセミコロンがあります.セミコロンのあと,0以上のblock itemが宣言され,続けてビヘイビア文,endfunction keywordとなります.
例:
以下の例は,'range'定義を使った,getbyteという名のfunctinoを定義します.
function [7:0] getbyte;
input [15:0] address;
begin
// code to extract low-order byte from addressed word
. . .
getbyte = result_expression;
end
endfunction
function宣言の2つ目の様式を使って,以下のように定義することができます.
function [7:0] getbyte (input [15:0] address);
begin
// code to extract low-order byte from addressed word
. . .
getbyte = result_expression;
end
endfunction
function定義は,暗黙的にfunctionと同じ名前で,関数内部の宣言をするものとします.この変数は,デフォルトで1bit reg変数か,function宣言中のtypeで与えられる型と同様になります.function定義は,function戻り値をfunction名と同じ名前の内部変数への代入によって,関数からの戻り値を初期化します.
function宣言と同じscopeにおいて,function名と同じ名前のobjectを宣言することはイリーガルです.関数内において,function内の式で使われる,function名の暗黙的な変数があります.これはまた,function内のscopeにおいても,function名と同じ名前のobjectを宣言することはイリーガルです.
以下のLRM 10.3.1の例の行は,このコンセプトを示します.
getbyte = result_expression;
function呼び出しは,式中のオペランドです.function呼び出しは,以下の様式です.
function_call ::= (From Annex A - A.8.2)
hierarchical_function_identifier{ attribute_instance } ( expression { , expression } )
function呼び出しへの,引数の評価順序は,未定義です.
例)
以下の例は,LRM 10.3.1で定義されたgetbyte functionを2回呼び出した結果を結合して,wordを作ります.
word = control ? {getbyte(msbyte), getbyte(lsbyte)}:0;
functionはtaskよりも多くの制約があります.以下の6つのルールが,使用法を抑制します.a) function定義は,時間制御文(time-controlled statements,'#','@',"wait")を含んではならない.b) functionはtaskをenableにしてはならない.c) function定義は,少なくとも1つの入力引数を含みます.d) function定義は,output/inoutと宣言された引数を持ちません.e) function定義は,function名と同じ名称の内部変数への代入による戻り値の代入を含みます.f) functionは,ノンブロッキング代入を持ちません.A function shall not have any non blocking assignments.
例)
この例は,integer値を返す"factorial"と呼ばれるfunctionを定義します.この"factorial" functionは,反復して呼び出され,戻り値を表示します.
module tryfact;
// define the function
function automatic integer factorial;
input [31:0] operand;
integer i;
if (operand >= 2)
factorial = factorial (operand - 1) * operand;
else
factorial = 1;
endfunction
// test the function
integer result;
integer n;
initial begin
for (n = 0; n <= 7; n = n+1) begin
result = factorial(n);
$display("%0d factorial=%0d", n, result);
end
end
endmodule // tryfact
The simulation results are as follows:
0 factorial=1
1 factorial=1
2 factorial=2
3 factorial=6
4 factorial=24
5 factorial=120
6 factorial=720
7 factorial=5040
"Constant function calls"は,"elaboration"時(LRM 12.1.3)において,複雑な値の計算の構築のサポート使われます."Constant function call"は,functionへの引数が定数式("constant expressions")である,呼び出しモジュールへのローカルな"constant function"のfunction起動です."Constant function call"は,以下の制約を満足する,通常のVerilog functionsのサブセットです.
"constant function call"は,"elaboration"("綿密な仕上げ"の意)の時に評価されます."elaboration"実行は,simulation時やelaboration時の複数の関数呼び出し間で使われる,変数の初期値に影響を与えない.これらの場合において,その変数は,通常のsimulationのために初期化されます.
例)
This example defines a function called clogb2 that returns an integer which has the value of the ceiling of the log base 2.
module ram_model (address, write, chip_select, data);
parameter data_width = 8;
parameter ram_depth = 256;
localparam adder_width = clogb2(ram_depth); //(訳コメント)定数項に対してfunctionを使う,てことですね.. やっと意味がわかった..
input [adder_width - 1:0] address;
input write, chip_select;
inout [data_width - 1:0] data;
//define the clogb2 function
function integer clogb2;
input depth;
integer i,result;
begin
for (i = 0; 2 ** i < depth; i = i + 1)
result = i + 1;
clogb2 = result;
end
endfunction
reg [data_width - 1:0] data_store[0:ram_depth - 1];
//the rest to the ram model
An instance of this ram_model with parameters assigned:
ram_model #(32,421) ram_a0(a_addr,a_wr,a_cs,a_data);