合并 SDO 文件数据

author-image

作者

此脚本使用 Quartus® II 软件在最大和最小时序分析期间生成的两个 SDO 文件创建一个具有合并时序参数的 SDO 文件。
Quartus II 软件生成单独的 SDO 文件,这些文件对每个三元组中的三个延迟值使用最小或最大延迟值。SDO 文件中的三元组支持最小、典型和最大延迟值,如 (min:typ:max)。Quartus II 软件在最大时序分析期间生成的 SDO 文件中的延迟三元组仅包含最大延迟值,如 (max:max:max)。在最小时序分析期间生成的 SDO 文件中的延迟三元组仅包含最小延迟值,如 (min:min:min)。
此脚本将包含最小值和最大值的 SDO 文件合并在一起,创建一个三元组仅包含最小和最大值(如 (min:max:max))的文件。请注意,对于典型延迟值,也将重复最大延迟值。Altera 不保证此脚本生成的文件适用于最小/最大值混合分析。

运行如下所示的脚本: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]

# 跟踪文件中的行数
set line_num 1

while { 1 } {

    # 读取包含最小值和最大值的 SDO 文件中的下一行
    set more_min [gets $min min_line]
    set more_max [gets $max max_line]

    # 在文件中没有更多数据时停止
    if { $more_min < 0 || $more_max < 0 } {

        # 一个文件中的行数可能大于
        # 另一个文件。在此处发出警告。
        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)"
        }

        # 由于至少一个文件没有更多数据,
        # 因此必须停止循环。
        break
    }

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

        # 如果此行中包含延迟三元组,必须
        # 将这些值合并

        # new_line 累加文本,以供打印。
        # 如果这些行中除延迟三元组以外的部分存在差异,
        #   则设置 line_differences。
        set new_line ""
        set line_differences 0

        # 当行中包含延迟三元组时...
        while { [regexp {\(\d+:\d+:\d+\)} $min_line] } {

            # 提取延迟三元组前面的所有文本、
            # 延迟值本身以及延迟三元组
            # 后面的所有文本
            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
            
            # 如果此行中除延迟三元组以外的部分存在差异,
            # 则设置一个标志
            if { ! [string equal $min_start $max_start] } {
                set line_differences 1
            }

            # 将合并的延迟三元组全部置于新行中
            append new_line $min_start \
                $min_value : $max_value : $max_value
        }

        # 检查此行中其余的文本是否存在
        # 差异。
        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"]
        }

        # 将此行中其余的部分(最后一个延迟三元组后面的部分)
        # 全部置于新行中
        append new_line $min_line

    } else {

        # 如果此行不包含延迟三元组,
        # 包含最小值和最大值的文件中的行应 
        # 完全相同(文件中包含日期戳的情况
        # 除外)。进行快速检查,确保这些行相同,
        # 如果存在差异,则打印警告。
        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
    }

    # 将此行写入到合并文件中
    puts $new $new_line

    incr line_num
}

# 停止文件循环。关闭所有文件
close $min
close $max
close $new

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