关闭设计的时序时,了解失败路径中的逻辑级数通常很有用。报告路径时序时,Timing Analyzer 会显示逻辑级数,但没有列出一组路径逻辑级数的默认报告。此设计示例定义了一个自定义程序,可用于创建显示一组路径逻辑级数的报告。
此自定义程序支持与 report_timing 命令相同的参数。应对自定义程序使用与 report_timing 命令相同的选项。此自定义程序还支持三个附加选项:-greater_than <value>、-less_than <value> 以及 -file <report file>。可以使用 -greater_than 和 -less_than 选项将报告仅限于逻辑级数大于或小于指定值的路径。可以使用 -file 选项将报告写入文件。
此自定义程序显示具有最差时序裕量的路径的逻辑级数。它不一定显示设计中逻辑级数最大的路径。具有最差时序裕量的路径并非总是逻辑级数最大的路径,但情况通常如此。
程序运行
此自定义程序包含以下步骤。
- 获取满足报告标准的路径列表
- 获取每个路径的逻辑级数
- 在图表中显示逻辑级数和路径信息
第 1 步:获取路径列表
此自定义程序使用 get_timing_paths 命令,此命令支持与 report_timing 命令相同的参数。可以使用任何 report_timing 选项来控制时序分析。例如,可以将逻辑级数报告仅限于以特定寄存器名称结尾的路径。以下 Tcl 代码显示了程序定义,并将所有参数传递到 get_timing_paths 命令。
proc report_levels_of_logic { args } { # 直接将所有参数传递到 get_timing_paths if { [catch { eval get_timing_paths $args } paths_col] } { post_message -type error $paths_col return } }
第 2 步:获取每个路径的逻辑级数
使用循环对 paths_col 变量中的路径集合进行迭代,并提取每个路径中的逻辑级数。将有关路径的信息保存在 Tcl 矩阵数据结构中,此结构将用于打印结果。保存的信息包括逻辑级数、路径裕量以及源节点名称和目标节点名称。
foreach_in_collection path_obj $paths_col { # 路径中的逻辑级数是多少? set levels_of_logic [get_path_info -num_logic_levels $path_obj] # 将路径信息添加到矩阵中。 $logic_levels_matrix add row [list \ $levels_of_logic \ [get_path_info -slack $path_obj] \ [get_node_info -name [get_path_info -from $path_obj]] \ [get_node_info -name [get_path_info -to $path_obj]] ] }
第 3 步:在图表中显示路径信息
最后,显示存储在矩阵变量中的所有路径信息。此示例使用 Tcl 报表包编排矩阵的打印格式。以下代码在矩阵中添加标题行,定义报告的视觉风格,设置单元格内边距,并显示报告。
# 添加标题行 $logic_levels_matrix insert row 0 \ [list "Levels of logic" "Slack" "From" "To"] # 我们需要定义一个样式,以便在表中打印结果 catch { ::report::rmstyle basicrpt } ::report::defstyle basicrpt {{cap_rows 1}} { data set [split "[string repeat " " [columns]];"] top set [split "[string repeat "+ - " [columns]]+"] bottom set [top get] topcapsep set [top get] topdata set [data get] top enable topcapsep enable bottom enable tcaption $cap_rows } # 创建报告,为列设置一定的内边距区域,并 # 使用指定格式打印矩阵 catch { r destroy } ::report::report r 4 style basicrpt for { set col 0 } { $col < [r columns]} { incr col } { r pad $col both " " } post_message "Levels of logic\n[r printmatrix $logic_levels_matrix]"
自定义程序
下面列出的自定义程序的代码包含将报告写入文件和限制报告路径(除非逻辑级数大于或小于用户指定值)的选项。
使用自定义程序的方法示例如下。
- report_levels_of_logic -setup -greater_than 10 -to [get_registers data*] -npaths 1000
- report_levels_of_logic -hold -from_clock core_50 -npaths 50 -file levels.txt
要使用自定义程序,请将下面的 Tcl 代码保存到名为 report_levels_of_logic.tcl 的文件中。然后在 Timing Analyzer Tcl 提示符下使用命令 source report_levels_of_logic.tcl。通过查找文件,可以定义自定义程序。然后可以使用新定义的命令 report_levels_of_logic,直到退出 Timing Analyzer。
package require cmdline package require struct::matrix package require report proc report_levels_of_logic { args } { set options { { "less_than.arg" "" "Limit to paths with less than this number" } { "greater_than.arg" "" "Limit to paths with greater than this number" } { "file.arg" "" "Output file name" } } array set opts [::cmdline::getKnownOptions args $options] # 务必使用参数调用程序 if { [string equal "" $opts(less_than)] && [string equal "" $opts(greater_than)] } { post_message -type warning "You must specify a numeric value\ for -less_than or -greater_than" return } # 务必使用数字参数值调用程序 if { ![string is double $opts(less_than)] } { post_message -type warning "You must specify a numeric value\ for -less_than" return } if { ![string is double $opts(greater_than)] } { post_message -type warning "You must specify a numeric value\ for -greater_than" return } # 创建一个用于保存失败路径相关信息的矩阵 set logic_levels_matrix [::struct::matrix] $logic_levels_matrix add columns 4 # 直接将所有未知参数传递到 get_timing_paths 路径 if { [catch { eval get_timing_paths $args } paths_col] } { post_message -type error $paths_col return } # 对时序路径列表进行遍历,获取有关 # 逻辑级数的信息 foreach_in_collection path_obj $paths_col { # 假设要报告路径,除非逻辑级数 # 处于指定界限之外。 set include_path 1 # 路径中的逻辑级数是多少? set levels_of_logic [get_path_info -num_logic_levels $path_obj] # 如果指定了下限,如果逻辑级数 # 大于或等于下限,则不报告路径 if { ! [string equal "" $opts(less_than)] } { if { $levels_of_logic >= $opts(less_than) } { set include_path 0 } } # 如果指定了上限,如果逻辑级数 # 小于或等于上限,则不报告路径 if { ! [string equal "" $opts(greater_than)] } { if { $levels_of_logic <= $opts(greater_than) } { set include_path 0 } } # 如果路径的逻辑级数处于界限之内, # 对其进行报告 if { $include_path } { $logic_levels_matrix add row [list \ $levels_of_logic \ [get_path_info -slack $path_obj] \ [get_node_info -name [get_path_info -from $path_obj]] \ [get_node_info -name [get_path_info -to $path_obj]] ] } } # 使用 get_timing_paths 对所有路径进行遍历 # 如果矩阵中有任何行,表明路径符合标准。 # 我们要在表中打印此信息。 if { 0 == [$logic_levels_matrix rows] } { # 没有符合标准的路径 # 打印快速消息 post_message "No paths meet the criteria to report levels of logic" #如果打开文件时出错,打印此 # 消息。否则,提示没有符合标准的路径 if { ! [string equal "" $opts(file)] } { if { [catch { open $opts(file) w } fh] } { post_message -type error "Couldn't open file: $fh" } else { puts $fh "No paths meet the criteria to report levels of logic" catch { close $fh } } } } else { # 添加标题行 $logic_levels_matrix insert row 0 \ [list "Levels of logic" "Slack" "From" "To"] # 我们需要定义一个样式,以便在表中打印结果 catch { ::report::rmstyle basicrpt } ::report::defstyle basicrpt {{cap_rows 1}} { data set [split "[string repeat " " [columns]];"] top set [split "[string repeat "+ - " [columns]]+"] bottom set [top get] topcapsep set [top get] topdata set [data get] top enable topcapsep enable bottom enable tcaption $cap_rows } # 创建报告,为列设置一定的内边距区域,并 # 使用指定格式打印矩阵 catch { r destroy } ::report::report r 4 style basicrpt for { set col 0 } { $col < [r columns]} { incr col } { r pad $col both " " } post_message "Levels of logic\n[r printmatrix $logic_levels_matrix]" # 如果指定了文件名,将报告保存到文件中 if { ! [string equal "" $opts(file)] } { if { [catch { open $opts(file) w } fh] } { post_message -type error "Couldn't open file: $fh" } else { puts $fh "Levels of logic" r printmatrix2channel $logic_levels_matrix $fh catch { close $fh } } } } }