Quartus® II Tcl 例: ロジックのレポートレベル

デザインを最適化するのに、レジスター間のロジックのレベルに関する情報をビューすることが役立ちます。以下のスクリプトは、デザイン内の異なるレベルのロジックを持つパスの数を含む、コンマ区切り値 (.csv) ファイルを生成します。このデータを図表にするか、Excel* でヒストグラムを作成して、ロジックのレベルごとのパス分布を示せます。

2 つのレジスター間に複数のロジックパスがある場合、このスクリプトは、ロジックの最大レベルのみカウントします。例えば、2 つのレジスターに、レベル 4 のパスが 1 つ、およびレベル 2 のパスが 2 つある場合、レベル 4 のパスが 1 つとカウントされます。

このスクリプトは、<revision name>.levels_of_logic.csv. という名前の CSV ファイルを生成します。

仮にスクリプトを保存するファイルの名前を、report_levels_of_logic.tcl とすると、下記のコマンドでこれを実行できます。

quartus_tan -t report_levels_of_logic.tcl -project <project name> [-revision <revision name>] [-name_pattern <string to match>]

-name_pattern オプションを使用して、デザインにおけるパスのカウントを特定の階層に制限できます。ツールコマンド言語 (Tcl) ワイルドカード・マッチングに一致する文字列を指定します。-name_pattern オプション用に値を指定しない場合、デフォルトの * になります。例えば、デザイン内の mult:inst6|lpm_mult:lpm_mult_component 階層間のレジスターのロジックレベルをレポートしたい場合、-name_pattern オプションの値に、specify mult:inst6|lpm_mult:lpm_mult_component* を指定します。

load_package advanced_timing package require cmdline set options {\ { "project.arg" "" "Project name" } \ { "revision.arg" "" "Revision name" } \ { "name_pattern.arg" "*" "Restrict to registers matching this pattern"} } array set opts [::cmdline::getoptions quartus(args) $options] array set num_levels [list] # プロジェクトを開いてリビジョン名を取得します if { [string equal "" $opts(revision)] } { project_open $opts(project) -current_revision } else { project_open $opts(project) -revision $opts(revision) } set rev [get_current_revision] # タイミング・ネットリストを準備します if { [catch { create_timing_netlist; create_p2p_delays } res] } { post_message -type error $res project_close qexit -error } # デザイン内にあるすべてのレジスターで繰り返します foreach_in_collection dest [get_timing_nodes -type reg] { # レジスターノードにフィードするキーパー # (レジスター、ピン、クロック) のリストを入手 set delays_from_keepers [get_delays_from_keepers $dest] # デスティネーションのレジスター名がパターンに合わない場合、 # 単に次へ行きます。 set dest_name [get_timing_node_info -info name $dest] if { ! [string match $opts(name_pattern) $dest_name] } { continue } # レジスターノードにフィードするすべてのキーパーを検証 foreach delay $delays_from_keepers { set src [lindex $delay 0] # キーパーにはピンおよびクロックを含められますが、ここで必要なのはレジスターのみです。 if { ! [string equal "reg" [get_timing_node_info -info type $src]] } { continue } # ソースのレジスター名がパターンに合わない場合、 # 単に次へ行きます set src_name [get_timing_node_info -info name $src] if { ! [string match $opts(name_pattern) $src_name] } { continue } # このポイントで、ソース名およびデスティネーション名はいずれも # パターンに合っており、これはレジスター間パスです。 # get_delay_path コマンドは、パス上のノードのリストを # 返します。パスの長さはリストの長さです。 # リストにはソースおよびデスティネーションのレジスターが含まれているため、 # レジスター間のロジックのレベルは - 2 set path [get_delay_path -type longest -from $src -to $dest] set levels_of_logic [expr { [llength $path] - 2 } ] # アレイ内の情報を保存します if { [info exists num_levels($levels_of_logic)] } { incr num_levels($levels_of_logic) } else { set num_levels($levels_of_logic) 1 } } } project_close # 情報をファイルに書き出します if { [catch {open ${rev}.levels_of_logic.csv w} fh] } { post_message -type error $fh } else { # 説明ヘッダーをそのファイルに書き込みます puts $fh "Levels of logic for project $opts(project) revision $rev" puts $fh "File generated by Quartus® II $quartus(version) on \ [clock format [clock seconds]]" puts $fh "\nReporting paths for register names matching $opts(name_pattern)" puts $fh "Levels of logic,Number in design" foreach level [lsort -integer [array names num_levels]] { if { [catch { puts $fh "$level,$num_levels($level)" } res] } { post_message -type error $res break } } catch { close $fh } }