Skip to content
VLSI Mentor

Tcl · Module 16

Standard Tcl vs Tool Commands: The Boundary

Every line in a flow script is one of two things, and they have completely different rules about where they will run. Telling them apart is the first skill of Part II.

Foundation18 min readtcledapart-iiportabilityinfo-commandstool-commands

Part II · Module 16 · Chapter 16.4 · Standard Tcl vs Tool Commands: The Boundary

Open any flow script and every line is one of two kinds:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
foreach cell [get_cells -hierarchical *fifo*] {
    puts "found $cell"
}

foreach and puts are Tcl. They work in tclsh, in every EDA tool, and in every other program that embeds Tcl. get_cells is a tool command — one vendor added it to one interpreter, and it exists nowhere else.

The two look identical, because Chapter 2.1 was right that everything is a command. Telling them apart anyway is the first real skill of Part II, because it decides what you can reuse, what you must document, and what will break when somebody runs your script somewhere else.

1. The boundary

Two parallel left-to-right flows. A standard Tcl command is defined by the language, exists in any interpreter, and is portable. A tool command is registered by one application, exists only inside that tool, and is not portable.Standard Tclforeach, set, lsort, regexpDefined by thelanguageabout 90 commands, fixedRuns anywhereportable across every toolTool commandget_cells, report_timingRegistered by onetoolthousands, andtool-specificRuns only thereabsent everywhere else12
Figure 1 — the two kinds of command in any flow script. Standard Tcl is defined by the language and runs anywhere; tool commands are registered by one application into its own interpreter and run only there. Both are invoked with identical syntax, which is why the boundary has to be learned rather than seen.

2. Part I never used one

Worth stating, because it is the evidence you already have.

Across the whole of Part I — fifteen modules — not a single example used get_cells, get_ports, report_timing, create_clock or any other vendor command. Every example ran in a plain tclsh.

That was deliberate, and it means the language you learned is the portable half. Everything from Part I will work inside any tool. Everything you learn from here on is an addition that may not.

3. The standard set is small enough to know

There are about ninety standard commands. Not thousands — ninety. A plain tclsh reports:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  total: 93

And they are the names you already recognise:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  append     apply      array      binary     break
  catch      cd         chan       clock      close
  concat     continue   dict       encoding   eof
  error      eval       exec       exit       expr
  file       for        foreach    format     gets
  glob       global     if         incr       info
  join       lappend    lassign    lindex     linsert
  list       llength    lrange     lsearch    lset
  lsort      namespace  open       package    proc
  puts       pwd        read       regexp     regsub
  rename     return     scan       set        source
  split      string     subst      switch     trace
  unset      uplevel    upvar      variable   while

That is the set, with Tcl's internal auto_* helpers and the event/channel plumbing a flow script never types left out. It is learnable. And it is the whole trick: if a command is not in that set, it came from somewhere else.

4. The quick heuristic, and where it fails

Vendor commands are overwhelmingly verb_noun with an underscore: get_cells, report_timing, create_clock, set_input_delay, write_verilog. Standard Tcl commands are nearly always a single lowercase word: foreach, lsort, string, expr.

The numbers back it up on this interpreter:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  standard commands containing an underscore: 5 of 93
    auto_execok auto_import auto_load auto_load_index auto_qualify

  single-word commands: 88

So the heuristic is: an underscore means it is probably a tool command. Tested:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  foreach          looks like a tool command: no   actually in plain Tcl: yes
  lsort            looks like a tool command: no   actually in plain Tcl: yes
  string           looks like a tool command: no   actually in plain Tcl: yes
  expr             looks like a tool command: no   actually in plain Tcl: yes
  get_cells        looks like a tool command: yes   actually in plain Tcl: no
  report_timing    looks like a tool command: yes   actually in plain Tcl: no
  create_clock     looks like a tool command: yes   actually in plain Tcl: no
  current_design   looks like a tool command: yes   actually in plain Tcl: no
  auto_load        looks like a tool command: yes   actually in plain Tcl: yes

5. The definitive test: ask the interpreter

info commands tells you what exists here — the introspection from Chapter 14.10 doing its most valuable job.

In a plain tclsh, the vendor commands are simply absent:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  info commands get_cells      : ''
  info commands get_ports      : ''
  info commands get_pins       : ''
  info commands get_nets       : ''
  info commands get_clocks     : ''
  info commands report_timing  : ''
  info commands create_clock   : ''
  info commands current_design : ''
  info commands link_design    : ''
  info commands read_verilog   : ''

Empty every time. These are not Tcl.

