Knowledge / Electronics (VLSI Design) / EDA tools and scripting: Tcl, Perl and Python for VLSI

EDA tools and scripting: Tcl, Perl and Python for VLSI

Electronics (VLSI Design) (B.E./B.Tech) · FPGA, tools and fabrication · free study notes for exams, placements and interviews

In short

Every commercial VLSI tool - Design Compiler, Genus, Innovus, PrimeTime, Vivado, Quartus, Calibre, Virtuoso - is driven by a text command language, and that language is almost always Tcl (Virtuoso is the exception - its scripting language is SKILL, with OCEAN for analog simulation). A chip is never built by clicking: the RTL-to-GDSII flow is a set of Tcl scripts that read design files, apply constraints, run synthesis or place-and-route, and write reports, while Perl or Python generates those scripts, parses the megabyte-long logs and builds the summary tables a lead reviews. Scripting is examined in university VLSI/EDA-lab courses and in "VLSI design flow" or "physical design" electives; GATE EC/VLSI tests the flow and constraint concepts rather than syntax. In Indian hiring (Intel, Qualcomm, Nvidia, AMD, Samsung, Texas Instruments, Synopsys, Cadence, Siemens EDA, Bosch, Einfochips, Sasken, Tessolve, Wipro/HCL design services), a CAD or physical-design interview reliably includes "write a Tcl proc", "parse this report with a regex" and "what does this SDC line mean".

Explained

Why scripting runs the VLSI flow

Tcl essentials for EDA

SDC - constraints are a Tcl script

Perl for VLSI: regex, reports and legacy flows

Python in the modern VLSI toolbox

Flow, environment and engineering practice

Key points

Formulas and examples

Slack = Required arrival time − Actual arrival time (ns). Setup: Slack = (T_clk − T_setup − T_skew − T_uncertainty) − (T_cq + T_comb + T_net)
WNS = min(slack over all paths); TNS = Σ(negative slacks only); both in ns
Maximum clock frequency f_max = 1 / (T_clk − WNS) with T_clk the constrained period (s), f in Hz
Multicycle setup path required time = N × T_clk − T_setup, where N = cycles set by set_multicycle_path N -setup
Utilisation = (Σ standard-cell area + macro area) / core area × 100 %
Runtime of a swept regression ≈ N_corners × N_configs × t_run / N_parallel_licences

Example 1 - a complete, minimal synthesis script in Tcl

# setup
set DESIGN   top
set RTL_DIR  ./rtl
set LIB_DIR  $env(STD_CELL_LIB)
set_app_var target_library  "$LIB_DIR/sc_tt_1v8_25c.db"
set_app_var link_library    "* $target_library"
set_app_var search_path     [list . $RTL_DIR $LIB_DIR]

