📄 report_failing.tcl
字号:
# ***************************************************************
# ***************************************************************
#
# Script used to write out a report on all failing paths
# for each Clock Setting (i.e. clock requirement)
# The report shows the source register, destination register,
# required delay, actual delay and slack together with the
# delay path between its source and destination
#
# This script is almost equivalent to doing a "List Path" command
# on every failed path from the GUI report window.
#
# ***************************************************************
# ***************************************************************
package require ::quartus::advanced_timing
package require ::quartus::report
# ----------------------------------------------------------------
#
proc build_names_db {} {
#
# Description: The Timing Analysis Netlist is based on node IDs
# However, the report panels are based on node names
# This function builds map that we can use to go from a node name
# to a node ID
#
# ----------------------------------------------------------------
global node_id
puts " Building names database"
# Build a map from a register string name to a register node ID
set reg_collection [ REPLACE_WITH_GET_NODES_COMMAND -type reg ]
foreach_in_collection node $reg_collection {
set reg_name [ REPLACE_WITH_NODE_INFORMATION_COMMAND -info name $node]
puts " $reg_name"
set node_id($reg_name) $node
}
puts " Done Building names database"
}
# ----------------------------------------------------------------
#
proc report_failing_paths { project_name out_file } {
#
# Description: Based on the "Clock Requirement" report panels,
# display an expanded report on all failing paths (negative slack)
# The function has the following steps:
# 1.- Calls function to builds a map between node names and node IDs
# 2.- Load report database for project_name
# 3.- Finds all "Clock Setup" report panels
# 4.- For each panel, it checks if the slack is negative
# 5.- If the slack is negative, it creates a report on the path
# which include src and dst node names, required and actual delays
# and the critical path between the src and dst.
# The report is written out to out_file
# 6.- Unloads report database
#
# ----------------------------------------------------------------
global node_id q_args
# Build map from register name to register node id
# This is needed as all Timing Analysis commands work on node ids
build_names_db
# We are going to use the report window to find all failed paths
load_report $project_name
# Get list of all report file panels
set panel_list [ REPLACE_WITH_REPORT_PANELS_COMMAND ]
foreach panel $panel_list {
# See if this is a clock requirement panel
if [string match "*Clock Setup*" $panel] {
puts $out_file "--------------------------------------------------------------"
puts $out_file "--> $panel"
puts $out_file "--------------------------------------------------------------"
# The clock report panel should have the following format
# Col0: Slack
# Col1: Actual fmax (period)
# Col2: Source Name
# Col3: Destination Name
# Col4: Source Clock Name
# Col5: Destination Clock Name
# Col6: Required Setup Relationship
# Col7: Required Longest register-to-register delay
# Col8: Actual Longest register-to-register delay
set num_rows [get_number_of_rows $panel]
set row 1
while { $row < $num_rows } {
set row_data [ REPLACE_WITH_REPORT_ROW_COMMAND -row $row $panel]
set slack [lindex $row_data 0]
# Remove "ns" from string
set int_slack [lindex $slack 0]
if { $slack < 0 } {
set actual [lindex $row_data 1]
set src_reg [lindex $row_data 2]
set dst_reg [lindex $row_data 3]
set required [lindex $row_data 6]
puts $out_file "Source Register : $src_reg"
puts $out_file "Destination Register : $dst_reg"
puts $out_file "Required P2P delay : $required"
puts $out_file "Actual P2P delay : $actual"
puts $out_file "Slack : $slack"
# Get paths between SRC and DST
if [catch {get_delay_path -from $node_id($src_reg) -to $node_id($dst_reg) -type longest} delay_path ] {
puts stderr "Error: No path found from $src_reg to $dst_reg"
} else {
puts $out_file "Longest P2P delay path :"
foreach element $delay_path {
set element_node [lindex $element 0]
set element_delay [lindex $element 1]
puts $out_file "\t$element_delay - [get_timing_node_info -info location $element_node] - [get_timing_node_info -info name $element_node]"
}
}
puts $out_file "---------------------------------------------------"
} else {
# We are done with not-met requirements. Just break
puts "Found [expr { $row - 1}] failing paths"
set row $num_rows
}
incr row
}
}
}
# Unload report
unload_report $project_name
}
# ----------------------------------------------------------------
#
proc main {} {
#
# Description: Like any other C program, this is the entry point
# The following steps are executed:
# 1.- Get project name from argument list
# 2.- Open such project
# 3.- Runs Timing Analysis
# 4.- Calls function to generate report file
# 5.- closes project
#
# ----------------------------------------------------------------
global q_args
# Get arguments to the script from predefined Quartus variable
set argc [llength $q_args]
if { $argc < 1 } {
puts stderr "USAGE: quartus_tan -t report_failing.tcl <project_name>"
exit -1
}
set project_name [lindex $q_args 0]
puts "Finding all failing reg-to-reg paths in project: $project_name"
if [project_exists $project_name] {
project_open $project_name
# Run Timing Analysis
if [catch {create_timing_netlist} tan_result] {
puts stderr "ERROR: Couldn't create timing netlist\n$tan_result"
exit -1
}
create_p2p_delays
puts "Timing Analysis is done"
# Write a report on failing paths
set report_file [open "${project_name}.paths" w]
report_failing_paths $project_name $report_file
close $report_file
puts "Generated report file: ${project_name}.paths\n"
project_close
} else {
puts stderr "ERROR: Project does not exist"
exit -1
}
}
main
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -