The exec command executes a system command(binary) from linux/unix while staying within TCLSH.
The exec command treats its arguments as the names and arguments for a set of programs to run.
In VLSI EDA Automation any external EDA-Software Binary can also be executed using exec while staying within the shell of Parent EDA Tool.
Simple Use of EXEC :
First we will understand the usage of exec w.r.to to basic TCL Language usage through an example.
We create a simple Hello World TCL script which we will use in the main script through exec.
Now , in the main code , we will use above mentioned TCL Code as well as few basic Linux binaries through exec as :
pwd , whoami and which .
Once executed this code gives the below output :
EDA Automation : Use of EXEC
By now you are able to understand the basic use of exec. In this section we will extend the use of exec to a situation similar to the EDA Automation use of exec.
When a TCL Script is executed in the EDA Tool Shell , it may encounter that sudden ERROR or WARNING has occurred. These two may crash the script. For better programming , your intent will always be to capture such error or warning without crashing the script. To serve this purpose we will use another TCL procedure "catch" which evaluates a TCL script snippet inside it and trap exceptional returns . Thus an actual ERROR or WARNING can be intervened in a sand-box mode and without its bare execution which can lead to a crash.
Let us exemplify the mentioned use through the below script :
Upon execution this script gives the below output :
First If-Else block :
The first if-block in the above code is used to capture the failure (if any by error/warning) . So, if there is no failure while the if-condition is checked , the code execution will move over to the else block. Here we do the successful code execution through the else block. Here intentionally the execution code is set to success for the if-block.
Second If-Else block :
While in the next if-else code block , the if condition is meant to fail i.e the real occurrence of error/warning . In this case code execution is limited to the if-block only and does not go to the else block at all , as it went in the previous if-else block.
So our purpose is served i.e error is encountered and printed on the screen without the crashing of the code !
What is EVAL ?
Tcl allow new command creation and execute them while running a tcl script.
Typically A tcl command is defined as "a list of strings where the first string is a command or procedure".
Any string or list which meets this criteria can be evaluated and executed by the command eval.
In VLSI EDA Automation, you may club a set of command which you need to repeat several times in your EDA-Tool shell for design or analysis .
Simple Use of EVAL :
To use the eval command first , we have to set or define a short-hand for "a set of tcl commands".
This we do as : set cmd {puts "Hello World !"}
The cmd variable works like a MACRO in C-Language and this is our shorthand . We can execute this MACRO afterwards as : eval $cmd
Here goes the detailed code-example , with multiple such MACRO, for understanding :
Upon execution this gives the below output :
Repetitive use of EVAL :
In this eval example , we write an up-counter using TCL code and eval. The increment variable is set as : set cmdIncr {incr i} where i is initiated with 0
The full code of the up-counter goes like this :
Upon execution of this code the output comes as :
Summary :
Eval & Exec are ways to execute internal macro & external binary respectively.
Eval provides a way short-hand to a bunch of tcl commands clubbed together.
Exec provides a way to call external binaries within TCLSH shell.
source "fileName" : Reads the TCL Script contained in "fileName" and executes it.
This allows a single Bigger TCL Script broken into multiple smaller TCL Scripts. Each part corresponding to a specific functionality.
This allows the code reuse with localisation & limitation.
You cannot use the reusable code Treated As LIBRARY.
File Structure : Source Example
We will understand the usage of the command source through code-example. The entire code is split into two parts. The first one (sourceEx1.tcl) contains the code to be sourced . The second part (sourceEx2.tcl) contains the code where the "sourceEx1.tcl" has to be used. The below info-graphics explains the split of the codes :
The "sourceEx1.tcl" is a simple code that defines three mathematical procedures as "mul" , "sub" and "div" for multiplication , subtraction and division respectively :
The "sourceEx2.tcl" is a simple code that first sources "sourceEx1.tcl" and then uses the theree mathematical procedures as shown below :
The example is simple enough to understand and gives the below output upon execution :
You may extend the concept in VLSI with proper procedures and APIs that can interact with a live design . Hence the actual utility will come into the picture .
Package in TCL :
Packages are used for creating reusable TCL Code Library.
Namespace is used to encapsulate proc & variables for the defined package.
The package can be a collection of Tcl scripts, binary library, or a combination of both.
File Structure :: Package Example
We will understand the usage of the command source through code-example. The entire code is split into three parts.
TCL Code :: A Package
In the first split (package1.tcl) we have defined the TCL package to be used.
The definition of the package is done using the command : package provide <package-name> <version number>
If we want to include any other package , we use : package require <package-name> <version-number>
The rest of the code is similar to the code we have used above. The only difference is that we have encapsulated the three procedures inside a namespace with same name as the package.
Packaging The Package:
In the second spilt (package2.tcl) the necessary TCL codes have been written to build this package in to a library. We use pkg_mkIndex to Build an index for automatic loading of packages as shown in the below code. Except for the last filed (i.e. the wildcard matching of the TCL file names ) , you may not have to touch the code at all at your end. In case you are using the same names of the file then the entire code remain untouched.
Upon execution of this code gives the below output :
Auto Generated File :: pkgIndex.tcl
The file (pkgIndex.tcl) gets auto-generated during the build process. You don't have to touch or edit it at all !
Use of the Package :: Code Reuse
In the third split (package3.tcl) we have used the build library. Here we use
lappend auto_path $thisDirectory
to append the present working directory to TCL search path "auto_path" . The we use "package require" syntax to use the already built library. Then we go on as usual to use the procedures written in the first split of the code. Here is the third split of code for your reference :
Upon execution of this code , we get the below output in the screen :
The entire article is well narrated in the below video :
In this article we will discuss about namespace in TCL.
Namespace :
A namespace allows you to place a bunch of code under the hood of a name.
Thus any naming conflicts with Classes, Functions and Constants etc are avoided between two namespaces.
It allows your code to live in that namespace.
Hence encapsulation of data & functions are done in various programming languages.
Namespace Hierarchy Separator is Generally “::”
Namespace Hierarchy Visualization :
We will understand the namespace concept using the below info-graphics !
The outer most space , as shown in above picture, is called the Built-In-Namespace. When you start writing any code this is the namespace that you writing the code in. This is true for any programming language , not only TCL. Then one level down , there comes the Global Namespace which is specified by you explicitly. If you go a further level down , you reach up to the Local Namespace. Now, you may go any further level down . Then the levels will be Local Namespace -1 , Local Namespace-2 ......... and so on. You may nominate the nomenclature of these local namespaces as per your own convention.
Namespace Creation in TCL :
To create any namespace of your own , you have to follow the syntax :
namespace eval <Your-Name-space-name>
Here is an example of an namespace with purpose as an up-counter :
namespace eval Counter {
variable num 1
proc increase { } {
variable num
return [incr num]
}
}
As you can see we can define variable and procedures exclusively for that namespace ! Here in the above example, the procedure increase does increases the counter upwards.
Now , at some later part of the code if we decide to include a procedure in the namespace, we do not have to go back and edit it ! Instead we can do it by writing the code snippet below :
namespace eval Counter {
variable clock 5
proc hello { } {
puts "Hello World"
}
}
You can see this block is similar to the previous block , only difference is that this block appends more information to the namespace we have defined earlier.
Important to remember that this block does not re-define or replace the existing namespace declared above !
Once these namespace are defined, we can use the procedures declared inside them as :
Counter::increase and Counter::hello
The entire code is combined in the below snippet :
While executed , it gives the below output !
Various puts statements were inserted to identify the various code-blocks of namespace both in and out !
Namespace :: Hierarchy :: Code Example
We have the hierarchy visualization in previous section . Now we will take a code example to realise the hierarchy.
Here we create the topmost global namespace as : namespace eval top {}
Within which we define our local namespace as : namespace eval within {}
The two names top and within are self-explanatory w.r.to the purpose of this section.
Here goes our entire code snippet for better understanding :
Which gives the output as :
So , the change of the hierarchical data is done by : set ::top::test 25
And the hierarchical access of procedure is done by : ::top::within::hello
In the above code example.
Namespace :: Export/Import :: Code Example
If we want to export any data from withing any namespace , the data transferred to the namespace immediately outside as shown by the first info graphics in this article.
So this export or import operation is very relative and not absolute !
To export everything from current scope to the namespace immediately outside , we can use : namespace export *
To import from an existing namespace we can use : namespace import <name-space-name>::*
To delete everything that we have just imported , we can use : namespace forget space::*
We can combine all these commads in the below example :
Which , upon execution , gives the below output :
The entire article is well narrated in the below video :
In this article we are going to discuss about various string operations in TCL regular expressions such as find and replace method, regular expression wildcard matching, regular expression group matching, and match status regular expression, replace and match count. We will also discuss file input/output method, named code block, inbuilt mathematical commands and TCL Shell commands.
Various String Operations in TCL :
The concept of string in TCL is very similar to any other programming language. It is a stream of characters. We will use code examples to understand the various string operations in TCL.
A Very Common Issue of a String Token is that many times it may come with extra leading or trailing spaces. To remove this spaces , we can use the TRIM proc in TCL .
We intentionally set a string with leading and trailing spaces as :
set statement " Fan is a student "
Then we can use the TCL procedure trim it as to remove the space from both sides as :
set statement [string trim $statement]
Here, we have saved memory consumption by saving the output back into same variable.
We can measure the length of a string and directly print on the screen as :
puts [string length $statement]
We can get the n-th character of a string by using the procedure "index" :
puts [string index $statement 4]
puts [string index $statement end]
To get the position of the sub-string "is" with the entire string we can use the below procedures :
puts [string first "is" $statement]
puts [string last "is" $statement]
If we interchange the position of string and sub-string , we cannot find it and it returns a value of "-1".
puts [string first $statement "is"]
To extract a range of sub-string starting from one index till another we use the range operator :
puts [string range $statement 4 end]
This will give "is a student".
We can replace a range of sub-string with a given one as :
puts [string replace $statement 9 end "professor"]
This will give output as "Fan is a professor".
We can check for a match for a given sub-string for a existing string as :
puts [string match "*student" $statement]
Here goes the entire code snippet :
And Here goes the output :
Regular Expressions (RegEx) in TCL :
The Regular Expression is common in every high level programming languages such as PERL, Shell, PHP , Python and TCL. The RegEX Engine underneath any of these programming languages is same and hence follow the the same expression construction rules as :
Regular expressions can be expressed in just a few rules/meta-characters :
^Matches the beginning of a string
$Matches the end of a string
.Matches any single character
*Matches any count (0-n) of the previous character
+Matches any count, but at least 1 of the previous character
[...]Matches any character of a set of characters
[^...]Matches any character *NOT* a member of the set of characters following the ^.
(...)Groups a set of characters into a subSpec.
We will use code examples to understand Regular expression matching in TCL.
Find and Replace :
To find a RegEx inside a string we use TCL Procedure "regexp" and to Replace the matched sub-string with a target string , we use "regsub" .
In the below example we carefully use a IF condition to check whether the match is found , if found then we will replace with the target string .
The output goes like this :
Wild Card Matching :
The meta-characters which are used for construction a RegEx in TCL , can be used to do a wild-card matching as shown in eh below code example :
In this code , the string is used as a list to iterate on its each element. The wildcard expression "b.*n" means "b followed by any characters(-as signified by .) and any number of times(-as signified by *)" . Hence the entire RegEX for wild card matching is constructed and used.
The pair of curly-brackets creates a group.
The Output are "brown" and "brwn" as both of them satisfied the wild card match criteria. None of the other words in the sentence matches the criteria.
Group Matching and Status :
We can create one or more RegEx Groups using more than one pair of curly-brackets. Here we are more focused on the match status which comes as a return value. And the matched strings, which we get using the below expression :
set sample "Where there is a will, There is a way."
set result [regexp {[a-z]+} $sample match]
Here the constructed group will match any characters in the range of a to z (-as signified by [a-z]) and at least once (-as signified by +) . The variable result captures the status and the variable match captures the matching string.
In the below code the grouping is extended to two :
And the code gives the output of :
Group Matching & Meta-Characters Experiment :
In the previous section we have used the group {[a-z]+} as a regular expression. In this section we will do some experiments with this by changing it in various ways. We will change one thing at a time inside this group to observe the effect.
The Variants are :
{[a-z]*} ----- This Matches none of the words from the string, as * matches 0 or more times.
{[A-Za-z]*} ----- This matches "Where" as we have included the Capital Letter Range with * remain unchanged.
{[A-Za-z]+} ----- This matches "Where" as we have included the Capital Letter Range and + means 1 or more times.
{.*} ----- This matches the entire string as . means any characters and * means 0 or more times.
{.+} ----- This matches the entire string as . means any characters and + means 1 or more times.
We combine all the variations in a single code as :
Which gives the below output when we run it !
TCL RegEx : Direct Replace and Match Count
We can use the regsub procedure without the if condition when we are certain about the presence .
regsub "way" $sample "abundance" sample2
Here we have send the output to a separate string than the input string.
The TCL Expression "[regexp -all {[^ ]+} $sample]" matches all the words inside the string $sample and the switch -all gives the count .
The entire code can be written as below :
Which will give the output as :
File I/O in TCL : Capturing Live Design Shell Data
In VLSI EDA Tools, the live design data analysis that you do get flashed into the live shell. Unless you do a hard copy of it in the disk, you are going to loose all them. This is the reason the File I/O is very important in VLSI EDA.
To open a file in read mode in TCL you simply have to write a line of code like :
set fRead [open infile.txt r]
Here the file handle is fRead and the procedure of file I/O is open. Notice r at the last.
To open a file in write mode in TCL you simply have to write a line of code like :
set fWrite [open outfile.txt w]
Here the file handle is fWrite and the procedure of file I/O is open. Notice w at the last.
Then we use a while loop till the end of the file is reached as : while { ![eof $fRead]} { .......................} Inside which we read the line like : set line [gets $fRead] And we can write a line like :
puts $fWrite $line Then finally we close both the file handles as : close $fRead close $fWrite The entire code is provided here for your trial :
Code Reuse in TCL : Named Code Block :
We can use a block of code repeatedly in an long TCL code. But first we have to define it. We can define a code block using set command and use it later by eval command as shown in the below example :
Inbuilt Mathematical Functions :
TCL has few inbuilt mathematical functions that are ready to use : Abs acos asin atan atan2 bool cos cosh entier exp fmod hypot isqrt log log10 max min pow rand round sin sinh sqrt srand tan tanh wide
TCLSH Shell Commands:
Some TCLSH Shell Commands that you may use similar to BASH/TCSH :
cd– Change Directory in side TCLSH history– to see commad history exit– Exit the TCLSH prompt error– Issue Error through your TCL Code [ error “here is your error message”] This Entire Article is well Narrated in the Below Two Videos :
In this article we are going to cover the Associative Array and Dictionary Data Structure in TCL. These two are marked in green in the below diagram. In the previous article we have covered the Basic Array i.e List in TCL.
Associative Array (HASH-Table):
An associative array is a look up table where we can do one to one mapping of the key and value pairs. In this mapping the the key values are unique from each other however the value fields can be same for two different values. Generally we do the one is to one mapping here. The key and the value pair could be of any type of data. One important thing about the associative array is that it do not have the the index values represented by integers. Rather the index values could be anything among string , integer, real number or alpha-numerical combination.
Here goes the first example to understand how to construct your first associative array.
set color(rose) red set color(sky) blue set color(medal) gold set color(leaves) green set color(blackboard) black
Here the name associative array is "colour". The keys are constituted of Strings as rose, sky, medal,leaves and blackboard.The corresponding values are red,blue, gold, green and black. In this Array the key value pairs are made in 1:1 manner. To access the value of key-value pair from the constructed associative array, we have to use a foreach loop in the following manner :
The Output looks like :
"Array Set" and "Array Get" Method for Construction and Access of the Associative Array:
There is an alternative method to create an associative array. This is called the array set method. In this method we use one single procedure (named array) to write all the key value pairs in a single go. Here is an example for you :
array set colorobject {
rose red
sky blue
medal gold
leaves green
board black
}
This array set method produces the same result as the the previously shown method. We have a similar procedure to get the Key Value pairs from the associative array. This is called the Array get method. We can combine these two in the below code as :
The Output looks like :
Checking whether a HASH-Key exist :
When you have to access the key-value pair , you have to be over sanguine that the key is present. Only then you will be able to access the key-value pair from the HASH-table structure. To do this we will use the info exist command on the key , take its return value in a if check block through which we decide any further action on this key & corresponding value.
Let us better understand with the below example :
The Output looks like :
Associative Array to List conversion & Vise-versa :
We can use the above mentioned Array-Get & Array-Set methods to convert a Associative Array to List & the opposite too. If we pipe the output of Array-Get to any variable to store it , the outcome becomes a list as :
seth2l [array get colorcount ]
To do the reverse i.e , convert a List into An Associative Array , we do the following :
array set l2h $h2l
One condition applies here , the elements of the List has to be even numbers to form the key-value pair.
Now , let us try the whole thing through below code :
The output looks like this :
Dictionaries in TCL :
In TCL 8.5 the dict command has been introduced. This provides efficient access to key-value pairs. Dictionary is like associative arrays, but order of sequence is not important. Dictionaries can be passed on to a procedure. Unlike arrays, dictionaries can nest dictionaries. Hence Dictionary help you to build complicated data structures, such as hierarchical databases. You can also combine dictionaries with other TCL data structures.
Creating of Dictionary :
The dictionary is created using the "dict create" method on even number of paired key-value combination as :
set FT [ dict create .txt Text .jpg Image .zip ZipArchive .doc Document ]
Here every odd number entry treated as key and the even numbered entry is treated as value.
We can add key-value pair even after this statement as :
dict set FT .mp3 Music
dict set FT .avi Video
Special For Loop for Dictionaries ONLY :
TCL has "dict for" dedicated for the dictionaries ONLY. Let us understand by the below example :
The output will look like this :
In this example the foreach loop is used to compare its output with the dict-for loop ! You can compare the two outputs from the snapshot above.
Checking whether a DICT-Key exist :
This checking is made simplified as compared to the associative array . "dict exist" method will return a positive value if the key really exist within the dictionary. You can understand this by the below code which is the continuation of the previous dictionary code mentioned just above.
The output looks like this :
Creating Complex Data Structure using Dictionary :
Beyond the paired key-value concept , the dictionary allows to create multiple attributed to a key. This is how :
dict set employeeInfo 12345-A forenames "Joe"
dict set employeeInfo 12345-A surname "Schmoe"
dict set employeeInfo 12345-A street "147 Short Street"
Here the key "12345-A" has three attributes against it "forenames" , "surname" and "street". We can increase the number of attributes beyond shown above. Here the dictionary name is "employeeInfo" which is created to store the employee database information in the example.
Here is the full example :
This data structure can be read and printed using the below code :
To iterate we have used the special for loop designed for dictionary only. The output of the above code looks like this.
To go through the explanatory video tutorial of this article , please watch the below videos :
In this article we will focus on the area of a different data structure available in TCL. Initially we will brief about three types of data structures and later will go in deeper for each of them. The three data structures that are available in TCL. The first one is list, the second one is called associative array, and the third one which is the newest and latest is called dictionary. You can see these three in the below figure.
List in TCL :
A list is the data-structure similar to the array in C-Language. The difference is that a list can contain any of the integer, string, float etc as a element. The different ways a list can be created are as follows :
set myList [list a b c]
set myList "a b c"
setmyList {a b c}
setmyList [list $a $b $c]
setmyList {$a $b $c}
Anyone of the above notation will be accepted as creation of a valid list.
Length of a list :
length$myList
The output should be stored in a variable.
The length of the list can be calculated using the procedure length as :
Joining of More Than One List :
To join more elements we can use append procedure for an existing lista delimited string can be splitted into a list by using split procedure as :
split <delimited-string> <delimeter>
Lists can be joined together using concat procedure as :
concat <list1> <list2> ..... <listn>
To understand you may copy and run the below example. Also you may follow the narration mentioned in the video down below.
Sorting Inside a List :
We can sort the content of a list using the losrt procedure. Its different argument switch will allow us in the below way:
To sort in asciii order we use : -ascii To sort in integer increasing order we use : -integer -increasing To sort in integer decreasing order we use : -integer -decreasing To sort in dictionary order we use : -dictionary To sort in real increasing order we use : -real -increasing To sort in real decreasing order we use : -real -decreasing all of the above-mentioned sorting is exemplified by this code:
Iterating Over A List :
The best way to iterating over a list is to use the foreach loop. The foreach loop is already explained and exemplified in previous article. However run the below example to understand the iteration with a counter :
Append, Insert and Replace Elements Inside a List :
We can use lindex proc to get the positional value of a list element by its index.
lindex <list> <index>
Gives the value at the <index> of the <list>
To make a entry in the List from the R.H.S , we can use the below syntax :
lappend <list> <element>
To make a entry in the List from the L.H.S , we can use the below syntax : linsert <list> 0 <element>
We can replace a range of elements in the the list by this syntax : lreplace <list> <start-index> <end-index> <new-element-to-be-inserted>
All the above mentioned cases can be observed through the below code-snippet :
List of List :
Lists can be nested in the below way :
list a b {c d e} {f {g h}} now {g h} is nested inside {f {g h}} which is further nested in the topmost list using list proc. We can use split/concat/linsert/lreplace on list of list operations as shown in below code:
Hierarchical Printing of List-of-List :
The below self-explanatory code example shows the way to do the hierarchical printing of list of list. For detailed explanation please watch the video down below in this page.
Searching a list element :
lsearch can be used to search any list element inside a existing list. This is explained through the below code example :
For detailed explanation please watch the video below :