But "does it exist here" alone cannot tell you which kind it is, because inside a tool both kinds exist. For that, compare against a baseline captured from a plain interpreter:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
# Capture once, from a plain tclsh:
#   foreach c [lsort [info commands]] { puts $c }  > baseline.txt

set baseline {}
set fp [open baseline.txt r]
while {[gets $fp line] >= 0} { lappend baseline [string trim $line] }
close $fp

foreach c {foreach get_cells report_timing} {
    set known [expr {[lsearch -exact $baseline $c] >= 0}]
    set here  [expr {[llength [info commands $c]] > 0}]
    puts [format "    %-14s in plain Tcl: %-3s   available here: %-3s  -> %s" \
        $c [expr {$known?"yes":"no"}] [expr {$here?"yes":"no"}] \
        [expr {$known ? "standard Tcl, portable" : ($here ? "a tool command, NOT portable" : "not available at all")}]]
}

Run inside a shell that has tool commands added:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
    foreach        in plain Tcl: yes   available here: yes  -> standard Tcl, portable
    get_cells      in plain Tcl: no    available here: yes  -> a tool command, NOT portable
    report_timing  in plain Tcl: no    available here: no   -> not available at all

Three outcomes, correctly distinguished. And the same comparison lists everything a shell adds:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  commands this shell adds: current_design get_cells get_ports read_design

6. Why it matters

Four practical consequences, in rough order of how soon they will bite you.

Portability. A script using only standard Tcl runs in any tool. One using get_cells runs only where get_cells is defined — and not necessarily in every tool from the same vendor, as Chapter 17.5 shows.

Documentation. A script that uses tool commands has an unstated requirement. Say it at the top, where Chapter 15.9 put the usage line:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
# Requires: a tool providing get_cells, get_ports and report_timing.
# Developed against <tool> <version>.

Testability. This is the one people miss. A procedure that takes a list of names can be tested in tclsh; one that calls get_cells itself cannot be tested without a tool licence and a design.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
# hard to test: reaches for the tool itself
proc count_fifos {} {
    return [llength [get_cells -hierarchical *fifo*]]
}

# easy to test: the caller supplies the data
proc count_matching {names pattern} {
    set n 0
    foreach c $names { if {[string match $pattern $c]} { incr n } }
    return $n
}

The second runs in tclsh against a list you wrote by hand. Pushing the tool calls to the edges and keeping the logic in standard Tcl is the same separation Chapter 15.7 made between bin/ and lib/ — and here it also buys you a test suite that needs no licence.

Checking before you run. A long flow should not fail at minute forty because a command is missing. The preflight from Chapter 14.10 §8 applies directly:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
proc require_commands {args} {
    set missing {}
    foreach c $args {
        if {![llength [info commands $c]]} { lappend missing $c }
    }
    if {[llength $missing]} {
        error "this tool does not provide: [join $missing {, }]" {} \
              [list TOOL MISSING $missing]
    }
}

require_commands get_cells get_ports report_timing

7. Reading someone else's script

Open an unfamiliar flow script and sort every command into three piles:

  1. Standard Tcl — foreach, set, if, lsort, regexp. You already know these; they are not where the difficulty is.
  2. Tool commands you recognise — get_cells, create_clock. Look them up in that tool's reference, not on the internet, because the options differ between vendors (Chapter 17.6).
  3. Commands that are neither — usually procedures the team wrote, sourced from a site library. info procs <name> and info body <name> will show you the source, which is Chapter 14.10 §4.

That third pile is where the surprises live, and it is the one people forget to check.

8. The honest summary

Part II is going to teach you a lot of commands that are not Tcl. That is the deal, and it is worth being clear-eyed about it:

  • The language you learned in Part I is permanent and portable.
  • The commands you learn from here are specific to tools, and some of them will be obsolete in ten years.
  • The skill that lasts is knowing which is which, and structuring scripts so the portable part is the large part.

A flow script where the tool calls are concentrated in a few procedures at the edge, and the logic is standard Tcl in the middle, survives a tool change. One where the two are interleaved on every line does not.

9. Exercises

Exercise 1. foreach cell [get_cells *] { ... } — which parts are Tcl and which are not?

Exercise 2. Roughly how many standard Tcl commands are there, and why does that number matter?

Exercise 3. State the underscore heuristic and give the counterexample from this chapter.

Exercise 4. Why is info procs the wrong way to identify tool commands? Give both reasons.

Exercise 5. What is the definitive test, and what does it need that info commands alone does not?

Exercise 6. Rewrite proc count_fifos {} { llength [get_cells -hierarchical *fifo*] } so it can be tested in tclsh.

Exercise 7. A flow fails after forty minutes with invalid command name "report_qor". What should have happened instead, and how?

Where this fits

Part of the Tcl curriculum.