TCL Training Verdi 201107
TCL Training Verdi 201107
TCL Training Verdi 201107
SpringSoft Notifications
Copyright
2011 SpringSoft, Inc. All rights reserved. No part of this training may be reproduced in any form or by any means without written permission of SpringSoft, Inc.
Trademarks
The product names used in this document are the trademarks or registered trademarks of their respective owners.
Confidentiality
The information in this document is confidential and is covered by a license agreement between SpringSoft and your organization. Distribution and disclosure are restricted.
Overview
Tcl Introduction Basic Tcl Syntax
Lab 1
Tcl Introduction
Basic Introduction What is Tcl?
Tcl stands for Tool Command Language A String basis scripting language Use source your_script.tcl to execute your Tcl script under tclsh
What is Tk?
Tk is an associated toolkit to create window-based interactive applications using Tcl
Tcl Introduction
What Can You Do in Verdi with Tcl? Use Tcl to combine Verdi commands to make your own feature to improve efficiency Add your new feature, which was created by Tcl scripts, to the Verdi menu command or bind-key Use NPI (Novas Programming Interface) to traverse the design without Verdi GUI
Tcl Introduction
Possible Applications in Verdi with Tcl Application of FSDB
Calculate FSDB results. For example, duty cycles Search and sort FSDB results. For example, search for small pulses
Application of KDB
Access to Verdi database to do calculations and queries. For example, extract snake path from the design
Tcl Introduction
Tcl Command Sets in Verdi
Verdi provides Tcl commands for each action in the GUI. All Tcl commands are categorized by module and have a set prefix. Prefix sys deb src wv sch tfg nMem fsm reg eco ta sid lx Module System Debussy (Verdi) nTrace nWave nSchema Temporal Flow View Memory/MDA nState nRegister nECO Transaction Siloti ListX
Tcl Introduction
Execute Tcl in Prompt Tcl is a Unix shell language, and it can be executed under /usr/local/bin/tclsh
Add #!/usr/local/bin/tclsh in the first line of your Tcl script Execute your Tcl script in the prompt Example: hello.tcl
In terminal
>chmod +x hello.tcl
>hello.tcl Hello!!
It is not necessary to declare a in advance, the variable in Tcl will be declared automatically after you assign a value to it.
unset a to erase variable a set x 4; set y Hello use semicolon (;) to separate two commands set text This line is \ use backslash to connect to next line split into two lines
NOTE: space cannot be added after the backslash (this is a common error)
#This line is comment create a comment; Tcl will not execute this line
b a a a a w
set a \$b
NOTE: Use info exist a to check whether variable a exists. If it exists, then 1 will be returned; otherwise, 0 will be returned.
8 10 b+2 = 10
set a \[expr\]
[expr]
b a a a w
The double quotation mark can avoid the effect of the semicolon ; (will be treated as a string), but all replacements and calculations will be executed
set a x is $x; y is $y x is 4; y is x+10
When the curly brace { } is inside the double quotation mark , the item inside the curly bracket will be calculated
Originally the items inside the curly brace { } will not be replaced and calculated Example:
set set
x CurlyBraces a x is {$x}
x is {CurlyBraces}
5 8 17 -6.71257
expr will adjust the data type automatically based on the value in the expression
The value after the decimal point will be rounded down if you use integers in an expression
expr 1/3 expr 1.0/3.0 set tcl_precision 10 expr 1.0/3.0 set tcl_precision 3 expr 1.0/3.0
NOTE: The value for tcl_precision means the total digit number (not including the decimal point and the first zero). For example, 333.333 is 6, 0.333 is 3.
3 4 10 8
Lab 1
Practice with Basic Syntax
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
set a 10 set b 22; set c 8 set a echo $a puts $a puts $a $b $c puts {$a $b $c} puts {$a $b $c} expr $a+$b+c set d [expr $a+$b+$c] set e $a+$b+$c set aa $d set bb \$d
10 (Create variable a and assign value 10) 8 (Use ; to write two commands in a line) 10 (Get the value of variable a) 10 (To invoke variable a) 10 (Print out variable a to terminal) 10 22 8 (Print out variable a, b, c to terminal) $a $b $c (Notice the usage of { and }) {10 22 8} ({ } will take no effect inside ) 40 (Use expr command to do calculation) 40 (Save the expression result to $d) 10+22+8 (Will not be calculated without expr) 40 (Assign the value of $d to variable aa) $d (\ to reserve special character)
Lab 1
Practice with Basic Syntax
14. 15. 16. 17. 18. 19. 20.
expr 10/3 3 (Result will be interger) expr 10.0/3 3.333333333333 (Result will be floating number, since 10.0 is floating number ) set tcl_precision 8 8 (Set precision to 8, default is 12) expr 10.0/3 3.3333333 (The valid digit number is 8, not including the decimal point ) expr 1.0/3 0.33333333 (The valid digit number is 8, not including the decimal point and the first integer zero) set k 0; incr k 1 (Equal to set k [expr $k+1], notice that the variable for incr does not need $) incr k 4 5 (Equal to set k [expr $k+4] )
NOTE: The double quotation mark can also be used to define a List, but the replacement and calculations will be executed inside the double quotation marks. set month {January February March April} set color red green blue
Example:
The curly brace can be used to group items in the List, for example:
a b {c d e} f {a b} { b {c d } } e {f g} H a b { c d e } f g {h I }
lindex
a b c 0
c d p t
set CellList INV lappend CellList AND2 NOR2 lappend CellList AND2 NOR2
linsert a d 1 b c linsert a d 1 b c
a b c d a {b c} d
Refer to Tcl Manual for detailed usage of above options Sorting a list using ASCII sorting: lsort {a10 B2 b1 a1 a2}
Examples:
B2 a1 a10 a2 b1
Sorting a list using Dictionary sorting: lsort -dictionary {a10 B2 b1 a1 a2} a1 a2 a10 b1 B2 Stripping duplicate values using sorting: lsort -unique {a b c a b c a b c}
a b c
Sorting with index list: lsort -integer -index 1 \ {{First 24} {Second 18} {Third 30}} {Second 18} {First 24} {Third 30}
lreplace {a b c d} 1 2 Z Y X lreplace {a b c d} 1 2
a Z Y X d a d
llength {a b c d}
lsearch: See if a list contains a particular element, and return the index number. Returns -1 if no matching element.
Syntax: lsearch options list pattern
Example:
24
( expr 5+12+7 )
concat {a b c} {d e} f {g h} { {i j} k} a b c d e f g h {i j} k
array exists arrayName: Returns 1 if arrayName is an array variable, 0 if there is no variable by that name or if it is a scalar variable array get arrayName pattern: Get the index which matches the specified pattern and return index value array get name fi* first Allen array get name last Rita first Allen array set arrayName list: Convert list to array. list must have a form like that returned by array get, consisting of an even number of elements array set colorcount {red 1 green 5 blue 4 white 9} array get colorcount blue 4 white 9 green 5 red 1 array size arrayName: Returns a decimal string giving the number of elements in the array. If arrayName is not the name of an array then 0 is returned array size colorcount 4
Verdi Tcl
To convert the string to upper case or lower case (upper: toupper; lower: tolower)
Do not use == to compare strings. In example below, although the two strings have different content, they will be treated the same with ==. Tcl will convert the string to numbers first, so that the hexadecimal (base-16) 0xa will be converted to decimal 10 this is not our expectation for comparing strings
if { 0xa == 10} { puts Correct }
Verdi is Verdi is
is Verdi
Verdi is
Verdi i
string is integer $v_string string is ascii $v_string Refer to Tcl manual for more types
0 1
To describe a pattern:
* : Matches any sequence of characters in string, including a null string
1 0
1 0
\x: Matches the single character x. This provides a way of avoiding the special interpretation of the characters * ? [ ] \ in pattern.
0 1
set pi [expr 2*asin(1.0)] 3.14159265359 puts [format Value: %s = %07.3f PI $pi] Value: PI = 003.142 %s : No conversion; just insert string %07.3f : Convert number to signed decimal string of the form xx.yyy, where 7 means the digit of floating decimal number (the floating point is also one digit), 3 means the precision after floating point, 0 means to fill 0 for the blank.
The scan command will search the string based on the defined format, and then save the matched string to variables sequentially set str AreaUsagePattern = scan $str %s %s %s key eq set Key set eq set value T3T57 value AreaUsagePattern = T3T57
Example:
Lab 2
Practice for basic data types
1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
set traffic1 red green yellow red green yellow set traffic2 [list red green yellow] red green yellow set traffic3 red {green1 green2} yellow red {green1 green2} yellow lindex $traffic1 0 red (Notice the index starts from 0) lindex $traffic1 1 green lindex $traffic1 end yellow (Get the last item) lindex $traffic3 1 green1 green2 lappend traffic1 blue red green yellow blue (Append blue into list traffic1, notice here the traffic1 does not need $) lrange $traffic1 1 2 green yellow (Get 1~2 range) linsert $traffic1 2 pink white red green {pink white} yellow blue (Notice that linsert will not put the value to $traffic1, so the traffic1 will still be red green yellow blue) lsort ascii decreasing $traffic1 yellow red green blue lsearch regexp $traffic1 .*ee.+ 1 (Find green and return the index 1) set str happy; split $str h a p p y (Separate words) set str h a p p y; join $str happy (Combine words)
Where the value of condition must be a Boolean expression If the condition is true then execute body1, if the condition is false then execute boody2
Example:
set A 10 set B 5 if {$A >= $B } { puts A >= B } else { puts A < B }
A >= B
{ {
{ {
Where test is a Boolean expression Body is the program to be executed when test is true
Example:
a
0 1 2 3 4 5 6 7 8 9 10
sum
0 0 1 3 6 10 15 21 28 36 45
new sum
0 1 3 6 10 15 21 28 36 45 55
## calculate the sum from 0~10 set a 0 set sum 0 while {$a <= 10} { set sum [expr $a+$sum] set a [expr $a + 1] } puts Total = $sum
Execute start Repeatedly evaluates test If the result of test is non-zero it invokes body Invokes the Tcl interpreter on next Back to step 2 to repeat the loop
Example:
## calculate the sum from 0~10 for {set a 0; set sum 0} {$a <= 10} {incr a} { set sum [expr $sum + $a] } puts Total = $sum
List: a Tcl list Body: the Tcl script The flow: For each element of list (in order from first to last), foreach assigns the contents of the element to varname, then executes body.
Example: set sum 0 set numList [list 1 2 3 4 5 6 7 8 9 10] foreach a $numList { set sum [expr $sum+ $a] } puts Total = $sum
-exact : use exact matching, this is default -regexp : use regular expression matching -- : Marks the end of options. The argument following this one will be treated as string even if it starts with a Refer to the Tcl manual for detailed usage
NOTE: The comment in switch command is only allowed in body; otherwise, it may cause problems in Tcl parser.
set date [exec date] set n [exec sort < /etc/passwd | uniq ]
If the external program gets error when executing, it will cause the exec command to get the unexpected value. To avoid this, you can use catch command to filter the error message:
catch {exec program arg1 arg2 } result NOTE: Use curly brace { } after catch command, this is because catch will invoke Tcl interpreter. The command will be executed before activate catch if you use the square bracket [ ]
catch returns a non-zero integer value and saves the error to resultVarName catch returns zero value and saves the return value to resultVarName proc cat {} { set fildid "" if { [catch { open ./abc.tcl r } fileid ] } { puts "opening file error: $fileid" } else { while { [ gets $fileid line ] } { puts $line } close $fileid } }
Example:
Manipulate Files
Commands for File Processing Frequently used commands for file processing:
open fileName access: Open a file-based or command pipeline channel puts channelId string: Write to a channel gets channelId varName: Read a line from a channel read channelId numChars: Read from a channel Close channelId r|w: Close an open channel
Example:
set filename input.data set input [open $filename r ] while { [gets $input read_line] >= 0 } { puts read_line=$read_line } close $input
Manipulate Files
File Processing open A better coding style for opening a file:
if { {catch { open data r } fileId } { puts cannot Open data : $fileId } else { ; close $fileId }
NOTE: Remember to close the file, otherwise the data may lost.
Manipulate Files
File Processing file file: Manipulate file names and attributes
Syntax: file option name arg1 arg2 ... Frequently used options:
file dirname name: Return the directory name of name file file executable name: Returns 1 if file name is executable, 0 otherwise. file exists name: Returns 1 if file name exists, 0 otherwise. file extension name: Returns the extension name of file name. file isdirectory name: Returns 1 if file name is a directory, 0 otherwise file size name: Returns the file size of file name. file mkdir name : Generate a directory name. file join path name: Concatenate path and name file rootname name: Returns name but filters the last component after .. file tail name: Returns name after the last directory separator.
Example:
file join work/verdi a.tcl file rootname /work/verdi/a.gds file tail /work/verdi/a.tcl work/verdi/a.tcl /work/verdi/a a.tcl
Lab 3
Write a simple Tcl script Refer to following while script for calculating (1+2+3++9+10), try to use for loop to write a script for calculating (1+3+5++9):
set a 0; set sum 0 while {$a <=10} { incr sum $a; incr a }; puts $sum
Go to General folder, enable the Enable TCL Command Entry Form option, the Command Entry form will be opened. The setting will be saved into novas.rc, and the Command Entry form will be opened automatically next time you invoke Verdi
Use replay to execute the Verdi.cmd file can reproduce previous steps
% setenv NOVAS_AUTO_SOURCE your_script.tcl % verdi & Search for TclAutoSource tag in [General] section in the novas.rc file Specify your Tcl script for the TclAutoSource tag, for example: [General] TclAutoSource = MyTclScript.tcl
Check all available Reason in Introduction Tk Command Client Adding Event Callbacks to Your Tk Application section of the Novas Command Language document (tcl.pdf in <Novas_install>/doc directory)
NOTE: you can also register a callback with a triggered reason after invoking Verdi, for example:
AddEventCallback [tk appname] AutoLoadSignal wvCreateWindow 1 To execute the Tcl procedure AutoLoadSignal when a nWave window is created tk appname: returns the name of the application, the application name will be Verdi if you source the Tcl script after invoking Verdi
Case Study - 1
Requirement Users have a signal list file which was generated from another EDA tool; they want a direct way to load all signals into nWave from the file without selecting each one in Get Signals form. Script introduction
file.list: the signal list generated from other EDA tool load_menu.tcl: create banner menu load.menu: define the banner menu load_signal.tcl: the main body of the script
Case Study - 1
The Script
To execute the script: verdi play load_menu.tcl & Input file: file.list
/system/addr[7:0] /system/clock
load_menu.tcl
fmAppendBannerMenu -win window_id -file load.menu
load.menu
Menu Load { "Load Signals From File" _L f.tcl dummy "source load_signal2.tcl" }
Case Study - 1
The Script
To execute the script: verdi play load_menu.tcl & Input file: file.list
/system/addr[7:0] /system/clock
load_menu.tcl
fmAppendBannerMenu -win window_id -file load.menu Append a banner load.menu menu item Menu Load Could be $_nTrace1 or any string. The file which defines If meaningless string is specified, the the banner menu { menu will apply to all existing windows "Load Signals From File" _L f.tcl dummy "source load_signal2.tcl" }
Case Study - 1
The Script
To execute the script: verdi play load_menu.tcl & Input file: file.list
/system/addr[7:0] /system/clock Give the name for load_menu.tcl The bind-key for the command, the banner menu fmAppendBannerMenu -win window_id -file load.menu TCL file name, needs to be one of the could be any string command name characters
load.menu
Menu Load { "Load Signals From File" _L f.tcl dummy "source load_signal.tcl" } Execute the tcl script when f.tcl : execute a tcl script The command name invoking the banner menu f.exec: execute a Verdi command under the banner menu
Case Study - 1
The Script load_signal.tcl
proc load_signal {} { global file_str set w .load toplevel $w wm title $w "Load Signals From File" label $w.msg -justify left -text "Please specify file name" pack $w.msg -side top frame $w.file pack $w.file -side top -fill x -pady 1 entry $w.file.file -relief sunken -textvar file_str label $w.file.file_label -text "file name" pack $w.file.file_label -side left pack $w.file.file -side left button $w.file.load -text Load -command "load" button $w.file.dismiss -text Dismiss -command "destroy $w" pack $w.file.load $w.file.dismiss -side left }
Case Study - 1
The Script load_signal.tcl
proc load_signal {} { global file_str set w .load toplevel $w wm title $w "Load Signals From File" label $w.msg -justify left -text "Please specify file name" Set a global variable file_str. pack $w.msg topin another procedure the variable can-side be used frame $w.file pack $w.file -side top -fill x -pady 1 Create .load as the top window. entry $w.file.file -relief sunken -textvar file_str Note: a window name must start with .. label $w.file.file_label -text "file name" pack $w.file.file_label -side left Specify the title for the .load window The syntax: wm title window pack $w.file.file -side left string button $w.file.load -text Load -command "load" button $w.file.dismiss -text Dismiss -command "destroy $w" pack $w.file.load $w.file.dismiss -side left }
Case Study - 1
The Script load_signal.tcl
proc load_signal {} { global file_str set w .load toplevel $w wm title $w "Load Signals From File" label $w.msg -justify left -text "Please specify file name" pack $w.msg -side top
label: Create and manipulate the label widget. frame $w.file -justify : When multiple lines of text displays in a widget, this option determines pack -side topeach -fill x -pady 1 be one of left, center, or right. how the $w.file lines line up with other. Must entry $w.file.file -relief sunken -textvar -text : Specifies a string to be displayed insidefile_str the widget.
label $w.file.file_label -text "file name" pack : The pack command -side is used to communicate with the packer, a geometry pack $w.file.file_label left manager that arranges theleft children of a parent by packing them in order around pack $w.file.file -side the edges of the parent button $w.file.load -text Load -command "load" -side: Specifies which side of the master the slave(s) will be packed against. button $w.file.dismiss Dismiss -command Must be left , right, top, or -text bottom . Defaults to top. "destroy $w" pack $w.file.load $w.file.dismiss -side left }
Case Study - 1
The Script load_signal.tcl
procCreate load_signal {} { widget .w.file a frame global file_str set w .load toplevel $w -fill x: If the slave's parcel is larger than its requested dimensions, this option may wm title $w "Load Signals From File" be used to stretch the slave. The argument x will stretch the slave horizontally to fill the entire width of its parcel. label $w.msg -justify left -text "Please specify file name" -pady amount: Amount specifies how much vertical internal padding to leave on pack $w.msg -side top each side of the slave. Amount defaults to 0. frame $w.file pack $w.file -side top -fill x -pady 1 entry $w.file.file -relief sunken -textvar file_str label $w.file.file_label -text "file name" pack $w.file.file_label -side left pack $w.file.file -side left Create a entry widget .w.file.file and pack the widget to its parent (.w.file). $w.file.load -textfor Load "load" values are raised, -relief:button creates the 3-D effect the-command widget. Acceptable button $w.file.dismiss -text ,Dismiss -command "destroy $w" sunken , flat, ridge, solid and groove pack $w.file.load $w.file.dismiss -side left -textvar : specify the variable for the input text. File_str is a global variable. }
Case Study - 1
The Script load_signal.tcl
proc load_signal {} { global file_str set w .load toplevel $w wm title $w "Load Signals From File" Create a button widget .w.file.load label -justify leftto -text specify -text:$w.msg Specifies a string be "Please displayed insidefile thename" widget pack $w.msg -side top a Tcl command to associate with the button -command : Specifies frame $w.file Create a button widget .w.file.dismiss and associate with Tcl command pack $w.file top the -fill x -pady 1 destroy $w-side to close window. entry $w.file.file -relief sunken -textvar file_str label $w.file.file_label -text "file name" Pack $w.file.file_label two buttons into -side the frame pack left and specify the position pack $w.file.file -side left button $w.file.load -text Load -command "load" button $w.file.dismiss -text Dismiss -command "destroy $w" pack $w.file.load $w.file.dismiss -side left }
Case Study - 1
The Script load_signal.tcl
proc load {} { global file_str set file_id [open $file_str r] while {[gets $file_id sig_line] >= 0} { wvAddSignal "$sig_line" } } load_signal The load procedure will be invoked when clicking Load button in load_signal procedure Declare file_str as a global variable, the value is inherited from the entry .w.file.file in the load_signal procedure Open the file with read access, get each line in the file and add signal into nWave To invoke the load_signal procedure
Case Study - 1
How does it works? verdi f run.f ssf rtl.fsdb play load_menu.tcl &
Case Study - 2
Readme File
[Function Abstract] This scripts generates an nWave session file before exiting and loads last session when nWave is invoked. When select Save and Close Win under File menu on nWave , it generates nWave session file named "<FSDBName>.rc" and "AutoSaveSignal.rc" automatically. If there is a file named "AutoSaveSignal.rc" when invoking nWave, it is loaded automatically. [Usage] % setenv NOVAS_AUTO_SOURCE AutoSave.tcl % verdi ... [Input File] [Output File] <FSDBNAME>.rc AutoSaveSignal.rc
Case Study - 2
The Script
proc AutoSaveSignal {} { global ary
Inherit $ary from GetFileName procedure
set wid [wvGetCurrentWindow] $fname: get the FSDB name from GetFileName procedure. Note it uses $ary($wid) to get the set fname $ary($wid)
same FSDB name in GetFileName procedure when there are multiple FSDB files
if { $fname != "" } { Save signals to FSDB_name.rc file wvSaveSignal -win $wid "$fname.rc" } Save signals to wvSaveSignal -win $wid "AutoSaveSignal.rc AutoSaveSignal.rc file wvCloseWindow -win $wid }
Close current nWave window
Case Study - 2
The Script
proc AutoLoadSignal {p1 p2} {
Note: here the p1 and p2 argument will be: $P1: wvCreateWindow $P2: 2a97b46aa8 (the window ID)
eMenuAppendItem -win $p2 -menuName File -itemName "Save and Close Win" -tclCmd "AutoSaveSignal" }
Create a Save and Close Win command under File menu, invoking the command will execute the AutoSaveSignal procedure.
Case Study - 2
The Script
proc GetFileName {p1 p2} { global ary set lname "" set wid [wvGetCurrentWindow] set sid [string last / $p2] set lid [string last . $p2]
Note: here the p1 and p2 argument will be: P1: wvOpenFSDBFile P2: /verdi/home/allen_shieh/demo/rtl.fsdb Get the window ID for current nWave window $sid: get the index for last / in $p2 $lid: get the index for last . in $p2
set lname [string range $p2 [incr sid] [incr lid -1]] # puts "$p1 $p2 $lname" set ary($wid) $lname }
To store the fsdb name in $ary array with $wid index
AddEventCallback [tk appname] AutoLoadSignal wvCreateWindow 1 AddEventCallback [tk appname] GetFileName wvOpenFSDBFile 1
Register callbacks to: 1. Execute procedure AutoLoadSignal when opening nWave window 2. Execute procedure GetFileName when loading FSDB
Lab 4
Practice for Writing a Useful Tcl Script Requirement:
When there is any pulse in the signal which is smaller than the specified time range, dump the signal name and the time when the pulse happens.
Hints:
Create an entry for specifying the time range by:
Creating a menu item and question box for entry, or: Using an environment variable, or: Adding parameters in the script Check <Novas_install>/doc/tcl.pdf to find proper commands
Reference
Get Help from Resources
Novas Command Language:
<Novas_install>/doc/tcl.pdf
Books:
Sams Teach Yourself Tcl/Tk in 24 Hours by Venkat V.S.S. Practical Programming in Tcl and Tk by Brent Welch and Ken Jones