Tcl in tool scripts

Each card shows a command to explain. A missed card returns later in the round and starts the schedule over. A card answered correctly moves up the schedule and next appears after 1, 3, 7, then 21 days. Keys 1 to 4 choose an option, h shows a hint, and Enter moves on. A hint keeps the card where it is on the schedule. An ordering card is answered by clicking its items in order, and one wrong click ends it. Time values are in nanoseconds. Progress is stored in this browser.

SourceTCL (Tool Command Language) is the scripting language every place-and-route and timing tool embeds, so the same skills carry between them. These cards follow the official Tcl manual pages, and each answer links to the page for that command. The examples are in the style the OpenROAD-flow-scripts scripts use, since that is Tcl written for a real flow. Reference: the Tcl manual (Tcl on GitHub).
All 6 cards in this section, with answers
  • set cells [get_cells *_reg*] puts [llength $cells]
    The tool returns objects, which not every list command handles.

    Hint: Ask whether what the tool returns is really a Tcl list.

    What comes back is a collection of objects. They carry properties that a name cannot, which is why get_property and get_full_name exist. Some tools return a collection type that needs its own commands, so mixing list commands with tool objects is a common source of confusion when a script moves between tools. Tcl reference

  • set args "" if { $::env(GPL_TIMING_DRIVEN) } { append args " -timing_driven" } global_placement {*}$args
    Expands the string into separate arguments instead of one long one.

    Hint: Read the last line: something is done to the variable before the command sees it.

    Without {*}, a command receives " -timing_driven" as one argument and rejects it. Building a command's options conditionally and expanding them is the standard way a flow turns variables into tool arguments. Tcl reference

  • set period_ns 2.0 create_clock -name clk -period $period_ns [get_ports clk]
    The number has no unit in Tcl; the tool reads it in library units.

    Hint: Ask what the tool does with the number, and where its unit comes from.

    Library units are usually nanoseconds, but not always. A script can hold a number that means something different to the tool than to its author, and nothing will complain. report_units shows what the tool is using, and set_units records the intent in a constraint file. Tcl reference

  • foreach path [find_timing_paths -path_delay max -group_path_count 10] { puts "[get_property $path slack]" }
    Iterates the path objects the tool returns, reading a property from each.

    Hint: Ask why the script asks for objects rather than reading a report.

    Parsing a printed report is brittle: its format changes between versions. Asking for objects and reading properties is stable, and it is why reporting commands usually have a find_ counterpart meant for scripts. Tcl reference

  • if { ![design_is_routed] } { error "routing did not finish" }
    Stops the flow before a later stage runs on a design that is not ready.

    Hint: Ask what this protects the rest of the flow from.

    A stage that runs on an unfinished design either fails confusingly much later or produces results that look plausible and are not. Checks between stages turn that into one clear failure at the point where something actually went wrong. Tcl reference

  • foreach c $cells { if { [get_property [get_cells $c] is_buffer] } { ... } }
    It queries the database once per cell, not once in total.

    Hint: Ask what the inner call does on every pass of the loop.

    A database query costs far more than a Tcl operation, and a loop over a million instances turns a second into an hour. The fix is to ask once, with a filter in the query, and loop over what comes back. This is the usual reason a constraint script takes longer than the tool stage it configures. Tcl reference