Tcl DISCUSSION

How do I pass bus names with square brackets like data[3] to get_ports in FPGA and EDA Tcl scripts?

Started by sohailanwar Tcl square bracketsbus names in SDCget_portsFPGA constraintsEDA tool scripting
5 replies 248 views 6 participants
Latest activity · 30 Sep 2026

How do I pass bus names with square brackets like data[3] to get_ports in FPGA and EDA Tcl scripts?

sohailanwar Tcl Forum
#1

I am writing timing constraints and pin assignments for an FPGA design in Tcl. A line such as set_input_delay 2.0 -clock clk [get_ports data[3]] fails with invalid command name "3". Putting the name in double quotes gives the same error, and when I build names in a loop with "data[$i]" I get invalid command name "0".

How should bus bits be written in constraint files and scripts, and how do I loop over all bits of a bus?

Community replies 5

Re: How do I pass bus names with square brackets like data[3] to get_ports in FPGA and EDA Tcl scripts?

#2

The error comes from Tcl itself, before the tool sees anything. Square brackets mean command substitution, so in get_ports data[3] the interpreter tries to run a command called 3 and insert its result. Double quotes do not help, because command substitution is still active inside them.

Braces switch substitution off, so the standard spelling in constraint files is [get_ports {data[3]}]: the outer brackets call get_ports, the braces deliver the literal text data[3] to it. Escaping each bracket with a backslash, data\[3\], is equivalent.

Re: How do I pass bus names with square brackets like data[3] to get_ports in FPGA and EDA Tcl scripts?

#3

For a computed index you need the variable substituted but the brackets left alone, which braces cannot do since they block $i as well. Two clean options: escape only the brackets inside quotes, get_ports "data\[$i\]", or build the name with format: get_ports [format {data[%d]} $i]. With i equal to 5 both produce data[5].

A loop over an 8-bit bus is then for {set i 0} {$i < 8} {incr i} { ... } with one of those forms in the body.

Re: How do I pass bus names with square brackets like data[3] to get_ports in FPGA and EDA Tcl scripts?

#4

Often no loop is needed, because the object queries accept wildcards: [get_ports {data[*]}] selects every bit of the bus, and one constraint can be applied to the whole set. Keep the braces here too; without them Tcl would try to run a command named *.

There is a second layer to be aware of: the tool's own pattern matcher. In ordinary Tcl glob matching, brackets denote a character set, and tools differ in whether they treat brackets in object names literally or as pattern syntax. If a braced name still matches nothing, check the pattern-matching section of your tool's Tcl or SDC reference; some flows need the brackets escaped inside the braces as well.

Re: How do I pass bus names with square brackets like data[3] to get_ports in FPGA and EDA Tcl scripts?

#5

Check what a query returned before relying on it. In Vivado the result can be used like a Tcl list, so llength [get_ports {data[*]}] should print 8 for an 8-bit bus, and foreach p [get_ports {data[*]}] { puts [get_property NAME $p] } lists the names. In Synopsys-style shells and in the Quartus timing analyzer the result is a collection handle, not a list: count it with sizeof_collection or get_collection_size respectively, and iterate with foreach_in_collection.

A query that silently matches nothing is the most common reason a constraint has no effect, so look for "no objects matched" warnings in the log as well.

Re: How do I pass bus names with square brackets like data[3] to get_ports in FPGA and EDA Tcl scripts?

#6

Two habits prevent most of these problems. First, brace every object name and pattern in constraint files as a matter of routine, including ones without brackets, such as [get_ports {clk}]; it costs nothing and the file survives later renaming to a bus. Second, remember that hierarchical names of generated logic can contain brackets, dots and backslash-escaped identifiers, so copy names from the tool's own report or netlist view instead of guessing them, and test a new query on the tool's Tcl console before putting it in the constraint file.

TEP COMMUNITY