Tcl · Module 16
Why EDA Tools Embed Tcl
A chip tool has thousands of commands and no way to predict how you will combine them. Embedding a command language is how it hands that decision to you.
Foundation17 min readtcledapart-iiembeddingtool-shellsautomation
Part II · Module 16 · Chapter 16.1 · Why EDA Tools Embed Tcl
Part I taught the language. Part II is about where you will actually use it: inside the tools that build chips.
Before any of that, one question is worth answering properly, because the answer explains almost everything about how these tools behave. Why does a synthesis tool contain a scripting language at all?
1. The problem a tool vendor has
Imagine you are building a timing analyser. You know a great deal about what engineers will want to ask: the worst path to a flop, the slack on one clock domain, which endpoints fail at a corner. You know almost nothing about what any particular team will want to do with the answers.
One team wants to loop over forty blocks and write a summary per block. Another wants to stop the flow when any path is worse than a threshold that depends on the design. A third wants to re-run with three different constraint files and compare. A fourth wants something you have never thought of.
You have three options.
Build a GUI for every combination. Impossible. The combinations are the point, and they are unbounded.
Invent a configuration format. You start with a file of settings. Then someone needs a condition, so you add if. Then a repetition, so you add a loop. Then a value computed from another value, so you add expressions and variables. You have now invented a programming language, badly, and your users have to learn it and it only works in your tool.
Embed a language that already exists. Ship a real interpreter, add your commands to it, and let people combine them however they like.
Every major EDA vendor took the third option, and most of them took the same language.
2. Why Tcl specifically
Tcl was designed for exactly this job. John Ousterhout built it in the late 1980s as a tool command language — a language meant to be embedded in other programs rather than used on its own. That is not a coincidence of history; it is the stated purpose, and it is in the name.
Four properties made it the obvious choice, and they still hold:
- Everything is a command. As Chapter 2.1 established,
set x 5andget_cells *have the same shape. A vendor adding a command does not extend a grammar — there is no grammar to extend. Their command looks exactly like a built-in one, because structurally it is one. - It is small and embeddable. The interpreter is a C library a program links against. The tool stays the main program; Tcl is a component inside it.
- Extending it is a C function call away. Registering a new command is a few lines. A tool with four thousand commands is the same mechanism four thousand times.
- It has no opinions about your domain. Tcl knows nothing about netlists or timing, which is exactly what you want from the glue.
3. What a tool shell actually is
Here is the sentence to hold on to for the whole of Part II:
A tool shell is a standard Tcl interpreter with extra commands and extra state added to it.
Not a Tcl-like language. Not a dialect. The same interpreter you have been using, with more commands registered in it and a design database behind them.
This is the same picture Chapter 1.3 drew for any host application. A chip tool is simply the most important example of one.
4. Proving it, with a shell you can run
No EDA tool is involved in what follows. Instead, here is a teaching mock — about forty lines of ordinary Tcl that adds a few design-query commands to a plain interpreter. It is not a real tool and it knows nothing about real hardware. Its only job is to demonstrate the mechanism, and because it is ordinary Tcl, everything below really ran.
# minishell.tcl — a teaching mock of what an EDA tool shell IS:
# a standard Tcl interpreter with extra commands and extra state added to it.
namespace eval ::design {
variable name ""
variable cells {}
variable ports {}
}
proc read_design {path} { ... } ;# loads the "design" into that state
proc current_design {} {
if {$::design::name eq ""} { error "no design loaded" }
return $::design::name
}
proc get_cells {{pattern *}} {
set out {}
foreach c $::design::cells {
if {[string match $pattern [lindex $c 0]]} { lappend out [lindex $c 0] }
}
return $out
}In a plain tclsh, those commands do not exist:
info commands get_cells -> ''
calling it -> 1 / invalid command name "get_cells"Source the mock into the same interpreter and they do:
info commands get_cells -> 'get_cells'
current_design -> cpu_top
get_cells * -> u_fifo u_alu u_ctrl u_decode
get_cells u_*c* -> u_ctrl u_decode
get_ports * -> clk reset_n data_in data_outNothing about Tcl changed. Four commands were registered, and some state appeared behind them. That is the whole of what a tool shell is, and a real one differs only in scale — thousands of commands instead of four, implemented in C instead of Tcl, and a real design database instead of a list.
5. The half that does not change
Now the consequence that matters most to you, and the reason Part I was worth doing.
Take an ordinary piece of standard-Tcl work — some list handling, an expr, a format, a regexp — and run it twice: once in a plain interpreter, once in one that has had the tool commands added.
llength pins : 4
lsort : clk data_in data_out reset_n
filtered : clk reset_n
expr : 42
format : 3.14
regexp : 1 -> out llength pins : 4
lsort : clk data_in data_out reset_n
filtered : clk reset_n
expr : 42
format : 3.14
regexp : 1 -> outByte for byte identical. A diff of the two runs reports no difference at all.
6. What the tool contributes
If the language is unchanged, the tool's contribution is worth naming precisely. It adds three things:
- Commands —
get_cells,report_timing,create_clockand several thousand others. Each is an ordinary Tcl command that happens to be implemented inside the tool. - State — a design database. The commands are not pure functions;
get_cells *answers differently before and after a design is loaded, because there is a loaded design behind it. The mock models this with a namespace variable; a real tool has the netlist, the timing graph, the physical data. - A session — the tool starts, sources some setup files, and stays alive while you work. Module 17 is about living inside that session.
The state is the part that trips people up. In Part I, lsort $x with the same $x always gave the same answer. get_cells * does not, because the thing it is asking about changes as the flow progresses.
7. What this buys you
Because it is a real language rather than a settings file, everything from Part I is available at the moment you need it:
- A loop over blocks is
foreach, not forty copied lines. - A conditional stop is
ifplusexitwith a status your build system reads. - Shared logic goes in a library file and is
sourced by every flow that needs it. - A failure can be
catched, reported with context, and turned into a non-zero status instead of a wall of text nobody reads. - A parameterised flow takes command-line arguments instead of being edited before each run.
None of that is an EDA feature. It is Part I, applied where it matters.
8. The honest limitations
Two things are worth being clear about before you spend a year writing these scripts.
A tool script is not portable. The Tcl is; the commands are not. A script using get_cells runs only in tools that define get_cells, which is why Chapter 16.4 is about telling the two apart and Chapter 17.5 is about what differs between vendors.
Tcl is the wrong place for heavy data work. Parsing a two-gigabyte report, doing statistics, or producing charts is miserable in Tcl and pleasant elsewhere. The usual division — Tcl inside the tool, something else outside it — is Chapter 16.3.
Knowing both limits early is what stops you writing a four-thousand-line Tcl program that should have been two hundred lines of Tcl and a separate script.
9. Exercises
Exercise 1. Why can a tool vendor not simply provide a GUI for everything?
Exercise 2. What goes wrong with inventing a configuration file format instead of embedding a language?
Exercise 3. Complete the sentence: a tool shell is ______.
Exercise 4. Name the three things a tool adds to the interpreter.
Exercise 5. Standard-Tcl work produced identical output before and after tool commands were added. Why does that matter to you?
Exercise 6. lsort $x with the same input always gives the same answer. Why is get_cells * not like that?
Exercise 7. Someone says Tcl is a bad language because it is old. What is the fair version of that criticism?
Where this fits
Part of the Tcl curriculum.
