automatic変数に適用してもよいです。下記のautomatics宣言と同じ制限を受けます。手続き構文以外使えない。手続き系継続代入文では使用不可(force/assign/release/deassign)ポート定義は、呼び出し側と呼び出され側で完全に一致する必要があります。系ならば、パック配列、アンパック配列を問わず渡せます。net系は渡せません。次のベンチは、巨大な配列をfunctionに渡しています。ポートで渡しているので、実体のコピーは起こらず、ポインタだけのコピーで済みます。実際、このベンチを実行してみると1msもかかりません。inoutの方は実行してみると数秒かかってしまいます。巨大な実体(101x101x32x32ビットのメモリ)のコピーに時間がかかってしまうためです。inoutは、値渡しのCOPYです。functionが呼ばれるときにCOPYされ、functionから戻るときにも実体分のCOPYが起こります。functionの呼び出し前後で計2回分の実体コピーが起こります。portでは、ポインタだけのコピーで済みますから巨大な配列では圧倒的に速いという訳です。endfunctionendmoduleTIPS:SVでは、functionもoutput/inout宣言できます。手続き構文以外使えない。手続き系継続代入文では使用不可(force/assign/release/deassign)の制限があります。static変数は、スレッドローカルではないSVでは、まず押さえておきたい重要な概念です。Verilog1995では、automatic変数はなくstaticの概念しかありません。一般のプログラミング言語の常識からはかけ離れた仕様です。Hardwareは、生まれたり死んだりしないので、いままでVerilogHDLで書いたきた人も意識することはなく、この事は気づかなかったかもしれません。テストベンチ、特にSV風にテストベンチを書こうとすると、やはり普通のプログラミング言語のように書きたい場合が多いのでautomaticが頻繁に登場することになります。ベンチから見ていきます。endtaskendmodule結果です。****この結果は、ModelSimと同じになりましたが、i=1,i=1になる処理系もあるかもしれません。そのために上書きされてしまいます。ここでの結果は、最後に書かれた方を表示していることになります。automaticで再帰が書ける自分自身を呼び出す関数を再帰関数と言います。次の関数は、足し算をする関数です。endfunctionendmodule殆どCと同じように書けますね。****さて、ここで問題です。この関数が何回呼ばれたかを数えたいとします。そこで、次のように記述を追加してみました。endfunction結果です。****カウンタが1から進みませんね。counterの属性もautomaticになります。automatic変数は、default初期値で生成の度、SIM実行中に初期化される規則になっています。intの初期値0で初期化されます。(これがintegerなら、4値32'hxで初期化されます。従って、++counterで常に1になってしまう、という訳です。couterだけは、staticだよ、とコンパイラに教えてやります。****期待通りになりました。static変数は、シミュレーションが始まる前に初期化され、シミュレーションが終わるまで死ぬことはありません。値はづっと保持、常に参照が可能です。再帰などによりfunctionは、複数のローカル変数が存在することに注意してください。スタックが開放されたときに自動的に消滅します。変数は、再帰されたとしても、共通のオブジェクトですので、特定できます。static変数は、SIM開始時には、初期値は、確定しており以降、消滅する心配がありません。