Top 20 TCL syntax helpful to improve TCL scripting skill for VLSI Engineers

One scripting language without which it will be very difficult to survive in VLSI Industry, that would definitely  be TCL (Tool Command Language). TCL is widely used everywhere in the VLSI industry because many tools are based on the tcl. We can directly interact with the tool using tcl CLI (Command Line Interpreter). 

It has been observed that many beginners initially hesitate to start the TCL scripting. Most of the cases user know the basic tcl commands but how to connect all them and create a script is the only problem. I would say even you know some basic tcl commands you can start writing your own script for your day to day requirements. Most important this is BEGIN the process of writing the script. Here I am presenting 20 common tcl syntax which I use frequently in my tcl scripting and hope it will help you to break the ice. Improvement and prefection will come as you practice but start is the most important. These 20 syntax will definitely help you lot to start and improve your tcl scripting a lot. 



1. foreach loop

Use:
Where we have to iterate on each element on a list of elements and have to perform some operation on each element.
Syntax:
foreach var $Var_list {
//operations for each $var
}
Example:
Supposed we want to print all the macros instance name, reference name and total count of macro in a block.
set macros [dbGet [dbGet top.insts.cell.baseClass block -p2].name]set i 0
foreach macro $macros {
set refName [dbGet top.insts.name $macro -p].cell.name
puts “$macro – $refName “
incr i
}
puts total macro count = $i


2. Nested foreach loop

Use: 

If we have to iterate on each element of a list and then further we need to iterate on each parameters associated with the element.
Syntax:
foreach i $list1 {
    //list2 is derived based on $i
    foreach j $list2 {
        //operations on $j
    }
}
Example:
Suppose we have to find the list of feedthrough pins and the total numbers of feedthrough pins in each edge of a rectilinear block. A script can be written like this for that.

set edges [dbget top.terms.edge -u]set i 0
foreach edge $edges {
    set j 0
    foreach pin [dbget [dbget top.terms.edge $edge -p].name ft* ] {
        puts “$edge $pin”
        incr j
    }
    puts “$edge : total ft pin count = $j”
    incr i
}
puts “Toal edge of block = $i”

3. for loop

Use: 
Where we want to repeat a loop in between a certain start and endpoint with a certain increment
Syntax:
for {initialization}{condition}{increment} {
statements
}
Example:
Suppose we want to know the metal layer’s width and pitch of all metal from M5 to M10 in innovus tool.

for {set i 5}{$i <= 10}{incr i}{
    set width [dbGet [dbGet top.head.layers.name M{$i} -p].minWidth]
    set pitch [dbGet [dbGet top.head.layers.name M{$i} -p].pitchX]
    puts “M{$i} $width $pitch”
}


4. Nested for loop

Same as above example only syntax change and one loop in running inside another loop.
Syntax:
for {initialization}{condition}{increment} {
    for {initialization}{condition}{increment} {
        statements
    }
}


5. while loop

Use: 

When we need to repeat a loop until a particular condition is true.
Syntax:
while {condition} {
    //statements
}
Example:
Suppose we need to read all the lines of a file one by one and store is a variable dynamically.

set fp [open my_report.tcl r]while {[gets $fp data] >= 0} {
    if {[regexp “VIOLATED” $data]} {
        //desired statement for operation
    }
}

    

6. if-else conditions

Use:
When we want to do something if certain condition is true. We can either put else statement or skip it.
Syntax:
if {bolean_condition} {
    //statements
} else {
    //Statements
}

Example:
Suppose we need to convert SVT cell to ULVT cell.

if {[regexp SVT $cell_ref]} {
    set eco_ref [regsub {SVT} $cell_ref “ULVT”]
}

7. if-elseif… else condition

Use: 

When we want to check another if condition if one prior if condition is not true.
Syntax:
if {bolean_condition} {
    //statements
} elseif {bolean_condition} {
    //Statements
} else {
    //statement
}

