报告逻辑级数

author-image

作者

关闭设计的时序时,了解失败路径中的逻辑级数通常很有用。报告路径时序时,Timing Analyzer 会显示逻辑级数,但没有列出一组路径逻辑级数的默认报告。此设计示例定义了一个自定义程序,可用于创建显示一组路径逻辑级数的报告。

此自定义程序支持与 report_timing 命令相同的参数。应对自定义程序使用与 report_timing 命令相同的选项。此自定义程序还支持三个附加选项:-greater_than <value>、-less_than <value> 以及 -file <report file>。可以使用 -greater_than 和 -less_than 选项将报告仅限于逻辑级数大于或小于指定值的路径。可以使用 -file 选项将报告写入文件。

此自定义程序显示具有最差时序裕量的路径的逻辑级数。它不一定显示设计中逻辑级数最大的路径。具有最差时序裕量的路径并非总是逻辑级数最大的路径,但情况通常如此。

程序运行

此自定义程序包含以下步骤。

  1. 获取满足报告标准的路径列表
  2. 获取每个路径的逻辑级数
  3. 在图表中显示逻辑级数和路径信息

第 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 }
            }
        }
    }
}