Skip to content
VLSI Mentor

Tcl · Module 27

Keeping the Flow Tool-Agnostic

Put a seam between what the flow wants and what the tool calls it. The seam works, and the chapter spends as long on where it does not as on where it does.

Advanced22 min readtcledapart-iiinfrastructureportabilityarchitecture

Part II · Module 27 · Chapter 27.5 · Keeping the Flow Tool-Agnostic

Flow scripts get written against one tool and then live longer than the decision to use it. A tool is replaced, a second one is brought in for a particular block, a licence runs out, or a vendor is acquired.

The question is whether that is an afternoon or a quarter.

1. The seam

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
proc ::tool::optimise {effort} {
    switch -- $::tool::BACKEND {
        alpha { ::tool::issue "a_synthesize -effort $effort" }
        beta  { ::tool::issue "b_compile -opt $effort" }
    }
}

Every procedure in the seam is named for what the flow wants — read_design, apply_constraints, optimise, write_netlist — and the switch is the only place a vendor command appears.

Two parallel left-to-right flows. Above, one flow script that names no vendor command passes through the intent seam, and backend alpha issues seven vendor commands. Below, the same script and the same seam, with one line selecting the other backend, and backend beta issues eight commands because it divides the work differently.One flow scriptno vendor commandThe intent seamone switch per stepBackend alpha7 commands issuedThe same scriptnot a line changedThe same seamone line selects itBackend beta8 commands issued12
Figure 1 — one flow script, two tools. Above: the flow script names no vendor command, so the intent seam translates each request into whatever this tool calls it, and backend alpha issues seven commands. Below: not a line of the flow script or the seam's interface changes — one line selects the other backend — and backend beta issues eight, because the two tools do not divide the work the same way.

The backends here record the command they would issue rather than issuing it, which is what makes the substitution demonstrable on a machine with no tool installed at all. alpha and beta are deliberately not real vendor names, for the reason Chapter 17.5 gives.

2. The flow script

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
# synth.tcl — ONE flow script. It names no vendor command anywhere.
proc run_synthesis {rtl top sdc outdir} {
    ::tool::read_design      $rtl $top
    ::tool::apply_constraints $sdc
    ::tool::optimise          high
    ::tool::report_timing_to  [file join $outdir timing.rpt]
    ::tool::write_netlist     [file join $outdir $top.v]
}

Run it against each backend in turn:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
=== backend alpha issued 7 command(s) ===
    a_read_hdl -sv rtl/core.sv
    a_read_hdl -sv rtl/fifo.sv
    a_elaborate core_top
    a_read_sdc constraints/core.sdc
    a_synthesize -effort high
    a_report_timing -max_paths 10 > work/timing.rpt
    a_write_netlist -format verilog work/core_top.v

=== backend beta issued 8 command(s) ===
    b_analyze -format sverilog rtl/core.sv rtl/fifo.sv
    b_elaborate -top core_top
    b_link
    b_source_constraints constraints/core.sdc
    b_check_constraints
    b_compile -opt high
    b_timing_report -paths 10 -out work/timing.rpt
    b_write -hierarchy -format verilog -output work/core_top.v
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
=== vendor command names anywhere in the flow script? ===
    0 vendor token(s) in the flow script

Seven commands against eight, entirely different names, from one unchanged script with zero vendor tokens in it.

3. What the seam buys

A flow script becomes reviewable by someone who does not know the tool. run_synthesis above says what synthesis is, in five lines, with no vendor knowledge required.

The vendor knowledge is in one file, so the question "what does this flow actually run" has a single answer rather than being distributed across thirty scripts.

Adding a backend is additive. A third tool is a third switch arm in each procedure, and no existing arm changes — so the work is bounded and the risk of breaking the working tool is near zero.

Testing without the tool becomes possible. The mock used here is a third backend in all but name: it records rather than issues, which means flow logic can be exercised in CI with no licence. That is the one benefit people do not anticipate and it is often the largest.

4. Leak one: reports

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
=== the command seam holds: one call, two command sets ===
    alpha  -> {a_synthesize -effort high}
    beta   -> {b_compile -opt high}

Now the reports those tools produce:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
=== but the REPORT formats are unrelated ===
    --- alpha ---
    ALPHA timing report
      endpoint u_mem/addr_reg_7/D   slack -0.0730  VIOLATED
      endpoint u_mem/dout_reg_3/D   slack  0.3120  MET
    --- beta ---
    # beta timing
    u_mem/addr_reg_7/D,-0.0730,violated
    u_mem/dout_reg_3/D,0.3120,met

