Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Copyright 2015, ARM Limited
- # All rights reserved.
- #----------------------------------------------------------------------------------------
- # Rubix SignOff Infrastructure
- #
- # File Content : Rubix Custom Commands (tcl scripts)
- # EDA Tool : Synopsys, PrimeTime
- # Date : 22-June-2015
- # Author : Ramnath Swamy
- # Company : ARM Ltd
- #
- #----------------------------------------------------------------------------------------
- ###########################################################################################
- # Main Procedures
- ###########################################################################################
- echo "RM-Info: Starting - Procs Script"
- echo " [info script]\n"
- #========================================================================================
- # Proc Type 1: Procs for STA Review
- #========================================================================================
- #----------------------------------------------------------------------------------------
- # Check For Un-Constrained Endpoints
- #----------------------------------------------------------------------------------------
- proc rbx_report_unconstrained_endpoints { args } {
- #.......................................................
- # Print help and quit
- #.......................................................
- if {[lsearch $args "-help"] > -1} {
- puts "rbx_report_unconstrained_endpoints -output <output_file> -remove_clocks <list_of_clocks> -omit_insts_strings <list_of_instance_name_strings>"
- return
- }
- #.......................................................
- # Arguments Handling
- #.......................................................
- # Default Argument Values
- set output ""
- set remove_clocks ""
- set omit_insts_strings ""
- # Check and get the values of the arguments
- if {[llength $args] != 2 && [llength $args] != 4 && [llength $args] != 6} {
- puts "\nRubix-Error: Missing or too many options given for rbx_report_unconstrained_endpoints command.\n"; return
- }
- foreach a $args {
- # Check if Wrong option is used
- if {[string match "-*" $a] && $a != "-output" && $a != "-remove_clocks" && $a != "-omit_insts_strings" } {
- puts "\nRubix-Error: Option $a is not valid for rbx_report_unconstrained_endpoints command.\n"; return
- }
- # Get the values of the options
- if {$a == "-output"} { set output [rbx_value -output $args] }
- if {$a == "-remove_clocks"} { set remove_clocks [rbx_value -remove_clocks $args] }
- if {$a == "-omit_insts_strings"} { set omit_insts_strings [rbx_value -omit_insts_strings $args] }
- }
- #.......................................................
- # Execute the main procedure
- #.......................................................
- # Suppress messages
- suppress_message "ATTR-1"
- global sh_product_version
- # remove_clocks - These could be for e.g. dft clocks when the check is done
- # to see all endpoints are constrained wrt functional clocks
- # Create Report file
- redirect $output {puts [format "%-10s" "***********************************************************************"]}
- redirect -append $output {puts [format "%-10s %-15s" " Rubix Custom Report" "\n"]}
- redirect -append $output {puts [format "%-10s %-15s" " Report" ": rbx_report_unconstrained_endpoints"]}
- if { $remove_clocks != ""} {
- redirect -append $output {puts [format "%-10s %-15s" " " " -remove_clocks \$removed_clocks"]}}
- if { $omit_insts_strings != ""} {
- redirect -append $output {puts [format "%-10s %-15s" " " " -omit_insts_strings \$omit_instance_strings"]}}
- redirect -append $output {puts [format "%-10s %-15s" " Design" ": [get_attribute [get_design] full_name]"]}
- redirect -append $output {puts [format "%-10s %-15s" " Version" ": $sh_product_version"]}
- redirect -append $output {puts [format "%-10s %-15s" " Date" ": [date]"]}
- redirect -append $output {puts [format "%-10s" "***********************************************************************"]}
- set all_omited_dpins_cnt 0
- set all_omited_cgpins_cnt 0
- # Remove clocks if asked to
- if {[llength $remove_clocks] > 0} {
- # Print clocks that were removed before producing this report
- redirect -append $output {puts " Unconstrained pins are generated after removing the following clocks"}
- redirect -append $output {puts "\n \$removed_clocks ="}
- foreach rclk $remove_clocks {
- remove_clock $rclk
- set remove_clocks [concat $remove_clocks $rclk]
- redirect -append $output {puts " $rclk"}
- }
- redirect -append $output {puts "***********************************************************************"}
- }
- set remove_clocks [lsort -unique $remove_clocks]
- # Omit Instances if asked to
- if {[llength $omit_insts_strings] > 0} {
- # Print instance strings that are omitted
- redirect -append $output {puts " All the instances with the following string(s) are omitted from the analysis"}
- redirect -append $output {puts "\n \$omit_instance_strings ="}
- foreach oinst $omit_insts_strings {
- redirect -append $output {puts " $oinst"}
- }
- redirect -append $output {puts "***********************************************************************"}
- }
- # Print clocks in the design
- redirect -append $output {puts "\n Unconstrained pins are generated with the following clocks in the session"}
- foreach clk [get_object_name [all_clocks]] {
- redirect -append $output {puts " $clk"}
- }
- redirect -append $output {puts "***********************************************************************"}
- # Get all the timing endpoints
- set data_inputs_all [get_pins -hier * -filter "is_data_pin==true"]
- set clk_gate_enables_all [get_pins -hier * -filter "is_clock_gating_pin==true && is_clock_pin==false"]
- # For Hierarchical Analysis
- foreach omit_inst $omit_insts_strings {
- set omit_insts_dinputs [get_pins -hier * -filter "is_data_pin==true && full_name =~ *$omit_inst*"]
- set data_inputs_all [remove_from_collection $data_inputs_all $omit_insts_dinputs]
- set omit_insts_cginputs [get_pins -hier * -filter "is_clock_gating_pin==true && full_name =~ *$omit_inst*"]
- set clk_gate_enables_all [remove_from_collection $clk_gate_enables_all $omit_insts_cginputs]
- set all_omited_dpins_cnt [expr $all_omited_dpins_cnt + [sizeof_collection $omit_insts_dinputs]]
- set all_omited_cgpins_cnt [expr $all_omited_cgpins_cnt + [sizeof_collection $omit_insts_cginputs]]
- }
- set data_inputs [get_object_name $data_inputs_all]
- set clk_gate_enables [get_object_name $clk_gate_enables_all]
- # Print un-constrained pins
- redirect -append $output {puts [format "%-25s %-50s" "\nUnconstrained Reason" "Unconstrained Pin"]}
- redirect -append $output {puts [format "%-25s" "-----------------------------------------------------------------------"]}
- foreach pin "$data_inputs $clk_gate_enables" {
- if {[sizeof_collection [get_timing_paths -to [get_pins $pin]]] < 1} {
- set unconstr_reason [get_attribute [get_pins $pin] dominant_exception]
- if {$unconstr_reason==""} {set unconstr_reason "Not Known"}
- redirect -append $output {puts [format "%-25s %-50s" "$unconstr_reason" "$pin"]}
- }
- }
- redirect -append $output {puts "\n\n***********************************************************************"}
- redirect -append $output {puts " Summary:"}
- redirect -append $output {puts " No of Data Endpoints unverified / verified = $all_omited_dpins_cnt/[llength $data_inputs]"}
- redirect -append $output {puts " No of ClkGate Endpoints unverified / verified = $all_omited_cgpins_cnt/[llength $clk_gate_enables]"}
- redirect -append $output {puts "***********************************************************************"}
- redirect -append $output {puts "\n1\n"}
- # Enable the suppressed messages
- unsuppress_message "ATTR-1"
- }
- #----------------------------------------------------------------------------------------
- # Proc Check if Shift Enable pins are controlled only by DFT Controller
- # If a SE pin of a FF is not controlled by DFT controller then the FF might be used
- # for Functional purpose.
- #----------------------------------------------------------------------------------------
- proc rbx_report_functional_si_endpoints { \
- scan_enable_control_pin
- { fmt csv } \
- } {
- set t1 [clock seconds]
- set all_se_pins [get_pins -hier */SE]
- # Print header
- puts [format "%-20s" "#*********************************************************************************************"]
- puts [format "%-30s %-15s" "#Report" ": rbx_report_functional_si_endpoints"]
- puts [format "%-30s %-15s" "#DFT Scan enable control pin" ": $scan_enable_control_pin"]
- puts [format "%-20s" "#*********************************************************************************************"]
- if { $fmt == "csv" } {
- puts [format "\nShift Enable Pin,Driver Pin"]
- } else {
- puts [format "%-200s %-50s" "Shift Enable Pin" " Driving Pin"]
- }
- # Check each SE pin of sequential cell
- suppress_message UITE-416
- foreach_in_collection pin $all_se_pins {
- set pin [get_attr [get_pins $pin] full_name]
- set driver [get_attr [get_attribute [get_timing_path -to $pin] startpoint] full_name]
- if { $driver != "$scan_enable_control_pin" } {
- puts [format "%-200s %-50s" "$pin" " $driver"]
- }
- }
- unsuppress_message UITE-416
- puts "\n1\n"
- set t2 [clock seconds]
- echo "\n# rbx_report_functional_si_endpoints RUNTIME: [rbx_get_runtime $t1 $t2] "
- }
- #----------------------------------------------------------------------------------------
- # Report a pba version of the 'report_constraint -all_violators' report for both setup and hold
- #----------------------------------------------------------------------------------------
- proc rbx_report_pba_timing_all_endpoints { args } {
- #.......................................................
- # Print help and quit
- #.......................................................
- if {[lsearch $args "-help"] > -1} {
- puts "rbx_report_pba_timing_all_endpoints -check_type \[setup | hold\] -output \[path/to/filename\] -overwrite"
- return
- }
- #.......................................................
- # Arguments Handling
- #.......................................................
- upvar pt_shell_mode pt_shell_mode
- upvar pba_recalculate_full_path pba_recalculate_full_path
- upvar pba_enable_path_based_physical_exclusivity pba_enable_path_based_physical_exclusivity
- # Default Argument Values
- set check_type "setup"
- set report_file ""
- set overwrite 0
- # Check and get the values of the arguments
- if {[llength $args] != 2 && [llength $args] != 4 && [llength $args] != 5 } {
- puts "\nRubix-Error: Missing or too many options given for rbx_report_pba_timing_all_endpoints command.\n"; return
- }
- foreach a $args {
- # Check if wrong option is used
- if {[string match "-*" $a] && $a != "-check_type" && $a != "-output" && $a != "-overwrite"} {
- puts "\nRubix-Error: Option $a is not valid for rbx_report_pba_timing_all_endpoints command.\n"; return
- }
- # Get the values of the options
- if {$a == "-check_type"} { set check_type [rbx_value -check_type $args] }
- if {$a == "-output"} { set report_file [rbx_value -output $args] }
- if {$a == "-overwrite"} { set overwrite 1 }
- }
- #.......................................................
- # Checks before starting execution
- #.......................................................
- if {[file exists $report_file] && $overwrite == 0} {
- puts "\nRubix-Error: Output file already exists."
- puts " Move or delete the exisitng file, use a different output file, or use -overwrite.\n"
- return
- }
- if {$pt_shell_mode != "primetime_master"} {
- puts "\nRubix-Error: This is a DMSA command.\n"
- return
- }
- #.......................................................
- # Execute the main procedure
- #.......................................................
- set t1 [clock seconds]
- set rpt [open "$report_file" w+]
- # Make sure all loaded scenarios are active
- current_scenario -all
- # create a variable in each of the scenarios containing the check type, then pull it in
- remote_execute { set scenario_check_type $check_type($standalone_scenario) }
- get_distributed_variables scenario_check_type
- # initialize list
- set scenario_list ""
- # populate list
- foreach scenario [get_attribute [current_scenario] full_name] {
- if {$scenario_check_type($scenario) == $check_type} {
- lappend scenario_list $scenario
- }
- }
- # set active scenarios
- current_scenario $scenario_list
- if {[llength $scenario_list] == 0} {
- puts "\nRubix-Error: No scenarios loaded which match the required check_type.\n"
- return
- }
- # Print header
- puts $rpt [format "%-20s" "#*********************************************************************************************"]
- puts $rpt [format "%-30s %-15s" "# Report" ": rbx_report_pba_timing_all_endpoints"]
- puts $rpt [format "%-30s %-15s" "# Check_type" ": $check_type"]
- puts $rpt [format "%-30s %-15s" "# Scenarios" ": [llength $scenario_list]"]
- foreach scenario $scenario_list { puts $rpt [format "%-15s %-15s" "#" "$scenario"] }
- puts $rpt [format "%-45s %-15s" "# pba_recalculate_full_path" ": $pba_recalculate_full_path"]
- if {!$pba_recalculate_full_path} { puts $rpt [format "%-15s %-15s" "#" "Consider setting true for reducing pessimism at the expense of runtime"] }
- puts $rpt [format "%-45s %-15s" "# pba_enable_path_based_physical_exclusivity" ": $pba_enable_path_based_physical_exclusivity"]
- if {!$pba_enable_path_based_physical_exclusivity} { puts $rpt [format "%-15s %-15s" "#" "Consider setting true for reducing pessimism at the expense of runtime"] }
- puts $rpt [format "%-20s" "#*********************************************************************************************\n"]
- remote_execute { set path_groups [get_object_name [get_path_groups *]] }
- get_distributed_variables path_groups -merge_type list
- switch $check_type {
- setup {
- set delay_type max
- }
- hold {
- set delay_type min
- }
- }
- echo "Rubix-Info: [llength $path_groups] path groups to report"
- echo " If this report takes too long, consider fixing timing first"
- # Report for all path groups
- set i 1
- foreach pg $path_groups {
- echo " Reporting path_group $i of [llength $path_groups]"
- incr i
- puts $rpt "+-------------------------------------------------+"
- puts $rpt "| Group $pg "
- puts $rpt "+-------------------------------------------------+"
- set timing_path_collection \
- [get_timing_paths -slack_lesser_than 0 \
- -delay_type $delay_type \
- -pba_mode ex \
- -max_paths 1000 \
- -group $pg \
- -attributes {slack endpoint} \
- ]
- if {[sizeof_collection $timing_path_collection] > 0} {
- puts $rpt [format "\t%-8s %-10s %-10s" "Slack" "Scenario" "Endpoint"]
- foreach_in_collection timing_path $timing_path_collection {
- puts $rpt [format "\t%-8.3f %-40s %-10s" \
- [get_attribute $timing_path slack] \
- [get_attribute $timing_path scenario_name] \
- [get_attribute [get_attribute $timing_path endpoint] full_name] \
- ]
- }
- } else {
- puts $rpt "\tNo failing paths"
- }
- }
- close $rpt
- #.......................................................
- # End of proc
- #.......................................................
- set t2 [clock seconds]
- echo "\n# rbx_report_functional_si_endpoints RUNTIME: [rbx_get_runtime $t1 $t2] "
- }
- #========================================================================================
- # Proc Type 2: Procs to check timing quality of the design
- #========================================================================================
- #----------------------------------------------------------------------------------------
- # Proc to check if clock network has multi-vt
- #----------------------------------------------------------------------------------------
- proc rbx_check_clock_cell_type { args } {
- #.......................................................
- # Print help and quit
- #.......................................................
- if {[lsearch $args "-help"] > -1} {
- puts "rbx_check_clock_cell_type -cts_lib_list cts_lib_list [-output_style csv | table]"
- return
- }
- #.......................................................
- # Arguments Handling
- #.......................................................
- # Default Argument Values
- set cts_lib_list ""
- set output_style table
- # Check and get the values of the arguments
- if {[llength $args] != 2 && [llength $args] != 4} {
- puts "\nRubix-Error: Missing or too many options given for rbx_check_clock_cell_type command.\n"; return
- }
- foreach a $args {
- # Check if Wrong option is used
- if {[string match "-*" $a] && $a != "-cts_lib_list" && $a != "-output_style"} {
- puts "\nRubix-Error: Option $a is not valid for rbx_check_clock_cell_type command.\n"; return
- }
- # Get the values of the options
- if {$a == "-cts_lib_list"} { set cts_lib_list [rbx_value -cts_lib_list $args] }
- if {$a == "-output_style"} { set output_style [rbx_value -output_style $args] }
- }
- #.......................................................
- # Execute the main procedure
- #.......................................................
- global sh_product_version
- set t1 [clock seconds]
- set all_nets [get_nets -hier *]
- # For printing one lib per line
- foreach clib $cts_lib_list {
- lappend cts_lib_list_stacked "\n\t$clib"
- }
- set cts_lib_list_stacked [string map {\{ "" \} ""} $cts_lib_list_stacked]
- puts [format "%-20s" "*********************************************************************************************"]
- puts [format "%-10s %-15s" " Rubix Custom Report" "\n"]
- puts [format "%-10s %-15s" " Report" ": rbx_check_clock_cell_type"]
- puts [format "%-10s %-15s" " " " -cts_lib_list $cts_lib_list_stacked"]
- puts [format "%-10s %-15s" " " " -output_style $output_style"]
- puts [format "%-10s %-15s" " Design" ": [get_attribute [get_design] full_name]"]
- puts [format "%-10s %-15s" " Version" ": $sh_product_version"]
- puts [format "%-10s %-15s" " Date" ": [date]"]
- puts [format "%-10s" "*********************************************************************************************"]
- switch $output_style {
- table {
- puts [format "%-150s %-20s %-30s" "Cell" " Reference" " Library used Currently"]
- puts [format "%-150s %-20s %-30s" "----" " ---------" " ----------------------"]
- }
- csv {
- puts "Cell,Reference,Library used Currently"
- puts "----,---------,----------------------"
- }
- }
- # Process all nets in the design
- foreach_in_collection net $all_nets {
- set net [get_attribute [get_nets $net] full_name]
- set driver [get_attribute [get_pins -quiet -leaf -of_objects [get_net $net] -filter "direction==out"] full_name ]
- # Extract only the clock nets and get the cells connected to it
- if { [sizeof_collection [get_attribute -quiet [get_pins -quiet $driver] clocks ]] > 0 } {
- set pins [filter_collection [get_pins -leaf -of_objects [get_nets $net]] "is_clock_pin==false"] ; # Ignore if the pin is clock pin (of FF)
- # Get the library name of each cell
- foreach_in_collection pin $pins {
- set cell [get_attribute [get_cells -of_objects [get_pins $pin]] full_name]
- set ref [get_attribute [get_cells -of_objects [get_pins $pin]] ref_name]
- set lib [string map [list "/$ref" ""] [get_attribute [get_lib_cells */$ref] full_name]]
- # Print if lib none of cts_lib_list list
- if { [lsearch $cts_lib_list $lib] < 0 } {
- switch $output_style {
- table { puts [format "%-150s %-20s %-30s" "$cell" " $ref" " $lib"]}
- csv { puts $cell,$ref,$lib"}
- }
- }
- }
- }
- }
- puts "\n1\n"
- set t2 [clock seconds]
- echo "\n# rbx_check_clock_cell_type RUNTIME: [rbx_get_runtime $t1 $t2] "
- }
- #----------------------------------------------------------------------------------------
- # Proc to get average clock latency
- #----------------------------------------------------------------------------------------
- proc rbx_report_average_clock_latency { \
- clocks_list \
- {clock_type launch} \
- {report_file rbx_report_average_clock_latency.rpt} \
- } {
- set t1 [clock seconds]
- set rpt [open "$report_file" w+]
- set rpt_csv [open "${report_file}_csv" w+]
- echo "RM-Info: Caculating average insertion delays of clocks. Results are written into following files."
- echo " [file normalize $report_file] and"
- echo " [file normalize ${report_file}_csv] \n"
- if { $clock_type == "launch" } {
- set lat_type "startpoint_clock_latency"
- } else {
- set lat_type "endpoint_clock_latency"
- }
- suppress_message UITE-416
- foreach f "$rpt $rpt_csv" {
- puts $f [format "%-20s" "#*********************************************************************************************"]
- puts $f [format "%-30s %-15s" "# Report" ": rbx_report_average_clock_latency"]
- puts $f [format "%-30s %-15s" "# Clock type" ": $clock_type"]
- puts $f [format "%-30s" "#---------------------------------------------------------------------------------------------"]
- puts $f [format "%-30s %-15s" "# Note" ": Depending on which clock path (launch/capture) is derated"]
- puts $f [format "%-30s %-15s" "# " " users can choose to measure insertion delay from either "]
- puts $f [format "%-30s %-15s" "# " " paths by setting \"clock_type\" to lauch or capture. "]
- puts $f [format "%-30s" "#*********************************************************************************************"]
- }
- puts $rpt [format "%-15s %-20s %-20s" "Clock" "Average Insertion Delay" " Sinks(ICG not included)"]
- puts $rpt [format "%-15s %-20s %-20s" "-----" "-----------------------" " -----------------------"]
- puts $rpt_csv [format "Clock,Average Insertion Delay,Sinks(ICG not included)"]
- puts $rpt_csv [format "-----,-----------------------,-----------------------"]
- foreach clk $clocks_list {
- set cp_pins [get_attribute -quiet [get_clocks -quiet $clk] clock_network_pins]
- set total_lat 0
- set num 0
- foreach_in_collection p $cp_pins {
- set lat [get_attribute [get_timing_path -from [get_pins $p]] $lat_type]
- if { $lat > 0 } {
- set total_lat [expr $total_lat + $lat]
- incr num
- }
- }
- puts $rpt [format "%-15s %-.2f %-20s" "$clk" "[expr $total_lat / $num]" " $num"]
- puts $rpt_csv [format "$clk,[expr $total_lat / $num],$num"]
- echo " - Finished caculating insertion delay of $clk."
- }
- echo ""
- puts $rpt "\n1\n"
- puts $rpt_csv "\n1\n"
- unsuppress_message UITE-416
- set t2 [clock seconds]
- puts $rpt "\n# rbx_report_average_clock_latency RUNTIME: [rbx_get_runtime $t1 $t2] "
- puts $rpt_csv "\n# rbx_report_average_clock_latency RUNTIME: [rbx_get_runtime $t1 $t2] "
- close $rpt
- close $rpt_csv
- }
- #----------------------------------------------------------------------------------------
- # Proc to get clock nets with Effective coupling capacitance
- #----------------------------------------------------------------------------------------
- proc rbx_report_xtalk_clock_nets { args } {
- #.......................................................
- # Print help and quit
- #.......................................................
- if {[lsearch $args "-help"] > -1} {
- puts "rbx_report_xtalk_clock_nets -ccap_threshold cap_value -omit_clocks clocks_list [-include_position] [-output_style csv | table]"
- return
- }
- #.......................................................
- # Arguments Handling
- #.......................................................
- # Default Argument Values
- set ccap_threshold 0
- set omit_clocks ""
- set include_position 0
- set output_style table
- # Check and get the values of the arguments
- if {[llength $args] < 0 || [llength $args] > 7 } {
- puts "\nRubix-Error: Missing or too many options given for rbx_report_xtalk_clock_nets command.\n"; return
- }
- foreach a $args {
- # Check if Wrong option is used
- if {[string match {-[A-Z|a-y]*} $a] && $a != "-ccap_threshold" && $a != "-include_position" && $a != "-omit_clocks" && $a != "-output_style"} {
- puts "\nRubix-Error: Option $a is not valid for rbx_report_xtalk_clock_nets command.\n"; return
- }
- # Get the values of the options
- if {$a == "-ccap_threshold"} { set ccap_threshold [rbx_value -ccap_threshold $args] }
- if {$a == "-omit_clocks"} { set omit_clocks [rbx_value -omit_clocks $args] }
- if {$a == "-include_position"} { set include_position 1 }
- if {$a == "-output_style"} { set output_style [rbx_value -output_style $args] }
- }
- #.......................................................
- # Execute the main procedure
- #.......................................................
- set t1 [clock seconds]
- global sh_product_version
- global si_enable_analysis
- global xtalk_clk_nets
- global xtalk_clk_nets_values
- set omit_clocks_stacked ""
- set xtalk_clk_nets 0
- set xtalk_clk_nets_values 0
- set ccap_list ""
- if { $si_enable_analysis == "true" } {
- # Get all nets in the design
- set all_nets [get_nets -hier *]
- # For printing one lib per line
- foreach oc $omit_clocks {
- lappend omit_clocks_stacked "\n\t $oc"
- }
- set omit_clocks_stacked [string map {\{ "" \} ""} $omit_clocks_stacked]
- # Print header
- puts [format "%-20s" "*********************************************************************************************"]
- puts [format "%-10s %-15s" " Rubix Custom Report" "\n"]
- puts [format "%-10s %-15s" " Report" ": rbx_report_xtalk_clock_nets"]
- puts [format "%-10s %-15s" " " " -ccap_threshold $ccap_threshold"]
- if { $include_position == 1} {
- puts [format "%-10s %-15s" " " " -include_position"]}
- if { $omit_clocks_stacked != ""} {
- puts [format "%-10s %-15s" " " " -omit_clocks \$omitted_clocks"]}
- puts [format "%-10s %-15s" " " " -output_style $output_style"]
- puts [format "%-10s %-15s" " Design" ": [get_attribute [get_design] full_name]"]
- puts [format "%-10s %-15s" " Version" ": $sh_product_version"]
- puts [format "%-10s %-15s" " Date" ": [date]"]
- puts [format "%-30s" "*********************************************************************************************"]
- if {[llength $omit_clocks] > 0} {
- puts "\n \$omitted_clocks ="
- foreach oclk $omit_clocks {
- puts " $oclk"
- }
- puts [format "%-30s" "*********************************************************************************************"]
- }
- puts [format "%-10s" "# Note: -Violating nets and their ccaps are stored in \"xtalk_clk_nets\" and \"xtalk_clk_nets_values\" tcl lists"]
- if { $include_position == 1 } {
- puts [format "%-30s" "# -Position ranges from 0 to 10. 0 -> leaf ; 10 -> trunk"]
- }
- puts [format "%-30s" "*********************************************************************************************"]
- if { $output_style == "csv" } {
- switch $include_position {
- 0 {puts "\n#Coupling-Cap,CCap %,Agrsr-Count,Driver-Ref-Name,Net,Driver-Name,Clocks"}
- 1 {puts "\n#Coupling-Cap,CCap %,Agrsr-Count,Position,Driver-Ref-Name,Net,Driver-Name,Clocks"}
- }
- } else {
- switch $include_position {
- 0 { puts [format "%-15s %-10s %-20s %-20s %-50s %-50s %-30s" "#Coupling-Cap" " CCap %" " Agrsr-Count" " Driver-Ref-Name" " Net" " Driver-Name" " Clocks"]
- puts [format "%-15s %-10s %-20s %-20s %-50s %-50s %-30s" "#------------" " ------" " -----------" " ---------------" " ---" " -----------" " ------"]}
- 1 { puts [format "%-15s %-10s %-20s %-20s %-20s %-50s %-50s %-30s" "#Coupling-Cap" " CCap %" " Agrsr-Count" "Position" " Driver-Ref-Name" " Net" " Driver-Name" " Clocks"]
- puts [format "%-15s %-10s %-20s %-20s %-20s %-50s %-50s %-30s" "#------------" " ------" " -----------" "--------" " ---------------" " ---" " -----------" " ------"]}
- }
- }
- # Process and print report
- foreach_in_collection net $all_nets {
- set net [get_attribute [get_nets -quiet $net] full_name]
- set driver [get_attribute [get_pins -quiet -leaf -of_objects [get_net $net] -filter "direction==out"] full_name ]
- # Initialise
- set ccap "x"
- set clocks "x"
- set ref_driver "x"
- set aggressor_count "x"
- # Filter out the clock nets and get its ccap, driver
- if { [sizeof_collection [get_attribute -quiet [get_pins -quiet $driver] clocks ]] > 0 } {
- if {$omit_clocks != ""} {
- set clocks [get_attribute [remove_from_collection [get_attribute -quiet [get_pins $driver] clocks] [get_clocks "${omit_clocks}"]] full_name]
- } else {
- set clocks [get_attribute [get_attribute -quiet [get_pins $driver] clocks] full_name]
- }
- set ccap [get_attribute -quiet [get_nets $net] total_effective_coupling_capacitance]
- set ba_ccap [get_attribute -quiet [get_nets $net] ba_capacitance_max]
- set ref_driver [get_attribute -quiet [get_cells -of_objects [get_pins $driver]] ref_name]
- set agrsr_count [get_attribute -quiet [get_nets $net] number_of_effective_aggressors]
- if { $include_position == 1 } {
- set all_leaves [sizeof_collection [get_attribute -quiet [get_clocks -quiet $clocks] clock_network_pins]]
- set current_leaves [sizeof_collection [all_fanout -from $driver -endpoints_only -flat -trace_arcs all]]
- }
- if { $ccap > $ccap_threshold } {
- lappend ccap_list [get_attribute -quiet [get_nets $net] total_effective_coupling_capacitance]
- lappend a_net($ccap) $net
- set a_ba_ccap_pct($net) [expr round(100*$ccap/$ba_ccap)]
- set a_driver($net) $driver
- set a_clocks($net) $clocks
- set a_ref_driver($net) $ref_driver
- set a_agrsr_count($net) $agrsr_count
- if { $include_position == 1 } {
- if {$all_leaves > 0 && $current_leaves > 0} {
- set a_position($net) [expr round(10*$current_leaves/$all_leaves)]
- if { $a_position($net) > 10 } { ; # Due to complex clocking sometimes this number exeeds 10, which is in-correct.
- set a_position($net) not_known_CODE1
- }
- } else {
- set a_position($net) not_known_CODE2 ; # Avoid erroring out when no leaves are found.
- }
- }
- }
- }
- }
- # Sort the ccap values in decending order
- set ccap_list [lsort -unique -decreasing $ccap_list]
- # For each ccap print ccap, net, driver, clocks
- foreach c $ccap_list {
- foreach n $a_net($c) { ; # There can be multiple nets with same ccap
- if { $output_style == "csv" } {
- switch $include_position {
- 0 {puts [format "$c,$a_ba_ccap_pct($n),$a_agrsr_count($n),$a_ref_driver($n),$n,$a_driver($n),$a_clocks($n)"]}
- 1 {puts [format "$c,$a_ba_ccap_pct($n),$a_agrsr_count($n),$a_position($n),$a_ref_driver($n),$n,$a_driver($n),$a_clocks($n)"]}
- }
- } else {
- switch $include_position {
- 0 {puts [format "%-15s %-10s %-20s %-20s %-50s %-50s %-30s" "$c" " $a_ba_ccap_pct($n)" " $a_agrsr_count($n)" " $a_ref_driver($n)" " $n" " $a_driver($n)" " $a_clocks($n)"]}
- 1 {puts [format "%-15s %-10s %-20s %-20s %-20s %-50s %-50s %-30s" "$c" " $a_ba_ccap_pct($n)" " $a_agrsr_count($n)" " $a_position($n)" " $a_ref_driver($n)" " $n" " $a_driver($n)" " $a_clocks($n)"]}
- }
- }
- }
- }
- } else {
- puts "\nRubix-Error: CrossTalk analysis is not enabled. \"set si_enable_analysis true\" before reporting the coupling on clock nets\n"
- }
- puts "\n1\n"
- set t2 [clock seconds]
- echo "\n# rbx_report_xtalk_clock_nets RUNTIME: [rbx_get_runtime $t1 $t2] "
- }
- #----------------------------------------------------------------------------------------
- # Proc to get details of nets reproted in report_si_bottleneck
- #----------------------------------------------------------------------------------------
- proc rbx_report_xtalk_bottlenecks { args } {
- # Processes reports of command report_si_bottleneck
- global sta_path
- #.......................................................
- # Print help and quit
- #.......................................................
- if {[lsearch $args "-help"] > -1} {
- puts "\nrbx_report_xtalk_bottlenecks -si_bottle_neck_rpt_lst <si_bottelnect_report_list> \[-signal_type clock|data|both\]\n"
- return
- }
- #.......................................................
- # Arguments Handling
- #.......................................................
- # Default Argument Values
- set si_bottle_neck_rpt_lst ""
- set signal_type "both"
- # Check and get the values of the arguments
- if {[llength $args] != 2 && [llength $args] != 4} {
- puts "\nRubix-Error: Missing or too many options given for rbx_report_xtalk_bottlenecks command.\n"; return
- }
- foreach a $args {
- # Check if Wrong option is used
- if {[string match {-*} $a] && $a != "-si_bottle_neck_rpt_lst" && $a != "-signal_type"} {
- puts "\nRubix-Error: Option $a is not valid for rbx_report_xtalk_bottlenecks command.\n"; return
- }
- # Get the values of the options
- if {$a == "-si_bottle_neck_rpt_lst"} { set si_bottle_neck_rpt_lst [rbx_value -si_bottle_neck_rpt_lst $args] }
- if {$a == "-signal_type"} { set signal_type [rbx_value -signal_type $args] }
- }
- # Update Needed: Check for -nosplit
- #.......................................................
- # Execute the main procedure
- #.......................................................
- global sh_product_version
- set t1 [clock seconds]
- set net_lst ""
- set file_lst ""
- foreach current_rpt $si_bottle_neck_rpt_lst {
- set rpt [open "$current_rpt" r]
- set start_reading 0
- # Read Each Line for PT Transition Report File
- foreach {line} [split [read $rpt] \n] {
- if {$line != 1} {
- # Remove leading blanks
- set line [string trim $line]
- regsub -all { +} $line {;} l
- # Get each word
- set words [split $l ";"]
- if {[llength $words] != 0} {
- # Start reading after header
- if {$start_reading == 1} {
- set net [lindex $words 0]
- set cost($net) [lindex $words 1]
- lappend cost_lst($net) [lindex $words 1]
- if {[info exists worst_cost($net)] && $cost($net) != ""} {
- set worst_cost($net) [expr $worst_cost($net) + $cost($net)]
- } else {
- set worst_cost($net) $cost($net)
- }
- if {[lsearch $net_lst $net] < 0} {
- lappend net_lst [lindex $words 0]
- }
- if {[info exists scen_count($net)]} {
- incr scen_count($net)
- } else {
- set scen_count($net) 1
- }
- }
- }
- if {[string match "------------------------*" [lindex $words 0]]} {
- set start_reading 1
- }
- }
- }
- }
- foreach n $net_lst {
- lappend worst_cost_lst $worst_cost($n)
- set wc $worst_cost($n)
- if {[sizeof_collection [get_attribute -quiet [get_nets $n] clocks]] > 0} {
- set is_clk_net($n) "true"
- } else {
- set is_clk_net($n) "false"
- }
- if {[info exists nets_of_wc($worst_cost($n))]} {
- lappend nets_of_wc($wc) $n
- lappend costs_of_wc($worst_cost($n)) $cost_lst($n)
- lappend scens_count_of_wc($worst_cost($n)) $scen_count($n)
- } else {
- set nets_of_wc($wc) $n
- set costs_of_wc($worst_cost($n)) $cost_lst($n)
- set scens_count_of_wc($worst_cost($n)) $scen_count($n)
- }
- }
- foreach f $si_bottle_neck_rpt_lst {
- set file_lst "$file_lst\n# $f"
- }
- # For printing one file per line
- foreach clib $si_bottle_neck_rpt_lst {
- lappend si_bottle_neck_rpt_lst_stacked "\n\t\t$clib"
- }
- set si_bottle_neck_rpt_lst_stacked [string map {\{ "" \} ""} $si_bottle_neck_rpt_lst_stacked]
- puts [format "%-20s" "*********************************************************************************************"]
- puts [format "%-10s %-15s" " Rubix Custom Report" "\n"]
- puts [format "%-10s %-15s" " Report" ": rbx_report_xtalk_bottlenecks"]
- puts [format "%-10s %-15s" " " " -si_bottle_neck_rpt_lst $si_bottle_neck_rpt_lst_stacked"]
- puts [format "%-10s %-15s" " " " -signal_type $signal_type"]
- puts [format "%-10s %-15s" " Design" ": [get_attribute [get_design] full_name]"]
- puts [format "%-10s %-15s" " Version" ": $sh_product_version"]
- puts [format "%-10s %-15s" " Date" ": [date]"]
- puts [format "%-10s" "*********************************************************************************************"]
- puts "\n"
- puts [format "%-11s %-18s %-12s %-15s %-20s" "# Is-Clock" "No of occurance" "Worst Cost" "Total Costs" "Net"]
- puts [format "%-11s %-18s %-12s %-15s %-20s" "# --------" "---------------" "----------" "-----------" "---"]
- foreach wc [lsort -decreasing $worst_cost_lst] {
- foreach n $nets_of_wc($wc) {
- if {$signal_type == "clock" && $is_clk_net($n) == "true"} {
- puts [format "%-11s %-18s %-12s %-15s %-20s" " $is_clk_net($n)" "$scen_count($n)" "[rbx_get_biggest $cost_lst($n)]" "[rbx_ladd $cost_lst($n)]" "$n"]
- } elseif {$signal_type == "data" && $is_clk_net($n) == "false"} {
- puts [format "%-11s %-18s %-12s %-15s %-20s" " $is_clk_net($n)" "$scen_count($n)" "[rbx_get_biggest $cost_lst($n)]" "[rbx_ladd $cost_lst($n)]" "$n"]
- } elseif {$signal_type == "both"} {
- puts [format "%-11s %-18s %-12s %-15s %-20s" " $is_clk_net($n)" "$scen_count($n)" "[rbx_get_biggest $cost_lst($n)]" "[rbx_ladd $cost_lst($n)]" "$n"]
- }
- }
- }
- puts "\n1"
- set t2 [clock seconds]
- puts "\n# rbx_report_xtalk_bottlenecks RUNTIME: [rbx_get_runtime $t1 $t2] \n"
- }
- #----------------------------------------------------------------------------------------
- # Proc to get the details of pins reported by report_noise command
- #----------------------------------------------------------------------------------------
- proc rbx_get_noise_pin_details { args } {
- #.......................................................
- # Print help and quit
- #.......................................................
- if {[lsearch $args "-help"] > -1} {
- puts "rbx_get_noise_pin_details -noise_report <noise_report> -noise_region <all | above_low | below_high | below_low | above_high>"
- return
- }
- #.......................................................
- # Arguments Handling
- #.......................................................
- # Default Argument Values
- set noise_report ""
- set noise_region "all"
- # Check and get the values of the arguments
- if {[llength $args] < 2 || [llength $args] > 4} {
- puts "\nRubix-Error: Missing or too many options for rbx_get_noise_pin_details command.\n"; return
- }
- foreach a $args {
- # Check if Wrong option is used
- if {[string match "-*" $a] && $a != "-noise_report" && [string match "-*" $a] && $a != "-noise_region"} {
- puts "\nRubix-Error: Option $a is not valid for rbx_get_noise_pin_details command.\n"; return
- }
- # Get the values of the options
- if {$a == "-noise_report"} { set noise_report [rbx_value -noise_report $args] }
- if {$a == "-noise_region"} { set noise_region [rbx_value -noise_region $args] }
- }
- #.......................................................
- # Execute the main procedure
- #.......................................................
- global sh_product_version
- global glitch_pin_list
- global glitch_net_list
- global aggressors
- set glitch_pin_list ""
- set glitch_net_list ""
- puts [format "%-20s" "*********************************************************************************************"]
- puts [format "%-10s %-15s" " Rubix Custom Report" "\n"]
- puts [format "%-10s %-15s" " Report" ": rbx_get_noise_pin_details"]
- puts [format "%-10s %-15s" " " " -noise_report $noise_report"]
- puts [format "%-10s %-15s" " " " -noise_region $noise_region"]
- puts [format "%-10s %-15s" " Design" ": [get_attribute [get_design] full_name]"]
- puts [format "%-10s %-15s" " Version" ": $sh_product_version"]
- puts [format "%-10s %-15s" " Date" ": [date]"]
- puts [format "%-10s" "*********************************************************************************************"]
- puts [format "%-10s %-10s %-75s %-75s %-75s %-75s %-75s %-75s" "# Slack_S" "Slack_H" "Is Clock" "Pin" "Net" "Driver" "Aggressors Count" "{ Aggressors }"]
- puts "#-----------------------------------------------------------------------------------------------------------------------------------------------------------"
- set rpt [open "$noise_report" r]
- set start_reading 0
- foreach {line} [split [read $rpt] \n] {
- if {$line != 1} {
- # Remove leading blanks
- set line [string trim $line]
- regsub -all { +} $line {;} l
- # Get each word
- set words [split $l ";"]
- # Get Noise type to analyze
- if {$noise_region == "all"} {
- if {[lindex $words 1] == "above_low" || [lindex $words 1] == "below_low" || [lindex $words 1] == "above_high" || [lindex $words 1] == "below_high"} {
- set start_reading 1
- } elseif {[llength $words] == 0} {
- set start_reading 0
- }
- } else {
- if {[lindex $words 1] == "$noise_region"} {
- set start_reading 1
- } elseif {[llength $words] == 0} {
- set start_reading 0
- }
- }
- # Start Reading
- if {$start_reading == 1} {
- if {[llength $words] == 5} {
- if {[lsearch $glitch_pin_list [lindex $words 0]] < 0} {
- set pin [lindex $words 0]
- set net($pin) [get_object_name [get_nets -of_objects $pin]]
- set driver($pin) [rbx_get_driver $pin]
- set aggressors($pin) [get_attr [get_nets [get_object_name [get_nets -of_objects $pin]]] aggressors]
- set slk_s($pin) [get_attr [get_timing_path -through $pin -delay max] slack]
- set slk_h($pin) [get_attr [get_timing_path -through $pin -delay min] slack]
- lappend glitch_pin_list $pin
- lappend glitch_net_list [get_object_name [get_nets -of_objects $pin]]
- # Determine if pin is clock or data
- if {[sizeof_collection [get_attribute -quiet [get_pins $pin] clocks]] < 1} {
- set sig_type($pin) "No"
- } else {
- set sig_type($pin) "Yes"
- }
- } else {
- set pin [lindex $words 0]
- set aggressors($pin) [lsort -unique "$aggressors($pin) [get_attr [get_nets [get_nets -of_objects $pin]] aggressors]"]
- if {$slk_s($pin) > [get_attr [get_timing_path -through $pin -delay max] slack]} {
- set slk_s($pin) [get_attr [get_timing_path -through $pin -delay max] slack]
- }
- if {$slk_h($pin) > [get_attr [get_timing_path -through $pin -delay min] slack]} {
- set slk_h($pin) [get_attr [get_timing_path -through $pin -delay min] slack]
- }
- }
- }
- }
- }
- }
- foreach p $glitch_pin_list {
- if {$slk_s($p) == ""} { set slk_s($p) "-"}
- if {$slk_h($p) == ""} { set slk_h($p) "-"}
- puts [format "%-10s %-10s %-75s %-75s %-75s %-75s %-75s %-75s" "$slk_s($p)" "$slk_h($p)" "$sig_type($p)" "$p" "$net($p)" "$driver($p)" "[llength $aggressors($p)]" "{ $aggressors($p) }"]
- }
- puts "\n1\n"
- close $rpt
- }
- #----------------------------------------------------------------------------------------
- # Get nets with SI delay from the PT reports
- #----------------------------------------------------------------------------------------
- proc rbx_get_si_violators_from_pt_reports { args } {
- #.......................................................
- # Print help and quit
- #.......................................................
- if {[lsearch $args "-help"] > -1} {
- puts "\n rbx_get_si_violators_from_pt_reports
- -pt_report_list <timing_report_list>
- \[-xtalk_delay_greater_than greater_delta_limit\]
- \[-pins | -nets\]
- \[-all | -violating\] \n"
- return
- }
- #.......................................................
- # Arguments Handling
- #.......................................................
- # Default Argument Values
- set pt_report_list ""
- set xtalk_delay_greater_than 0
- set pins_or_nets pins
- set all_or_violating all
- # Check and get the values of the arguments
- if {[llength $args] < 2 || [llength $args] > 6} {
- puts "\nRubix-Error: Missing or too many options given for rbx_get_si_violators_from_pt_reports command.\n"; return
- }
- # Check if two or more mutually exclusive options are used
- if {[lsearch $args -nets] > -1 && [lsearch $args -pins] > -1} {
- puts "\nRubix-Error: Options -nets and -pins are mutually exclusive.\n"; return
- }
- if {[lsearch $args -all] > -1 && [lsearch $args -violating] > -1} {
- puts "\nRubix-Error: Options -all and -violating are mutually exclusive.\n"; return
- }
- foreach a $args {
- # Check if Wrong option is used
- if {[string match {-[A-Z|a-y]*} $a] && $a != "-pt_report_list" && $a != "-xtalk_delay_greater_than" \
- && $a != "-pins" && $a != "-nets" && $a != "-all" && $a != "-violating"} {
- puts "\nRubix-Error: Option $a is not valid for rbx_get_si_violators_from_pt_reports command.\n"; return
- }
- # Get the values of the options
- if {$a == "-pt_report_list"} { set pt_report_list [rbx_value -pt_report_list $args] }
- if {$a == "-xtalk_delay_greater_than"} { set xtalk_delay_greater_than [rbx_value -xtalk_delay_greater_than $args] }
- if {$a == "-pins"} { set pins_or_nets pins }
- if {$a == "-nets"} { set pins_or_nets nets }
- if {$a == "-all"} { set all_or_violating all }
- if {$a == "-violating"} { set all_or_violating violating }
- }
- # Update Needed: Check for -nosplit
- #.......................................................
- # Execute the main procedure
- #.......................................................
- # Suppress messages
- suppress_message "ATTR-3"
- global sh_product_version
- global all_xtalk_nets_to_print
- # Initialize
- set all_xtalk_nets_to_print ""
- set all_xtalk_pins_to_print ""
- set violating_xtalk_nets_to_print ""
- set violating_xtalk_pins_to_print ""
- set violating_xtalk_nets ""
- set violating_xtalk_pins ""
- # For printing one lib per line
- foreach ptrep $pt_report_list {
- lappend pt_report_list_stacked "\n\t\t$ptrep"
- }
- set pt_report_list_stacked [string map {\{ "" \} ""} $pt_report_list_stacked]
- puts [format "%-20s" "*********************************************************************************************"]
- puts [format "%-10s %-15s" " Rubix Custom Report" "\n"]
- puts [format "%-10s %-15s" " Report" ": rbx_get_si_violators_from_pt_reports"]
- puts [format "%-10s %-15s" " " " -pt_report_list $pt_report_list_stacked"]
- puts [format "%-10s %-15s" " " " -xtalk_delay_greater_than $xtalk_delay_greater_than"]
- puts [format "%-10s %-15s" " " " -$pins_or_nets"]
- puts [format "%-10s %-15s" " " " -$all_or_violating"]
- puts [format "%-10s %-15s" " Design" ": [get_attribute [get_design] full_name]"]
- puts [format "%-10s %-15s" " Version" ": $sh_product_version"]
- puts [format "%-10s %-15s" " Date" ": [date]"]
- puts [format "%-10s" "*********************************************************************************************"]
- puts "\n"
- # Open Files for Reading/Writing
- foreach current_rpt $pt_report_list {
- set rpt [open "$current_rpt" r]
- # Read Each Line from PT report
- foreach {line} [split [read $rpt] \n] {
- # Remove leading blanks
- set line [string trim $line]
- if {[string match "*NAME OVERFLOW*" $line]} { ; # Lines with this string will be evaluated leading to unrealistic number of nets
- set line "dont_evaluate_line"
- } elseif {[string match "*:*" $line]} {
- set line "dont_evaluate_line"
- } else {
- regsub -all { +} $line {;} l
- }
- # Get each word
- set words [split $l ";"]
- # Detect the net
- if {[lindex $words 1] == "(net)"} {
- set net [lindex $words 0]
- } else {
- set net ""
- }
- # Stop processing if the reports does not contain delta-delay
- if {([lindex $words 0] == "Point" && [lsearch $words Delta] < 0) } {
- puts "\nRubix-Error: Following timing reports does not contain delta delay. Report timing with -delta option."
- puts " $current_rpt\n"
- return
- }
- # Stop processing if the reports contains more than required details
- if {([lindex $words 0] == "Point" && [llength $words] > 5) } {
- puts "\n"
- puts "Rubix-Error: Following timing reports contains more details than expected."
- puts " Report timing with only -delta/-nets/-nosplit options and without any option like -cap, -tran that add more columns to the report."
- puts " $current_rpt\n"
- return
- }
- # Detect the line with Detla delay greater than the given threshold
- if {([llength $words] == 7) && ([lindex $words 2] > $xtalk_delay_greater_than || [lindex $words 2] < -$xtalk_delay_greater_than)} {
- lappend all_xtalk_nets_to_print $net_on_previous_line
- lappend all_xtalk_pins_to_print [lindex $words 0]
- set delta_del($net_on_previous_line) [lindex $words 2]
- set delta_del([lindex $words 0]) [lindex $words 2]
- # Check if clock or data
- if {[sizeof_collection [get_attribute -quiet [get_nets $net_on_previous_line] clocks]] < 1} {
- set sig_type($net_on_previous_line) "data"
- } else {
- set sig_type($net_on_previous_line) "clock"
- }
- # Check if clock or data
- if {[sizeof_collection [get_attribute -quiet [get_pins [lindex $words 0]] clocks]] < 1} {
- set sig_type([lindex $words 0]) "data"
- } else {
- set sig_type([lindex $words 0]) "clock"
- }
- lappend violating_xtalk_nets $net_on_previous_line
- lappend violating_xtalk_pins [lindex $words 0]
- }
- # Detect the line with slack and check if it is met or violating and decide wheather to print the nets/pins or not
- if {[lindex $words 0] == "slack" && [lindex $words 1] == "(VIOLATED)"} {
- set violating_xtalk_nets_to_print [concat $violating_xtalk_nets_to_print $violating_xtalk_nets]
- set violating_xtalk_pins_to_print [concat $violating_xtalk_pins_to_print $violating_xtalk_pins]
- set violating_xtalk_nets ""
- set violating_xtalk_pins ""
- } elseif {[lindex $words 0] == "slack" && [lindex $words 1] == "(MET)"} {
- set violating_xtalk_nets ""
- set violating_xtalk_pins ""
- }
- set net_on_previous_line $net
- }
- close $rpt
- }
- # Decide to print nets from all paths or just violating paths
- switch $all_or_violating {
- all {set nets_to_print $all_xtalk_nets_to_print; set pins_to_print $all_xtalk_pins_to_print}
- violating {set nets_to_print $violating_xtalk_nets_to_print; set pins_to_print $violating_xtalk_pins_to_print}
- }
- # Print the nets with xtalk
- if {$pins_or_nets == "nets"} {
- puts ""
- puts "Total number of nets with crosstalk more than +-${xtalk_delay_greater_than}ns = [llength [lsort -unique $nets_to_print]]"
- puts ""
- puts [format "%-12s %-15s %-12s" "Delta Delay" "Signal Type" "Net"]
- puts [format "%-12s %-15s %-12s" "-----------" "-----------" "---"]
- foreach n [lsort -unique $nets_to_print] {
- puts [format "%-12s %-15s %-12s" "$delta_del($n)" "$sig_type($n)" "$n"]
- }
- } elseif {$pins_or_nets == "pins"} {
- puts ""
- puts "Total number of pins with crosstalk more than +-${xtalk_delay_greater_than}ns = [llength [lsort -unique $pins_to_print]]"
- puts ""
- puts [format "%-12s %-15s %-12s" "Delta Delay" "Signal Type" "Pin"]
- puts [format "%-12s %-15s %-12s" "-----------" "-----------" "---"]
- foreach p [lsort -unique $pins_to_print] {
- puts [format "%-12s %-15s %-12s" "$delta_del($p)" "$sig_type($p)" "$p"]
- }
- }
- puts "\n1\n"
- # Un-Suppress messages
- unsuppress_message "ATTR-3"
- }
- #----------------------------------------------------------------------------------------
- # Get Common Glitch Nets
- #----------------------------------------------------------------------------------------
- proc rbx_get_glitch_nets { log_file_list } {
- global glitch_pin_list
- global glitch_net_list
- global aggressors
- set glitch_pin_list ""
- set glitch_net_list ""
- set max_occurance [expr 2*[llength $log_file_list]]
- puts [format "%-12s %-18s %-10s %-10s %-75s %-75s %-75s %-75s" "# Occurance" "Aggressors_count" "WNS_S" "WNS_H" "Pin" "Net" "Driver" "Aggressors"]
- puts "#-----------------------------------------------------------------------------------------------------------------------------------------------------------"
- foreach log_file $log_file_list {
- set log [open "$log_file" r]
- set start_reading 0
- foreach {line} [split [read $log] \n] {
- # Remove leading blanks
- set line [string trim $line]
- regsub -all { +} $line {;} l
- # Get each word
- set words [split $l ";"]
- # Get each word
- if {[lindex $words 1] != "Slack_S" && [llength $words] >= 6} {
- if {[lsearch $glitch_pin_list [lindex $words 2]] < 0} {
- set pin [lindex $words 2]
- set net($pin) [lindex $words 3]
- set driver($pin) [lindex $words 4]
- set occurance($pin) 1
- set aggressors($pin) [lreplace $words 0 4]
- set aggressors_count($pin) [llength $aggressors($pin)]
- set wns_s($pin) [lindex $words 0]
- set wns_h($pin) [lindex $words 1]
- lappend glitch_pin_list $pin
- lappend glitch_net_list [get_object_name [get_nets -of_objects $pin]]
- } else {
- set pin [lindex $words 2]
- incr occurance($pin)
- set aggressors($pin) [lsort -unique "$aggressors($pin) [lreplace $words 0 4]"]
- if {$aggressors_count($pin) < [llength $aggressors($pin)]} {
- set aggressors_count($pin) [llength $aggressors($pin)]
- }
- if {$wns_s($pin) > [lindex $words 0]} { set wns_s($pin) [lindex $words 0]}
- if {$wns_h($pin) > [lindex $words 1]} { set wns_h($pin) [lindex $words 1]}
- }
- }
- }
- close $log
- }
- for {set i $max_occurance} {$i >= 1} {incr i -1} {
- foreach p $glitch_pin_list {
- if {$i == $occurance($p)} {
- if {$wns_s($p) != "-" } { set wns_s($p) [format "%.3f" "$wns_s($p)"] }
- if {$wns_h($p) != "-" } { set wns_h($p) [format "%.3f" "$wns_h($p)"] }
- puts [format "%-12s %-18s %-10s %-10s %-75s %-75s %-75s %-75s" "$occurance($p)" "$aggressors_count($p)" "$wns_s($p)" "$wns_h($p)" "$p" "$net($p)" "$driver($p)" "$aggressors($p)"]
- }
- }
- }
- puts "\n---EOF---\n"
- }
- #----------------------------------------------------------------------------------------
- # Triage RC-011
- #----------------------------------------------------------------------------------------
- proc rbx_analyze_rc011 { args } {
- #.......................................................
- # Print help and quit
- #.......................................................
- if {[lsearch $args "-help"] > -1} {
- puts "\nrbx_analyze_rc011 -pt_log <primetime_log_file_with_rc011> -check_type \[setup | hold\] -rc011_slack_lesser_than \n"
- return
- }
- #.......................................................
- # Arguments Handling
- #.......................................................
- # Default Argument Values
- set pt_log ""
- set check_type setup
- set rc011_slack_lesser_than 0
- #set output_style table
- # Check and get the values of the arguments
- if {[llength $args] != 2 && [llength $args] != 4 && [llength $args] != 6} {
- puts "\nRubix-Error: Missing or too many options given for rbx_analyze_rc011 command.\n"; return
- }
- foreach a $args {
- # Check if Wrong option is used
- if {[string match {-[A-Z|a-y]*} $a] && $a != "-pt_log" && $a != "-check_type" && $a != "-rc011_slack_lesser_than"} {
- puts "\nRubix-Error: Option $a is not valid for rbx_analyze_rc011 command.\n"; return
- }
- # Get the values of the options
- if {$a == "-pt_log"} { set pt_log [rbx_value -pt_log $args] }
- if {$a == "-check_type"} { set check_type [rbx_value -check_type $args] }
- if {$a == "-rc011_slack_lesser_than"} { set rc011_slack_lesser_than [rbx_value -rc011_slack_lesser_than $args] }
- }
- #.......................................................
- # Execute the main procedure
- #.......................................................
- global sh_product_version
- global sh_continue_on_error
- set t1 [clock seconds]
- puts [format "%-20s" "*********************************************************************************************"]
- puts [format "%-10s %-15s" " Rubix Custom Report" "\n"]
- puts [format "%-10s %-15s" " Report" ": rbx_analyze_rc011"]
- puts [format "%-10s %-15s" " " " -pt_log $pt_log"]
- puts [format "%-10s %-15s" " " " -check_type $check_type"]
- puts [format "%-10s %-15s" " " " -rc011_slack_lesser_than $rc011_slack_lesser_than"]
- puts [format "%-10s %-15s" " Design" ": [get_attribute [get_design] full_name]"]
- puts [format "%-10s %-15s" " Version" ": $sh_product_version"]
- puts [format "%-10s %-15s" " Date" ": [date]"]
- puts [format "%-10s" "*********************************************************************************************"]
- puts [format "%-15s" "Type:"]
- puts [format "%-15s" " OL - Over Table Limit"]
- puts [format "%-15s" " UL - Under Table Limit"]
- puts "\n"
- suppress_message UITE-416
- set top_sh_continue_on_error $sh_continue_on_error
- set sh_continue_on_error true
- set log [open "$pt_log" r]
- set already_tested_arcs_max ""
- set already_tested_arcs_min ""
- set rc011_max_tran_cap_starts 0
- set rc011_min_tran_cap_starts 0
- set endpoints_max_all ""
- set endpoints_min_all ""
- set rc011_clock_pins ""
- puts [format "%-6s %-12s %-20s %-15s" "Type" "RC011-Slack" "Path-${check_type}-Slack" "Endpoint"]
- puts [format "%-6s %-12s %-20s %-15s" "----" "-----------" "----------------" "--------"]
- puts [format "%-6s %-12s %-16s %-15s %-15s %-6s" "" "" "" "" "Stage Delay" "RC011-Data-Pins"]
- puts [format "%-6s %-12s %-16s %-15s %-15s %-6s" "" "" "" "" "-----------" "---------------"]
- foreach {line} [split [read $log] \n] {
- if {$line != 1} {
- # Remove leading blanks
- set line [string trim $line]
- regsub -all { +} $line {;} l
- # Get each word
- set words [split $l ";"]
- #.......................................................
- # Detect the start of RC-011 max transition/Capacitance messages and Process
- #.......................................................
- if {[string match "Warning: An extrapolation *uses the last library index*" $line]} {
- set rc011_max_tran_cap_starts 1
- set rc011_max_tran_cap_line_no 0
- }
- if {$rc011_max_tran_cap_starts == 1} {
- incr rc011_max_tran_cap_line_no
- # Get extrapolation %
- if {$rc011_max_tran_cap_line_no == 1} {
- set extrapolation_pct [lindex $words 23]
- regsub -all {%} $extrapolation_pct {} extrapolation_pct
- }
- # Get Instance, from Pin and to Pin
- if {$rc011_max_tran_cap_line_no == 2} {
- regsub -all {.*-->} [lindex $words 6] {} to_pin
- regsub -all {/.-->.*} [lindex $words 6] {} instance
- regsub -all {/..-->.*} $instance {} instance
- regsub -all {/...-->.*} $instance {} instance
- regsub -all {\-\->.*} [lindex $words 6] {} from_pin_fullname
- }
- # Detect the end of RC-011 message
- if {$rc011_max_tran_cap_line_no == 3} {
- # Mark the end of RC-011 message
- set rc011_max_tran_cap_starts 0
- # Get the slew on pin
- regsub -all {.*/} [lindex $words 3] {} actual_slew
- regsub -all {,} $actual_slew {} actual_slew
- # Get the lib slew
- regsub -all {\]} [lindex $words 8] {} lib_slew
- # Process the first appearing RC-011 and skip the rest
- if {[lsearch $already_tested_arcs_max "${from_pin_fullname}$to_pin"] < 0} {
- set fp $from_pin_fullname
- set tp $to_pin
- lappend already_tested_arcs_max "${fp}$tp"
- if {[sizeof_collection [get_attribute -quiet [get_pins $from_pin_fullname] clocks]] < 1} {
- # Process setup and hold timing differently
- if {$check_type == "setup"} {
- set delay_type max
- set delay_index 0
- } elseif {$check_type == "hold"} {
- set delay_type min
- set delay_index end
- }
- # Delay of the affected ARC
- set stage_del($fp) [lindex [lsort -decreasing [get_attribute [get_timing_arcs -from $fp -to $instance/$tp] delay_${delay_type}_rise]] $delay_index]
- set stage_del($fp) [format "%.3f" "$stage_del($fp)"]
- set lib_tbl_max_del [expr $stage_del($fp)*((100-$extrapolation_pct)/100.0)] ; # Delay corresponding to maximum slew and load in the .lib
- if {$lib_slew != "" && $actual_slew != ""} {
- set slew_excess_ratio [expr $actual_slew/$lib_slew]
- }
- set delay_excess [expr $lib_tbl_max_del*$slew_excess_ratio] ; # Delay corresponding to current slew
- # Get Slack of the timing path through the RC-011 timing arc and stage-delay (= delay of the timing arc affected)
- set endpoints_max [get_object_name [all_fanout -endpoints_only -from $instance/$tp]]
- set endpoints_max_all "$endpoints_max_all $endpoints_max"
- foreach ep $endpoints_max {
- set slack($ep) [get_attribute [get_timing_path -delay $delay_type -through $fp -through $instance/$tp -to $ep] slack]
- if {$slack($ep) != ""} {
- # Convert the slack to 3 decimal places
- set slack($ep) [format "%.3f" "$slack($ep)"]
- }
- set slack_reduction [format "%.3f" [expr ($delay_excess - $stage_del($fp))]]
- # Setup slack reduces if delay of the affected arc is more than 10% of maximum table delay
- if {$check_type == "setup"} {
- if {[info exist rc011_slack_max($ep)]} {
- set rc011_slack_max($ep) [format "%.3f" [expr $rc011_slack_max($ep) - $slack_reduction]]
- } else {
- set rc011_slack_max($ep) [format "%.3f" [expr $slack($ep) - $slack_reduction]]
- }
- }
- # Hold slack increases if delay of the affected arc is more than 10% of maximum table delay
- if {$check_type == "hold"} {
- if {[info exist rc011_slack_max($ep)]} {
- set rc011_slack_max($ep) [format "%.3f" [expr $rc011_slack_max($ep) + $slack_reduction]]
- } else {
- set rc011_slack_max($ep) [format "%.3f" [expr $slack($ep) + $slack_reduction]]
- }
- }
- # Cells Causing RC-011 for a given FF
- if {[info exist rc011_pins_max($ep)]} {
- set rc011_pins_max($ep) "$rc011_pins_max($ep) $fp"
- } else {
- set rc011_pins_max($ep) "$fp"
- }
- }
- } else {
- set rccp $fp
- set rc011_clock_pins "$rc011_clock_pins $fp"
- if {[info exist rccp_type($rccp)] && $rccp_type($rccp)=="UL"} {
- set rccp_type($rccp) "OL, UL"
- } else {
- set rccp_type($rccp) "OL"
- }
- }
- }
- }
- }
- #.......................................................
- # Detect the start of RC-011 min transition/Capacitance messages
- #.......................................................
- if {[string match "Warning: An extrapolation *limited the extrapolation to*" $line]} {
- set rc011_min_tran_cap_starts 1
- set rc011_min_tran_cap_line_no 0
- }
- if {$rc011_min_tran_cap_starts == 1} {
- incr rc011_min_tran_cap_line_no
- # Get extrapolation %
- if {$rc011_min_tran_cap_line_no == 1} {
- set extrapolation_pct [lindex $words 19]
- regsub -all {%} $extrapolation_pct {} extrapolation_pct
- }
- # Get Instance, from Pin and to Pin
- if {$rc011_min_tran_cap_line_no == 2} {
- regsub -all {.*-->} [lindex $words 6] {} to_pin
- regsub -all {/.-->.*} [lindex $words 6] {} instance
- regsub -all {/..-->.*} $instance {} instance
- regsub -all {/...-->.*} $instance {} instance
- regsub -all {\-\->.*} [lindex $words 6] {} from_pin_fullname
- }
- # Detect the end of RC-011 message
- if {$rc011_min_tran_cap_line_no == 3} {
- # Mark the end of RC-011 message
- set rc011_min_tran_cap_starts 0
- # Get the slew on pin
- regsub -all {.*/} [lindex $words 3] {} actual_slew
- regsub -all {,} $actual_slew {} actual_slew
- # Get the lib slew
- regsub -all {.*\[} [lindex $words 7] {} lib_slew
- #puts "lib_slew $lib_slew"
- # Process the first appearing RC-011 and skip the rest
- if {[lsearch $already_tested_arcs_min "${from_pin_fullname}$to_pin"] < 0} {
- set fp $from_pin_fullname
- set tp $to_pin
- lappend already_tested_arcs_min "${fp}$tp"
- if {[sizeof_collection [get_attribute -quiet [get_pins $from_pin_fullname] clocks]] < 1} {
- # Process setup and hold timing differently
- if {$check_type == "setup"} {
- set delay_type max
- set delay_index 0
- } elseif {$check_type == "hold"} {
- set delay_type min
- set delay_index end
- }
- # Delay of the affected ARC
- set stage_del($fp) [lindex [lsort -decreasing [get_attribute [get_timing_arcs -from $fp -to $instance/$tp] delay_${delay_type}_rise]] $delay_index]
- set stage_del($fp) [format "%.3f" "$stage_del($fp)"]
- set lib_tbl_min_del [expr ($stage_del($fp)*100)/(100-$extrapolation_pct)] ; # Delay corresponding to minimum slew and load in the .lib
- if {$lib_slew != "" && $actual_slew != ""} {
- set slew_excess_ratio [expr $actual_slew/$lib_slew]
- }
- set delay_excess [expr $lib_tbl_min_del*$slew_excess_ratio] ; # Delay corresponding to current slew
- # Get Slack of the timing path through the RC-011 timing arc and stage-delay (= delay of the timing arc affected)
- set endpoints_min [get_object_name [all_fanout -endpoints_only -from $instance/$tp]]
- set endpoints_min_all "$endpoints_min_all $endpoints_min"
- foreach ep $endpoints_min {
- set slack($ep) [get_attribute [get_timing_path -delay $delay_type -through $fp -through $instance/$tp -to $ep] slack]
- if {$slack($ep) != ""} {
- # Convert the slack to 3 decimal places
- set slack($ep) [format "%.3f" "$slack($ep)"]
- }
- set slack_reduction [format "%.3f" [expr ($stage_del($fp) - $delay_excess)]]
- # Setup slack increases if delay of the affected arc is less than 80% of minimum table delay
- if {$check_type == "setup"} {
- if {[info exist rc011_slack_min($ep)]} {
- set rc011_slack_min($ep) [format "%.3f" [expr $rc011_slack_min($ep) + $slack_reduction]]
- } else {
- set rc011_slack_min($ep) [format "%.3f" [expr $slack($ep) + $slack_reduction]]
- }
- }
- # Hold slack reduces if delay of the affected arc is less than 80% of minimum table delay
- if {$check_type == "hold"} {
- if {[info exist rc011_slack_min($ep)]} {
- set rc011_slack_min($ep) [format "%.3f" [expr $rc011_slack_min($ep) - $slack_reduction]]
- } else {
- set rc011_slack_min($ep) [format "%.3f" [expr $slack($ep) - $slack_reduction]]
- }
- }
- # Cells Causing RC-011 for a given FF
- if {[info exist rc011_pins_min($ep)]} {
- set rc011_pins_min($ep) "$rc011_pins_min($ep) $fp"
- } else {
- set rc011_pins_min($ep) "$fp"
- }
- }
- } else {
- set rccp $fp
- set rc011_clock_pins "$rc011_clock_pins $fp"
- if {[info exist rccp_type($rccp)] && $rccp_type($rccp)=="OL"} {
- set rccp_type($rccp) "OL, UL"
- } else {
- set rccp_type($rccp) "UL"
- }
- }
- }
- }
- }
- }
- }
- close $log
- foreach ep [lsort -u $endpoints_max_all] {
- if {$rc011_slack_max($ep) < $rc011_slack_lesser_than} {
- puts [format "%-6s %-12s %-20s %-15s" "\nOL" "$rc011_slack_max($ep)" "$slack($ep)" "$ep"]
- foreach i $rc011_pins_max($ep) {
- puts [format "%-6s %-12s %-16s %-15s %-15s %-6s" "" "" "" "" "$stage_del($i)" "$i"]
- }
- }
- }
- foreach ep [lsort -u $endpoints_min_all] {
- if {$rc011_slack_min($ep) < $rc011_slack_lesser_than} {
- puts [format "%-6s %-12s %-20s %-15s" "\nUL" "$rc011_slack_min($ep)" "$slack($ep)" "$ep"]
- foreach i $rc011_pins_min($ep) {
- puts [format "%-6s %-12s %-16s %-15s %-15s %-6s" "" "" "" "" "$stage_del($i)" "$i"]
- }
- }
- }
- puts "\n\n"
- puts [format "%-10s %-12s" "Type" "RC011-Clock-Pin"]
- puts [format "%-10s %-12s" "----" "---------------"]
- foreach j [lsort -u $rc011_clock_pins] {
- puts [format "%-10s %-12s" "$rccp_type($j)" "$j"]
- }
- puts "\n1\n"
- unsuppress_message UITE-416
- set sh_continue_on_error $top_sh_continue_on_error
- }
- #----------------------------------------------------------------------------------------
- # Find clock pins in report_constraints file
- #----------------------------------------------------------------------------------------
- proc rbx_get_clock_pins_from_pt_rpt_constraints { args } {
- #.......................................................
- # Print help and quit
- #.......................................................
- if {[lsearch $args "-help"] > -1} {
- puts "\n rbx_get_clock_pins_from_pt_rpt_constraints -pt_report_list <report_constraints_file_list> -constraint_type <constraint_type>\n"
- return
- }
- #.......................................................
- # Arguments Handling
- #.......................................................
- # Default Argument Values
- set pt_report_list ""
- # Check and get the values of the arguments
- if {[llength $args] < 4} {
- puts "\nRubix-Error: Missing options for rbx_get_clock_pins_from_pt_rpt_constraints command.\n"; return
- }
- foreach a $args {
- # Check if Wrong option is used
- if {[string match {-[A-Z|a-y]*} $a] && $a != "-pt_report_list" && $a != "-constraint_type"} {
- puts "\nRubix-Error: Option $a is not valid for rbx_get_clock_pins_from_pt_rpt_constraints command.\n"; return
- }
- # Get the values of the options
- if {$a == "-pt_report_list"} { set pt_report_list [rbx_value -pt_report_list $args] }
- if {$a == "-constraint_type"} { set constraint_type [rbx_value -constraint_type $args] }
- }
- #.......................................................
- # Execute the main procedure
- #.......................................................
- set t1 [clock seconds]
- global sh_product_version
- # Suppress messages
- suppress_message "ATTR-3"
- # For printing one lib per line
- foreach ptrep $pt_report_list {
- lappend pt_report_list_stacked "\n\t\t$ptrep"
- }
- set pt_report_list_stacked [string map {\{ "" \} ""} $pt_report_list_stacked]
- puts [format "%-20s" "*********************************************************************************************"]
- puts [format "%-10s %-15s" " Rubix Custom Report" "\n"]
- puts [format "%-10s %-15s" " Report" ": rbx_get_clock_pins_from_pt_rpt_constraints"]
- puts [format "%-10s %-15s" " " " -pt_report_list $pt_report_list_stacked"]
- puts [format "%-10s %-15s" " " " -constraint_type $constraint_type"]
- puts [format "%-10s %-15s" " Design" ": [get_attribute [get_design] full_name]"]
- puts [format "%-10s %-15s" " Version" ": $sh_product_version"]
- puts [format "%-10s %-15s" " Date" ": [date]"]
- puts [format "%-10s" "*********************************************************************************************"]
- puts "\n"
- puts [format "%-6s %-6s %-6s %-6s" "Pin" "Required" "Actual" "Slack" ]
- puts "----------------------------------------------------------------------------------------------------------------------"
- foreach current_rpt $pt_report_list {
- # Initialisation
- set constr_position 0
- set heading_seperator 0
- # Open Files for Reading/Writing
- set pt_rpt_con [open "$current_rpt" r]
- # Read Each Line for PT Transition Report File
- foreach {line} [split [read $pt_rpt_con] \n] {
- # Remove leading blanks
- set line [string trim $line]
- regsub -all { +} $line {;} l
- # Get each word
- set words [split $l ";"]
- # Detect the portion under "max_transition"
- if {[lindex $words 0] == "$constraint_type"} {
- set constr_position 1
- }
- # Process only the max_transition portion
- if {($constr_position == 1) && ($heading_seperator < 2)} {
- ## Write pins if they clock pins and if they are violating transition
- if {[string match "*VIOLATED*" [lindex $words 4]] && [llength [get_attribute [get_pins [lindex $words 0]] clocks]] > 0} {
- puts [format "%-6s %-6s %-6s %-6s %-6s" "[lindex $words 0]" "[lindex $words 1]" "[lindex $words 2]" "[lindex $words 3]" "[lindex $words 4]"]
- }
- ## Stop Writing
- if {[string match "*--------------------------------------------*" [lindex $words 0]]} {
- incr heading_seperator
- }
- }
- }
- }
- puts "\n1"
- set t2 [clock seconds]
- puts "\n# rbx_get_clock_pins_from_pt_rpt_constraints RUNTIME: [rbx_get_runtime $t1 $t2] \n"
- close $pt_rpt_con
- # Enable the suppressed messages
- unsuppress_message "ATTR-3"
- }
- #----------------------------------------------------------------------------------------
- # Check if the transition limit is within lib limit
- #----------------------------------------------------------------------------------------
- proc rbx_get_lib_transition { pin_list } {
- puts "Slack\t - Actual Tran\t - Lib Limit\t - Pin"
- foreach p $pin_list {
- set lib_tran [get_attribute [get_pins $p] max_transition]
- set rise_tran [get_attribute [get_pins $p] actual_rise_transition_max]
- set fall_tran [get_attribute [get_pins $p] actual_fall_transition_max]
- if {$rise_tran > $fall_tran} {
- set tran $rise_tran
- } else {
- set tran $fall_tran
- }
- puts "[expr $lib_tran - $tran]\t - $tran\t - $lib_tran\t - $p"
- }
- }
- #----------------------------------------------------------------------------------------
- # Write a "TransitionFile" for EDI
- #----------------------------------------------------------------------------------------
- proc rbx_write_transition_file { \
- pt_rpt_constraints_file \
- edi_trans_file \
- { comment "" } \
- } {
- set t1 [clock seconds]
- global version_name
- global standalone_scenario
- global library_corner($standalone_scenario)
- # Initialisation
- set constr_position 0
- set heading_seperator 0
- # Open Files for Reading/Writing
- set pt_rpt_con [open "$pt_rpt_constraints_file" r]
- set edi_tr_fl [open "$edi_trans_file" w]
- puts $edi_tr_fl "#*******************************************************************************************************"
- puts $edi_tr_fl "# Transition File for EDI"
- puts $edi_tr_fl "#-------------------------------------------------------------------------------------------------------"
- puts $edi_tr_fl "# Written by \"rbx_write_transition_file\" on [date]"
- puts $edi_tr_fl "#-------------------------------------------------------------------------------------------------------"
- puts $edi_tr_fl "# Comment:"
- puts $edi_tr_fl "# $comment"
- puts $edi_tr_fl "#*******************************************************************************************************"
- puts $edi_tr_fl ""
- puts "\nRM-Info: Reading file $pt_rpt_constraints_file..."
- # Read Each Line for PT Transition Report File
- foreach {line} [split [read $pt_rpt_con] \n] {
- # Remove leading blanks
- set line [string trim $line]
- regsub -all { +} $line {;} l
- # Get each word
- set words [split $l ";"]
- # Detect the portion under "max_transition"
- if {[lindex $words 0] == "max_transition"} {
- set constr_position 1
- }
- # Process only the max_transition portion
- if {($constr_position == 1) && ($heading_seperator < 2)} {
- ## Write Transition File for EDI
- if {[lindex $words 4] == "(VIOLATED)"} {
- puts $edi_tr_fl "setTranTime -maxR [lindex $words 2] [lindex $words 0]"
- }
- ## Stop Writing Transition file if max_transition portion is over
- if {[string match "*--------------------------------------------*" [lindex $words 0]]} {
- incr heading_seperator
- }
- }
- }
- puts "\nRM-Info: Writing transition file $edi_trans_file..."
- puts $edi_tr_fl "\n#--- EOF ---"
- set t2 [clock seconds]
- puts $edi_tr_fl "\n# rbx_write_transition_file RUNTIME: [rbx_get_runtime $t1 $t2] "
- close $pt_rpt_con
- close $edi_tr_fl
- }
- #----------------------------------------------------------------------------------------
- # Trace buffer/inverter chain
- #----------------------------------------------------------------------------------------
- proc rbx_trace_buf_inv_chain { pin_list } {
- foreach p $pin_list {
- set trace_pin $p
- set stop_tracing 0
- while {$stop_tracing==0} {
- set driver_inpin_count [sizeof_collection [get_pins -of_objects [get_cells -of_objects [rbx_get_driver $trace_pin]] -filter "direction==in"]]
- set driver_inpin [get_pins -of_objects [get_cells -of_objects [rbx_get_driver $trace_pin]] -filter "direction==in"]
- if {$driver_inpin_count == 1} {
- lappend nets [get_object_name [get_nets -of_objects $driver_inpin]]
- set trace_pin $driver_inpin
- } else {
- set stop_tracing 1
- }
- }
- }
- return $nets
- }
- #----------------------------------------------------------------------------------------
- # Get Cell worst from/to setup/hold slacks
- #----------------------------------------------------------------------------------------
- proc rbx_report_cell_interface_timing {\
- pin_clock_pairs \
- report_file \
- } {
- set rpt_csv [open "${report_file}" w+]
- puts $rpt_csv "check,reg_to_mem,mem_to_reg"
- foreach pcp $pin_clock_pairs {
- set pin [lindex $pcp 0]
- set clock [lindex $pcp 1]
- set cell [get_object_name [get_cells -of_objects [get_pins $pin]]]
- set to_setup [get_attribute [get_timing_path -to [get_pins $cell/*] -from [get_clocks $clock] -max_path 1] slack]
- set to_hold [get_attribute [get_timing_path -to [get_pins $cell/*] -from [get_clocks $clock] -max_path 1 -delay min] slack]
- set from_setup [get_attribute [get_timing_path -from [get_pins $cell/*] -to [get_clocks $clock] -max_path 1] slack]
- set from_hold [get_attribute [get_timing_path -from [get_pins $cell/*] -to [get_clocks $clock] -max_path 1 -delay min] slack]
- set to_setup [lindex $to_setup 0]
- set to_hold [lindex $to_hold 0]
- set from_setup [lindex $from_setup 0]
- set from_hold [lindex $from_hold 0]
- puts $rpt_csv "$clock,$cell"
- puts $rpt_csv "setup,${to_setup},${from_setup}"
- puts $rpt_csv "hold,${to_hold},${from_hold}"
- puts $rpt_csv ""
- }
- close $rpt_csv
- }
- #--------------------------------------------------------------------------------
- # Proc to get clock latency statistics
- #--------------------------------------------------------------------------------
- proc rbx_report_clock_latency { check clk_name} {
- echo "clock,latency,pin,type"
- foreach_in_collection reg [get_cells -hierarchical * -filter "is_hierarchical == false && ref_name =~ *DFF*"] {
- ## Get clk pin **
- set clk_pin [get_pins -of_objects $reg -filter "direction == in && is_clock_pin == true"]
- set pin_name [get_attribute $clk_pin full_name]
- ## Get path types **
- set is_ip false
- set is_op false
- set is_from_reg false
- set is_to_reg false
- set d_pins [get_pins -quiet -of_objects $reg -filter "direction == in && is_data_pin == true && lib_pin_name =~ D*"]
- foreach_in_collection pin $d_pins {
- if { [regexp {^v} [lindex [lindex [lindex [get_attribute $pin arrival_window] 0] 0] 0]] } {
- set is_ip true
- }
- if { [regexp $clk_name [lindex [lindex [lindex [get_attribute $pin arrival_window] 0] 0] 0]] } {
- set is_from_reg true
- }
- }
- set q_pins [get_pins -quiet -of_objects $reg -filter "direction == out && lib_pin_name =~ Q*"]
- foreach_in_collection pin $q_pins {
- if { [sizeof_collection [filter_collection [all_fanout -flat -endpoints_only -from $pin] "object_class =~ port"]] > 0 } {
- set is_op true
- }
- set ep_pin_collection [filter_collection [filter_collection [all_fanout -flat -endpoints_only -from $pin] "object_class =~ pin"] "lib_pin_name =~ D*"]
- if { [sizeof_collection $ep_pin_collection] > 0 } {
- set is_to_reg true
- }
- }
- set R2R [expr $is_from_reg && $is_to_reg]
- set I2O [expr $is_ip && $is_op]
- set I2R [expr $is_ip && $is_to_reg]
- set R2O [expr $is_from_reg && $is_op]
- foreach thing [lindex [get_attribute $clk_pin arrival_window] 0] {
- # check for pos_edge
- if { [lindex $thing 1] == "pos_edge" } {
- # get clock name
- set pin_clock_name [lindex $thing 0]
- if {$pin_clock_name == $clk_name} {
- if {$check == "setup" } {
- # get max_r_f
- set clock_lat [lindex [lindex $thing 3] 1]
- } else {
- # get min_r_f
- set clock_lat [lindex [lindex $thing 2] 1]
- }
- if {$R2R} {
- echo $pin_clock_name,$clock_lat,$pin_name,R2R
- }
- if {$I2O} {
- echo $pin_clock_name,$clock_lat,$pin_name,I2O
- }
- if {$I2R} {
- echo $pin_clock_name,$clock_lat,$pin_name,I2R
- }
- if {$R2O} {
- echo $pin_clock_name,$clock_lat,$pin_name,R2O
- }
- }
- }
- }
- }
- }
- # --- EOF ---
- #----------------------------------------------------------------------------------------
- # Print Setup/Hold violations to endpoints
- #----------------------------------------------------------------------------------------
- proc rbx_report_pin_setup_hold { to_from_through endpoint_pin_list } {
- puts "Setup\tHold\tPin"
- foreach i [get_object_name [get_pins $endpoint_pin_list]] {
- set s_slk [get_attribute [get_timing_path $to_from_through [get_pins $i] ] slack]
- set h_slk [get_attribute [get_timing_path $to_from_through [get_pins $i] -delay min] slack]
- puts "$s_slk\t$h_slk\t$i"
- }
- }
- #----------------------------------------------------------------------------------------
- # Get Slacks from PBA report
- #----------------------------------------------------------------------------------------
- proc rbx_get_slacks {
- report_file \
- } {
- set rpt [open "$report_file" r]
- foreach {line} [split [read $rpt] \n] {
- if {$line != 1} {
- # Remove leading blanks
- set line [string trim $line]
- regsub -all { +} $line {;} l
- # Get each word
- set words [split $l ";"]
- if {"[lindex $words 1][lindex $words 2][lindex $words 3]" == "(withderatingapplied)"} {
- set derated_slack [lindex $words 5]
- } elseif {"[lindex $words 1][lindex $words 2][lindex $words 3]" == "(withnoderating)"} {
- set non_derated_slack [lindex $words 5]
- }
- }
- }
- close $rpt
- return [list $derated_slack $non_derated_slack]
- }
- #========================================================================================
- # Proc Type 3: Procs for Design Exploration and Debug
- #========================================================================================
- #----------------------------------------------------------------------------------------
- # Get Fanout FF
- #----------------------------------------------------------------------------------------
- proc rbx_get_fo_ff { pin {ret list}} {
- set ff_list [all_fanout -from $pin -endpoints_only -flat]
- set ff_count [sizeof_collection $ff_list]
- if {$ret == "list"} {
- return $ff_list
- } else {
- return $ff_count
- }
- }
- #----------------------------------------------------------------------------------------
- # Get Pin Driver
- #----------------------------------------------------------------------------------------
- proc rbx_get_driver {pin} {
- suppress_message "SEL-003"
- set driver [get_object_name [get_pins -quiet -leaf -of_objects [get_net -of_object [get_pins $pin]] -filter "direction==out"]]
- if {$driver == ""} {set driver "UNKNOWN"}
- unsuppress_message "SEL-003"
- return $driver
- }
- #----------------------------------------------------------------------------------------
- # Get Cell Driver
- #----------------------------------------------------------------------------------------
- proc rbx_get_driver_cell {pin } {
- set driver [get_pins -leaf -of_objects [get_net -of_object [get_pins $pin]] -filter "direction==out"]
- set driver_name [get_attribute [get_pins $driver] full_name]
- set driver_cell [get_attribute [get_cell -of_object [get_pins $driver]] ref_name]
- puts "$driver_name,$driver_cell"
- }
- #----------------------------------------------------------------------------------------
- # Get pin Receiver
- #----------------------------------------------------------------------------------------
- proc rbx_get_receivers {pin} {
- set receivers [get_pins -of_objects [get_net -of_object [get_pins $pin]] -filter "direction==in"]
- return $receivers
- }
- #----------------------------------------------------------------------------------------
- # Get Coreceivers
- #----------------------------------------------------------------------------------------
- proc rbx_get_coreceivers {pin} {
- get_receivers [get_driver $pin]
- }
- #----------------------------------------------------------------------------------------
- # Print Reference Name
- #----------------------------------------------------------------------------------------
- proc rbx_print_ref_name { instance_list } {
- foreach i $instance_list {
- set r [get_attribute [get_cells $i] ref_name]
- puts [format "%-40s %-15s" "$r" "$i"]
- }
- }
- #----------------------------------------------------------------------------------------
- # Get instance names of complex cells
- #----------------------------------------------------------------------------------------
- proc rbx_get_complex_cells { } {
- foreach_in_collection c [remove_from_collection [get_cells -hier * -filter "is_hierarchical!=true"] [get_cells -hier * -filter "is_combinational==true"]] {
- if {[get_attribute [get_cells $c] number_of_pins]>15} {
- echo "[get_object_name [get_cells $c]]"
- }
- }
- }
- #----------------------------------------------------------------------------------------
- # Check if start point is a latch
- #----------------------------------------------------------------------------------------
- proc rbx_is_startpoint_latch {\
- pin_list \
- } {
- global timing_report_unconstrained_paths
- suppress_message "SEL-003 UITE-416 ATTR-3"
- set init_rep_uncon_path $timing_report_unconstrained_paths
- set timing_report_unconstrained_paths true
- foreach p $pin_list {
- set sp_clk [get_object_name [get_attribute [get_timing_path -to $p] startpoint_clock]]
- set ep_clk [get_object_name [get_attribute [get_timing_path -to $p] endpoint_clock]]
- set arr [get_attribute [get_timing_path -to $p] arrival]
- set sp_clk_lat [lindex [get_attribute [get_timing_path -from [get_cells -of_objects $p]] startpoint_clock_latency] 0]
- set current_startpoint [get_object_name [get_attribute [get_timing_path -to $p] startpoint]]
- set startpoint_is_latch [get_attribute [get_timing_path -to $p] startpoint_is_level_sensitive]
- if {$startpoint_is_latch=="false"} {
- #puts "$current_startpoint\t\t$p"
- puts "[expr $arr - $sp_clk_lat] - $p"
- }
- }
- unsuppress_message "SEL-003 UITE-416 ATTR-3"
- set timing_report_unconstrained_paths $init_rep_uncon_path
- }
- #----------------------------------------------------------------------------------------
- # Show Arcs
- #----------------------------------------------------------------------------------------
- proc rbx_show_arcs {args} {
- set arcs [eval [concat get_timing_arcs $args]]
- echo [format "%15s %-15s %8s %8s %s" "from_pin" "to_pin" "rise" "fall" "is_cellarc"]
- echo [format "%15s %-15s %8s %8s %s" "--------" "------" "----" "----" "----------"]
- foreach_in_collection arc $arcs {
- set is_cellarc [get_attribute $arc is_cellarc]
- set fpin [get_attribute $arc from_pin]
- set tpin [get_attribute $arc to_pin]
- set rise [get_attribute $arc delay_max_rise]
- set fall [get_attribute $arc delay_max_fall]
- set from_pin_name [get_attribute $fpin full_name]
- set to_pin_name [get_attribute $tpin full_name]
- #echo [format "%15s -> %-15s %8s %8s %s" $from_pin_name $to_pin_name \
- [format_float $rise] [format_float $fall] \
- $is_cellarc]
- puts [format "%15s -> %-15s %8s %8s %s" $from_pin_name $to_pin_name $rise $fall $is_cellarc]
- }
- }
- #----------------------------------------------------------------------------------------
- # Get the difference between rise and fall timing through the set of pins
- #----------------------------------------------------------------------------------------
- proc rbx_get_rise_fall_diff { pin_list } {
- set max_rise 0
- set max_fall 0
- set min_rise 0
- set min_fall 0
- for {set i 0} {$i < [llength $pin_list]} {incr i 2} {
- set max_rise [expr $max_rise + [lindex [get_attr [get_timing_arc -from [lindex $pin_list $i ] -to [lindex $pin_list [expr $i+1] ]] delay_max_rise] 0]]
- set max_fall [expr $max_fall + [lindex [get_attr [get_timing_arc -from [lindex $pin_list $i ] -to [lindex $pin_list [expr $i+1] ]] delay_max_fall] 0]]
- set min_rise [expr $min_rise + [lindex [get_attr [get_timing_arc -from [lindex $pin_list $i ] -to [lindex $pin_list [expr $i+1] ]] delay_min_rise] 0]]
- set min_fall [expr $min_fall + [lindex [get_attr [get_timing_arc -from [lindex $pin_list $i ] -to [lindex $pin_list [expr $i+1] ]] delay_min_fall] 0]]
- }
- set high_pulse_change [expr $min_fall - $max_rise]
- set low_pulse_change [expr $min_rise - $max_fall]
- puts "high_pulse_change = $high_pulse_change"
- puts "low_pulse_change = $low_pulse_change"
- }
- #----------------------------------------------------------------------------------------
- # Find the clocks propagating to a pin
- #----------------------------------------------------------------------------------------
- proc rbx_find_clocks {pin} {
- get_attribute [get_pins $pin] clocks
- }
- #----------------------------------------------------------------------------------------
- # Estimate ECO
- #----------------------------------------------------------------------------------------
- proc rbx_estimate_eco {inst cell} {
- estimate_eco -nosplit -sort_by area -lib_cells [get_lib_cells */$cell*] $inst
- }
- #----------------------------------------------------------------------------------------
- # Estimate size_cell
- #----------------------------------------------------------------------------------------
- proc rbx_estimate_size_cell {inst cell {check max}} {
- estimate_eco -nosplit -sort_by slack -$check -lib_cells [get_lib_cells */$cell*] $inst
- }
- #----------------------------------------------------------------------------------------
- # Print one element of PT list in one line
- #----------------------------------------------------------------------------------------
- proc rbx_print_list { pt_lst } {
- foreach i [get_object_name $pt_lst] {
- echo $i
- }
- }
- #----------------------------------------------------------------------------------------
- # Print Clock Freq
- #----------------------------------------------------------------------------------------
- proc rbx_print_clk_freq { clk_list } {
- puts [format "%-20s %-15s" "Clock" "Frequency in MHz"]
- foreach c $clk_list {
- puts [format "%-20s %-15s" "$c" "[expr round(1000/[get_attr [get_clocks $c] period])]"]
- }
- }
- #########################################################################################
- # Child Procedures
- # Procs Used within the above procs
- #########################################################################################
- #----------------------------------------------------------------------------------------
- # Proc to get runtime
- #----------------------------------------------------------------------------------------
- proc rbx_get_runtime {\
- start_clock_seconds \
- end_clock_seconds \
- } {
- set time [expr $end_clock_seconds - $start_clock_seconds]
- if {$time < 60} { return "$time seconds" }
- if {$time > 60 && $time < 3599} { return "[expr $time/60] minutes" }
- if {$time > 3599} { return "[expr $time/3600]:[expr ($time%3600)/60] hours" }
- }
- #----------------------------------------------------------------------------------------
- # Format Float
- #----------------------------------------------------------------------------------------
- proc rbx_format_float {number {format_str "/f %.2f"}} {
- switch -exact -- $number {
- UNINIT { }
- INFINITY { }
- default {set number [format $format_str $number]}
- }
- return $number;
- }
- #----------------------------------------------------------------------------------------
- # Get Value of an option
- #----------------------------------------------------------------------------------------
- proc rbx_value { argument arg} {
- set [set argument] "[lindex $arg [expr [lsearch $arg $argument] + 1]]"
- return "[set $argument]"
- }
- #----------------------------------------------------------------------------------------
- # Add a list of integers
- #----------------------------------------------------------------------------------------
- proc rbx_ladd { integer_list } {
- set sum 0
- foreach i $integer_list {set sum [expr $sum + $i]}
- return $sum
- }
- #----------------------------------------------------------------------------------------
- # Get the biggest integer from the list
- #----------------------------------------------------------------------------------------
- proc rbx_get_biggest { integer_list } {
- set biggest ""
- foreach i $integer_list {
- if {$biggest == "" || $i > $biggest} {
- set biggest $i
- }
- }
- return $biggest
- }
- #########################################################################################
- # +Pointer to Man Pages
- # +set for help command to display the custom commands
- #########################################################################################
- #########################################################################################
- # Pointer to man pages
- # set sh_user_man_path <path_to_man_pages/cat1/rbx_*.cat1>
- # Following makes PrimeTime help command to display these commands
- # Man pages exist for the custom commands that are un-commented
- define_proc_attributes rbx_report_unconstrained_endpoints -info "Rubix Custom Command: "
- #define_proc_attributes rbx_report_functional_si_endpoints -info "Rubix Custom Command: "
- define_proc_attributes rbx_report_pba_timing_all_endpoints -info "Rubix Custom Command: "
- define_proc_attributes rbx_check_clock_cell_type -info "Rubix Custom Command: "
- #define_proc_attributes rbx_report_average_clock_latency -info "Rubix Custom Command: "
- define_proc_attributes rbx_report_xtalk_clock_nets -info "Rubix Custom Command: "
- define_proc_attributes rbx_report_xtalk_bottlenecks -info "Rubix Custom Command: "
- define_proc_attributes rbx_get_noise_pin_details -info "Rubix Custom Command: "
- define_proc_attributes rbx_get_si_violators_from_pt_reports -info "Rubix Custom Command: "
- #define_proc_attributes rbx_get_glitch_nets -info "Rubix Custom Command: "
- define_proc_attributes rbx_analyze_rc011 -info "Rubix Custom Command: "
- define_proc_attributes rbx_get_clock_pins_from_pt_rpt_constraints -info "Rubix Custom Command: "
- #define_proc_attributes rbx_get_lib_transition -info "Rubix Custom Command: "
- #define_proc_attributes rbx_write_transition_file -info "Rubix Custom Command: "
- #define_proc_attributes rbx_trace_buf_inv_chain -info "Rubix Custom Command: "
- #define_proc_attributes rbx_report_cell_interface_timing -info "Rubix Custom Command: "
- #define_proc_attributes rbx_report_clock_latency -info "Rubix Custom Command: "
- #define_proc_attributes rbx_report_pin_setup_hold -info "Rubix Custom Command: "
- #define_proc_attributes rbx_get_slacks -info "Rubix Custom Command: "
- #define_proc_attributes rbx_get_fo_ff -info "Rubix Custom Command: "
- #define_proc_attributes rbx_get_driver -info "Rubix Custom Command: "
- #define_proc_attributes rbx_get_driver_cell -info "Rubix Custom Command: "
- #define_proc_attributes rbx_get_receivers -info "Rubix Custom Command: "
- #define_proc_attributes rbx_get_coreceivers -info "Rubix Custom Command: "
- #define_proc_attributes rbx_print_ref_name -info "Rubix Custom Command: "
- #define_proc_attributes rbx_get_complex_cells -info "Rubix Custom Command: "
- #define_proc_attributes rbx_is_startpoint_latch -info "Rubix Custom Command: "
- #define_proc_attributes rbx_show_arcs -info "Rubix Custom Command: "
- #define_proc_attributes rbx_get_rise_fall_diff -info "Rubix Custom Command: "
- #define_proc_attributes rbx_find_clocks -info "Rubix Custom Command: "
- #define_proc_attributes rbx_estimate_eco -info "Rubix Custom Command: "
- #define_proc_attributes rbx_estimate_size_cell -info "Rubix Custom Command: "
- #define_proc_attributes rbx_print_list -info "Rubix Custom Command: "
- #define_proc_attributes rbx_print_clk_freq -info "Rubix Custom Command: "
- #define_proc_attributes rbx_get_runtime -info "Rubix Custom Command: "
- #define_proc_attributes rbx_format_float -info "Rubix Custom Command: "
- #define_proc_attributes rbx_value -info "Rubix Custom Command: "
- #define_proc_attributes rbx_ladd -info "Rubix Custom Command: "
- #define_proc_attributes rbx_get_biggest -info "Rubix Custom Command: "
- # --- EOF ---
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement