LRM読解(Chap.10-3)
10.3 Functions と function呼び出し ~ Functions and function calling functionの目的は,式中で使用するための値を返すことです.この節では,functionの定義の仕方と使い方について解説します.
10.3.1 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
10.3.2 関数からの戻り値 ~ Returning a value from a function
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;
10.3.3 function呼び出し ~ Calling a function
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;
10.3.4 functionルール ~ Function rules
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
10.3.5 constant functionの使い方 ~ Use of constant functions
"Constant function calls"は,"elaboration"時(LRM 12.1.3)において,複雑な値の計算の構築のサポート使われます."Constant function call"は,functionへの引数が定数式("constant expressions")である,呼び出しモジュールへのローカルな"constant function"のfunction起動です."Constant function call"は,以下の制約を満足する,通常のVerilog functionsのサブセットです.
- 階層的な参照を含まない
- constant functionの中で呼び出されたどんなfunctionも,current moduleへの局所的なconstant functionになります.(Any function invoked within a constant function shall be a constant function local to the current module.)
- System functions は呼び出されないこと.
- "constant function"の中のすべての"system tasks"が無視されるものとします。
- "constant function"の中の"system function"は,イリーガルになります.(All system functions within a constant function shall be illegal.)
- 呼び出す"system task"は"$display"で,"elaboration time"において呼び出されたときは無視されます.(The only system task that may be invoked is $display, and it shall be ignored when invoked at elaboration time.)
- 関数内で使われている全てのparameter値は,"constant function"呼び出しを使う前に定義されるべき.
i.e. "constant function"呼び出しの評価で使われるどんな"parameter"も, 元の"constant function"呼び出し位置で,その"parameter"の使用を構成する.(適用する?)
- "parameter"でもなく,"function"でもない全ての識別子は,current functionへ局所的として宣言されるべき.それら(they:functions?)が,defparam文(LRM 12.2.1)によって,直接的・間接的に影響を受ける"parameter"を使うならば,結果は未定義です.これは,errorを提供できるか,または,"constant function"が不定値を返すことができます.
- "generate"scope内で宣言されない
- 定数式を要求するあらゆるコンテキスト内で,"constant function"自身を使わない.(They shall not themselves use constant functions in any context requiring a constant expression.)
"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);