Example:
Suppose we need to read a report file inside a script and generate an eco file in which if there is Weak Driver then need to upsize the driver from D1–> D3, D2–>D4 and D3–>D5. We can write script as follow.

set fp [open existing.rpt r ]set fp1 [open new_ecofile w+]while {[gets $fp data] >= 0 } {
    if {[regexp “Weak Driver” $data]} {
        set inst [lindex $data 7]         set cell [lindex $data 8]         if {[regexp D1BWP $cell]} {
            regsub “D1BWP” $cell “D3BWP” newCell
        } elseif {[regexp D2BWP $cell]} {
            regsub “D2BWP” $cell “D4BWP” newCell
        } elseif {[regexp D3BWP $cell]} {
            regsub “D3BWP” $cell “D5BWP” newCell
        }
        if { [ info exists newCell ]} {
        puts $fp1 “ecoChangeCell -inst {$inst} -cell $newCell”
    }
}
close $fp
close $fp1



8. Arithmetic operations

Use:
When we need to add/subract/multiply/devide some numbers

Syntax:
set s [expr $a + $b + $c]set d [expr $a – $b ]set m [expr $a * $b]set d1 [expr $a / $b ]
Example:

If we need to know, how much space will take a 4X, a 8X and a 16X decap cell together.

set cell4X [dbget [dbget head.libCells.name $decap4 -p].size_x -u]set cell8X [dbget [dbget head.libCells.name $decap8 -p].size_x -u]set cell16X [dbget [dbget head.libCells.name $decap16 -p].size_x -u]set distX [expr $cell16X + $cell16X + $cell4X]puts $distX

Note: Be careful like in the following cases

like:
>expr 3/2
>1

>expr 3/2.0
>1.5

9. regexp

Use:
To match the regular expression. Regular expression has a wide list, we will see only few which we use mostly.
Syntax :
regexp {pattern} $string
Example: 

Suppose we want to change the D1, SVT cell to D2, LVT we can check the cell with regexp and then we can perform regsub for substitution and generate an eco file.

if {[regexp {D1BWP240H11.*PDSVT} $clock_cell_ref]} {
    regsub {D1BWP240H11} $clock_cell_ref {D2BWP240H8} new_clock_cell_ref
    regsub {PDSVT} $new_clock_cell_ref {PDLVT} new_clock_cell_ref
    puts $fp_w “ecoChangeCell -inst $clock_cell -cell $new_clock_cell_ref”
}

10. regsub

Use:
To substitute the regular expression
Syntax:
regsub {old_pattern} $string {new_pattern} new_string_name
Example:
As explained in the regexp section

11. Reading a file

Use:
Many times we have to read a report file inside the tcl scripting to make some fixes based on the violation reported. We read the file line by line and store the data in a file pointer variable dynamically.
Syntax:
set fp [open existing_file_name r]

Example:

we can read a file line by line in a variable like this.


    set fp1 [open $old r]     while {[gets $fp1 data] >= 0 } { 
         // $data variable will get string line by line of old file
     }
    close $fp1



12. Writing a file

Example:
We can write a file and close that as follow.

set fp2 [open $new w+] puts $fp2 “Whatever we want to write in file will go line by line”
close $fp2

13. proc

Use: 

If we need to use a few lines of code, again and again, we can make a proc using those codes and can call easily by the proc name. No need to write code every time.
Syntax:
proc proc_name {} {
// lines of code
}
proc_name

Example: 
If we need to find the basic details of a block, we can write a proc something like this.

proc blockInfo {} {
    puts “Block name: [dbget top.name]”
    puts “All Layers: [dbget head.layers.name]”
    puts “Block Area: [dbget top.fPlan.area]”
    puts “Box size: [dbget top.fPlan.box_size]”
    puts “Boxes: [dbget top.fPlan.boxes]”
    puts “Toatl pins: [dbget top.numTerms], Inputs – [dbget top.numInputs], Outputs –                    [llength [dbget top.terms.isOutput 1 -p]]”
    puts “Macro Count: [llength [dbget top.insts.cell.baseClass block -p2]]”
    // Many more parameters can be added
}

We just need to source above file and call the proc blockInfo proc, it will display all the above info of block.


14. proc with arguments

Use: 

Sometimes we need to pass some arguments in proc and we want the result of proc based on user argument.
Syntax:
proc proc_name { arg1 arg2 arg3 …} {
    // lines of code
}
proc_name arg1 arg2 arg3

Example:
Suppose we want to write a general proc in which if we pass the net_name, it should return the net_length of that particular net. We can write that as follow.

proc netLength {net_name} {
    set net_length 0
    set net_wires_length [dbget [dbget top.nets.name $net_name -p].wires.length]     foreach i $net_wires_length {
        set net_length [expr $net_length + $i]     }
    puts $net_length
}

Note: 

 We can also set a default value of the proc argument. So in case the user does not pass the argument value, proc will take the default value.
Syntax:
proc proc_name {{arg1 10} {arg2 20}} {
set a $arg1
set b $arg2
// More statements
}

So if we call the proc like
proc_name
it will take the default value of arg1 and arg2 and will set a 10 and set b 20.

But if we call this proc like
proc_name 50 
It will set a 50 and b 20

we can also call like
proc_name 50 45 
In the above way  proc will set a 50 and b 45




15. exec

Use: 

To use bash command inside tcl script
Syntax:
exec date

Example:
set timestamp_prefix [exec date +%m%d_%H_%M]


16. dbGet/dbSet/dbQuery

Use:
These are the innovus tool-specific commands, and widely used in innovus tool related scripting.
Syntax and Examples will be discussed in a separate article.

The link will made available here [Not now].

17. list operations

Use: 

There are various list operations, all are important in various way and frequently used.
Syntax:
llenght, lappend, lindex, lreplace, lset, lsort etc.

Example: 
Kindly do the man command for more details

18. alias

Use: 
To shorten a long command or a command with its switches to a short command.
Syntax:
alias short_commad “original_commad”

Example:
alias si “selectInst”
alias sn “selectNet”

19. grep

Use: 

To find the particular pattern
Syntax:
exec grep “pattern” $file_name
egrep and zgrep are also used in place of grep.

Example: 
Will discuss in details in a separate article
Link [Not now]



20. sed

Use: 

sed is called stream editor, it can do lots of tasks. we use generally sed to replace or delete a particular pattern in a file or string.
Syntax:
exec sed 

Example-1: 
If we want to replace a line having particular unique pattern completely by another line . We can do that like folow.

exec sed -i “s|Pattern .*|$new_line|” $file_name

Example 2:
If we want to write some lines of code which are stored in a file just after a line having some uniqe pattern. we can do that as follow

set num [exec sed -n “/^Source Script.*/=” $file_name ]
incr num
exec sed -i “$num r $script_file” $file_name

Example 3:

If we want to delete all lines having a unique pattern

exec sed -i “/DEL*/d” $file_name


Note: grep, sed and awk is a very handy command for various operations, these commands has explained in more details in the following article.
Link [Not available now]


Thank You.

5 thoughts on “Top 20 TCL syntax helpful to improve TCL scripting skill for VLSI Engineers”

  1. Hello,
    There is a mistake in foreach example in 3rd line:
    mistake is “set refName [dbGet top.insts.name $macro -p].cell.name”
    but it need another dbGet with in a square brackets like this
    “set refName [dbGet [dbGet top.insts.name $macro -p].cell.name]”
    I hope soon you will clear this mistake in the code…

    Reply
  2. In for loop example there is a mistake in 2nd line of code:
    mistake “set width [dbGet [dbGet top.head.layers.name M5 -p].minWidth]”
    here you wrote “top.head.layers.name” but actually “head.layers.name” this is correct
    correct command is set width “[dbGet [dbGet head.layers.name M5 -p].minWidth]”
    I hope soon you will clear this mistake in the code…

    Reply

Leave a Comment