Timing Analyzer Instance and Entity in Scripts

author-image

By

When you write custom scripts for the Timing Analyzer, you should be aware of how different Tcl API functions handle and return entity and instance names in node names. There is a setting in the Quartus® II software called Display entity name for node name that controls whether node names are displayed with or without entity names.
The Tcl API function get_registers can always accept names that include entities for its filter, regardless of the setting of Display entity name for node name. The get_registers function always returns names according to the setting of Display entity name for node name.
Table 1 shows examples of the node name returned by the command get_registers <filter>, where a design includes a register named ram:my_ram|ctrl:ctrl_1|addr[0].

The Tcl API functions get_pins and get_cells behave differently than get_registers. The get_pins and get_cells functions accept and return only names that contain instance names. They do not accept or return names with entities, regardless of the value of Display entity name for node name.
Table 2 shows examples of the node name returned by get_pins <filter>, where a design includes a register named ram:my_ram|ctrl:ctrl_1|addr[0] with a clock pin named clk. The get_cells function behaves the same way, though it accepts and returns cell names.

Note:

  1. The get_pins function produces a warning indicating that the specified filter could not be matched with a pin.

When you are aware of the difference in the way get_registers, get_pins, and get_cells handle and return node names that include entities, you can avoid subtle problems that can occur when you combine the functions. The following example shows code that works when Display entity name for node name is off, but fails when it is on.

foreach_in_collection reg_id [get_registers foo*] {
    set reg_name [get_node_info -name $reg_id]
    # ...
    set pin_id [get_pins ${reg_name}|clk]
    # If reg_name includes entities, the get_pins call always fails
}

When Display entity name for node name is off, the variable reg_name does not include entity names, so the get_pins call succeeds. When Display entity name for node name is on, the variable reg_name does include entity names, so the get_pins call fails.

Solutions

The easiest way to avoid potential problems is to turn off Display entity name for node name and use only instance names to refer to nodes. This solution ensures that the names returned by get_registers are instance-only names and work with get_pins and get_cells.

If you do not turn off Display entity name for node name, and you pass names returned by get_registers to get_pins or get_cells, you must ensure that you remove all entity names. You can use a simple regsub expression to remove most entity names. The following Tcl command removes all entity names from a node name, as long as the entity names contain only letters, digits, and underscores (characters in the \w character class).

regsub -all {\w*:} $reg_name {} reg_name

The regular expression pattern listed does not handle every valid character in HDL identifiers. It does not handle generated entity names that include backslashes (\), the dollar sign character ($) in simple Verilog HDL identifiers, escaped Verilog HDL identifiers, or extended identifiers in VHDL. You can construct more advanced regular expressions to handle entity names with those characters, but it is simpler to turn off Display entity name for node name.
The following example shows how to integrate the regsub expression with the non-working example above. In the following example, the regsub expression removes entity names from the register name (subject to the character exclusions described), so the get_pins call does not fail. The example works regardless of the value of Display entity name for node name.

foreach_in_collection reg_id [get_registers foo*] {
    set reg_name [get_node_info -name $reg_id]
    regsub -all {\w*:} $reg_name {} reg_name
    # reg_name no longer includes entities
    # ...
    set pin_id [get_pins ${reg_name}|clk]
    # reg_name no longer includes entities, so get_pins succeeds
}