LRM読解(Chap.10-3)

2008/11/05Verilog::文法import

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);