Combine SDO File Data

author-image

By

This script creates an SDO file with combined timing parameters from two SDO files generated by the Quartus® II software during maximum and minimum timing analysis.
The Quartus II software generates separate SDO files that use the minimum or maximum delay value for the three delay values in each triplet. Triplets in SDO files support minimum, typical, and maximum delay values like this: (min:typ:max). An SDO file generated by the Quartus II software for maximum timing analysis has delay triplets that include only maximum delay values, like this: (max:max:max). An SDO file generated during minimum timing analysis contains delay triplets that include only minimum delay values, like this: (min:min:min).
This script combines SDO files with minimum and maximum values to create one file with triplets that have both the minimum and maximum numbers, like this: (min:max:max). Note that the maximum delay value is also duplicated for the typical delay value. The file generated by this script is not guaranteed by Altera to work for mixed minimum/maximum analysis.

Run the script like this: quartus_sh -t combine_sdo.tcl -min_sdo <min sdo file> -max_sdo <max sdo file> -new_sdo <new sdo file>

package require cmdline

variable ::argv0 $::quartus(args)

set options { \
                  { "min_sdo.arg" "" "File name of SDO with min timing" } \
                  { "max_sdo.arg" "" "File name of SDO with max timing" } \
                  { "new_sdo.arg" "" "File name of SDO with min/max timing" } \
              }
array set opts [::cmdline::getoptions ::argv0 $options "Bad option"]

set min [open $opts(min_sdo)]
set max [open $opts(max_sdo)]
set new [open $opts(new_sdo) w]

# Keep track of the line number in the file
set line_num 1

while { 1 } {

    # Read the next line from the min and max sdo files
    set more_min [gets $min min_line]
    set more_max [gets $max max_line]

    # Finish when there's no more data in the files
    if { $more_min < 0 || $more_max < 0 } {

        # It is possible that one file could have more lines
        # than the other. Warn about that here.
        if { $more_min >= 0 } {
            post_message -type warning \
                "Skipped lines beginning with line $line_num in $opts(min_sdo)"
        }
        if { $more_max >= 0 } {
            post_message -type warning \
                "Skipped lines beginning with line $line_num in $opts(max_sdo)"
        }

        # Because at least one of the files has no more data,
        # the loop has to stop.
        break
    }

    if { [regexp {\(\d+:\d+:\d+\)} $min_line] } {

        # If the line has a delay triplet in it, the values
        # must be combined

        # new_line accumulates the text to print out.
        # line_differences is set if there differences in the
        #   lines besides the delay triplets.
        set new_line ""
        set line_differences 0

        # While there are delay triplets in the line...
        while { [regexp {\(\d+:\d+:\d+\)} $min_line] } {

            # Extract everything up to the delay triplet, the
            # delay value itself, and everything after the 
            # delay triplet
            regexp {^(.*?\()(\d+):\d+:\d+(\).*$)} $min_line \
                match min_start min_value min_line
            regexp {^(.*?\()\d+:\d+:(\d+)(\).*$)} $max_line \
                match max_start max_value max_line
            
            # Set a flag if there are differences in the line
            # besides the delay triplet
            if { ! [string equal $min_start $max_start] } {
                set line_differences 1
            }

            # Put the combined delay triplet together in the new line
            append new_line $min_start \
                $min_value : $max_value : $max_value
        }

        # Check whatever text in the line is left over for
        # differences.
        if { ! [string equal $min_line $max_line] } {
            set line_differences 1
        }

        if { $line_differences } {
            post_message -type warning \
                [join [list \
                           "These parts of line $line_num are different." \
                           " $opts(min_sdo): $min_line" \
                           " $opts(max_sdo): $max_line"] \
                     "\n"]
        }

        # Put the rest of the line, after the last delay triplet,
        # together in the new line
        append new_line $min_line

    } else {

        # If the line does not have a delay triplet in it,
        # the lines from the min and max files should be 
        # identical (except for example if there's a date stamp
        # in the file). Do a quick check to make sure the lines 
        # are the same and print a warning if they're different.
        if { ! [string equal $min_line $max_line] } {
            post_message -type warning \
                [join [list \
                           "Line $line_num is different." \
                           " The new file contains the first line below." \
                           "  $opts(min_sdo): $min_line" \
                           "  $opts(max_sdo): $max_line"] \
                     "\n"]
        }
        set new_line $min_line
    }

    # Write the line out to the combined file
    puts $new $new_line

    incr line_num
}

# Done looping through the files. Close everything
close $min
close $max
close $new

post_message "Done combining files into $opts(new_sdo)"