Quartus® II Tcl Example: Elaborate Nodes in Timegroups

author-image

By

Timegroups are an efficient way to make timing assignments. You can specify wildcards that include nodes matching the pattern in the group, and specify wildcards that exclude nodes matching the pattern from the group. You might need to see a list of all the nodes in the timegroup to verify you specified the right wildcard patterns.

These scripts elaborate the nodes in a timegroup in your design. The script iterates over every timing node in your design, comparing the timing node's name with each timegroup inclusion pattern, then each timegroup exclusion pattern.

There is a limitation with this script; it does not handle nested timegroups. Including or excluding a timegroup as an element of another timegroup is valid, but not supported by this script.

To include all bits of a bus in a timegroup, use an asterisk after the bus name in versions 4.2 and below of the Quartus II software. Beginning with version 5.0, you can specify a bus name without an asterisk. The script includes a check for this behavior, based on the software version number.

global quartus
load_package advanced_timing
load_package project

# Determine whether the script is running in 4.2 and before,
# or 5.0 and later. 5.0 and later recognizes <bus name> as 
# a valid timegroup entry, while 4.2 and before require
# <bus name>* as a timegroup entry.
regexp {^Version (\d)} $quartus(version) match qver
if { $qver < 5 } {
    set need_asterisk 1
} else {
    set need_asterisk 0
}

project_open [lindex $quartus(args) 0]

create_timing_netlist

set tg_name [lindex $quartus(args) 1]

post_message "The following nodes are members of the timegroup $tg_name:"

set tg_name [escape_brackets $tg_name]
set tg_members [timegroup -get_members $tg_name]
set tg_exceptions [timegroup -get_exceptions $tg_name]

# This loop walks through every timing node in the design 
foreach_in_collection node_id [get_timing_nodes -type all] {

    set node_name [get_timing_node_info -info name $node_id]

    # If the node name is not in a bus, clear the bus_name.
    # Otherwise set it.
    if { ! [regexp {(.*?)\[\d+\]} $node_name match bus_name] } {
        set bus_name ""
    }
    
    # Now that we have the node name, check to see whether it matches  
    # any patterns in the specified timegroup  
    set matches 0  
    foreach_in_collection member $tg_members {

        set esc_name [escape_brackets [lindex $member 2]]
        if { [string match $esc_name $node_name] } {
            set matches 1
        } elseif { ! $need_asterisk && \
            [string match $esc_name $bus_name] } {
            set matches 1
        }
    }

    # If $matches is 1 here, the timing node matched a member name  
    # in the timegroup. However, it could still match an exception.  
    # Check for that here.
    if { $matches } {
        
        foreach_in_collection exception $tg_exceptions {
            
            set esc_name [escape_brackets [lindex $exception 2]]
            if { [string match $esc_name $node_name] } {
                set matches 0
            } elseif { ! $need_asterisk && \
                [string match $esc_name $bus_name] } {
                set matches 0
            }
        }
    }

    # We've looked at all the exceptions. If $matches is still 1,
    # then the node name matched the member pattern and did not
    # match an exception pattern, so print out the node name.
    if { $matches } {
        post_message $node_name
    }
}

project_close