Timing Analyzer 示例:失败时钟汇总报告

author-image

作者

此页面的脚本对设计中所有受支持运行条件下的所有时钟执行建立时间、保持时间、恢复时间和移除时间分析。此脚本创建了一个表,列出了所有失败时序分析的相关信息。此脚本将此表写入名为 <revision>.failing_clock_domains 的文件。如果分析没有失败,此脚本将在此文件中写入一条消息,提示分析没有失败。

可以使用此脚本快速、轻松地了解设计的失败时序分析的结果。如果将脚本保存在名为 failing_clock_domains.tcl 的文件中,请使用以下命令运行脚本。

quartus_sta --report_script=failing_clock_domains.tcl <project name> [-c <revision name>]

在任何时序分析失败时,脚本生成的表的示例如下。此表包含最差情况裕量、总负裕量 (TNS)、时钟名称、失败分析所处的运行条件以及失败分析类型。

时序分析失败的时钟域

+--------+---------------+------------+-----------------------+-----------------+
; Slack  ; End Point TNS ; Clock      ; Operating conditions  ; Timing analysis ;
+--------+---------------+------------+-----------------------+-----------------+
; -0.113 ; -0.321        ; IF_RXCLK   ; Slow 1100mV 85C Model ; Setup           ;
; -0.098 ; -0.223        ; core_clk   ; Fast 1100mV 0C Model  ; Hold            ;
+--------+---------------+------------+-----------------------+-----------------+

复制以下 TCL 代码,并将其粘贴和保存到一个文件中,以便使用脚本。

# 报告设计是否有负裕量时钟域。
# 如果有负裕量时钟域,将此信息添加到
# 一个表中,并将其写入一个文件。
# 在适当的情况下更改此处的文件名
set output_file_name [get_current_revision].failing_clock_domains

package require struct::matrix
package require report

# 创建一个用于保存失败路径相关信息的矩阵
set failing_paths_matrix [::struct::matrix];
$failing_paths_matrix add columns 5

# 必须对所有运行条件进行分析
set all_operating_conditions_col [get_available_operating_conditions]

# 对每个时钟域进行这些类型的分析
set analysis_list [list "setup" "hold" "recovery" "removal"]

# 对所有运行条件进行遍历
foreach_in_collection operating_conditions_obj $all_operating_conditions_col {

   # 设置运行条件,更新时序网表
   set_operating_conditions $operating_conditions_obj
   update_timing_netlist

   # 获取运行条件的英语文本名称
   set operating_conditions_display_name   [get_operating_conditions_info -display_name $operating_conditions_obj]

   # 进行每种类型的分析   
   foreach analysis_type $analysis_list {

      # 如需打印,获取分析类型的名称
      set analysis_display_name [string totitle $analysis_type]

      # 获取有关所有时钟域的信息
      set clock_domain_info_list [get_clock_domain_info -${analysis_type}]

      # 对所有时钟域进行遍历,拉取具有负裕量的
      # 所有时钟域
      foreach domain_info $clock_domain_info_list {

         # domain_info 包含时钟名称、裕量及其 TNS。
         # 提取这些时钟域。      
         foreach { clock_name slack endpoint_tns edge_tns } $domain_info { break }

         # 如果裕量为负,在表中将要报告的信息
         # 合并成一行
         if { 0 > $slack } {
            $failing_paths_matrix add row [list $slack $endpoint_tns $clock_name \
               $operating_conditions_display_name $analysis_display_name]
         }
      }
      # 对特定时序分析(建立时间、保持时间等)
      # 的所有时钟域进行遍历
   }
   # 对特定运行条件的所有分析类型
   # 进行遍历
}
# 对所有运行条件进行遍历
# 准备将汇总结果写入文件

# 如果矩阵中有任何行,表明有时序分析失败的路径。
# 我们要在表中打印此信息。如果表中没有
# 任何行,表明没有时序分析失败的路径,请写入成功消息
if { 0 == [$failing_paths_matrix rows] } {

   # 打印快速消息
   post_message "There are no clock domains failing timing"

   # 如果打开文件时出错,打印此
   # 消息。否则,提示没有时序分析失败的域
   if { [catch { open $output_file_name w } fh] } {
      post_message -type error "Couldn't open file: $fh"
   } else {   
      puts $fh "There are no clock domains failing timing"
      catch { close $fh }
   }
} else {
   # 对矩阵行进行排序,使最差裕量位于第一行
   $failing_paths_matrix sort rows -increasing 0

   # 插入标题行
   $failing_paths_matrix insert row 0[list "Slack" "End Point TNS" "Clock" \
      "Operating conditions" "Timing analysis" ]   

   # 需要定义一个样式,以便在表中打印结果
   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 5 style basicrpt
   for { set col 0 } { $col < [r columns]} { incr col } {
      r pad $col both " "
   }
   post_message "Clock domains failing timing\n[r printmatrix $failing_paths_matrix]"

   # 将报告保存到一个文件
   if { [catch { open $output_file_name w } fh] } {
      post_message -type error "Couldn't open file: $fh"   
   } else {
      puts $fh "Clock domains failing timing"
      r printmatrix2channel $failing_paths_matrix $fh
      catch { close $fh }
   }
}