# read RTL (abort cleanly if a file is bad)
foreach f [glob -nocomplain $RTL_DIR/*.v] {
    if {[catch {read_verilog $f} msg]} { puts "ERROR reading $f: $msg"; exit 1 }
}
current_design $DESIGN
link

# constraints
create_clock -name clk -period 2.5 [get_ports clk]
set_clock_uncertainty 0.05 [get_clocks clk]
set_input_delay  0.6 -clock clk [remove_from_collection [all_inputs] [get_ports clk]]
set_output_delay 0.5 -clock clk [all_outputs]
set_false_path -from [get_ports rst_n]
set_max_transition 0.3 [current_design]

compile_ultra -no_autoungroup
report_timing -max_paths 10 > reports/$DESIGN.timing.rpt
report_area              > reports/$DESIGN.area.rpt
report_qor               > reports/$DESIGN.qor.rpt
write -format verilog -hierarchy -output netlist/$DESIGN.v
write_sdc constraints/$DESIGN.sdc

Example 2 - Tcl proc and collection iteration (classic interview exercise) Count flip-flops and list cells whose area exceeds a limit.

proc big_cells {limit} {
    set n 0
    foreach_in_collection c [get_cells -hier *] {
        set a [get_attribute $c area]
        if {$a > $limit} {
            puts [format "%-40s %8.3f" [get_object_name $c] $a]
            incr n
        }
    }
    return $n
}
puts "FF count   : [sizeof_collection [all_registers -cells]]"
puts "Big cells  : [big_cells 5.0]"

Example 3 - slack, f_max and a multicycle path (numbers) A path is constrained at create_clock -period 2.5 (400 MHz). The report gives T_cq = 0.12 ns, T_comb = 2.31 ns, T_net = 0.18 ns, T_setup = 0.09 ns, skew 0.05 ns, uncertainty 0.05 ns.

Example 4 - Perl one-file report parser Extract every violating endpoint and its slack, then print WNS and TNS.

#!/usr/bin/perl
use strict; use warnings;
my ($wns, $tns, %slack) = (0, 0);
open(my $fh, "<", $ARGV[0]) or die "cannot open $ARGV[0]: $!";
my $ep = "";
while (<$fh>) {
    $ep = $1 if /^\s*Endpoint:\s+(\S+)/;
    if (/^\s*slack\s+\(VIOLATED\)\s+(-?\d+\.\d+)/) {
        $slack{$ep} = $1;
        $tns += $1;                      # already negative
        $wns  = $1 if $1 < $wns;
    }
}
close $fh;
printf "WNS = %.3f ns   TNS = %.3f ns   violating paths = %d\n",
       $wns, $tns, scalar keys %slack;
for my $k (sort { $slack{$a} <=> $slack{$b} } keys %slack) {
    printf "  %-45s %7.3f\n", $k, $slack{$k};
}

If the file holds slacks −0.300, −0.120 and −0.045 on three endpoints: WNS = −0.300 ns, TNS = −0.465 ns, count = 3.

Example 5 - Python regression harness with utilisation check

import re, subprocess, pandas as pd
from jinja2 import Template

tcl = Template(open("syn.tcl.j2").read())
rows = []
for period in [2.0, 2.5, 3.0]:
    open("run.tcl", "w").write(tcl.render(period=period, design="top"))
    subprocess.run(["dc_shell", "-f", "run.tcl"], stdout=open(f"log_{period}.txt", "w"))
    log = open(f"log_{period}.txt").read()
    wns  = float(re.search(r"slack \(\w+\)\s+(-?\d+\.\d+)", log).group(1))
    area = float(re.search(r"Total cell area:\s+([\d.]+)", log).group(1))
    rows.append({"period_ns": period, "fmax_MHz": round(1000/(period - wns), 1),
                 "wns_ns": wns, "area_um2": area, "met": wns >= 0})
pd.DataFrame(rows).to_csv("summary.csv", index=False)

With WNS = −0.30 ns at 2.0 ns, +0.10 ns at 2.5 ns and +0.55 ns at 3.0 ns:

period (ns)WNS (ns)f_max (MHz)timing met
2.00−0.301000/2.30 = 434.8no
2.50+0.101000/2.40 = 416.7yes
3.00+0.551000/2.45 = 408.2yes

Utilisation check: core area 400 µm × 400 µm = 160,000 µm²; cells total 96,000 µm², one macro 12,000 µm² → utilisation = 108,000/160,000 = 67.5 % (healthy; above about 80 % routing congestion usually appears).

TclPerlPython
Role in flowInside the tool - drives itLegacy log parsing, text generationFlow glue, data analysis, verification
Runs inside dc_shell / Innovus / VivadoYes, nativelyNoOnly via vendor Python shells
Regex strengthregexp/regsub, adequateBest-in-class, built into syntaxre module, very good
Data structuresLists, arrays, dictsArrays, hashes, referencesRich: list/dict/set/objects, pandas
Readability / maintenanceVerbose, quoting-sensitiveTerse, can get crypticHighest
Typical interview askWrite a proc, explain {} vs ""Write a regex to pull slackParse report into CSV, cocotb basics

Where it is used

Interview questions

Common mistakes

Related topics

Static timing analysis and constraints · ASIC physical design: floorplan, placement, CTS and routing · Logic synthesis and RTL coding guidelines · Programmable logic: PLDs, CPLDs and FPGAs · Verification: SystemVerilog, UVM and assertions · Design for testability: scan and ATPG.

Open in the Knowledge reader →Find jobs →