ローカル変数とグローバル変数 - 2022.1 日本語

Vivado Design Suite ユーザー ガイド: Tcl スクリプト機能の使用 (UG894)

Document ID
UG894
Release Date
2022-06-08
Version
2022.1 日本語

プロシージャ内で作成された変数はローカルで、関数のスタック内で実行時に作成されます。ローカル変数はプロシージャ内でのみアクセス可能で、変数名がプロシージャ外の変数名と競合することはありません。たとえば、プロシージャ内で作成されたローカル変数 foo とプロシージャ外で作成された foo とは別のもので、これらの変数にはそれぞれ独立したコンテキストがあります。ローカル変数は、ほかの変数と同様に set Tcl キーワードで作成します。

プロシージャの引数として定義されたパラメーターは、デフォルトでローカル変数となります。プロシージャが呼び出されると (例: reportCriticalPaths $myfilename)、呼び出し変数 (例: $myfilename) はプロシージャのスタック内にコピーされます。この場合、呼び出し変数が多数の要素を含む Tcl リストであると、ランタイムおよびメモリ使用量が増加します。呼び出し変数の内容を変更することが必要な場合もあります。Tcl では、変数の内容を渡す代わりに、変数名を参照として渡す方法があります。変数が参照として渡されると、プロシージャ内での変数の変更により、呼び出し空間内の呼び出し変数も直接変更されます。参照として渡すパラメーターを定義するには、プロシージャの本文でキーワード upvar を使用します。前述の lshift ではこの手法を使用しています。

proc lshift {listVar} {
   upvar 1 $listVar L
   set r [lindex $L 0]
   set L [lreplace $L [set L 0] 0]
   return $r
 }

サンプル プロシージャ myproc では、変数の内容 lshift ではなく変数名 args を渡すことにより、$args を呼び出しています。

グローバル変数は、プロシージャ外で作成された変数で、グローバル名前空間に属しています。プロシージャ内でグローバル変数を参照するには、global キーワードを使用し、その後に変数名を記述します。

proc printEnv {} {
  global env
  foreach var [lsort [array names env]] { puts " $var = $env($var)" }
}

上記の例では、システム環境変数を表示する printEnv というプロシージャを定義しています。Tcl 配列 env は、Vivado ツールの起動時に初期化されるグローバル変数です。printEnv プロシージャでは、global env コマンドを使用してグローバル env 変数を参照しています。グローバル変数を定義したら、ローカル変数と同様にアクセスできます。グローバル変数は、読み出しおよび変更できます。

グローバル変数は、名前空間の修飾子を指定してアクセスすることもできます。グローバル名前空間の修飾子は「::」なので、プロシージャでグローバル変数 env を参照するには「::env」を使用します。構文は、どのグローバル変数でも同じです。次に例を示します。

proc printEnv {} {
  foreach var [lsort [array names ::env]] { puts " $var = $::env($var)" }
}

printEnv では env 変数への完全パスを指定しているので、global env env を宣言する必要はありません。

注記: グローバル変数はプロシージャの範囲外で作成された変数名に依存するので、グローバル変数の使用はお勧めしません。プロシージャに大きな Tcl リストを渡す必要性を回避するため、グローバル変数が使用されることがあります。グローバル変数を使用する前に、upvar 手法を考慮してみてください。
注記: プロジェクト モードで run 基盤を使用する場合は、フック スクリプトを使用して Vivado 環境内で定義されたグローバル変数を共有することはできません。推奨されるスクリプト間での情報の共有方法については、ユーザー入力の取得を参照してください。
注記: close_project および close_design コマンドでは、Tcl インタープリターのステートは変更されません。すべてのグローバル変数およびユーザーの作成した名前空間は、これらのコマンドを実行後にもそのまま保持されます。