Control flow

The cards come in more than one shape: a command to explain, and a snippet with a fault to find. 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 7 cards in this section, with answers
  • if { $slack < 0 } { puts "failing" } else { puts "met" }
    The braces keep the condition unsubstituted so `if` evaluates it as an expression.

    Hint: Ask why the condition is in braces rather than quotes.

    if evaluates its condition the way expr does, so the same rule applies: braces stop the text being substituted first. Note also that } else { must sit on the line the brace closes, since a newline would end the command. Tcl reference

  • foreach {name value} $pairs { puts "$name = $value" }
    Takes two elements per pass, binding them to the two names.

    Hint: Two variable names in braces. Ask how many elements each pass consumes.

    A flat list of alternating keys and values is a common shape in tool output, and this is how it is walked. foreach can also take several lists at once, stepping through them in parallel. Tcl reference

  • switch $stage { place { global_placement } route { global_route } default { error "unknown stage: $stage" } }
    Runs the branch that matches, and default catches anything else.

    Hint: Ask what the last branch is for, and what happens without it.

    Only the matching branch runs. Without a default an unmatched value does nothing at all, silently, which is how a typo in a stage name becomes a script that appears to work. Patterns are glob-style unless -exact or -regexp is given. Tcl reference

  • for {set i 0} {$i < $n} {incr i} { ... } while {[gets $fh line] >= 0} { ... }
    Both are ordinary commands whose arguments are braced scripts.

    Hint: Count the pieces of the first line and ask what each one is.

    The loop takes four arguments: a start script, a test expression, a step script, and a body. Nothing here is special syntax, which is why the opening brace must sit on the same line as the command: a newline would end it. Tcl reference

  • foreach c $cells { if { [string match "FILLER*" $c] } { continue } if { $found } { break } }
    The first goes to the next item; the second ends the loop entirely.

    Hint: One skips the rest of this pass, the other leaves the loop.

    Both are implemented as return codes rather than as jumps, which is why they work inside a braced body but not inside a procedure called from one. A procedure that wants to stop its caller's loop has to return a value the caller tests. Tcl reference

  • switch -glob -- $name { *_reg* - *_ff* { set kind register } default { set kind logic } }
    Glob matching, with the first pattern falling through to the next body.

    Hint: One branch has a body of a single hyphen.

    A body of one hyphen means use the next one, which is how several patterns share code. The double hyphen ends the options, so a value beginning with one is not mistaken for a switch. Without -glob the match is exact, and -regexp is also available. Tcl reference

  • if { $slack < 0 } { puts "failing" }
    The newline ends the command, so the body is not passed to it.

    Hint: Remember that the body is an argument, not a block.

    A command ends at a newline, so this is a conditional with no body, followed by a script that the interpreter tries to run as a command. The opening brace has to sit on the same line, which is why every Tcl script looks the way it does. Tcl reference