Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion projects/adrv9361z7035/ccbob_cmos/system_project.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
source ../../../scripts/adi_env.tcl
source $ad_hdl_dir/projects/scripts/adi_project_xilinx.tcl
source $ad_hdl_dir/projects/scripts/adi_board.tcl
set ADI_POST_ROUTE_POD_PRE_SCRIPT [file normalize $ad_hdl_dir/projects/scripts/route_design.tcl]
set ADI_POST_ROUTE_SCRIPT [file normalize $ad_hdl_dir/projects/scripts/auto_timing_fix_xilinx.tcl]

adi_project_create adrv9361z7035_ccbob_cmos 0 {} "xc7z035ifbg676-2L"
adi_project_files adrv9361z7035_ccbob_cmos [list \
Expand Down
2 changes: 1 addition & 1 deletion projects/adrv9361z7035/ccbob_lvds/system_project.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
source ../../../scripts/adi_env.tcl
source $ad_hdl_dir/projects/scripts/adi_project_xilinx.tcl
source $ad_hdl_dir/projects/scripts/adi_board.tcl
set ADI_POST_ROUTE_POD_PRE_SCRIPT [file normalize $ad_hdl_dir/projects/scripts/route_design.tcl]
set ADI_POST_ROUTE_SCRIPT [file normalize $ad_hdl_dir/projects/scripts/auto_timing_fix_xilinx.tcl]

adi_project_create adrv9361z7035_ccbob_lvds 0 {} "xc7z035ifbg676-2L"
adi_project_files adrv9361z7035_ccbob_lvds [list \
Expand Down
2 changes: 1 addition & 1 deletion projects/adrv9361z7035/ccfmc_lvds/system_project.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
source ../../../scripts/adi_env.tcl
source $ad_hdl_dir/projects/scripts/adi_project_xilinx.tcl
source $ad_hdl_dir/projects/scripts/adi_board.tcl
set ADI_POST_ROUTE_POD_PRE_SCRIPT [file normalize $ad_hdl_dir/projects/scripts/route_design.tcl]
set ADI_POST_ROUTE_SCRIPT [file normalize $ad_hdl_dir/projects/scripts/auto_timing_fix_xilinx.tcl]

adi_project_create adrv9361z7035_ccfmc_lvds 0 {} "xc7z035ifbg676-2L"
adi_project_files adrv9361z7035_ccfmc_lvds [list \
Expand Down
2 changes: 1 addition & 1 deletion projects/adrv9364z7020/ccbob_cmos/system_project.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
source ../../../scripts/adi_env.tcl
source $ad_hdl_dir/projects/scripts/adi_project_xilinx.tcl
source $ad_hdl_dir/projects/scripts/adi_board.tcl
set ADI_POST_ROUTE_POD_PRE_SCRIPT [file normalize $ad_hdl_dir/projects/scripts/route_design.tcl]
set ADI_POST_ROUTE_SCRIPT [file normalize $ad_hdl_dir/projects/scripts/auto_timing_fix_xilinx.tcl]

adi_project_create adrv9364z7020_ccbob_cmos 0 {} "xc7z020clg400-1"
adi_project_files adrv9364z7020_ccbob_cmos [list \
Expand Down
2 changes: 1 addition & 1 deletion projects/adrv9364z7020/ccbob_lvds/system_project.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
source ../../../scripts/adi_env.tcl
source $ad_hdl_dir/projects/scripts/adi_project_xilinx.tcl
source $ad_hdl_dir/projects/scripts/adi_board.tcl
set ADI_POST_ROUTE_POD_PRE_SCRIPT [file normalize $ad_hdl_dir/projects/scripts/route_design.tcl]
set ADI_POST_ROUTE_SCRIPT [file normalize $ad_hdl_dir/projects/scripts/auto_timing_fix_xilinx.tcl]

adi_project_create adrv9364z7020_ccbob_lvds 0 {} "xc7z020clg400-1"
adi_project_files adrv9364z7020_ccbob_lvds [list \
Expand Down
177 changes: 129 additions & 48 deletions projects/scripts/auto_timing_fix_xilinx.tcl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
###############################################################################
## Copyright (C) 2025 Analog Devices, Inc. All rights reserved.
### SPDX short identifier: ADIBSD
## SPDX short identifier: ADIBSD
###############################################################################
# This script attempts to automatically fix timing violations after routing
# using phys_opt_design. It will make multiple attempts up to a maximum number
Expand All @@ -13,8 +13,98 @@
# in nanoseconds. For example, a threshold of -1.0 means that only violations
# where "0 > WNS > -1.0 ns" will be automatically fixed.
#
puts "INFO: starting auto timing fix (ATF)..."
set attempt 0
# If after all ATF attempts a HOLD violation persists, route_design is called
# and the ATF loop is re-run.
#

# ATF loop function
# Arguments:
# prefix - string prefix for checkpoint and log file names
# max_attempts - maximum number of fix attempts
# wns_threshold - WNS threshold for automatic fix (should be negative)
# Returns a list: {status final_wns delay_type attempts_made}
# status: "success", "failure", "no_paths", "no_violations", "threshold_exceeded", "unknown_type"
proc run_atf_loop {prefix max_attempts wns_threshold} {
set attempt 0
set status "unknown"
set final_wns 0.0

write_checkpoint -force "${prefix}_before_system_top_placed.dcp"

while {$attempt < $max_attempts} {
# Get the single worst timing path object in the design
set worst_path [get_timing_paths -nworst 1 -max_paths 1 -delay_type min_max]
if {[llength $worst_path] == 0} {
set status "no_paths"
break
}
set wns [get_property SLACK $worst_path]
set delay_type [get_property DELAY_TYPE $worst_path] ;# Returns "max" for Setup, "min" for Hold

if {$wns >= 0.0} {
set status "success"
set final_wns $wns
break
}

# Check if autofix should be attempted based on WNS threshold
if {$wns > $wns_threshold} {
incr attempt
puts "INFO: ATF: \[$prefix\] WNS = ${wns} ns of type $delay_type. Attempting automatic fix (${attempt} of ${max_attempts})."
report_timing_summary -delay_type min_max -max_paths 5 -nworst 1 -file "${prefix}_${attempt}_before_timing_summary.txt"
} else {
set status "threshold_exceeded"
set final_wns $wns
break
}

# Attempt fix via phys_opt_design
if {$delay_type eq "min"} {
phys_opt_design -hold_fix
} elseif {$delay_type eq "max"} {
phys_opt_design
} else {
puts "ERROR: ATF: \[$prefix\] Unknown path type '${delay_type}'. Aborting automatic fix."
set status "unknown_type"
set final_wns $wns
break
}

# Update final values after each attempt
set final_wns $wns
}

# Get final timing status after loop
set worst_path [get_timing_paths -nworst 1 -max_paths 1 -delay_type min_max]
if {[llength $worst_path] > 0} {
set final_wns [get_property SLACK $worst_path]
set delay_type [get_property DELAY_TYPE $worst_path]
if {$final_wns >= 0.0} {
set status "success"
}
}

report_timing_summary -delay_type min_max -max_paths 5 -nworst 1 -file "${prefix}_${attempt}_final_timing_summary.txt"

# Write appropriate checkpoint based on status
if {$status eq "success"} {
puts "INFO: ATF: \[$prefix\] Auto Timing Fix SUCCESS after ${attempt} attempts - final WNS is ${final_wns} ns."
write_checkpoint -force "${prefix}_success_system_top_placed.dcp"
} elseif {$status eq "no_paths"} {
puts "ERROR: ATF: \[$prefix\] No constrained timing paths found."
} elseif {$status eq "threshold_exceeded"} {
puts "WARNING: ATF: \[$prefix\] WNS (${final_wns} ns) exceeds threshold (${wns_threshold} ns). Automatic fix aborted."
write_checkpoint -force "${prefix}_aborted_system_top_placed.dcp"
} else {
puts "WARNING: ATF: \[$prefix\] Auto Timing Fix FAILURE after ${attempt} attempts - final WNS is ${final_wns} ns."
write_checkpoint -force "${prefix}_failure_system_top_placed.dcp"
}

return [list $status $final_wns $delay_type $attempt]
}

# Main script execution --------------------------------------------------------
puts "INFO: starting Auto Timing Fix (ATF)..."

# Set default values if not provided
if {![info exists ADI_AUTOFIX_WNS_THRESHOLD]} {
Expand All @@ -26,56 +116,47 @@ if {![info exists ADI_AUTOFIX_MAX_ATTEMPTS]} {
puts "INFO: ATF: ADI_AUTOFIX_MAX_ATTEMPTS not set, using default of $ADI_AUTOFIX_MAX_ATTEMPTS"
}

write_checkpoint -force "AutoTimingFix_before_system_top_placed.dcp"
while {$attempt < $ADI_AUTOFIX_MAX_ATTEMPTS} {
# Get the single worst timing path object in the design
set worst_path [get_timing_paths -nworst 1 -max_paths 1 -delay_type min_max]
if {[llength $worst_path] == 0} { break } ; # No paths found
# Run first stage of ATF
puts "INFO: ATF: Starting Stage 1..."
set result [run_atf_loop "ATF_Stage1" $ADI_AUTOFIX_MAX_ATTEMPTS $ADI_AUTOFIX_WNS_THRESHOLD]

# Check if we need to call route_design and retry
# Only do this if:
# 1. Timing was not fixed
# 2. The remaining violation is HOLD type (delay_type == "min")
#
# NOTE: This route_design workaround addresses hold timing issues that appear in
# Vivado 2024.x/2025.x where phys_opt_design -hold_fix alone is insufficient.
# This remedy was suggested by an AMD employee through the Xilinx forums.
# References:
# https://adaptivesupport.amd.com/s/question/0D5Pd00000pVOyuKAG/unexpected-hold-errors-when-moving-to-vivado-20251?language=en_US
# https://adaptivesupport.amd.com/s/question/0D5Pd0000153gqkKAA/persistent-hold-timing-violations-after-upgrading-to-vivado-2025x-physoptdesign-holdfix-ineffective?language=en_US
#
# Get the single worst timing path object in the design
set worst_path [get_timing_paths -nworst 1 -max_paths 1 -delay_type min_max]
if {[llength $worst_path] > 0} {
set wns [get_property SLACK $worst_path]
if {${wns} >= 0.0} { break } ; # No violations remain
set delay_type [get_property DELAY_TYPE $worst_path] ;# Returns "max" for Setup, "min" for Hold
# Check if autofix should attempt based on WNS threshold
if {$wns > $ADI_AUTOFIX_WNS_THRESHOLD} {
incr attempt
puts "INFO: ATF: WNS = ${wns} ns of type $delay_type. Attempting automatic fix (${attempt} of ${ADI_AUTOFIX_MAX_ATTEMPTS})."
report_timing_summary -delay_type min_max -max_paths 5 -nworst 1 -file "AutoTimingFix_${attempt}_before_timing_summary.txt"
} else {
break ; # Abort automatic fix due to WNS threshold
}
# Attempt fix via phys_opt_design
if {$delay_type eq "min"} {
phys_opt_design -hold_fix
} elseif {$delay_type eq "max"} {
phys_opt_design
} else {
puts "ERROR: ATF: Unknown path type '${delay_type}'. Aborting automatic fix."
break
if {$wns < 0.0} {
if {$delay_type eq "min"} {
puts "INFO: ATF: HOLD violation persists after Stage 1. Calling route_design (Vivado 2024.x/2025.x workaround)..."
route_design
puts "INFO: ATF: route_design completed. Starting Stage 2..."
set result [run_atf_loop "ATF_Stage2" $ADI_AUTOFIX_MAX_ATTEMPTS $ADI_AUTOFIX_WNS_THRESHOLD]
}
}
}

report_timing_summary -delay_type min_max -max_paths 5 -nworst 1 -file "AutoTimingFix_${attempt}_final_timing_summary.txt"

# Print a final report
if {[llength $worst_path] == 0} {
# Loop broke early due to no paths found
puts "ERROR: ATF: No constrained timing paths found. Exiting."
} elseif {${attempt} == 0 && ${wns} >= 0.0} {
# Loop broke early due to no violations on first check
puts "INFO: ATF: No timing violations detected on first check. No action required."
} else {
# Loop broke after at least one attempt
set worst_path [get_timing_paths -nworst 1 -max_paths 1 -delay_type min_max]
set final_wns [get_property SLACK $worst_path]
if {$final_wns >= 0} {
puts "INFO: ATF: auto timing fix SUCCESS after ${attempt} attempts - final WNS is ${final_wns} ns."
write_checkpoint -force "AutoTimingFix_success_system_top_placed.dcp"
} elseif {$final_wns <= $ADI_AUTOFIX_WNS_THRESHOLD} {
puts "WARNING: ATF: WNS (${wns} ns) exceeds threshold (${ADI_AUTOFIX_WNS_THRESHOLD} ns). Automatic fix aborted."
write_checkpoint -force "AutoTimingFix_aborted_system_top_placed.dcp"
# Print final summary for Jenkins pipeline
set worst_path [get_timing_paths -nworst 1 -max_paths 1 -delay_type min_max]
if {[llength $worst_path] > 0} {
set wns [get_property SLACK $worst_path]
set delay_type [get_property DELAY_TYPE $worst_path] ;# Returns "max" for Setup, "min" for Hold
puts "INFO: ATF: final WNS is ${wns} ns of type ${delay_type}."
if {$wns < 0.0} {
puts "WARNING: ATF: Auto Timing Fix FAILURE. Timing closure is NOT achieved."
} else {
puts "WARNING: ATF: auto timing fix FAILURE after ${attempt} attempts - final WNS is ${final_wns} ns."
write_checkpoint -force "AutoTimingFix_failure_system_top_placed.dcp"
puts "INFO: ATF: Auto Timing Fix SUCCESS. Timing closure IS achieved."
}
}

puts "INFO: auto timing fix (ATF) finished."
puts "INFO: ATF: Auto Timing Fix finished."
7 changes: 0 additions & 7 deletions projects/scripts/route_design.tcl

This file was deleted.