5. Leak two: a feature one tool does not have

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
proc ::tool::optimise_with_retiming {effort} {
    switch -- $::tool::BACKEND {
        alpha { ::tool::issue "a_synthesize -effort $effort -retime" }
        beta  { error "this backend has no retiming option" {} {TOOL NOFEATURE retime} }
    }
}
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
=== and an option one tool has and the other does not ===
    alpha  {a_synthesize -effort high -retime}
    beta   REFUSED: this backend has no retiming option

The design decision is in that output: the backend refuses rather than silently dropping the option.

A backend that quietly ignored -retime would produce a netlist that was not retimed, with nothing anywhere saying so — the exact Part II failure shape, alongside Chapter 25.4 §2's test that failed and exited 0 and Chapter 23.1 §5's floorplan command that succeeded at an impossible utilisation.

Refusing forces a decision at the seam, where somebody can make it:

  • implement the feature another way on that backend, and say in a comment that it is an approximation,
  • declare the flow unsupported there, which is honest and sometimes correct,
  • or make the option advisory, with the flow checking a capability flag rather than the backend pretending.

That third option is worth the extra machinery when it is common:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
proc ::tool::supports {feature} {
    set caps [dict create alpha {retime incremental} beta {incremental multicorner}]
    return [expr {[lsearch -exact [dict get $caps $::tool::BACKEND] $feature] >= 0}]
}
if {[::tool::supports retime]} { ::tool::optimise_with_retiming high } else { ::tool::optimise high }

Now the flow script contains a conditional about a capability, not about a tool name — which keeps it tool-agnostic while admitting that the tools differ.

6. Leak three: the same word meaning different things

The leak that cannot be demonstrated in a mock, and is the worst of the three.

Both backends take an effort option, and ::tool::optimise high maps to -effort high on one and -opt high on the other. The names translate cleanly. What does not translate is how much work "high" is — the runtime, the optimisations attempted, the quality of result, and whether it is the highest setting or the middle one.

So two runs through the seam are not comparable even though the flow script is identical. Chapter 24.2 §6's rule applies with full force: a result is comparable only against another result from the same tool, same version, same settings — and the seam, by making the scripts look identical, makes it easier to forget that.

There is no code fix. The honest handling is documentation at the seam:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
# optimise: maps to each tool's main optimisation command.
#   alpha -effort {low|medium|high}   high ~= 2x medium runtime
#   beta  -opt {1..5}, high -> 4      beta's 5 has no alpha equivalent
# NOT comparable across backends. A QoR comparison must fix the backend.

A comment is a weak mechanism, and it is the right one here because the alternative is pretending the abstraction is tighter than it is.

7. Where not to use a seam

Being complete about the honesty the registry asks for.

Do not abstract something you have one implementation of. A seam with a single backend is indirection with no payoff, and it is harder to review than the vendor command. Write the vendor command, and introduce the seam when a second tool actually arrives — the refactor is mechanical, and guessing the interface in advance is how you get an interface shaped like one tool.

Do not abstract the thing the tool is uniquely good at. If you chose a tool for a specific capability, hiding that capability behind a generic name defeats the choice. Name it for what it is and accept that this part of the flow is tool-specific.

Do not abstract interactive debugging. Chapter 27.2's helpers are typed by a human who knows which tool they are in. A seam there costs keystrokes and buys nothing.

Do not claim the abstraction is complete. The three leaks above are the ones in a four-procedure seam; a real one has more. "An afternoon rather than a rewrite" is the right order of magnitude for the commands and is optimistic once the parsers are counted.

8. Exercises

Exercise 1. What is each seam procedure named for, and where does a vendor command appear?

Exercise 2. Why is the 7-against-8 asymmetry more informative than a symmetric mapping?

Exercise 3. Why must the interface be shaped around the flow's intent rather than the first tool?

Exercise 4. Name the benefit of a seam that people do not anticipate.

Exercise 5. The seam abstracts issuing. What does it not abstract, and what does that cost?

Exercise 6. Why should a backend refuse a missing feature rather than drop it?

Exercise 7. Give the three ways to handle a feature one backend lacks.

Exercise 8. Why is "the same word meaning different things" the worst leak?

Exercise 9. Why does the seam make that leak easier to forget?

Exercise 10. Give two cases where a seam is the wrong choice.

Where this fits

Part of the Tcl curriculum.