Skip to content
VLSI Mentor

Tcl · Module 28

Partitioning the Flow

Four languages, one flow. The boundaries are decidable on criteria you can check rather than taste — and they are usually drawn wrongly in one of two specific directions.

Intermediate22 min readtcledapart-iiarchitecturepythonbash

Part II · Module 28 · Chapter 28.4 · Partitioning the Flow

Three chapters have each claimed a piece: the shell launches, Make decides what is stale, Python works over the results. This one is about why those are the right pieces, and what it looks like when they are not.

1. The partition

Two parallel left-to-right flows showing the partition and the two ways it is drawn wrongly. Above, each language keeps what it is good at: the shell launches, make decides what is stale, Tcl drives the tool session, and Python works over the data afterwards. Below, the two failure directions are a dashboard grown inside the tool session, and flow logic pushed out into the shell where there is no floating-point arithmetic.Shell and makelaunch and stalenessTcl in the sessionthe flow itselfPython aftercompare and renderToo far righta dashboard in the toolThe boundarydrawn on criteriaToo far leftflow logic in the shell12
Figure 1 — the partition, and the two ways it is drawn wrongly. Above: each language keeps what it is good at — the shell and Make launch the run and decide what is stale, Tcl drives the tool session because that is the only language inside it, and Python works over the data afterwards. Below: the boundary is drawn on criteria, and the two failure directions are a dashboard grown inside the tool session on one side and flow logic pushed out into the shell on the other.
Part of the flowLanguageBecause
CI's entry pointshellit sets the environment of a child process (28.1)
What is out of dateMakeit is a dependency graph over files (28.2)
Everything inside the tool sessionTclit is the only language in there (17.1)
Comparison across runs, aggregation, renderingPythonthe question is about several runs (28.3)

The third row is not a preference and deserves saying plainly: inside a tool session there is no choice. The session's interpreter is Tcl, the design database is reachable only from it, and anything else has to generate Tcl and feed it in. That one constraint fixes the middle of the partition and leaves the edges to be argued about.

2. The criteria

Four questions, each with an answer you can check rather than debate.

Does it need the design database? If yes, it is Tcl, inside the session. There is no second option.

Does it span more than one run? If yes, it is outside — a session knows about one run (Chapter 28.3 §1).

Is it a dependency question over files? If yes, Make. "Is the netlist older than the SDC" is what Make exists for, and reimplementing it with [ a -nt b ] is a worse Make.

Does it need arithmetic on the flow's numbers? If yes, it is not the shell — and §3 is why that is a wall rather than a preference.

3. The shell cannot do the flow's arithmetic

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
=== can each language do the flow's arithmetic? ===
    bash integer   : 16388
    bash float     : bin/limits.sh: line 3: 1.5 + 2.5 : syntax error: invalid arithmetic operator (error token is ".5 + 2.5 ")
    bash float     : bin/limits.sh: line 4: 159268.01 - 158940.33 : syntax error: invalid arithmetic operator (error token is ".01 - 158940.33 ")
    via bc         : 327.68
    tclsh          : 327.6800000000221
    python3        : 327.6800000000221

4. And the three languages disagree on one subtraction

Look again at the last three lines:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
    via bc         : 327.68
    tclsh          : 327.6800000000221
    python3        : 327.6800000000221

Same subtraction, two different answers. And the one that looks wrong is the right one.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
=== why bc's answer looks different ===
    bc default scale    : 327.68
    bc scale=20         : 327.68
    bc 1/3  (scale 0)   : 0
    bc 1/3  scale=10    : .3333333333
    tcl  1.0/3.0        : 0.3333333333333333
    python 1/3          : 0.3333333333333333

=== so the three disagree in different ways ===
    bc  : arbitrary-precision DECIMAL, truncated at 'scale'
    tcl : IEEE 754 double
    py  : IEEE 754 double — identical to tcl, bit for bit
    do tcl and python agree exactly? : yes  (0.3333333333333333)

5. Wrong direction one: too far right

The boundary pushed too far into the tool session. The symptom is a dashboard, a cross-run database, or an HTML generator living in Tcl.

