Python for VLSI · Module 1 · Python in the VLSI Engineering Workflow
Python, Tcl and Bash — Who Owns Which Layer
Every engineer who has automated anything in a chip flow has had this argument, and most of the advice available is dogma in both directions. This chapter does not give you a rule, because a rule would be wrong on the next project. It gives you a model: a small number of questions that tell you which layer a job belongs to, grounded in the one distinction that actually matters — whether the job needs to see inside a running tool. Bash is genuinely the right answer for some things, tool-native Tcl is genuinely the right answer for others, and a great deal of the work in between is where Python earns its place. By the end you will be able to take a concrete automation job, ask three questions about it, and defend your answer to a colleague who would have chosen differently.
Foundation12 min readPython for VLSITclBashEDA FlowsEngineering Judgment
Module 1 · Chapter 1.3 · Python, Tcl and Bash — Who Owns Which Layer
1. The Engineering Problem
Two engineers on the same project, both experienced, both right about something.
Engineer A wants the nightly regression driven from Python. Her argument: it has to hold 600 results, group failures by cause, diff against last night and produce a report. That is a data problem.
Engineer B wants it in Bash. His argument: the flow is five commands in a row, the shell already has the environment set up, and Bash launches things better than anything else.
They are arguing about the wrong thing. They are arguing about a language when the regression is actually several jobs at different layers, and the jobs have different natural answers. Setting up the environment and launching one thing really is a shell job. Holding 600 records and grouping them really is not.
2. The Three Layers
Here is the model. Three layers, each with a job it is genuinely good at.
Bash — the shell layer. Its job is to set up an environment and launch commands. Environment variables, module loads, a cd into a run area, one command, and an exit status. A shell is unbeatable at being a shell.
Tcl — inside many EDA tools. This is the part that surprises people coming from software. A great many EDA tools embed their own command interpreter, and for a large share of them it is Tcl. Inside that interpreter, commands can query the live design database: the elaborated netlist, the loaded timing graph, the actual cells and nets. Nothing outside the tool can see any of that.
Python — the cross-tool flow and data layer. Deciding what should run, launching several different tools, reading what they produced, holding the results, and turning them into evidence. It sits around the tools, as Chapter 1.1 established.
The invocation chain
Where this becomes concrete is that the layers call each other, in one direction:
Two things to notice in Figure 1.
The chain runs outward to inward: the shell knows least about the design, the tool's own interpreter knows most. Each layer hands off to the one that can see more than it can.
And the dashed edge is the interesting one. Python can write the Tcl, but it cannot run the Tcl commands that touch the design — only the tool can. That single asymmetry is the most useful thing in this chapter, and §4 turns it into a question you can ask.
3. The Comparison, Stated Carefully
A table, with one rule about how to read it: these are fits, not ownerships. "Strong fit" means this is usually a comfortable choice, not this is the only correct choice.
| The need | Bash | Tcl | Python |
|---|---|---|---|
| Set up an environment, launch one command | strong fit | possible | possible |
| Rebuild only what changed | make is usually better than all three | ||
| Query or modify a loaded design database | no access | strong fit where the tool embeds it | no access |
| Constrain or report inside a timing tool | no access | strong fit where the tool embeds it | generates the script |
| Parse a multi-section report into records | limited | possible | strong fit |
| Hold several hundred results and compare runs | limited | possible | strong fit |
| Drive several different tools in one flow | possible | tool dependent | strong fit |
| Produce a report for humans and for scripts | limited | possible | strong fit |
Notice how many cells say "possible". That is deliberate and it is true: Tcl is a complete programming language and people have written substantial flow managers in it. The table is about comfortable fit, not capability.
4. The Three Questions
This is the part to take away. For any automation job, ask these in order:
Question 1 — Does this need to see inside the tool while it is loaded? If the job needs the elaborated netlist, the timing graph, the cell list, the loaded design — it belongs in the tool's own interpreter. This question has priority over the other two, because it is the only one that is about capability rather than convenience. Nothing outside the tool can do this job at all.
Question 2 — Is this mostly about launching one thing in an environment?
Set variables, load a module, cd, run one command, return its status. That is a shell job. Wrapping it in Python adds a layer and buys nothing.
Question 3 — Does this hold data, or make decisions across several results? Several fields per item, many items, grouping, comparing, reporting. That is where Python is comfortable, for exactly the reasons Chapter 1.2 laid out.
Working the questions
Try them on four real jobs:
| The job | Q1: inside the tool? | Q2: launch one thing? | Q3: holds data? | Natural first choice |
|---|---|---|---|---|
| Report all paths failing setup in one corner | yes — needs the timing graph | no | no | tool-native Tcl |
Set $PROJECT_ROOT, load the tool, run the flow | no | yes | no | Bash |
| Run 40 tests × 15 seeds, collect and group results | no | no | yes | Python |
| Run timing across 8 corners and compare the WNS | partly — each run does | no | yes — 8 results to compare | both: Python decides and compares, generated Tcl does each run |
The last row is the common and important case, and it is why the dashed edge in Figure 1 matters. The job splits across two layers. Python decides which eight corners, writes the script for each, launches the tool, reads the eight reports and compares them. The tool's Tcl does the part only it can do.
That shape looks like this from the outside:
python run_sta.py --corners slow_125c,fast_m40c --report wnsAnd inside that script, the two-layer handoff is two steps:
write_tcl(corners, "run_sta.tcl")
run(["dc_shell", "-f", "run_sta.tcl"])Read it as English. The first line writes out a Tcl file saying what should be constrained and reported for these corners — that is Python deciding. The second line launches the tool and hands it that file; -f is the tool's own flag for read your commands from here. Everything the Tcl then does happens inside the tool, against the design database, which is the part Python could never have done.
Two honest notes: write_tcl and run are not built into Python — they stand for work we build in Modules 19 and 20. And the square brackets [ ] make an ordered list of the command and its arguments, which is how Python hands a command to another program; Module 13 explains why the list form matters.
We build this properly in Module 20. Nothing about the Tcl itself is being taught here — the point is only the division of labour.
5. The Misconception Worth Naming
The mirror image of "everything should be Python" is just as common on experienced teams: Tcl can do everything Python can, so why add a language?
The literal claim is true. Tcl is a full language with lists, associative arrays, file I/O and regular expressions. You can write the 600-result regression manager in Tcl.
The useful response is not to argue capability. It is to note where the two are actually used:
- The Tcl you write inside a tool has something Python can never have: the design database. That is a genuine, permanent advantage and it is why the layer exists.
- The Tcl you would write outside a tool has no such advantage — it is competing on ordinary language qualities, and that is where the data-structure and testing pressures from Chapter 1.2 apply to it exactly as they do to awk.
6. A Common Wrong Approach
The specific failure this chapter is trying to prevent: re-implementing in Python what the tool already does from the inside.
It looks like this. An engineer wants the list of cells in a hierarchy. Rather than asking the tool, they parse the netlist file in Python. It half-works. Then it breaks on a generate block, then on a hierarchical reference, then on the next tool version's formatting — and each fix makes it more fragile.
The tool has a command that answers this exactly, from the elaborated database, and it is right every time.
And the mirror-image mistake, for balance: writing a 200-line Python wrapper whose whole job is to set two environment variables and run one command. That was eight lines of shell. Chapter 23.6 comes back to this question — is Python even the right language here? — as the closing design-review question of the entire track.
7. Exercises
Reasoning only.
Exercise 1 — Run the three questions
For each job, answer Q1/Q2/Q3 and name your first choice, in one line each: (a) list every flip-flop in a module whose clock comes from a specific source; (b) launch tonight's regression from cron with the right environment; (c) find which of last night's 600 runs failed for a new reason; (d) constrain a clock and report the worst path in one corner; (e) generate a filelist from the source tree.
Exercise 2 — Find a split job
Find one job in your own flow that genuinely splits across two layers, like the eight-corner example. Name which part must be inside the tool and which part is bookkeeping around it. This shape is far more common than a job that lives cleanly in one layer.
Exercise 3 — Defend the other side
Take a job you answered "Python" for in Exercise 1 and write the strongest one-sentence case for doing it in the shell or in tool Tcl instead. If you cannot make a case at all, check whether you have understood the alternative.
Exercise 4 — Audit your own flow's boundary
Find the place in your flow where one language hands off to another. What is passed across — arguments, a file, an environment variable, an exit status? Chapter 20.2 is about exactly this handoff, and noticing where yours is now will make that chapter concrete.
8. Related Tutorials
Work that belongs inside the simulator, not around it:
- Introduction to SVA — checking a property cycle by cycle with access to the design's state; the clearest case of the boundary drawn in §2.
- Design and Testbench Creation — the layer Python drives and never replaces.
The same handoff, seen from another track:
- GLS in Regression — the three-layer chain of Figure 1, drawn around gate-level runs.
9. Summary
- The question is never which language, it is which layer. A real flow has jobs at the shell layer, the flow-and-data layer, and inside the tool — usually calling each other in that order.
- The layers hand off outward to inward. The shell knows least about the design; the tool's own interpreter knows most. Each layer calls the one that can see more than it can.
- One question outranks the others: does this need to see inside the tool while it is loaded? That is about capability, not preference. Nothing outside the tool can do it.
- Tcl's advantage is its position, not the language. Inside a tool, with the design database, it is often unbeatable. Outside one, it competes on ordinary language qualities.
- Real projects divide this differently, for reasons. A back-end flow run entirely from tool Tcl and a verification flow run entirely from Python can both be correct. If a project's boundary surprises you, ask why before changing it.
- Do not rebuild what the tool already knows, and do not wrap eight lines of shell in two hundred lines of Python. Both are the same mistake in opposite directions.
You should now be able to take a concrete automation job, ask three questions, and defend the answer to someone who would have chosen differently.
So far every chapter has been about where automation belongs. The next one is about whether — because plenty of tasks that could be automated should not be. Chapter 1.4 — What Is Worth Automating, and What Is Not gives you the questions to ask before writing any code at all.
Where this fits
Part of the Python curriculum.
