Quartus® II Tcl 示例:查找时序节点

author-image

作者

Quartus II 时序网表中的节点用 ID(正整数)表示。每个节点都有一个名称,即后拟合网表中的名称。在使用 ::quartus::advanced_timing 包中的命令搜索时序网表时,通常会按照节点名称搜索节点。例如,您想要查找特定 I/O 引脚的扇出。为此,您需要查找具有待查找引脚名称的节点 ID。以下示例程序在网表中的所有时序节点中搜索您指定的名称,并返回匹配节点的 ID,如果没有匹配的节点,则返回 -1。

package require ::quartus::advanced_timing

proc find { name } {
    
    foreach_in_collection node_id [get_timing_nodes -type all] {

        set node_name [get_timing_node_info -info name $node_id]
           
        if { [string equal $name $node_name ] } {
            return $node_id
        }
    }   
    
    return -1
}

在 Tcl 脚本中,可以调用以下示例中所示的程序:

set id [find clk_33MHz]
if { $id == -1 } {
    post_message -type warning "Couldn't find clock pin node"
}

改进示例代码

可通过多种方法改进示例代码。

添加通配符支持以及返回多个 ID

对于层次路径长的名称,难以请求精确匹配。更改示例,使其支持通配符匹配,可以更轻松地搜索层次路径长的节点。通过进行额外修改,对所有匹配项返回多个节点 ID,就可以使用脚本返回多组节点 ID。这样可以更轻松地对总线中的所有位进行迭代。

由于通配符可以匹配多个名称,因此需要支持返回多个 ID 的功能。一种简单的方法是返回名称与模式匹配的所有节点 ID 的列表。如果没有与模式匹配的名称,则返回一个空列表。

以下示例搜索时序网表中的所有节点,然后返回名称与模式匹配的所有节点 ID 的列表。此示例使用 Tcl 全局样式匹配,支持星号 (*)、问号 (?) 和方括号 ([])。

package require ::quartus::advanced_timing

proc find { pattern } {
    
    set return_ids {}
    foreach_in_collection node_id [get_timing_nodes -type all] {

        set node_name [get_timing_node_info -info name $node_id]
           
        if { [string match $pattern $node_name ] } {
            lappend return_ids $node_id
        }
    }   
    
    return $return_ids
}

请记住,Tcl 在 string match 命令中使用方括号分隔要匹配的字符。如以下示例所示,调用 find 命令后,匹配的是 addr1 和 addr0,而非 addr[10]!

set matches [find addr[10]]

由于总线名称使用方括号表示各个位,因此应将方括号用作总线位选择器,对模式进行转义。如以下示例所示,使用 scape_brackets 命令调用 find 命令后,将返回名为 addr[10] 的节点的节点 ID。

set matches [find [escape_brackets addr[10]]]

除非您想要使用方括号表示要匹配的字符范围,否则应始终使用 escape_brackets 命令对传递到 find 命令的模式进行转义。

添加节点类型筛选

您可能想要限制在其中搜索匹配名称的节点的类型。在时序网表较大的设计中,这样可以加快搜索速度。可以使用 get_timing_nodes 命令的 -type 选项将返回集合中的节点仅限于引脚、寄存器、时钟以及各种其它类型的节点。

以下示例以上一个模式匹配示例为基础。如果未指定模式,则默认为 *,可匹配各种节点。有一个用于限制节点类型的选项,默认为“全部”。

此示例使用 Quartus II 软件附带的 cmdline Tcl 包,提供了一种简单的方法,可以自文档化的方式将参数传递到程序。

package require ::quartus::advanced_timing
package require cmdline

proc find { args } {
    
    set options {\
        { "pattern.arg" "*" "Pattern to search for" } \
        { "type.arg" "all" "Node type to search" } \
    }
    array set opts [::cmdline::getoptions args $options]

    set return_ids {}
    foreach_in_collection node_id [get_timing_nodes -type $opts(type)] {

        set node_name [get_timing_node_info -info name $node_id]
           
        if { [string match $opts(pattern) $node_name ] } {
            lappend return_ids $node_id
        }
    }   
    
    return $return_ids
}

以下代码显示了使用上一个示例的多种方法。

# 返回时序网表中的每个节点 ID。
# 模式默认为 *
# 类型默认为“全部”
find 

# 返回时序网表中所有引脚的节点 ID
# 模式默认为 *
find -type pin

# 返回以 addr 开头的引脚的节点 ID
find -pattern addr* -type pin

# 返回处于总线 0 位的寄存器的节点 ID
find -pattern [escape_brackets *[0]] -type reg]