It happens for a good reason: the data is right there, in a dict, already parsed. Adding thirty lines to format it as a table is obviously easier than writing a file and a second program.

What it costs, and the first three are from Chapter 28.3 §1:

  • A sign-off licence is held while formatting a table.
  • It cannot be tested without the tool, so it never is.
  • It cannot answer a question about more than one run, which is most of the questions worth asking.
  • And it grows. A table becomes a trend becomes a comparison becomes a page, each step a small addition to a file nobody meant to own, in a language with no library for any of it.

The tell is easy to check: does this code touch the design database? A procedure that only reads a dict the flow built is not doing tool work, and it is in the wrong place.

6. Wrong direction two: too far left

The boundary pushed out of the session, into the shell or Make. The symptom is awk parsing a report, grep | sed extracting a slack, a for loop over corners in bash, or arithmetic in bc.

This one also happens for a reason: the shell is where the person already is.

What it costs:

  • No floating-point arithmetic (§3), so a third language arrives.
  • No data structures. A list of scenarios with reasons attached (Chapter 26.4) is a dict in Tcl and a set of parallel arrays in bash 3.2 — which has no associative arrays at all.
  • It throws away structure that already existed. The tool session had the slack as a number, in a dict, keyed by endpoint. Printing it to a report and extracting it with awk is a round trip through text that loses the typing, the structure and the error handling, and gains Module 24's entire set of parsing hazards.

7. What belongs nowhere

Three things that look like they need a home and should not have one.

A second copy of the configuration. The shell wrapper knowing the library path and setup.tcl knowing it is Chapter 27.3 §1's copy-that-drifts. One owner, and the others receive it — via the environment, or an argument, or by reading the same file.

A language chosen for familiarity against a criterion. "I know Python better" is a real consideration for the parts §2 leaves open, and not for the parts it does not: no amount of Python fluency gets you inside a tool session, and no amount of shell fluency gets you floating-point arithmetic.

Glue between two glues. A shell script that calls Make which calls a shell script which calls Tcl has one layer too many, and the symptom is that nobody can say what runs when a stage fails. Four languages is already the maximum a flow can carry; the goal is a short path from CI to the tool, not a complete separation of concerns.

8. The partition as a review

  • Does every piece of code touching the design database live in Tcl? It has to.
  • Does anything outside the session do arithmetic on flow numbers? If it is the shell, it cannot; if it is bc, check its scale.
  • Is any number computed twice, in two languages? Compute once, pass the result.
  • Does anything parse a report the same flow produced as data? That is pure loss.
  • Does any Tcl in the session format output for humans? That belongs outside.
  • Does the dependency logic live in Make, rather than in a shell -nt test?
  • Is the configuration owned in one place, with the others receiving it?
  • Can somebody say what runs when a stage fails, in one sentence? If not, there is a layer too many.

That last question closes Module 28 and, with it, the practical half of Part II. Everything from Module 21 onward has been one argument in different clothes: a flow is only as trustworthy as its ability to tell you what it actually did — which is why so much of it has been about exit statuses, provenance, denominators and second independent measurements rather than about the Tcl.

9. Exercises

Exercise 1. Which part of the partition is not a choice, and why?

Exercise 2. State the four criteria.

Exercise 3. What does 1.5 + 2.5 do in bash, and why does the error message mislead?

Exercise 4. Why is "no float arithmetic" a wall rather than a preference for an EDA flow?

Exercise 5. bc says 327.68 and Tcl says 327.6800000000221. Which is right, and why?

Exercise 6. Why does bc scale=20 give the same answer as the default?

Exercise 7. What does bc do with 1/3, and why is that a trap?

Exercise 8. Why do Tcl and Python agree bit for bit?

Exercise 9. State the rule about computing a quantity once.

Exercise 10. Give the tell for "too far right" — one question you can ask of a procedure.

Exercise 11. State the sharpest rule about the "too far left" direction, and the one legitimate exception.

Exercise 12. What is wrong with a shell script calling Make calling a shell script calling Tcl?

Where this fits

Part of the Tcl curriculum.