Vivado Design Suite には、完全な Tcl インタープリターがビルトインされており、新しいカスタム コマンドやプロシージャを簡単に作成できます。Tcl スクリプトを記述して Vivado IDE から読み込んで実行したり、プロシージャを記述して、引数を取り、エラーをチェックして、結果を返す新しい Tcl コマンドとして使用できます。
Tcl プロシージャは proc
コマンドで指定します。プロシージャ名、引数のリスト、実行するコードの本文を引数として指定します。次に、プロシージャ定義の簡単な例を示します。
proc helloProc { arg1 } {
# This is a comment inside the body of the procedure
puts "Hello World! Arg1 is $arg1"
}
通常プロシージャでは、定義済みの引数と、オプションでデフォルト値を指定します。引数にデフォルト値がある場合、その前の必須の引数がすべて指定されていれば、プロシージャを呼び出したときにその引数を指定する必要はありません。プロシージャは、return
コマンドを使用して値を返すよう指定していない場合、空のリストを返します。
次の例では、3 つの定義済み引数を持つ reportWorstViolations
というプロシージャを定義しています。
proc reportWorstViolations { nbrPaths corner delayType } {
report_timing -max_paths $nbrPaths -corner $corner -delay_type $delayType -nworst 1
}
プロシージャを実行する際、次の例に示すように、すべての引数を指定する必要があります。
%> reportWorstViolations 2 Slow max
%> reportWorstViolations 10 Fast min
次の例では、同じプロシージャで 3 つの引数のうち最後の 2 つにデフォルト値があります。corner
のデフォルト値は Slow
、delayType
のデフォルト値は Max
です。プロシージャの定義でデフォルト値が設定されているので、プロシージャを呼び出す際は corner
および
delayType
引数の指定はオプションです。
proc reportWorstViolations { nbrPaths { corner Slow } { delayType Max } } {
report_timing -max_paths $nbrPaths -corner $corner -delay_type $delayType -nworst 1
}
このプロシージャを実行する際は、次のすべての呼び出し方法が有効です。
%> reportWorstViolations 2
%> reportWorstViolations 10 Fast
%> reportWorstViolations 10 Slow Min
次のプロシージャの例には必須の引数 nbrPath
がありますが、それ以外にも追加の引数を指定できます。この場合、プロシージャを定義する際に引数のリストとして Tcl キーワード args
を使用します。args
キーワードは、任意の数の要素 (0 を含む) を含む Tcl リストを示します。
proc reportWorstViolations { nbrPaths args } {
eval report_timing -max_paths $nbrPaths $args
}
Tcl コマンドを実行する際、Tcl コマンドで使用可能なまたは必須のコマンド ライン引数の代わりに変数置換を使用できます。この場合、Tcl eval
コマンドを使用してコマンドの一部として Tcl 変数を含めたコマンド ラインを評価する必要があります。上記の例では、引数のリスト変数 ($args
) が report_timing
コマンドに変数として渡されるので、eval
コマンドが必要です。
プロシージャを実行する際は、次のいずれの形式でも機能します。
%> reportWorstViolations 2
%> reportWorstViolations 1 -to [get_ports]
%> reportWorstViolations 10 -delay_type min_max -nworst 2
最初の例では、値 2 が $nbrPaths
引数に渡され、-max_paths
に適用されます。2 番目と 3 番目の例では、それぞれ 1 と 10 が -max_paths
に適用され、その後の文字列は $args
に代入されます。
次の例は、非プロジェクト モードのサンプル スクリプトで使用されていた reportCriticalPaths
コマンドを示します。このプロシージャでは 1 つの引数 $filename
が使用され、コメントで各セクションを説明しています。
#------------------------------------------------------------------------
# reportCriticalPaths
#------------------------------------------------------------------------
# This function generates a CSV file that provides a summary of the first
# 50 violations for both Setup and Hold analysis. So a maximum number of
# 100 paths are reported.
#------------------------------------------------------------------------
proc reportCriticalPaths { fileName } {
# Open the specified output file in write mode
set FH [open $fileName w]
# Write the current date and CSV format to a file header
puts $FH "#\n# File created on [clock format [clock seconds]]\n#\n"
puts $FH "Startpoint,Endpoint,DelayType,Slack,#Levels,#LUTs"
# Iterate through both Min and Max delay types
foreach delayType {max min} {
# Collect details from the 50 worst timing paths for the current analysis
# (max = setup/recovery, min = hold/removal)
# The $path variable contains a Timing Path object.
foreach path [get_timing_paths -delay_type $delayType -max_paths 50 -nworst 1] {
# Get the LUT cells of the timing paths
set luts [get_cells -filter {REF_NAME =~ LUT*} -of_object $path]
# Get the startpoint of the Timing Path object
set startpoint [get_property STARTPOINT_PIN $path]
# Get the endpoint of the Timing Path object
set endpoint [get_property ENDPOINT_PIN $path]
# Get the slack on the Timing Path object
set slack [get_property SLACK $path]
# Get the number of logic levels between startpoint and endpoint
set levels [get_property LOGIC_LEVELS $path]
# Save the collected path details to the CSV file
puts $FH "$startpoint,$endpoint,$delayType,$slack,$levels,[llength $luts]"
}
}
# Close the output file
close $FH
puts "CSV file $fileName has been created.\n"
return 0
}; # End PROC