Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
100% found this document useful (1 vote)
287 views

tcl scripting(vlsi) (1)

Uploaded by

shagufta.mujeeb
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
287 views

tcl scripting(vlsi) (1)

Uploaded by

shagufta.mujeeb
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 241

Fundamentals

of

TCL scripting -- SIOL


Workshop Overview
• Objectives
— Introduce TCL
— Understand TCL uses and strengths
— Learn how to write simple TCL scripts
— Demonstrate how TCL can be used for VLSI scripting

• Format
— Real-world VLSI TCL scripting examples
Why TCL?
• Productivity
• Portability
— Ms Windows, UNIX variants, Macintosh, OpenVMS, BeOS, …

• Availability
— Download, use, modify and re-distribute without royalties

• Interfacing between the tools


— Can bridge incompatible interfaces, platforms, distant locations

• Many available extensions


— GUI programming (TK, Tix, BLT, Togl, ...)
— Interaction with command-line applications (expect, …)
— Database (OraTCL), object-oriented programming ([incr TCL]),
...

TCL stands for “Tool Command Language”.


TCL was originally developed to replace ad-hoc scripting languages used by
research VLSI tools at UC Berkeley. While it started as an SoC Design scripting
language, TCL popularity grew fast and today it has been reported to be used in
many different applications ranging from hand-held devices to mission-critical
systems. TCL is now a mature and very powerful portable scripting language
with many extensions available for various application areas.
Commercial support for TCL has been provided by a variety of companies,
including Sun Microsystems, Scriptics and at the present day ActiveState
Corporation. Future developments of TCL are being overseen by an
independent body - a TCL Core Team.
TCL : Main Features
• Rapid application development

• Embeddable My
TCL
application

expect My
extension
• Extendible
. ..
TK

TCL
• Flexible integration
Application A Application B
TC
• Easy to learn (e.g. Solaris) (e.g. WinNT)
L

TCL allows for complex applications to be developed quickly. An interactive nature


of the TCL development environment provides immediate feedback on the
operation of the developed application.
TCL scripting can be easily embedded into applications written in C or C++. This
allows for application’s internal functions to become visible as TCL commands.
Furthermore, build-in TCL command set provides a powerful facilities for
controlling the execution of these new commands, analysis of data, arithmetic
functions, data input/output and others. This is the approach used by many SoC
Design vendors today.
TCL was designed to be extendible. New functionality can be added easily
by defining new TCL commands using TCL or C/C++..
TCL is an ideal tool for solving application integration problems, involving for
example incompatible interfaces, different operating systems, applications running
on different machines across the network, etc.
TCL has a simple syntax and few basic language rules, which makes it easy
to learn.
TCL in EDA
• Quickly becoming the standard VLSI scripting language
• Typical uses
— simulation, synthesis and test automation scripting
— data analysis and visualixation
— design flow integration
— netlist conversion, analysis and hacking
— linking incompatible tools running on different platforms
— scripting front-ends for command-line based applications
— IP core customixation scripting
— automated test benches, regression testing, HW/SW co-verification
— portable system demonstrators/applications
— project/EDA system administration (installation, backup, etc.)

TCL was adopted by the SoC Design industrial community as a “standard” scripting
language for SoC Design tool scripting. Availability of a common language eases
design tool integration, reduces training costs, but also accelerates SoC Design tool
development as a common standardized TCL support may be implemented using
freely downloadable sources.
TCL shell (tclsh)
• Command-line interface
— Interactive incremental testing (try & see)

• Available within many modern SoC Design


tools
• Executable file names
— For example for TCL 8.3: tclsh8.3,
tclsh83.exe
— During this course: tclsh
Command prompt
(UNIX or Ms Windows) $$ tclsh
tclsh
%% puts
puts "Hello
"Hello world!"
world!" Recognized
Try this: TCL command
Hello
prompt Hello world!
world! TCL
%% info commands
info commands
commands
Standard output (UNIX tell
tell socket
socket subst
subst open
open eof
eof pwd
pwd glob
glob list
list exec
terminal) exec pid auto_load_index time unknown eval
pid auto_load_index time unknown eval lrange
lrange fblocked lsearch auto_import
fblocked lsearch auto_import ... ...
Leave tclsh
%% exit
exit
$$

You may also come across tools which use TCL versions 7.6, 8.2 and beyond.
There are significant differences between these versions (new commands and
new command options) and therefore it is advisable to consult tool documentation
for any incompatibilities.

tclsh syntax
tclsh ?fileName arg arg ...?
Working with TCL scripts (UNIX)
• Interactive & iterative process

1. EDIT

2. TEST
From a TCL
From a UNIX shell: interpreter:
$$ tclsh
tclsh
tclsh my_script.tcl
$$ tclsh my_script.tcl %% source
source my_script.tcl
my_script.tcl
Hello
Hello world!
world! Hello
Hello world!
world!
$$ !!
!! %% !!
Repeat Hello !!
last UNIX
Hello world!
world! Repeat Hello
Hello world!
world!
...
... last TCL ...
command ...
command %% exit
exit

Writing a TCL script typically involves an iterative process of editing and testing
TCL script files. This process is identical for all platforms supported by TCL.
Working with TCL scripts (Ms Windows)
• Interactive & iterative process

1. EDIT

2. TEST
From a TCL
From Command/MSDOS Prompt: interpreter:
C:\>
C:\> tclsh
tclsh
C:\> tclsh my_script.tcl
C:\> tclsh my_script.tcl %% source
source my_script.tcl
my_script.tcl
Press Hello
Hello world!
world! Repeat Hello
Hello world!
world!
↑ C:\> tclsh my_script.tcl
C:\> tclsh my_script.tcl last TCL
%% !!
!!
Hello command
to repeat Hello world!
world! Hello
Hello world!
world!
last ...
... Or use ...
...
command %% exit
↑ exit

While a command-line TCL interpreter is a typical interface available to an SoC


Design tool TCL script writer, there are also other TCL development tools which
provide more advanced features. One example of such a tool is TCLPro, which
provides TCL debugging, syntax checking, TCL application packaging and other
features. For more information on TCLPro, please visit dev.scriptics.com.

Debugger
controls

Command Variable
stack traces
TCL
script
display

Breakpoints

Commandreturn
value and error
code
TCL Interpreter in SoC Design Tools
• TCL interpreter is typically embedded in your SoC
Design tool command console (GUI or command line)
— Try invoking info commands in your favorite SoC Design
tool!

HERE
HERE

HERE
HERE

HERE
HERE

TCL-enabled SoC Design tools will be discussed in more detail later in this
Workshop.
Help!
• Command hints and manual pages
%% info
info
wrong
wrong ## args:
args: should
should be
be "info
"info option
option
?arg
?arg arg
arg ...?"
...?"
%% info
info xyzzy
xyzzy
bad
bad option
option "xyzzy":
"xyzzy": should
should bebe args,
args,
body,
body, cmdcount,
cmdcount, commands,
commands, complete,
complete,
default,
default, exists,
exists, globals,
globals, level,
level,
library,
library, locals, patchlevel, procs,
locals, patchlevel, procs,
script,
script, tclversion,
tclversion, oror vars
vars
%% info
info commands
commands
tell
tell socket
socket subst
subst open
open eof
eof pwd
pwd glob
glob
list
list exec pid auto_load_index time
exec pid auto_load_index time
unknown
unknown eval
eval lrange
lrange fblocked
fblocked lsearch
lsearch
auto_import
auto_import
...
...

%% man
man info
info

UNIX only!

Command-line hints provide quick feedback on the command syntax and available
options. Manual pages are the best source of information for each TCL command.
They are well written and updated with each release of TCL distribution.
Manual page browsing using man command works only on UNIX platforms (TCL
interpreter actually invokes man command from the native UNIX environment). On
UNIX, TCL manual pages are typically located in section n of the on-line UNIX
manual. You may use -S option to select this section in case of command name
conflict with another UNIX application, for example
man -S n file
will retrieve manual page for TCL file command and not for the UNIX file
command.
Microsoft Windows users may use Windows help file provided with the Windows
TCL distribution. The help file contains manual pages identical to those in the
UNIX distribution.
Furthermore, manual pages may be downloaded from
http://dev.scriptics.com/ in HTML format for both platforms.
EDA vendors distribute proprietary documentation for additional TCL
commands provided by their SoC Design tools.
Quiz 1
• What categories of SoC Design tools
support TCL?
(a) high-level synthesis
(b) HDL simulation
(c) automatic placement & routing
(d) prototyping & testing tools
(e) all of the above

Answer
TCL Scripting for SoC Design

TCL Basics 1
Aims and Topics
• Aim
— To familiarixe with TCL syntax and operation of a TCL
interpreter

• Topics
— TCL syntax
— Variables
— Substitution
— Command evaluation
TCL Commands
• TCL is CASE SENSITIVE
• TCL script is composed of “commands”
spaces or tabs newline terminates
TCL
separate command words the command
script

TCL
commands
info commands Enter ↵

TCL interpreter first


breaks the command
into words

info commands

• TCL command is composed of “words”


Command
name
1st
argument
2nd
argument
3rd
argument
...
TCL Script Processing
Summary
Command Separation

Word Grouping

Substitution

Command Evaluation

Each line of a TCL script is processed in four steps indicated above. If you want
to be able to write effective TCL scripts you need to understand how this process
works.
The previous slide outlined command separation. In the following we will look at
the steps which follow next.
Word Grouping With "" and {}
• Use "" or {} to group words together

puts "Hello world!" puts {Hello world!}

quote characters brace characters


are discarded are discarded

puts Hello world! puts Hello world!

spaces, tabs and newlines


are preserved within "" or {}

• ""/{} inside {} and {} inside "" are treated as ordinary


characters
• "" inside "" are pair-matched

Note that there are other differences between grouping with "" and {}
(more later!).

Word grouping examples:

puts
puts "Hello
"Hello {{ world!
world! }}
}} "" puts Hello { world! }}

puts
puts "Hello
"Hello "" world!
world! ""
"" ""
Syntax Error!
escape " with a backslash
puts "Hello \"
puts "Hello world! \"
\" world! \" "" puts Hello " world! "
puts
puts "Hello
"Hello "world!"
"world!" ""
Syntax Error!
puts
puts {Hello
{Hello {{ world!
world! }}
}}}} puts Hello { world! }}

puts
puts {Hello
{Hello "" world!
world! ""
""}}
puts Hello " world! ""
puts
puts {Hello
{Hello }world!{
}world!{ }}
Syntax Error!

having a space or a tab might be important!


TCL Syntax Summary
• Other elements of TCL
syntax
— Comments start with #
— In-line commands are separated with ;
— All characters with special meaning can be escaped with \
both newline and semicolon (;)
terminate the command

## This
This is
is aa comment
comment
cmdName
cmdName arg
arg arg
arg arg
arg ...
...
cmdName
cmdName arg
arg arg
arg arg
arg ...;
...; cmdName
cmdName arg
arg arg
arg arg
arg ...
... command must be
terminated before
an in-line comment
cmdName arg
cmdName arg arg
arg arg ...; ## This
arg ...; This is
is an
an inline
inline comment
comment
escape a newline to
cmdName arg \\
cmdName arg continue on subsequent
arg arg ...
arg arg ... lines \ Enter ↵

## Even
Even aa comment
comment can
can be
be split
split across multiple \\
across multiple
lines!
lines!
Variables
• No need to declare variables
— Use set to create a variable and assign/retrieve its value
— Use unset to delete one or more variables

• TCL is typeless—variables store STRING values

%% set
set aa "Hello
"Hello world!"
world!"
Hello assigns Hello world! to variable a and returns this new value
Hello world!
world!
%% set
set aa with no value, set returns the value of the named variable
Hello
Hello world!
world!
%% set
set bb reading variable which wasn’t previously defined is an error
can’t
can’t read
read "b":
"b": no
no such
such variable
variable
%% set
set bb 123
123 value 123 is a string containing characters 1, 2 and 3
123
123
%% unset
unset aa bb deletes variables a and b from the TCL interpreter
%% (deleting variable which wasn’t previously defined is an error)

set and unset syntax

set varName ?value?


unset varName ?varName varName ...?
Variable Names and Values
Use only letters, digits and
• Variable names underscores in variable
names to maintain
— Are CASE SENSITIVE readability!

— May be composed of ANY characters

• Strings can also represent numeric values:


— Integers: 123 (decimal), 0x7b or 0x7B (hexadecimal), 0173 (octal)
— Real numbers: 3.14159, 1.23e+2 or 1.23E2, 123.0
— Boolean: 0 (false), 1 (true)
%% set
set aa 123;
123; set
set AA 456
456 %% set
set reg
reg 0173
0173 integer (octal)
a and A 456
456 0173
0173
are %% set
different
set aa %% set
set reg
reg 0x7b
0x7b integer (hex)
123
123 0x7b
0x7b
variables
set !£%^&*
%% set !£%^&* "bad
"bad idea!"
idea!" %% set
set pi
pi 3.14159
3.14159 real number
bad
bad idea!
idea! 3.14159
3.14159
in TCL this is a
set !£%^&*
%% set !£%^&* valid variable
%% set
set match_found
match_found 11 Boolean
bad
bad idea!
idea! name! 11
Substitution and Command Evaluation
• After separating commands and word grouping,
TCL command is processed in further two stages:
remember me?
Command Separation

Word Grouping

variable
Substitutiom backslash
command

Command Evaluation
Substitution
• All command words are searched for special constructs which
trigger substitution
— Words are examined from left to right, character by character

$
start

• Each character is processed exactly ONCE


Variable Substitution ($)
• Each occurrence of $varName is replaced with the
corresponding variable value
— Except where $ is escaped (\$)

%% set
set dd 10;
10; set
set pp 22
22
%% puts "Time == $d
puts "Time $d ns"
ns" puts Time = $d ns
Time == 10
Time 10 ns
ns

$d is replaced by its
value (10)

puts Time = 10 ns

NOTE: word boundaries remain


unchanged!
More on Variable Substitution
• Use ${varName} to indicate variable name when
— No space is required after the variable’s value
— Name contains characters other than letters, digits or underscores

• $followed by a character which is not a letter, digit or


underscore is treated as an ordinary character
⇒ Constructs such as $$a are allowed
%% puts
puts "Time
"Time == $dns"
$dns"
can’t
can’t read
read ”dns":
”dns": no
no such
such variable
variable
no space after variable’s value
%% puts "Time == ${d}ns
puts "Time or $p%"
${d}ns or $p%" ($p% doesn’t need ${}!)
Time == 10ns
Time or 2%
10ns or 2%
%% puts
puts "This
"This is
is $!£%^&*"
$!£%^&*" use ${} to indicate the variable name
This
This is
is $!£%^&*
$!£%^&*
%% puts
puts "This is aa ${!£%^&*}"
"This is ${!£%^&*}"
$ is treated as an ordinary character
This is aa bad
This is bad idea!
idea!
(doesn’t need to be escaped)
%% puts
puts "The
"The price
price is
is $$d."
$$d."
The
The price
price is
is $10.
$10.
Backslash Substitution (\)
• Replaces \<character> with its substitution equivalent
— Except where \ is escaped (\\)

%% puts
puts "Flag\t\"rst\"
"Flag\t\"rst\" on"
on" puts Flag\t\"rst\" on
Flag
Flag "rst"
"rst" on
on
tab quotes quotes

puts Flag "rst" on

NOTE: word boundaries remain


unchanged!
More on Backslash Substitution
• Backslash substitution can be used to insert
— Special terminal characters
• \n (newline), \t (tab), \b (backspace), \a (audible alert), ...
— Any character using its binary value
• \x4f or \x4F (hexadecimal value), \117 (octal value)
— Escape special characters or just replicate other characters
• \$ (dollar), \\ (backslash), \" (quotes), \} (brace), \ (space)
• \i (character i), ...

%% puts
puts "Synthesis done. \a\a\a"
"Synthesis done. \a\a\a" beeps 3 times
Synthesis
Synthesis done.
done.
%% puts "ABC == \x41\102\x43"
puts "ABC \x41\102\x43" inserting binary values into a TCL
ABC == ABC
ABC ABC string
%% puts
puts "Some specials: \$\"\\"
"Some specials: \$\"\\" escaping special characters $, “ and \
Some specials: $"\
Some specials: $"\
Everyone’s Favourite: The Newline
• Inserting newlines
%% puts
puts "Line
"Line 11 %% puts
puts "Line
"Line 1\nLine
1\nLine 2"
2"
newlines within "" Line
Line 2"
Line 2" Line 11
or {} are reserved Line
Line
Line 11 Line 22
insert a newline with \n
Line
Line 22 %%
2nd newline inserted
%% by puts

• Avoiding newlines
%% puts
puts "Line
"Line 1\
1\ escaped newline + zero or more spaces or tabs are
replaced with a space!
Line
Line 2"
2"
Line
Line 11 Line
Line 22
%%

%% puts
puts "No\
"No\
— If you don’t want the space, use \b
\bSpace"
\bSpace"
delete the substituted NoSpace
NoSpace
space with a backspace %%

Newlines are very useful for improving readability of user messages, simulation
data, serial bitstream, formatting raw data strings, etc. The above examples
demonstrate some of the typical uses of newlines in TCL scripts.
Command Substitution ([])
• Each occurrence of [<commands>] is replaced with the value
returned from the last command executed in <commands>
— Except where [] are escaped (\[ and \])
%% set
set dd 10
10 puts Time = [set d]ns
10
10
%% puts "Time == [set
puts "Time [set d]ns"
d]ns" set d

Time == 10ns
Time 10ns Command Separation

Word Grouping

Substitution

Command Evaluation

10

puts Time = 10ns

NOTE: word boundaries remain


unchanged!
Nested Command Substitution
• Command substitution can be nested
— Each occurrence of [] will trigger a new command substitution
%% set
set aa "eggs"
"eggs"
eggs
eggs
%% puts
puts "Two nested [set
"Two nested [set bb [set
[set a]]"
a]]"
Two nested eggs
Two nested eggs

puts "Two nested [set b [set a]]"


set a

set b [set a]

set b eggs

eggs

eggs
puts Two nested eggs
Word Grouping with []
• [] can be used for word grouping too!
— Do not escape word separators and grouping quotes within []

puts [set
%% puts [set bb "No
"No [set
[set aa "escapes
"escapes here"]"]
here"]"]
No
No escapes
escapes here
here [] group the argument to puts

puts [set b "No [set a "escapes here"]"]

set a "escapes here"

set b "No escapes here"

escapes here

No escapes here

puts No escapes here


Command Evaluation

Command Separation

Word Grouping

variable
Substitution backslash
command

Command Evaluation ?
Command Evaluation
• TCL interpreter searches for a matching TCL
command (command name is the 1st word) and then
passes all arguments to it
• Next the command will execute
— Can interpret arguments in any way (strings, numbers, etc.)

• When done, the command will return a result back


to the interpreter No escapes here

• Commands
— Built-in puts puts No escapes here

— User-defined
set
Quiz 2
file: examples/quiz2.tcl
set
set aa 10
10
set
set bb "{$a}\{
"{$a}\{ #[set
#[set cc 14]"
14]"
puts
puts "$b"
"$b"

• What is the value stored in b?


space
(a) {10}{
(b) 10{ #14
(c) {10}{ #[set c 14]
(d) $a{ #14
(e) {10}{ #14
(f) {$a}\{ #[set c 14]
(g) {$a}{ #14
(h) This vill genevate a syntas evvov!

Answer
TCL Scripting for SoC Design

TCL Basics 2
Aims and Topics
• Aim
— To learn about using TCL for arithmetic calculations, basics of
file manipulation and structured scripting

• Topics
— Mathematical operations
— Basic file manipulation
— Basic procedures
Mathematical Operations
• TCL supports all usual operators and
functions
• Mathematical
— Arithmetic
— Relational
— Logical
— Bit-wise
— Various functions

• But also
— String pattern matching
— List, array, string manipulation
— File I/O, inter-process, network
— ... (more later)
TCL as a Calculator
• Use expr command to evaluate mathematical expressions
10 - 20
%% expr
expr 11 ++ 11
22
%% set
set aa 10;
10; set
set bb 20
20 expr
20 substitution performed first by the
20 TCL interpreter and then by the
%% expr
expr $a
$a -- $b
$b expr command
-10
-10
%% expr
expr {$a
{$a -- $b}
$b} substitution performed only by the $a - $b

-10 expr command!


-10
expr

Enclose the expression


in braces for efficiency

• Use real number strings to invoke real number operators


%% expr
expr 99 // 22 integer division
44 9 / 2.0 If a variable may contain integers
%% expr AND real numbers, consider adding
expr 9 / 2.0 real number division
+ 0.0
4.5
4.5 in the expression, e.g.
set a [expr {$a + 0.0}]

expr syntax expr arg ?arg arg ...?

The improved speed of calculation when the expression is enclosed in braces can
be observed even on a simple example above.
expr {$a -$b} executes 7 times faster than expr $a - $b

Try: source examples/expr_speed.tcl

Execution time Relative execution time


expr $a - $b 7µs 7
expr {$a -$b} 1µs 1
TCL 8.0.5 on Pentium III/1GHz PC, 256MB RAM, Windows
2000
Available Operators
• Arithmetic operators accept
highest
integers and reals precedence -a, !a, ~a

• Relational operators accept a*b, a/b, a%b


integers, reals and stvings a+b, a-b

• Logical operators accept integers a<<b, a>>b


and reals a<b, a>b, a<=b, a>=b
— non-xero = true a==b, a!=b
— xero = false a&b
• Bit-wise operators accept a^b
integers only a|b
• Evaluated from left to right in a&&b
the order from highest to lowest a||b
precedence lowest a?b:c
precedence

Operator Description Operands


-a negative of a integer, real
!a logical NOT: 1 if a is zero, 0 otherwise integer, real
~a bit-wise complement of a integer
a*b, aƒb multiply a and b, divide a by b integer, real
a%b remainder after integer division of a by b integer
a+b, a-b add a and b, subtract b from a integer, real
a<<b, a>>b left-shift a by b bits, right-shift a by b bits integer
a<b, a>b, 1 if the comparison is true: a less than b, integer, real, string
a<=b, a>=b a greater than b, a less than or equal to
b, a greater than or equal to b
a==b, a!=b 1 if the comparison is true: a is equal to integer, real, string
b, a is not equal to b
a&b bit-wise AND of a and b integer
a^b bit-wise exclusive OR of a and b integer
a|b bit-wise OR of a and b integer
a&&b logical AND: 1 if both a and b are non- integer, real
zero, 0 otherwise
a||b logical OR: 1 if either a or b is non-zero, integer, real
0 otherwise
a?b:c if a is non-zero then evaluates to b, integer, real (for a)
otherwise evaluates to c
Examples: TCL Operators
%% set
set aa 22 3rd
22 1st 2nd
OK because > and <= have higher
%% expr
expr $a
$a >> 00 &&
&& $a
$a <=
<= 33 precedence than &&
11
%% expr
expr !(($a
!(($a ==
== 1)
1) ||
|| ($a
($a ==
== 2))
2)) Always use parentheses () to
1 = true ensure readability.
00
%% expr
expr $a
$a ||
|| 00
0 = false
11
non-zero evaluates to true

bits 7 6 5 4 3 2 1 0
0000 0111 (7)
%% set
set aa 0x07
0x07 AND 0000 0100 (4) read bit 2
0x07
0x07 0000 0100 (4)
%% expr $a && 0x04
expr $a 0x04
44 0000 0111 (7)
set bit 3 to 1
%% set
set aa [expr $a || 0x08]
[expr $a 0x08] OR 0000 1000 (8)
15
15 0000 1111 (15)
%% set
set a_neg [expr ~$a
a_neg [expr ~$a ++ 1]
1]
-15 INV 0000 1111 (15)
-15 1111 0000 (-16) change the sign
+ 0000 0001 (1) (2's complement)
1111 0001 (-15) NB: equivalent to
set a_neg -$a

%% expr When using strings in expressions:


expr "TCL"
"TCL" ==
== "TCL"
"TCL"
syntax
syntax error
error in
in expression
expression "TCL
"TCL ==
== TCL"
TCL" • enclose strings within "" or {}
%% expr
expr {"TCL"
{"TCL" ==
== "TCL"}
"TCL"} • enclose the entire expression in {}
11
%% expr
expr {$a
{$a >> 2.3
2.3 ?? "over"
"over" :: "under"}
"under"}
under
under lexicographical comparison
%% expr (TCL is AFTER TCL, i.e. it has
expr {"TCL"
{"TCL" << "TCL"}
"TCL"} GREATER index)
11
%% expr
expr {"0x0"
{"0x0" ==
== "000"}
"000"} Avoid using ==, !=, >, <, >=, <=
11 for string comparison if the strings
! could resemble numerical values!

0000 1111 0
0001 1110 0 shift LEFT by 2 bits
%% expr $a <<
expr $a << 22 left shift always inserts 0
60 0011 1100 (60)
60
%% expr $a >>
expr $a >> 11
77 0000 1111 shift RIGHT by 1 bit
%% expr $a_neg >>
expr $a_neg >> 11 0000 0111 (7)
-8
-8 right shift always propagates
the sign bit!
1111 0001
1111 1000 (-8)
Mathematical Functions
• These functions can be used INSIDE math expressions

acos(x) exp(x) abs(x)


asin(x) log(x) ceil(x)
atan(x) log10(x) floor(x)
atan2(x,y) pow(x,y) round(x)
cos(x) sqrt(x)
expr
cosh(x) int(x)
sin(x) fmod(x,y) double(x)
sinh(x) hypot(x,y)
tan(x) srand(x)
tanh(x) rand()

Although TCL was not built as a language for mathematical computations, it


provides a number of useful mathematical functions. All these functions have to be
used inside expressions formed using the expr command (consult expr manual
page for more details on supported functions).

Examples:
π
trigonometric functions expect
expr sin(3.1415927
%% expr sin(3.1415927 // 2.0)
2.0) arguments in RADIANS
1.0
1.0
%% expr returns real number even when the
expr pow(2,
pow(2, 16)
16) arguments are integers...
65536.0
65536.0
%% expr ...but this can be easily converted back to
expr int(pow(2,
int(pow(2, 16))
16)) integer, if needed
65536
65536
%% expr
expr ceil(sqrt(2))
ceil(sqrt(2)) returns nearest integer GREATER than √2
2.0
2.0
%% expr
expr floor(sqrt(2))
floor(sqrt(2)) returns nearest integer LESS than √2
1.0
1.0
%% expr returns a FLOATING-POINT reminder
expr fmod(4.57,
fmod(4.57, 2.0)
2.0) after the division of 4.57 by 2.0
0.57
0.57
%% expr
expr int(rand()*10)
int(rand()*10) returns a random integer in the interval
0-9 (inclusive)
66
rand() returns a random real number in the interval
0 (inclusive) to 1 (exclusive)
Incrementing and Decrementing
• Can be done using expr command...
%% set
set aa 10
10
10
10
%% set
set aa [expr
[expr $a
$a ++ 1]
1]
11
11
%% set
set aa [expr
[expr $a
$a -- 5]
5]
66

• ...but TCL also provides an efficient replacement:


incr
%% set
set aa 10
10
10
10
%% incr
incr aa increment constant is optional (defaults to 1)
11
11
%% incr
incr aa -5
-5 decrement by using a negative increment constant
66

incr syntax incr varName ?increment?

Generating random numbers in TCL:


Random numbers can be used during testing to generate random events or noise
signals. TCL provides a better number random generator than that provided by a
typical C math library.
TCL uses a “minimal” generator of Park and Miller with the period of 231 - 2
(around
2.1 x 109). If you need to generate more than about 1,000,000,000 reliable
random numbers in your scripting application, consider writing your own random
number generator. An excellent reference for various random generation and test
algorithms is Chapter 7 in the following book:
Numerical Recepies in C: The Art of Scientific Computing by W.H.Press et al.,
Cambridge University Press, 1992, second edition, ISBN 0-521-43108-5
Numerical Accuracy
• In math calculations, the variable values are converted from
strings to numbers and then back to strings
— Integers are converted accurately
— Real numbers (floating-point)
• Default conversion precision is 12
• Set using the tcl_precision variable default floating-point precision is 12
(i.e. 12 significant digits)
%% expr
expr 1.0
1.0 // 300.0
300.0 Set precision to 17 to avoid loss
0.00333333333333
0.00333333333333 of accuracy during the conversion
%% set
set tcl_precision
tcl_precision 17
17 (assuming IEEE floating-point ALU).
17
17
%% expr
expr 1.0
1.0 // 300.0
300.0 with the precision set to 17, the automatic
0.0033333333333333335
0.0033333333333333335 rounding is DISABLED

• Internal number representation is platform dependent


— Typically: integer: 32 bits, floating-point: 64 bits

TCL interpreter is written in C, therefore the numerical accuracy depends on


the accuracy of underlying C implementation.
TCL integers are implemented as long C data types and real numbers
are implemented as double C data types.
Basic Procedures
• Use proc command to create new TCL commands
— New commands look and behave just like built-in commands
proc name arguments body

%% proc
proc average
average {n1
{n1 n2
n2 n3
n3 n4}
n4} {{ proc

without return set


set sum
sum [expr
[expr {($n1+$n2+$n3+$n4)/4.0}]
{($n1+$n2+$n3+$n4)/4.0}] average
the procedure returns return $sum
return $sum
the value returned by
the last executed
}}
%% average variables n1, n2, n3, n4
command average 11 22 33 44 and sum are available only
1 2 3 4

2.5
2.5 INSIDE the procedure, i.e
%% average
average -10
-10 10
10 -50
-50 33 they are local variables average
-11.75
-11.75

• Why should I use procedures?


— Store frequently used algorithms (code reuse, productivity gain)
— Structure your scripts (better readability, easier maintenance)
Global Variables
• Sometimes it is necessary to access variables OUTSIDE the
procedure body
• global command allows to access variables defined at global
scope from inside a procedure body

%% set
set appname
appname "My
"My script"
script"
My
My script
script variable appname is available globally - both
%% proc
proc print_error
print_error {msg}
{msg} {{ INSIDE and OUTSIDE the procedure.
global
global appname
appname This is a global variable.
puts
puts "$appname:
"$appname: $msg"
$msg"
}}

Minimize the use of GLOBAL variables to


improve script readability and to ease the
maintenance.

global syntax global varname ?varname ...?


TCL Interpreter Summary

Command Separation

Word Grouping

variable
Substitution backslash
command

Command Evaluation
expr cd average
set
puts incr
pwd ...
glob proc
Grouping with {} and "" Revisited
• Quotes ("") enable substitution
– [], $, \ substitutions performed as usual

• Braces ({}) disable substitution


— No substitutions are performed
— Special substitution characters ([], $, \) are treated as ordinary
characters (no special interpretation)
— BUT escaping the newline character with \ is allowed

%% set
set aa xyz
xyz
xyz
xyz
all substitutions
%% puts
puts "Substituting
"Substituting as
as usual:
usual: \x41,
\x41, $a,\
$a,\ performed as usual
number
number == [set b 123]"
[set b 123]"
Substituting
Substituting as usual: A,
as usual: A, xyz, number == 123
xyz, number 123
substitutions disabled,
puts {Substitution
%% puts {Substitution disabled:
disabled: \x41,
\x41, $a,\
$a,\ BUT \<newline>
number
number == [set
[set bb 123]}
123]} substitution is allowed
Substitution
Substitution disabled:
disabled: \x41,
\x41, $a,
$a, number
number == [set
[set bb 123]
123]
When Do I Use "" and when Do I Use {}?
• Use "" for
— Quoting string values
— Immediate processing
• Substitutions performed BEFORE the command is executed

• Use {} for
— Avoiding substitution
— Deferred processing
store frequently-used expressions, which
• Delay substitutions until “LATER” will be used later

use braces to avoid substituting


%% set cost {$a*0.1
set cost {$a*0.1 ++ $b*0.6
$b*0.6 ++ $c*0.3}
$c*0.3} the values of $a, $b, $c immediately
$a*0.1
$a*0.1 ++ $b*0.6
$b*0.6 ++ $c*0.3
$c*0.3
%% set
set aa 100;
100; set
set bb 200;
200; set
set cc 300
300
300
300
evaluate the previously stored
%% expr
expr $cost
$cost expression with the current
220.0
220.0 variable values
NOTE: No braces!

Note that in the last command, the $cost argument must not be enclosed in
braces! This is because two rounds of substitutions are required to be performed
on the argument to expr. First the TCL interpreter substitutes $cost for the
expression $a*0.1 + $b*0.6 $c*0.3 and then the expr command substitutes
values for $a, $b and $c.
Quiz 3
file: examples/quiz3.tcl
%% set
set aa 22
22
%% proc
proc print_q
print_q {a}
{a} "puts
"puts {Value
{Value == $a}"
$a}"
%% proc
proc print_b {a}
print_b {a} {puts
{puts "Value
"Value == $a"}
$a"}
%% print_q
print_q 33
Value == ???
Value ???
%% print_b
print_b 33
Value == ???
Value ???

• What value will print_q and print_b print?


(a) both will print 3
(b) print_q will print 2, print_b will print 3
(c) print_q will print 3, print_b will print 2
(d) both will print 2

Answer
LAB 1: Extracting Bits from Integers
• Using a TCL interpreter in an interactive mode,
extract 4 least significant bits from a positive integer
number between 0 to 15.

• Example:
LSB

... 1 0 0 1
%% set
set aa 99
99
%% set
set b0
b0 [[ ...
... ]]
11
...
... insert your code here
...
...
...
...
%% set
set bb "$b3$b2$b1$b0"
"$b3$b2$b1$b0"
1001
1001
LAB 1: Extracting Bits from Integers (2)
• Stage 1
— Use expr TCL command with the following arithmetic operators
$a >> 1 shift content of variable a right by 1 bit
$a & 1 apply bit-wise AND on the contents of variable a to
extract the least significant bit
— Use command substitution []to assign individual bits to four
variables, e.g. b0, b1, b2 and b3, and then store the result in b
— Do NOT use if or other control flow commands (not covered yet)!

• Stage 2
– Store the algorithm as a new TCL command to_bits (returns the result)
— Print b after the result to indicate binary format, e.g. 1010b
– Print a warning message if the input value is outside the valid 0-15 range
• use the a?b:c operator to test whether input falls within the valid range
TCL Scripting for SoC Design

Control Flow
Aims and Topics
• Aim
– To learn how to control command execution in
TCL

• Topics
– What is control flow?
– Conditional commands
– Looping commands
– Loop control
What is Control Flow?
• A collection of TCL commands which can be used to
control when and how many times commands are
executed
• Conditional command
execution
conditionally – if
execute or skip
commands – switch

• Looping commands
repeat – for
commands
– foreach
– while

• Loop control
– break
– continue
Conditional Execution: if
• Execute commands IF the condition is true
– Condition is evaluated in the same way as expr expression
– Enclose the condition and if command body in {} unless you require
substitution

condition then is optional

if
if {$area $area_desired} then
{$area << $area_desired} then {{ if 1 (true) if
puts
puts "Desired area constraint met."
"Desired area constraint met." condition body
}}
0 (false)

if body

Use indentation
to improve readability!
Conditional Execution: if-else
• Execute if body commands IF the condition is true,
ELSE execute else body

if 1 (true) if
if condition
if {$area
{$area << $area_desired}
$area_desired} then
then {{ body
puts
puts "Desired area constraint met."
"Desired area constraint met." 0 (false)
}} else
else {{
puts
puts "Area
"Area constraint
constraint VIOLATED."
VIOLATED." else
else is
optional
}} body

else body
Conditional Execution: if-elseif-else
• Test for more than one condition with elseif
– Any number of elseif’s can be used

then is optional 1 (true)


if if
condition body
if
if {$area
{$area << $area_desired}
$area_desired} then
then {{
puts
puts "Desired area constraint met."
"Desired area constraint met." 0 (false)
}} elseif
elseif {$area $area_max} then
{$area << $area_max} then {{
puts
puts "Maximum
"Maximum area
area constraint
constraint met."
met." elseif 1 (true) elseif
}} else {
else { condition body
puts
puts "Area
"Area constraints
constraints VIOLATED."
VIOLATED." 0 (false)
}}
else
body

Complete if syntax

if expr1 ?then? body1 elseif expr2 ?then? body2 \


elseif ... ?else? ?bodyN?
Conditional Execution: switch
• Useful for command branching
– Similar to if with many elseif’s
string == 1 (true)
-- is optional (more later) string (stored in cellName’s value) pattern 1
pattern 1 body
switch
switch --
-- $cellName
$cellName {{ 0 (false)
AND
AND {incr and_count}
{incr and_count} pattern
patterns OR
OR {incr
{incr or_count}
or_count} bodies 1 (true)
string == pattern 2
INV
INV {incr
{incr inv_count}
inv_count} pattern 2 body
}}
0 (false)

• default pattern matches all strings string == 1 (true)


pattern 3
pattern 3 body
switch
switch --
-- $cellName
$cellName {{
AND 0 (false)
AND {incr and_count}
{incr and_count}
OR
OR {incr
{incr or_count}
or_count} default
default INV
must be INV {incr
{incr inv_count}
inv_count} body
the LAST default
default {puts
{puts "Unrecognized
"Unrecognized cell."} cell."}
pattern }}
Always provide default pattern
to capture unexpected errors.

switch command syntax (variant 1)

switch ?options? string {pattern1 body1 ?pattern2 body2 ...?}

The above are trivial examples. Pattern bodies may contain more than one
command.
If default is not the last pattern, it will be matched as an ordinary string "default".
Matching Multiple Patterns with switch
• To match several different patterns use ‘-’ separator...
switch
switch --
-- $cellName
$cellName {{
AND2 -- AND3
AND2 AND3 {incr
{incr and_count}
and_count} incr and_count will be executed
OR2 - when $cellName is AND2 or AND3
OR2 -
OR3
OR3 {incr
{incr or_count}
or_count} Use one line for each pattern
INV
INV {incr inv_count}
{incr inv_count} to improve readability!
default
default {puts
{puts "Unrecognized
"Unrecognized cell."}
cell."}
}}
Always use -- to prevent
match patterns using switch from confusing
glob-style pattern matching strings with options.

• ...or select how patterns switch -glob


switch -glob --
-- $cellName
$cellName {{
AND*
AND* {incr
{incr and_count}
should be matched: OR* {incr
and_count}
or_count}
OR* {incr or_count}
-exact exactly (default) INV
INV {incr
{incr inv_count}
inv_count}
default
default {{
-glob glob-style matching
puts
puts "Unrecognized
"Unrecognized cell."}
cell."}
-regexp regular expressions }}

Regular expression pattern matching will be discussed later in Session 8 -


Regular Expressions.
Changing Patterns during Run-Time
• switch patterns can be changed during run-time!
— DO NOT enclose switch command body in {} to ALLOW
substitution BEFORE the switch command is executed

newlines
must be
set hier_path
set hier_path "/DecoderModule/mp3/U*"
"/DecoderModule/mp3/U*" escaped
switch
switch -glob
-glob -- $cellName \\
-- $cellName
patterns defined ${hier_path}AND*
${hier_path}AND* {incr and_count} \\
{incr and_count}
during run-time ${hier_path}OR*
${hier_path}OR* {incr or_count} \\
{incr or_count}
using substitution
${hier_path}INV
${hier_path}INV {incr inv_count} \\
{incr inv_count}
default
default {puts "Unrecognized cell."}
{puts "Unrecognized cell."}

switch command syntax (variant 2 - allows substitution)

switch ?options? string pattern1 body1 ?pattern2 body2 ...?

switch matching patterns can be changed during the run-time. For example, the
switch statement above allows to define the path for the cells to be searched for
by changing the value of the hier_path variable.
Patterns searched for in the above command are:
• /DecoderModule/mp3/U*AND*
• /DecoderModule/mp3/U*OR*
• /DecoderModule/mp3/U*INV
Looping: for
• Use for to execute commands specified number of times
– LAB 1 revisited

set execute
set aa 9;
9; set
set bb ""
"" start
start test next execute
next
for
for {set
{set ii 0}
0} {$i
{$i << 4}
4} {incr
{incr i}i} {{
set
set bit [expr ($a >> $i) & 0x1]
bit [expr ($a >> $i) & 0x1] evaluate
1 (true)
execute
set b "$bit$b"
set b "$bit$b" test body
}} body
0 (false)

• test is evaluated in the same way as expr expression


• Enclose start, test, next and body in {} unless you require
substitution

for syntax for start test next body


Looping: foreach
• Use foreach to execute loop body for each element in a list
– Elements are processed from left to right
– Number of iterations is equal to the number of elements

%% set
set lib_cells
lib_cells "INV
"INV AND
AND OR"
OR"
INV
INV AND
AND OR
OR

loop variable name list of elements to iterate through

foreach cell
%% foreach cell $lib_cells
$lib_cells {{ execute
puts "Found library cell: $cell" body
}– usingputs2"Foundloop valibraryriables cell:
$cell" next
Found library cell: INV 1 (true) assign next
} bod element
Found library cell: AND elements to the
y available
Found library cell: INV loop variables
Found library cell: OR ?
Found library cell: AND
%Found 0 (false)
library cell: OR
%
Multiple Loop Variables with foreach
• Useful for parsing results returned from other commands

%% set
set cell_counts
cell_counts "INV
"INV 55
55 AND
AND 10
10 OR
OR 20"
20"
INV
INV 55
55 AND
AND 10
10 OR
OR 20
20

two loop variables group loop variables into a single TCL


word
foreach {cell
%% foreach {cell quantity}
quantity} $cell_counts
$cell_counts {{
puts
puts "Found
"Found library cell: $cell
library cell: $cell $quantity
$quantity times"
times"
}}
Found
Found library
library cell:
cell: INV
INV 55
55 times
times
Found
Found library
library cell:
cell: AND
AND 10
10 times
times
Found
Found library
library cell:
cell: OR
OR 20
20 times
times
%%

foreach syntax
foreach varName list body

or for multiple loop variables

foreach varList1 list1 ?varList2 list2 ...? body


Looping: while
• Use while loop to execute commands in a loop which
– Terminates by meeting a certain condition

set
set number
number 20
20 test
set
set bits
bits 11 evaluate 1 (true) execute
while
while {(pow(2,
{(pow(2, $bits)
$bits) -- 1)
1) << $number}
$number} {{ test body
incr bits
incr bits
}} 0 (false)
bod
y

– Never terminates (indefinite loop)


while
while {1}
{1} {{
puts
puts "TCL
"TCL forever!"
forever!"
}}

while syntax while test body


Loop Control: break and continue
• Use break to terminate the loop
– Usually used together with conditional commands
while
while {1}
{1} {{
puts
puts "TCL
"TCL is
is NOT
NOT forever..."
forever..." when rand() > 0.9, terminate
if
if {rand()
{rand() >> 0.9}
0.9} {break}
{break} the loop
}}

• Use continue to advance the loop to the next iteration


immediately
– Skips the rest of the current iteration
foreach
foreach cell
cell $lib_cells
$lib_cells {{ skip the loop iteration for INV cell
if
if {$cell ==
{$cell == "INV"}
"INV"} {continue}
{continue} (puts is not executed for INV
puts
puts "Found
"Found cell
cell with
with 2+
2+ inputs:
inputs: $cell"
$cell" cell)
}}

break and continue TCL commands do not take any arguments.


Control Flow: Syntax Summary
if {condition} then
if {condition} then {{ for
for {start}
{start} {test}
{test} {next}
{next} {{
body
body body
body
}} }}

if {condition1} then
if {condition1} then {{ foreach
foreach varName
varName list
list {{
body1
body1 body
body
}} elseif
elseif {condition2}
{condition2} {{ }}
body2
body2
}} elseif
elseif {condition3}
{condition3} {{
body3
body3 Group conditions, while
while {test}
{test} {{
}} tests and bodies with body
body
{} unless you }}
require substitution.
switch
switch string
string {{
pattern1
pattern1 {body1}
{body1} break
break terminate the loop
pattern2 {body2}
pattern2 {body2}
skip the current
pattern3 --
pattern3 match pattern3 OR pattern4 continue
continue iteration
pattern4
pattern4 {body4}
{body4}
default if present,
default {default
{default body}
body} default must be the LAST pattern
}}
Braces & Spaces (Grouping Mistakes)
WRONG RIGHT
if
if {$a
{$a >> 0}
0} puts
puts "positive"
"positive" if
if {$a 0} {puts
{$a >> 0} {puts "positive"}
"positive"}
body NOT
grouped!
if
if {$a
{$a >> 0}{
0}{ if
if {$a
{$a >> 0}
0} {{
missing space
puts "positive" puts "positive"
puts "positive" between }{ ! puts "positive"
}} }}
Use braces and you
won't need to worry
condition NOT grouped!
about spaces!
if $a
if $a >> 00 {puts
{puts "positive"}
"positive"} if {$a >> 0}
if {$a 0} {puts
{puts "positive"}
"positive"}

if {$a
if {$a >> 0} {{
0} if {$a
if {$a >> 0} {{
0}
puts
puts "positive"
"positive" puts
puts "positive"
"positive"
}} TWO }} else
else {{
else commands! puts "negative"
else {{ puts "negative"
puts
puts "negative"
"negative" }}
}}
Quiz 4
set a 0 file:
while {$a < 150} { examples/quiz4.tcl

incr a
switch $a {
100 {continue}
140 {set a 300}
200 {break}
}
}
puts "Value of a = $a"

• What is the value of a ?


(a) 150
(b) 100
(c) 140
(d) 300
(e) 200

Answer
TCL Scripting for SoC Design

Strings
Aims and Topics
• Aim
— To learn about how to work with strings in
TCL

• Topics
— Constructing strings
— String operations
— Extracting information from strings
— Binary strings
What is a String?
• Any collection of characters
— Letters, digits, special characters, binary characters, etc.

• In TCL, everything is a string


— Universal data type from/to which everything can be converted
— Easy to manipulate

o
Constructing Strings
• Strings in TCL can be constructed in a variety of
ways
— Typing the string characters
%% set
set aa "Hello";
"Hello"; set
set bb "world";
"world";
— Substitution and set world
world
— TCL append command %% set
set cc "$a
"$a $b!"
$b!"
Hello
Hello world!
world!
%% append
append dd $a
$a "" "" $b
$b "!"
"!"
Hello
Hello world!
world!

variabIe d wiII be created


if it doesn't exist
• append command is optimised for speed
%% set
set test_files
test_files
test/testO.tcl
test/testO.tcl ...
... test/test9999.tcl
test/test9999.tcl
%% foreach
foreach ff $test_files
$test_files {append
{append test_script
test_script "source
"source $f\n"}
$f\n"}
%% set test_script
set test_script
source
source test/testO.tcl
test/testO.tcl
...
... Use append when constructing
source test/test9999.tcl long strings!
source test/test9999.tcl

append syntax append varName ?value value ...?

It might seem that there is no justification for having append, when the same effect
can be achieved using substitution. However, the append command is significantIy
faster when constructing Iong strings. In the above exampIe, if the body of the
foreach Ioop is repIaced with
set test_script "${test_script}source $f\n"
the Ioop wiII be 200 times slower!

Try: source examples/append_vs_set.tcl

Execution time Relative execution time


substitution 7.76s 204
append 38.1ms 1
TCL 8.0.5 on Pentium III/1GHz PC, 256MB RAM, Windows
2000
Comparing Strings
• Can be done with ==, but this can fail when string characters
resemble numbers
%% expr
expr {"OxO"
{"OxO" ==
== "OOO"}
"OOO"}
! 11

• Use string compare instead (robust string comparison)


%% expr {[string compare
expr {[string compare "OxO" "OOO"] ==
"OxO" "OOO"] == 0}
0}
00

• Return value:
O strings str1 and str2 are IDENTICAL
1 string str1 is lexicographically AFTER string str2
-1 string str1 is lexicographically BEFORE string str2

string compare syntax

string compare str1 str2


String Matching
• Similar to comparison, but allows the first string to contain
match patterns
string match pattern string

%% string
string match
match "*/mp3/*"
"*/mp3/*" "ƒDecoderModule/mp3/U4"
"ƒDecoderModule/mp3/U4"
11
%% string
string match
match "*/mp3/*"
"*/mp3/*" "/DecoderModule/mpeg2/U12"
"/DecoderModule/mpeg2/U12"
OO

glob-styIe match pattern

• Return value:
O pattern does NOT match string
1 pattern matches string
Glob-style Match Patterns
• glob-style patterns are similar to UNIX shell wildchar
patterns
• glob-style patterns use the following special characters
? matches any SINGLE character
* matches any sequence of xero or more characters
\c matches the SINGLE (escaped) character c
[abc] matches any SINGLE character in abc
[a-b] matches any SINGLE character between a-b (inclusive)
{abc,xyz,...} matches any of the strings abc, xyz, etc.

• glob also understands UNIX shell tilde substitution


~ login user’s home directory
~user specified user's home directory (UNIX only!)

~user is Iimited to UNIX pIatforms onIy.


Other Useful String Commands
• string is a mega-command with many useful functions
— Takes an input string and returns its modified value
– string does NOT modify the input string

string toupper
%% string toupper "Vhdl
"Vhdl Edif
Edif TCL"
TCL" convert Iowercase characters to
VHDL UPPERCASE
VHDL EDIF
EDIF TCL
TCL
string tolower
%% string tolower "DECODER.VHD"
"DECODER.VHD" convert UPPERCASE characters to Iowercase
decoder.vhd
decoder.vhd
string trim
%% string trim "" Area:
Area: 2345
2345 remove white spaces (spaces, tabs,
"" newIines, carriage returns) from the
beginning and the end of the string
Area:
Area: 2345
2345
string trim
%% string trim "((a+b)))"
"((a+b)))" ")("
")(" remove onIy the specified characters,
e.g. ) and ( in this case
a+b
a+b
string trimleft
%% string trimleft "..ƒmp3/"
"..ƒmp3/" "ƒ."
"ƒ." remove onIy the specified characters (/ and .)
mp3/
mp3/ and onIy from the BEGINNING of the string
string trimright
%% string trimright "../mp3ƒ"
"../mp3ƒ" "ƒ"
"ƒ" remove onIy the specified characters (/)
../mp3
../mp3 and onIy from the END of the string

FuII syntax for the commands above:

string toupper string

string tolower string

string trim string ?chars?

string trimleft string ?chars?

string trimright string ?chars?


Examples: Comparing l Matching Strings
• Be aware of lexicographical rules
UPPERCASE characters are aIways
%% string
string compare
compare "A"
"A" "a"
"a" BEFORE Iowercase characters...
-1
-1
... which might not be what you
%% string
string compare
compare "Z"
"Z" "a"
"a" expect!
-1
-1
%% string
string compare
compare "Z"
"Z" [string
[string toupper
toupper "a"]
"a"]
11 Convert strings to either
lowercase or UPPERCASE
if you want to compare
alphabetically.

• Typical use of string comparison/matching


if {[string match
if {[string match *.edif
*.edif $file]}
$file]} {{
returns 1 puts
if there is a
puts "Found EDIF file: $file
"Found EDIF file: $file (.edif)"
(.edif)"
match }} elseif {[string match
elseif {[string match *.edn
*.edn [string
[string tolower
tolower $file]]}
$file]]} {{
puts "Found EDIF file: $file (.edn or .EDN)"
puts "Found EDIF file: $file (.edn or .EDN)"
}} elseif {![string compare
elseif {![string compare "README.txt"
"README.txt" $file]}
$file]} {{
returns 0 puts
puts "Found
"Found the
the README
README file!"
file!"
if the strings }}
are identicaI
String Formatting
• Strings can be formatted into various forms using the
format command
— Printing numbers in hexadecimal, octal or decimal format
— Aligning text and numbers in columns
— Generating text in the format expected by other tools

• Typical examples
%% set
set add
add 65365;
65365; set
set dd 31;
31; set
set period
period .OOOOO462
.OOOOO462
.OOOOO462
.OOOOO462
%% format "Writing %d
format "Writing (%#x, %#o)
%d (%#x, %#o) to address %#x"
to address %#x" $d
$d $d
$d $d
$d $add
$add
Writing 31
Writing (0x1f, 037)
31 (0x1f, 037) to address 0xff55
to address 0xff55

%% format
format "Max
"Max period:%15.2e (%f) seconds"
period:%15.2e (%f) seconds" $period
$period $period
$period
Max
Max period:
period: 4.62e-006
4.62e-006 (0.000005)
(0.000005) seconds
seconds

set number precision to 2 and defauIt precision is 6


(min) fieId width to 15

format syntax

format formatString ?arg arg ...?

format command is simiIar in capabiIities to printf famiIy of functions


in C.
Scanning Strings
• scan command extract values from a string according to
a format specification
— No need to know the character indices
— Useful for
• Extracting data from error messages and report logs
• Parsing input text from the user, and more...
— BUT regular expressions are more powerful (more later)

• Typical example
%% set
set report
report "Total
"Total size:
size: 12345
12345 cells;
cells; Clock:
Clock: 24
24 MHz"
MHz"
Total
Total size:
size: 12345
12345 cells;
cells; Clock:
Clock: 24
24 MHz
MHz
%% scan
scan $report
$report "%s%s%d"
"%s%s%d" w1 w2 cells
w1 w2 cells
returns the number 33
of matched strings %% set
set cells
cells
12345
12345
conversion specifiers: variabIes into which the matching strings
string, string, integer wiII be assigned

scan syntax

scan string format varName ?varName ...?

WhiIe scan is a usefuI command for scanning simpIe string patterns, reguIar
expressions offer more powerfuI method for scanning strings (Session 8).
Using Character Indices
• Individual characters can be manipulated using their index
values with the string command
H e I I o w o r I d !
the first character
has index 0
0 1 2 ..................... 11

• Character index retrieval


– string first and string last search for the first or the last position
of character sequences

• Accessing characters using indices


– string index retrieves a character with a given index
– string range retrieves characters within the specified range
– string length counts the number of characters
Examples: Character Indices
data = 090FF00FF20001600B7914FF203C899FE
O123456789O123456789O123456789O12 end = index
1 2 3 of the Iast
returns the index of the first character in the match character

string first
%% string first "FF2"
"FF2" $data
$data string index
%% string index $data
$data 13
13
77 11
string last
%% string last "FF2"
"FF2" $data
$data string range
%% string range $data
$data 1O
1O 21
21
22
22 OOO16OOB7914
OOO16OOB7914
string length
%% string length $data
$data string range
%% string range $data 25 end
$data 25 end
33
33 O3C899FE
O3C899FE

• Retrieve the data packet between two FF2 marks


%% set
set mark
mark "FF2"
"FF2"
FF2
FF2
%% set
set packet string range
packet [[ string range $data
$data \\
[expr [string first
[expr [string first $mark $data]
$mark [string length
$data] ++ [string length $mark]]
$mark]] \\
[expr [string last
[expr [string last $mark
$mark $data]
$data] -- 1]
1] ]]
0001600B7914
0001600B7914

Syntax for the above commands:

string first string1 string2

string last string1 string2

string index string charIndex

string range string firstIndex lastIndex

string length string


Quiz 5
set msg "T eciga lsrt" file:
set code "O 4 9" examples/quiz5.tcl

set i O
set j O

while {$i != ([string length $msg]-1)} {


foreach k $code {
set i [expr $k+$j]
append secret_msg [string index $msg $i]
}
incr j
}
puts $secret_msg

• What is the value of secret_msg ?


(no options, sorry!)

Answer
LAB 2: Working with a String Bitstream
• Write a procedure get_filename which will extract the
design file name from a Xilinx FPGA bitstream file (.bit).
• Example:
% source bitstream.tcl this wiII read the FPGA
bitstream and store it in the TcI
% get_filename $bitstream variabIe bitstream
file_ad.ncd
VariabIe bitstream contains
bitstream is string in
hexadecimaI format.

• Xilinx bitstream file has the following format


IittIe-endian order (most significant byte on the Ieft),
may contain OxOO, ... unsigned, Iength incIudes the traiIing OxOO
but not Ox61-Ox65
0x61 length (2 bytes) design file name 0x00

0x62 length (2 bytes) part name 0x00


0x63 length (2 bytes) date 0x00
0x64 length (2 bytes) time 0x00
0x65 length (4 bytes) FPGA configuration data
LAB 2: Working with a String Bitstream (2)
• Stage 1
— Search for the file name field markers using string first, e.g.
set first_marker_index [string first 61 $bitstream]
— Extract the file name hex characters from $bitstream using the
string range command (from/to indices need to be adjusted)
— Use a for loop to extract ASCII characters from the extracted file
name string (in hexadecimal format) using the format command, e.g.
set ascii_char [format "%c" "0x$hex_character"]
— Return the file name

• Stage 2
– Extract the other fields from the bitstream header
• NOTE: the field data may also contain characters Ox61-Ox65 (a-e) !
— Check whether the file name field has the correct length
TCL Scripting for SoC Design

Lists and Arrays


Aims and Topics
• Aim
— To learn how to use TCL lists and
arrays

• Topics
— Lists
• building lists
• manipulating lists
— Arrays
• building arrays
• manipulating arrays
— Lists versus Arrays
What is a List?
• List is a collection of ORDERED elements
— List elements are strings
• Can represent anything (string values, other lists, other TCL
data structures, etc.)
— List elements are separated by whitespaces
• Spaces, tabs, newlines

list element
separator
• TCL list of 5 "lemon"

elements: %% set
set fruits
fruits "apple
"apple lemon
lemon banana
banana pear
pear grapes"
grapes"
apple
apple lemon
lemon banana
banana pear
pear grapes
grapes
Manipulating List Elements
• Use llength to count the number of elements in a list
%% llength
llength $fruits
$fruits
55

• Retrieving list elements using indices


– lindex returns an element with a given index
– lrange returns elements within the given index range
— Both return an empty string if the elements could not be found
fruits = apple lemon banana pear grapes
the first element
has index 0
0 1 ....................... 4
index of the last element end

%% lindex
lindex $fruits
$fruits 11 %% lrange
lrange $fruits
$fruits 00 22
lemon
lemon apple
apple lemon
lemon banana
banana
%% lindex $fruits end
lindex $fruits end %% lrange $fruits 33 end
lrange $fruits end
grapes
grapes pear
pear grapes
grapes

Syntax for the commands above

llength list

lindex list index

lrange list firstIndex lastIndex


Nested Lists
• Lists can be nested
lists within the cells list
— Use {}’s to define lists within lists

%% set
set cells
cells "inv
"inv {and2
{and2 or2}
or2} {and3
{and3 or3}
or3} or4"
or4"
inv
inv {and2
{and2 or2}
or2} {and3
{and3 or3}
or3} or4
or4
TCL returns {}'s
to indicate list lists within the 2nd element of the cells list
grouping.
The {}'s are NOT
part of the list!
%% set
set cells
cells "inv
"inv {{and2
{{and2 nand2}
nand2} {or2
{or2 nor2}}"
nor2}}"
inv
inv {{and2
{{and2 nand2}
nand2} {or2
{or2 nor2}}
nor2}}

• Useful for storing complex data structures, e.g.


number of
library source file cell data cell name inputs cell area

%% set
set library
library "ams.vhdl
"ams.vhdl {and
{and 22 100}
100} {or
{or 22 120}
120} {inv
{inv 11 20}"
20}"
ams.vhdl
ams.vhdl {and
{and 22 100}
100} {or
{or 22 120}
120} {inv
{inv 11 20}
20}
Building Lists (1)
• Use word grouping with "" (or {})
• Use list command all arguments become list elements

%% set
set fruits
fruits [list
[list apple
apple lemon
lemon banana
banana pear
pear grapes]
grapes]
apple
apple lemon
lemon banana
banana pear
pear grapes
grapes

• list command respects the list grouping,


while "" remove one level of grouping
%% set
set basket
basket "apple
"apple lemon"
lemon"
apple
apple lemon
lemon
%% set
set fruits_list
fruits_list [list
[list $basket
$basket banana
banana pear
pear grapes]
grapes]
{apple 4 elements
{apple lemon}
lemon} banana
banana pear
pear grapes
grapes
compare! %% set
set fruits_quotes
fruits_quotes "$basket
"$basket banana
banana pear
pear grapes"
grapes"
apple 5 elements
apple lemon
lemon banana
banana pear
pear grapes
grapes

list syntax list ?arg arg ...?


Building Lists (2)
• Use lappend to insert new list elements at the END
—Optimised for speed
—Will create the list variable if it does not exist
name of the list to append
one or more elements to append
(not $fruits!)

%% lappend
lappend fruits
fruits strawberry
strawberry orange
orange
apple
apple lemon
lemon banana
banana pear
pear grapes
grapes strawberry
strawberry orange
orange

• Equivalent to
%% set
set fruits
fruits "$fruits
"$fruits strawberry
strawberry orange"
orange"
apple
apple lemon
lemon banana
banana pear
pear grapes
grapes strawberry
strawberry orange
orange

—Slow, but simple! Use lappend when


building long lists!

lappend syntax lappend varName ?value value ...?

lappend is significantly faster then substitution when constructing long lists.


Let’s demonstrate the performance difference between using substitution and
lappend when constructing lists of various sizes. In the following, list
a is constructed in a for loop. The body of the loop contains either
set a "$a item" or lappend a "item"

Try: source examples/lappend_vs_set.tcl

List size 1000 10000 100000


substitution 4 ms 214 ms 193 s
lappend 3 ms 30 ms 314 ms
speed-up 1.3 7.1 615
TCL 8.0.5 on Pentium III/1GHz PC, 256MB RAM, Windows
2000
Building Lists (3)
• Join two or more lists together with concat
— Returns a new list
— Removes one level of list grouping (same effect as with "")
%% set
set basket
basket "apple
"apple pear
pear grapes"
grapes"
apple
apple pear
pear grapes
grapes
%% set
set basket_exotic
basket_exotic "lemon
"lemon banana"
banana"
lemon
lemon banana
banana
%% set
set fruits
fruits [concat
[concat $basket
$basket $basket_exotic]
$basket_exotic]
apple
apple pear
pear grapes
grapes lemon
lemon banana
banana 5 elements
compare! %% set
set fruits
fruits [list
[list $basket
$basket $basket_exotic]
$basket_exotic]
{apple 2 elements = lists within a list
{apple pear
pear grapes}
grapes} {lemon
{lemon banana}
banana}

— Eliminates leading and trailing spaces


%% set
set fruits
fruits [concat
[concat $basket_exotic
$basket_exotic {{ orange
orange }]
}]
lemon
lemon banana
banana orange
orange
spaces are
compare! %% set
set fruits
fruits "$basket_exotic
"$basket_exotic {{ orange
orange }"
}" removed
lemon
lemon banana
banana {{ orange
orange }}

concat syntax concat ?arg arg ...?


Inserting and Replacing List Elements
• Use linsert to insert new list elements at ANY position
%% set
set fruits
fruits "apple
"apple lemon
lemon banana
banana pear
pear grapes"
grapes" insert BEFORE the
apple
apple lemon
lemon banana
banana pear
pear grapes
grapes element with index 1
%% set
set fruits
fruits [linsert
[linsert $fruits
$fruits 11 apricot]
apricot]
apple apricot
apple apricot lemon
lemon banana
banana pear
pear grapes
grapes
%% set linsert can insert
set fruits
fruits [linsert
[linsert $fruits
$fruits 44 cherry
cherry plum]
plum] one or more elements
apple
apple apricot
apricot lemon banana cherry
lemon banana cherry plum
plum pear
pear grapes
grapes

• Use lreplace to replace or delete existing list elements


replace elements within
this index range
%% set
set fruits
fruits [lreplace
[lreplace $fruits
$fruits 00 11 pineapple
pineapple peach]
peach] (from-to)
pineapple
pineapple peach
peach lemon
lemon banana
banana cherry
cherry plum
plum pear
pear grapes
grapes
%% set
set fruits
fruits [lreplace $fruits 33 end]
[lreplace $fruits end] delete elements within
pineapple
pineapple peach
peach lemon
lemon the index range

%% set
set fruits
fruits [lreplace
[lreplace $fruits
$fruits 11 11 orange]
orange] use IDENTICAL indices
pineapple if only ONE element is
pineapple orange
orange lemon
lemon
to be replaced
%% set
set fruits
fruits [lreplace
[lreplace $fruits
$fruits 00 0]
0] (or deleted)
orange
orange lemon
lemon

Syntax for the commands above:

linsert list index element ?element element ...?

lreplace list firstIndex lastIndex ?element element ...?


Example: Reversing the List
• TCL does not provide a command which could reverse
the order of elements in a list
— Easy to write using the existing list commands

proc lreverse
proc lreverse {l}
{l} {{
set
set reversed_l
reversed_l """"
foreach
foreach element
element $l
$l {{
set
set reversed_l [linsert
reversed_l [linsert $reversed_l
$reversed_l 00 $element]
$element]
}}
return
return $reversed_l
$reversed_l
}}

• Then use as an ordinary TCL


command
% set fruits "apple lemon banana
% set fruits "apple lemon banana pear
pear grapes"
grapes"
apple
apple lemon
lemon banana
banana pear
pear grapes
grapes
%% set
set reversed_fruits
reversed_fruits [lreverse
[lreverse $fruits]
$fruits]
grapes
grapes pear
pear banana
banana lemon
lemon apple
apple
Converting between Lists and Strings
• It is easy to convert between strings and lists
– split splits the string into a set of list elements
– join joins the list element into a string
— List element separator can be any string (1 space is the default)

• Typical uses
— Manipulate hierarchical paths (rename elements, change the
separator, determine the depth of hierarchy, etc.)
list element separator
— Extract useful information from strings, and more... characters (1 or more)

split the path string


%% set
set dir_list
dir_list [split
[split "/Decoder/mp3/buffer/gnd"
"/Decoder/mp3/buffer/gnd" "/"]
"/"] into list elements
{}
{} Decoder
Decoder mp3
mp3 buffer
buffer gnd
gnd
empty
element
%% set
set dir_list
dir_list [lreplace
[lreplace $dir_list
$dir_list end
end end
end "GND"]
"GND"] capitalize the name
{} of the last element
{} Decoder
Decoder mp3
mp3 buffer
buffer GND
GND
%% set
set new_path
new_path [join
[join $dir_list
$dir_list "::"]
"::"] reconstruct the
::Decoder::mp3::buffer::GND
::Decoder::mp3::buffer::GND path using the
:: separator

Syntax for the commands above:

split string ?splitChars?

join list ?joinString?


Searching Lists
• Use lsearch to search the list for the FIRST element
matching the search pattern

lsearch ?mode? list pattern

• Search mode (?mode?) can be


-exact exact matching
-glob glob-style pattern matching, this is the DEFAULT
-regexp regular expression pattern matching (more later)

• Return value
-1 pattern does NOT match any elements in the list
0-end index of the first element matching the pattern
Examples: Searching Lists
• Glob-style pattern matching
%% set
set cell_list
cell_list "inv
"inv and2
and2 or2
or2 and3
and3 or3
or3 or4"
or4"
or2 inv
inv and2
and2 or2
or2 and3
and3 or3
or3 or4
or4
found at %% lsearch $cell_list or*
lsearch $cell_list or*
index 2 glob-style search patterns
22
%% lsearch
lsearch -glob $cell_list xor*
-glob $cell_list xor*
-1
-1

-1 = not found optional


(-glob is the default)

• Exact matching
%% lsearch
lsearch -exact $cell_list or4
-exact $cell_list or4
55 exact strings to be matched
%% lsearch
lsearch -exact $cell_list and
-exact $cell_list and
-1
-1
Sorting Lists
• Use lsort to sort list elements
returns the list of TCL commands
(UNSORTED)
%% set
set sorted_cmds
sorted_cmds [lsort
[lsort [info
[info commands]]
commands]]
after
after append
append array
array auto_execok
auto_execok auto_import
auto_import auto_load
auto_load
auto_load_index
auto_load_index auto_mkindex auto_mkindex_old auto_qualify
auto_mkindex auto_mkindex_old auto_qualify SORTED list
auto_reset
auto_reset binary
binary break
break case
case catch
catch cd
cd clock
clock close
close concat
concat of commands
...
...

• lsort is a very powerful sorting command; various features


are available through lsort options
— Sort in increasing (default) or decreasing order
— Sort strings using ASCII (default) or dictionary comparison
— Sort numbers using integer or real number comparison
— Sort using a custom comparison command

lsort syntax lsort ?options? list


Example: Sorting Blocks in a Hierarchy
• Sort design blocks using their hierarchical position
— Top-level first, bottom-level least Decoder sorting
order
set
set blocks
blocks "/Decoder/mp3/u1
"/Decoder/mp3/u1 mp3 GND
/Decoder/mp3/buffer/u1
/Decoder/mp3/buffer/u1 /Decoder/mp3/u2
/Decoder/mp3/u2 u1 u2 buffer
/Decoder
/Decoder /Decoder/mp3
/Decoder/mp3 /Decoder/GND"
/Decoder/GND"
u1

• First define a custom hierarchy comparison command


proc hier_cmp
proc hier_cmp {p1
{p1 p2}
p2} {{ custom comparison
command should return:
set
set p1_list
p1_list [split
[split $p1
$p1 "/"]
"/"]
set p2_list [split $p2 "/"] +int when p1 > p2
set p2_list [split $p2 "/"] 0 when p1 = p2
expr
expr {[llength
{[llength $p1_list]
$p1_list] -- [llength
[llength $p2_list]}
$p2_list]} -int when p1 < p2
}}

• Then use lsort to sort the blocks


%% lsort
lsort -command
-command hier_cmp
hier_cmp $blocks
$blocks compare using the custom
/Decoder comparison command
/Decoder /Decoder/mp3
/Decoder/mp3 /Decoder/GND
/Decoder/GND /Decoder/mp3/u1
/Decoder/mp3/u1 (hier_cmp)
/Decoder/mp3/u2
/Decoder/mp3/u2 /Decoder/mp3/buffer/u1
/Decoder/mp3/buffer/u1

The above example demonstrates one of the main features of TCL—


productivity. TCL allows for complex tasks to be coded rapidly.
Lists: Summary
• A powerful TCL data object, which maintains the
order of its elements
• Can be created using a variety of methods
— substitution
— concatenation
— append

• List elements can be accessed using an integev index


• TCL provides commands for list manipulation
— Creating lists
— Inserting/deleting list elements
— Searching for elements matching a pattern
— Sorting list elements
What is an Array?
• An array is a collection of LABELLED elements
— TCL arrays are associative; each element is identified by a Łey
(also called ‘index’, ‘label’ or ‘address’)
array variable name
— Array element values and keys
are €TRINC€

• Assigning/reading the
value
value of an array element
array variable name key value

set IT_people(john)
%% set IT_people(john) memo
memo
memo
memo
set IT_people(john)
%% set IT_people(john)
memo
memo key

enclose the key within will return an ERROR if the


parenthesis key cannot be found

All keys in the array must be defined before the key is to be accessed. For
example, set IT_people(edward) will generate an error message.
Basic Array Operations
• Arrays and their elements can be manipulated as other
TCL variables
— Retrieve element’s value using variable substitution
%% puts
puts "John
"John received
received aa $IT_people(john)."
$IT_people(john)."
John
John received
received aa memo.
memo.

— Remove the element or the entire array


%% unset IT_people(john)
unset IT_people(john)
%% unset IT_people
unset IT_people

• Element key can be also stored in a variable


%% set
set name
name "john"
"john"
john
john
%% puts
puts "John
"John received
received aa $IT_people($name)."
$IT_people($name)."
John
John received
received aa memo.
memo.
Manipulating Arrays
• New array elements can be added
— One at a time
%% set
set IT_people(phil)
IT_people(phil) "fax
"fax message"
message"
fax
fax message
message

— One or more elements in one command using array set


%% array
array set
set IT_people
IT_people {{
bill
bill "vacancy notice"
"vacancy notice"
key value
angela
angela "pay
"pay slip"
slip"
}}

• Use array get to retrieve the entire contents of the array


%% array
array get
get IT_people
IT_people
angela
angela {pay
{pay slip}
slip} phil
phil {fax
{fax message}
message} bill
bill {vacancy
{vacancy notice}
notice} john
john memo
memo

key value array set and array get


are useful when converting
between arrays and lists

Syntax for the commands above

array set arrayName list

array get arrayName ?pattern?

use optional pattern to


retrieve only those
elements which match
the glob-style pattern
Multi-dimensional Arrays
• Arrays may represent multi-dimensional objects
— Use keys which ‘look’ like multi-dimensional indices
— Keys are still €TRINC€, only they contain special characters
(e.g. commas) looks like two indices (0, 0),
Avoid spaces in array keys!
but this is really a string "0,0"!
image(O,O) and
%% set
set image(0,0)
image(0,0) 255
255 image(O, O) are two
255 DIFFERENT array elements!
2D array 255
%% set
set image(0,1)
image(0,1) 33
33
33
33
%% puts
puts "Pixel
"Pixel intensity
intensity at
at (0,1)
(0,1) is
is $image(0,1)."
$image(0,1)."
Pixel
Pixel intensity
intensity at
at (0,1)
(0,1) is
is 33.
33.

3D array %% set
set frame_set(10,100,2)
frame_set(10,100,2) 250
250 string!
250
250
%% set
set synthesis_results(smallest,23ns)
synthesis_results(smallest,23ns) 34mW
34mW
easy to combine 34mW
34mW
1D, 2D, 3D, ... %% set
elements in ONE array!
set image(filename)
image(filename) lena.rgb
lena.rgb
lena.rgb
lena.rgb
Examining Arrays
• Use array mega-command to obtain information about
array variables
— Check for the existence of the array variable
• Returns 0 if the variable is not an array or it does not exist
• Returns 1 otherwise
array exists
%% array exists IT_people
IT_people
11

— Retrieve the number of elements in the array


array size
%% array size IT_people
IT_people
44

— Retrieve the list of array keys


array names
%% array names IT_people
IT_people
angela
angela phil
phil bill
bill john
john

Syntax for the above commands

array exists arrayName

use optional pattern to


array size arrayName
retrieve only the keys
matching the glob-style
pattern
array names arrayName ?pattern?

array mega-command provides other useful functions. For example it is possible


to retrieve array elements sequentially using array startsearch, array
nextelement, array anymore, and array donesearch. For more details, consult
array manual page.
Examples: Using Arrays
• Look-up table %% array set ports
array set ports {{
and2
and2 {i1
{i1 i2
i2 o1}
o1}
or2
or2 {i1 i2 o1}
{i1 i2 o1}
inv
inv {i1
{i1 o1}
o1}
half_add
half_add {i1
{i1 i2
i2 o1
o1 cout}
cout}
full_add
full_add {i1 i2 cin o1
{i1 i2 cin o1 cout}
cout}
}}
%% set
set cell
cell "and2"
"and2"
and2
and2
%% puts
puts "Cell
"Cell $cell
$cell has
has ports:
ports: $ports($cell)"
$ports($cell)"
Cell
Cell and2
and2 has
has ports:
ports: i1
i1 i2
i2 o1
o1

• 2D image data storage


(0,0)
%% for
for {set
{set xx 0}
0} {$x
{$x << 256}
256} {incr
{incr x}
x} {{
for
for {set y 0} {$y < 256} {incr y}
{set y 0} {$y < 256} {incr y} {{
set image($x,$y)
set image($x,$y) $y $y
}}
}}

(255,255)
Lists versus Arrays
LISTS ARRAYS
• Can store various elements • Can store various elements
• Order of elements is preserved • Order of elements if NOT
preserved
• Elements are retrieved using an • Elements are retrieved using
INTEGER index a STRING key
• Lists are manipulated using the • Arrays are manipulated using
list value the name of the array variable
%% set
set ll [list
[list rr gg b]
b] %% array
array set
set aa {{
rr gg bb order is NOT rr RED
preserved
RED gg GREEN
GREEN bb BLUE
BLUE }}
order is %% llength
llength $l
$l %% array
array names
names aa
preserved 33 list l is accessed by array a is accessed
bb rr gg
its value $l (not l) by the name of array
variable a (not $a)

• Since TCL 8.0 there is NO PERFORMANCE


DIFFERENCE between TCL lists and arrays

Lists and arrays provide two ways of storing multiple data elements. When
deciding between the two, it is best to choose a data structure which is the most
natural representation of the data.
For example, a phone book is most naturally represented in an array as names
can be used as array keys. A list of files is usually represented using lists, as this
allows easy file browsing, sorting and manipulation.

Before TCL 8.0 lists access was much slower than array access. Since TCL 8.0
both lists and arrays are internally represented using similar data structures. TCL
then provides advantages of using linked lists, but with the performance of array
access.
Quiz 6
set a_list {apple lemon pear} file:
array set a_array {0 apple 1 lemon 2 pear} examples/quiz6.tcl

set b [lindex $a_list 3]


puts "b = \"$b\""
set c [$a_array(3)]
puts "c = \"$c\""

• What are the values stored in b and c?


(a)b = "" and c = "" (both are empty strings)
(b)b = pear and c = pear
(c)b = pear, but c assignment generates an error
(d)b = apple, but c assignment generates an error
(e)b = "", but c assignment generates an error
b assignment generates an error and c = ""

Answer
LAB 3: Sorting Design Blocks
• Write a procedure sort_by_area which will sort the design
blocks according to their area
– decoder is a global list which contains the list of design blocks
– block_area is a global array which stores areas of all leaf blocks
• For example $block_area(/Decoder/mp3/u1) is the area
of the /Decoder/mp3/u1 block
Decoder

mp3 GND

u1 u2 buffer

• Example: u1

%% source
source decoder.tcl
decoder.tcl
%% sort_by_area
sort_by_area $decoder
$decoder
/Decoder/GND
/Decoder/GND /Decoder/buffer/u1
/Decoder/buffer/u1 /Decoder/mp3/u1
/Decoder/mp3/u1 /Decoder/mp3/u2
/Decoder/mp3/u2
LAB 3: Sorting Design Blocks (2)
• Stage 1
— Sort the decoder list using a custom sorting command
• Use global block_area to allow access to the block_area global
variable from within the custom comparison command

• Stage 2
— Include both the sorted block names and their respective areas
in the returned result
• Each element is a list with 2 elements: block name & area
— Construct a sub-list containing only the leaf blocks extracted
from the list of all design cells available in the decoder_full variable
• Use lsearch [array names block_area] $block_name
to check whether an area figure can be obtained for the block
— Calculate the total area for all blocks in the decoder list,
including the hierarchical blocks (mp3 and Decoder)
TCL Scripting for SoC Design

File IIO and Program Access


Aims and Topics
• Aim
— To learn about how to access files, execute programs
and create simple networking applications

• Topics
— Reading from and writing to files
— Invoking external programs
— Multi-process communication
File Manipulation Revisited
• Simple file manipulation with cd, pwd and glob
• file command provides many other operations, e.g.:
%% file
file mkdir
mkdir ~/project/daily_backup
~/project/daily_backup CREATE a directory
%% file
file copy
copy add_v2.vhdl
add_v2.vhdl ~/project/daily_backup
~/project/daily_backup COPY a file/directory
%% file
file rename
rename sub_v4.vhdl sub.vhd
sub_v4.vhdl sub.vhd RENAME a file/directory
%% file
file rename
rename sub.vhd
sub.vhd ~/project/archive
~/project/archive MOVE a file/directory
%% file
file delete
delete compile.log
compile.log DELETE a file/directory

test whether the file


%% file
file isdirectory
isdirectory ~/project
~/project is a directory
11
%% file extract only the directory
file dirname
dirname ~/project/README
~/project/README name from the path
~/project
~/project
%% file extract file modification time
file mtime
mtime add_v2.vhdl
add_v2.vhdl (more on time later)
994776518
994776518
%% file test whether the
file exists
exists add_v3.vhdl
add_v3.vhdl file exists
00 Prefer using file TCL
%% file
file readable
readable add_v2.vhdl
add_v2.vhdl test whether the command to platform-
11 file is readable specific file commands
to improve portability.

Full syntax for the file mkdir dir ?dir ...?


commands
above:
file copy ?-force? ?--? source target

file copy ?-force? ?--? source ?source ...? targetDir

file rename ?-force? ?--? source target

file rename ?-force? ?--? source ?source ...? targetDir

file delete ?-force? ?--? pathName ?pathName ...?

file isdirectory name


file exists name
file dirname name
file readable name
file mtime name
Opening and Closing Files
• Use open to open a file for access
— Returns a channel identifier (also called a file id or descriptor) which
is UNIQUE for each opened file
r read only (default)
r+ read/write (file must already exist)
w write only
file name access mode
w+ read/write
a append only
a+ read/append
%% set
set fid
fid [open test1.dat w]
[open test1.dat w]
file24
file24

file24 is the
channel identifier

• After you finish accessing the file, close it with close


— Channel identifier is invalidated after the file was closed
%% close
close $fid
$fid To improve performance,
do not leave files open when
they are not being used.

open syntax open fileName

open fileName access

open fileName access permissions

close syntax
close channelId
Catching Command Errors
• Use the catch command to trap and handle errors from
specific commands/scripts
%% catch
catch {set
{set fid
fid [open
[open does_not_exist.txt r]} result
does_not_exist.txt r]} result
11
set result
%% set result
couldn’t
couldn’t open
open "does_not_exist.txt":
"does_not_exist.txt": no
no such
such file
file or
or directory
directory

— Returns 1 if there was an error executing TCL command,


0 otherwise
– result contains the error message returned by the command,
or the command result (if the command did not generate an error)

• Beware !
– catch also suppresses syntax and programming errors
— Use catch at lowest possible level to catch only the errors you expect!
Writing to Files
• Use puts to write to files
— Returns an enpty stving on success, error message otherwise
write "Hello world!" + newline
%% puts
puts $fid
$fid "Hello
"Hello world!"
world!" into an open file with channel ID $fid
%%
%% puts -nonewline
puts -nonewline $fid
$fid "Hello
"Hello world!"
world!" write "Hello world!" only
%% (no newline)

• Special channels are available for standard terminal I/O


– stdout (standard terminal output), stderr (standard terminal
error output), stdin (standard terminal input)

puts stdout
%% puts stdout "Hello
"Hello world!"
world!" write "Hello world!" + newline
Hello
Hello world!
world! to standard terminal output
%% puts (stdout channel is the default)
puts "Hello
"Hello world!"
world!"
Hello
Hello world!
world!
write an error message to standard terminal
puts stderr
%% puts stderr "Error:
"Error: invalid
invalid input!"
input!" error output
Error:
Error: invalid
invalid input!
input!

Full puts syntax: puts ?-nonewline? ?channelId? string

Be warned that stdin/out and stderr exist only when there is a terminal window. On
NT stdout and stderr are identical.
File Pointer Position
• Files are accessed using an “invisible” file pointer
— Positioned at the beginning when the file is opened
— Moves forward with each file read
moves forward as the characters are read

test1.dat: T H I S I S L I N E 1 \n T H I S ...

0 1 2 ...
the file origin
has index 0

• Use seek to set the file pointer to the desired position


file pointer offset offset origin

%% seek
seek $fid
$fid 55 start
start move the file pointer 5 positions AFTER the file origin
%% seek
seek $fid
$fid 88 current
current move the file pointer 8 positions AFTER the current position
%% seek
seek $fid
$fid -10 end
-10 end move the file pointer 10 positions BEFORE the end of the file

seek syntax seek channelId offset ?origin?


Reading Lines
• Use gets to read LINES from an open channel
— There are two alternative forms
gets returns the next line read from an open
%% set
set line [gets $fid]
line [gets $fid] channel with $fid identifier.
THIS (next line = all characters until the end of line)
THIS IS
IS LINE
LINE 11
%% set
set chars [gets $fid
chars [gets $fid line]
line] gets stores the next line into variable line,
14
14 and returns the number of characters read
or -1 if the end of file was reached

• Typical uses
— Processing files and communication channel data line-by-line
set
set fid
fid [open
[open "test1.dat"
"test1.dat" r]
r]
while
while {[gets $fid line] >= 0}
{[gets $fid line] >= 0} {{
puts "test1.dat: $line"
puts "test1.dat: $line" the while loop will terminate at the end
}} of file (gets will return -1)
close
close $fid
$fid

— Building INTERACTIVE command-line scripts

gets syntax gets channelId ?varName?


Example: Interactive Command-Line Script
file: examples/interactive.tcl
puts
puts "Welcome
"Welcome to
to aa simple
simple interactive
interactive script!"
script!"

source to_bits.tcl
source to_bits.tcl source other scripts if required

enter an indefinite while loop


while {1}
while {1} {{ (can be broken with exit)
puts
puts "\nCommand:"
"\nCommand:" print the prompt and collect the
gets stdin
gets stdin line
line input from the user

skip if no command was supplied by


if
if {$line
{$line ==
== ""}
""} {continue}
{continue} the user

parse and execute the commands


switch
switch --
-- [lindex
[lindex $line
$line 0]
0] {{
quit
quit -- exit
exit {break}
{break}
dec2bits
dec2bits {puts
{puts [[ to_bits
to_bits [lindex
[lindex $line
$line 1] 1] ]}]}
dir - ls
dir - ls {puts [ glob *
{puts [ glob * ]}]}
default
default {puts stderr
{puts stderr "Error:
"Error: unrecognized
unrecognized command"}
command"}
}}
}}
puts
puts "Thank
"Thank you!"
you!"
Reading Characters
• Use read to read CHARACTERS from an open channel
— There are two alternative forms
read next 7 characters from an open
%% set
set seven_chars [read $fid
seven_chars [read $fid 7]
7] channel $fid
THIS
THIS IS
IS

read until the end of the file from an open


%% set
set file [read -nonewline
file [read -nonewline $fid]
$fid] channel $fid
THIS
THIS IS
IS LINE
LINE 11
...
... discard the last newline, if present
THIS
THIS IS
IS LINE
LINE 99 (optional)

• Typical uses
— Reading the content of an entire file for further processing
— Processing text or binary files character-by-character
— Reading characters from communication channels

read syntax: read channelId numBytes

read ?-nonewline? channelId


Checking for the End of File
• Use eof command to check for the end of file position
— Returns 1 at the end of file, 0 otherwise
— Provides a simple alternative to gets end of file detection
while
while {![eof
{![eof $fid]}
$fid]} {{ repeat the while loop until the end of file
gets
gets $fid
$fid line
line
puts
puts "test1.dat: $line"
"test1.dat: $line"
}}

• Example: processing files character-by-character


set
set src
src [open
[open "test1.dat"
"test1.dat" r]
r]
set
set dest [open "test2.dat"
dest [open "test2.dat" w]
w]
while
while {![eof
{![eof $src]}
$src]} {{
set
set cc [read $src 1]
[read $src 1] read ONE character at the time
puts -nonewline
puts -nonewline $dest
$dest "$c$c$c"
"$c$c$c" write the result to the output file
}} (e.g. write 3 copies of the input character)
close
close $src
$src
close $dest
close $dest

eof syntax: eof channelId


Portability Issues
• End-of-line is represented by \n on ALL TCL platforms
— Incompatible end-of-line characters are automatically converted to
the end-of-line characters used by the host platform
file: examples/correct_newlines.tcl

proc correct_newlines
proc correct_newlines {src_file
{src_file dest_file}
dest_file} {{
set src [open $src_file
set src [open $src_file r]r]
set
set dest
dest [open
[open $dest_file
$dest_file w]
w] destination file will use end-
puts
puts $dest [read $src]
$dest [read $src] of-line characters
close of the host platform
close $src
$src
close $dest
close $dest
}}

• For portable file manipulation


— Avoid code dependent on the case of characters in filenames
— Avoid using special characters (<>:"/\|.) in filenames
— Use TCL file manipulation commands (cd, pwd, glob,
file), NOT the platform-specific commands

TCL also supports the compatible subset of the native platform's file path
convention. However, this will only work on one native platform. It is advisable
avoid using this and use portable TCL file path handling instead.
Although the forward slash is the directory separator, one should use file split and
file join to analyze and construct the filenames.
Channel Buffering

S NO
T
... I H I
buffering
\n
1 T H

E
puts N
I L
THIS IS LINE 1\n
S
THIS IS LINE 2\n
I T
H
LINE
channel buffer buffering

THIS IS LINE 1\n


THIS IS LINE 2\n
THIS IS LINE 3\n
FULL
... buffering
THIS IS LINE 9\n

There is an internal buffer associated with each I/O channel. For example, when
puts command puts characters into a channel, the characters are first buffered
and only then send to the channel.
There are three possible methods of channel buffering:
•NO buffering: the characters are not buffered at all. The characters are output
as they are received. This type of buffering is slow due to frequent I/O operations.
Try: source examples/buffering_none.tcl
•LINE buffering: the output is flushed after each end-of-line character. Line
buffering is the default type of buffering for terminal devices (such as stdout).
Try: source examples/buffering_line.tcl
•FULL buffering: the output is flushed after the internal buffer was filled with
characters. Full buffering is the default for file access as this provides a good
performance trade-off (I/O access occurs only after the internal buffer was filled).
Try: source examples/buffering_full.tcl
Configuring Channel Buffers
• fconfigure is used to configure the type of channel buffering
none no buffering
line line buffering
file: examples/buffering_none.tcl full full buffering

...
...
fconfigure stdout -buffering
fconfigure stdout -buffering none
none buffering mode
...
...

• The contents of the channel buffer can be flushed at


ANY TIME using the flush command
file: examples/interactive2.tcl
...
...
puts
puts -nonewline
-nonewline ">
"> ""
flush stdout
flush stdout flushes the stdout channel
gets buffer to print the prompt
gets stdin
stdin line
line
...
...

Use fconfigure to change properties of an open channel at ANY time during


channel access. Channel properties which can be changed include:
• Automatic end-of-line conversion
• End-of-file character
• Channel blocking and buffering

fconfigure syntax

fconfigure channelId

fconfigure channelId optionName

fconfigure channelId optionName optionValue ?optionName optionValue?

flush syntax

flush channelId
Invoking External Programs
• Use exec to invoke external programs
external program ...and its arguments

%% exec
exec zip
zip archive.zip
archive.zip test1.dat
test1.dat
adding:
adding: test1.dat
test1.dat (92
(92 bytes
bytes security)
security) (deflated
(deflated 72%)
72%)

external program output is returned back to the TCL interpreter

• auto_noexec variable controls whether the interpreter


searches the native shell for unrecognixed commands
— If auto_noexec does not exist
%% zip
zip archive.zip
archive.zip test1.dat
test1.dat
adding:
adding: test1.dat
test1.dat (92
(92 bytes
bytes security)
security) (deflated
(deflated 72%)
72%)
no exec
required
— If auto_noexec is defined (contains ANY value)
set auto_noexec
%% set auto_noexec ""
""
%% zip
zip archive.zip
archive.zip test1.dat
test1.dat
invalid
invalid command
command name
name "zip"
"zip"

exec syntax exec ?switches? arg ?arg ...?


Problems with Multiple Arguments
• Trying to remove ALL log files, but...
%% glob
glob *.log
*.log
simulation.log
simulation.log synthesis.log
synthesis.log test.log
test.log W HY?
%% exec
exec rm
rm [glob
[glob *.log]
*.log]
simulation.log
simulation.log synthesis.log
synthesis.log test.log:
test.log: no
no such
such file
file or
or directory
directory

exec rm simulation.log synthesis.log test.log

Treated by rm as ONE file name!

• ...easily solved with eval


eval
– eval will force another round of word separation
and substitutions before the exec command is executed
exec rm simulation.log synthesis.log test.log

%% eval
eval exec
exec rm
rm [glob
[glob *.log]
*.log]

eval syntax eval arg ?arg ...?


Problems Executing External Programs
• tclsh is NOT a UNIX shell (/bin/sh, /bin/tcsh, etc.)
— UNIX shell wildchars, substitution and quoting do NOT work

%% exec
exec tar
tar -cvf archive.tar projectƒ*
-cvf archive.tar projectƒ* UNIX shell wildchars
! tar: don’t work in TCL!
tar: projects/*:
projects/*: Cannot
Cannot stat:
stat: No
No such
such file
file or
or directory
directory
...
...
%% eval
eval exec
exec tar
tar -cvf archive.tar [glob
-cvf archive.tar [glob projectƒ*]
projectƒ*] use glob instead
...
...
NOTE!

• tclsh is NOT a Windows/DOS shell (command.com)


— Built-in Windows/DOS commands cannot be executed directly

!
%% set
set dir_list [exec dir
dir_list [exec dir C:*.*]
C:*.*] dir is a built-in command
couldn’t
couldn’t execute
execute "dir":
"dir": no
no such
such file
file or
or directory
directory
%%
%% set
set dir_list [exec COMMAND.COM
dir_list [exec COMMAND.COM ƒC
ƒC dir
dir C:*.*]
C:*.*] invoke command.com
...
... with built-in command as
an argument instead

Similarly to Windows/DOS shell example above, you may also invoke commands
using a UNIX shell directly. For example, an alternative way
of executing the tar command above is
exec /bin/sh -c "tar -cvf archive.tar project/*"
This will execute correctly as the string given to the -c option is executed
by the UNIX shell (/bin/sh).
InputIOutput Redirection
• TCL implements a range of I/O redirection operators
— Redirection of standard input, output and error channels
to/from files (overwrite and append modes)
— Receive standard input from a TCL string
— Piping standard output to standard input between two commands

read from a TCL write standard output to a file


string
%% exec compress <<
exec compress << "Hello world!" >> foo.Z
"Hello world!" foo.Z
%%
%% set
set stats
stats [exec
[exec zcat foo.Z || wc]
zcat foo.Z wc]
00 22 12
12
pipe standard output from zcat as
standard input to wc
Processes in TCL
• Start a new process with exec and & (ampersand)...
— Returns the process ID on success, an error message otherwise
external program to invoke

%% exec notepad.exe &&


exec notepad.exe
1476
1476

process ID

• ...or using open with a pipe and use the pid command
to retrieve the process ID
external program to invoke
pipe
the standard output from the ipconfig
%% set
set fid [open "|
fid [open ipconfig" r]
"| ipconfig" r] program can be accessed as a CHANNEL
file24
file24
%% pid
pid $fid
$fid
1164
1164

process ID

pid syntax pid ?field?


Multi-Process Communication
CLIENT SERVER

commands
HHDDLL H
Haarrddw
waarree
SSimmuulaatoorr results tteessttrrigg

external program
(can be another TCL read/write mode (bi-directional communication)
script!)
%% set
set fid [open "|
fid [open test_rig" r+]
"| test_rig" r+] IMPORTANT: set-up LINE buffering
file24 (FULL buffering is the default for files)
file24
%% fconfigure
fconfigure $fid -buffering line
$fid -buffering line
%% puts $fid "test1 100"
puts $fid "test1 100"
%% gets
gets $fid
$fid
test1:
test1: 1000
1000 H
Haarrddw
waarree
%% puts
puts $fid
$fid "test2
"test2 200"
200" tteessttrrigg
%% gets
gets $fid
$fid
test2:
test2: 400
400
%% close
close $fid
$fid

The above is the example of SYNCHRONOUS communication, i.e. the client


application always waits for the response from the server before proceeding
further.
TCL can be also used to build ASYNCHRONOUS communication channels,
which are typically used in servers and GUI applications.
For more details on writing multi-process and networking applications in TCL
can be found in Appendix C - Client-Server Applications and Networking.
Quiz 7

set fid [open "test3.dat" w] file:


puts -nonewline $fid "Hello\n world!" examples/quiz7.tcl

• What is the contents of test3.dat?


(a) nothing (file test3.dat is an empty file)
(b)Hello
(c)Hello\n
(d)Hello\n world!
(e)Hello\n world!\n
(f) file test3.dat does not exist

Answer
TCL Scripting for SoC Design

Regular Expressions
Aims and Topics
• Aim
– To gain proficiency in using regular expressions for advanced
string processing

• Topics
– Regular expressions (REs): what and why?
– Regular expression patterns
– RE-based string searching
– RE-based string replacement
Why Regular Expressions?
• String search capabilities already exist in TCL
– lsearch, string match, switch, etc.
– Inefficient for complex string search/replace operations

• Regular Expressions can handle complex and repetitive


string manipulation tasks efficiently
entity add is
...
a : in std_logic_vector(7 downto 0); entity add32 is
cin : in std_logic; ...
... a : in std_logic_vector(0 to 31);
end add; transformed using
a set of rules cin : in std_logic;
...
architecture struct of add is end add32;
...
sum <= result(7 downto 0); architecture struct of add32 is
cout <= result(8); ...
... sum <= result(0 to 31);
end struct;
cout <= result(32);
...
end struct;
What are Regular Expressions?
• Special string patterns which can match strings using
various rules
— Context-specific
— Generic (will work for many different strings)

• Example
— RE for an output port declaration in a VHDL entity:
regular expression *[a-zA-Z][a-zA-ZO-9_]*
*[a-zA-Z][a-zA-ZO-9_]* *:
*: *out
*out [a-zA-Z][a-zA-ZO-9_]*
[a-zA-Z][a-zA-ZO-9_]*

entity add is
port (
cin : in std_logic;
a : in std_logic_vector(7 downto 0); string matching the regular expression
b : in std_logic_vector(7 downto 0);
y : out std_logic_vector(7 downto 0);
cout: out std_logic
);
end add; NOTE: RE string matching is based on context
(e.g. signal which is a 1-bit output port). Therefore
the matching will work for signals of any name or type.
Regular Expression Basics
• Alphabet and digit characters are matched as usual
a matches a SINGLE given character, i.e. character a
VHDL matches a SEQUENCE of given characters, i.e. string VHDL

• Regular expressions use several special characters


. matches ANY SINGLE character
[] matches a SINGLE character from a sequence, e.g.
[abc] a or b or c (single character)

[A-Z] an uppercase letter (character range)


[^A-Z] a character which is NOT an uppercase letter
a character which is either a letter (lowercase or uppercase),
[a-zA-Z0-9_] a digit or an underscore
* matches 0 or more occurrences of a preceding ATOM
a* 0 or more characters a, e.g a or aaaaa, but also '' (no character)
[a-z]* 0 or more lowercase letters
[A-Z][a-z]* word with the first letter in uppercase (0 or more lowercase letters)
.* 0 or more occurrences of any character, i.e. ALL characters
Searching with Regular Expressions
• Use regexp command for RE-based string search
variable which will store the
regular expression pattern string to search matched string

%% regexp
regexp {[A-Z][A-Z]*}
{[A-Z][A-Z]*} "which
"which is
is better:
better: VHDL
VHDL or Verilog?" m_var
or Verilog?" m_var
11
%% set Enclose RE patterns within {} to protect
set m_var
m_var patterns from TCL substitution (unless
VHDL
VHDL the substitution is desired)

– regexp returns 1 if the match was found, 0 otherwise

• Use -nocase option for case-insensitive search


%% regexp
regexp -nocase
-nocase --
-- {[A-Z][A-Z]*}
{[A-Z][A-Z]*} "which
"which is
is better: ..." m_var
better: ..." m_var
11
%% set
set m_var
m_var Always use -- to prevent regexp from
which
which confusing patterns with options.

• RE patterns always match the LONGEST possible string


of characters
Example: Find the First VHDL Entity Line
file: examples/find_entity_line.tcl

set
set fid
fid [open
[open "adder.vhdl"
"adder.vhdl" r]
r]
set
set add
add [read
[read $fid]
$fid]
close
close $fid
$fid

regexp
regexp -nocase
-nocase --
-- {{ *entity
*entity *[a-z][a-z0-9_]*
*[a-z][a-z0-9_]* *is
*is *} $add e_line
*} $add e_line
puts "$e_line"
puts "$e_line"

%% cd
cd examples
examples
source find_entity_line.tcl
%% source find_entity_line.tcl
entity
entity add
add is
is

file: examples/adder.vhdl
entity add is
port (
...
);
end add;
...

regexp syntax

regexp ?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?


More RE Symbols
• Characters and strings matching
^ matches the BEGINNING of a line, e.g.
^architecture string architecture at the beginning of a line

$ matches the END of a line, e.g.


;$ character ; at the end of line

• Alternatives
x|y matches ONE of the two possible atoms, e.g.
out|in string out OR string in
[a-z]|[0-9] lowercase letter OR a digit

• Use () to group atoms together, e.g.


([a-z][a-z]*)|[0-9] lowercase word of 1 or more letters OR a digit
More RE Symbols (2)
• Sequence matching
+ matches 1 or more occurrences of a preceding atom
+ 1 or more spaces, equivalent to *)
[a-z]+ 1 or more lowercase letters
(a word composed of lowercase letters)
? matches 0 or 1 occurrence of a preceding atom
? 0 or 1 space, equivalent to ( |)
[a-z]? 0 or 1 lowercase letter

• Meaning of all special RE characters can be escaped


with a backslash (\)
1 or more digits preceded by either a character - or
((\+?)|-)[0-9]+ optionally character +, i.e. an INTEGER

• TCL also provides an advanced version of REs (AREs)


which further simplify string searching
– See re_syntax TCL manual page for more details (TCL 8.2 and
later)
Searching for Strings within Strings
• REs can easily locate a sub-pattern within a pattern
– Use RE sub-expressions for sub-string matching

• Example: extract VHDL entity name


file: examples/adder.vhdl
entity add is
...
end add;

file: examples/find_entity_name.tcl

...
...
regexp
regexp -nocase
-nocase --
-- {{ *entity
*entity +([a-z][a-z0-9_]*)
+([a-z][a-z0-9_]*) +is
+is *}
*} $add
$add \\
e_line e_name
e_line e_name
a sub-expression is
holds the entire holds the 1st matched enclosed within ()
matched string sub-string
puts
puts "$e_name"
"$e_name"

source find_entity_name.tcl
%% source find_entity_name.tcl
add
add
Example: Extracting VHDL Port Direction
file: examples/adder.vhdl
• More than one entity add is
port (
sub-pattern can be used cin : in std_logic;
a : in std_logic_vector(7 downto 0);
— Add additional sub-pattern b : in std_logic_vector(7 downto 0);
y : out std_logic_vector(7 downto 0);
variables as necessary cout: out std_logic
);
end add;
...

file: examples/find_port_dir.tcl
...
...
regexp
regexp -nocase
-nocase --
-- \\
{{ *([a-z][a-zO-9_]*)
*([a-z][a-zO-9_]*) +:
+: +([a-z]+)[^;]*;}
+([a-z]+)[^;]*;} $add
$add \\
p_line p_name p_dir
p_line p_name p_dir
puts
puts "$p_name
"$p_name ($p_dir)"
($p_dir)"

source find_port_dir.tcl
%% source find_port_dir.tcl
cin
cin (in)
(in)
Using Indices with regexp
• With -indices option regexp will extract string
index range instead of a string
regexp -indices
%% regexp -indices --
-- {[A-Z][a-z]+}
{[A-Z][a-z]+} "VHDL
"VHDL or Verilog?" idx
or Verilog?" idx
11
%% set
set idx
idx
88 14
14 indices or the first and the last character of the matched string
%% string
string range
range "VHDL
"VHDL or
or Verilog?
Verilog? [lindex
[lindex $idx
$idx 0]
0] [lindex
[lindex $idx
$idx 1]
1]
Verilog
Verilog

• Typical uses
– Searching for an insertion position
– Repetitive search
– Index-based string manipulation
Example: Searching for All Occurrences
• Find all entity port lines
– Use matched pattern indices to resize the search buffer

file: examples/find_all_port_lines.tcl
...
...
set { *[a-z][a-z0-9_]* *: *(in|out) +[a-z][a-z0-9_]*(\([^()]+\))?}
set buf
buf $add
$add
set llist ""
set llist ""
while
while {[regexp -nocase -indices
{[regexp -nocase -indices ---- <port_RE>
<port_RE> $buf
$buf idx]}
idx]} {{
## store
store matched
matched port
port line
line
lappend
lappend llist
llist [string
[string range
range $buf
$buf [lindex
[lindex $idx
$idx 0]
0] [lindex
[lindex $idx
$idx 1]]
1]]

## resize
resize the
the search
search buffer
buffer
set
set buf [string range
buf [string range $buf
$buf [expr
[expr [lindex
[lindex $idx
$idx 1]+1]
1]+1] end]
end]
}}
...
...

Note that since TCL version 8.3, regexp provides the -start option, which
allows to move the search pointer without the need to manipulate the search
buffer as above.
Example: Filtering Command Logs
• Extract warnings from a Simplicity .srr log file
file: examples/filtercore.srr
...
Synthesizing work.interface.rtl
@W:"c:\lab6\interface.vhd":82:39:82:43|Signal aver2 in the sensitivity list is not used in the process
Post processing for work.interface.rtl
...

file: examples/extract_warnings.tcl

proc extract_warnings
proc extract_warnings {f} {f} {{
set
set in_file
in_file [open
[open $f$f r]
r]
while
while {[gets $in_file line]
{[gets $in_file line] >= >= 0}
0} {{
if {[regexp @W $line]}
if {[regexp @W $line]} { {
regexp
regexp -nocase
-nocase -- -- \\ extracted output
{([a-z_]+\.vhd)[0-9:"|]+([a-z_\.
{([a-z_]+\.vhd)[0-9:"|]+([a-z_\. 0-9]+)}
0-9]+)} \\
$line
$line buf
buf filename
filename msgmsg
puts
puts "$filename\t\t$msg"
"$filename\t\t$msg"
}}
}}
close
close $f
$f
}}
String Substitution
• Use regsub for RE-based string substitution
replace the matched variable which will store the
RE pattern to search for input string pattern with this result

%% regsub
regsub --
-- {[a-z]+}
{[a-z]+} "cin std_logic;" "carry_in"
"cin :: std_logic;" "carry_in" new_str
new_str
11
%% set
set new_str
new_str
carry_in
carry_in :: std_logic;
std_logic;

– regsub does not modify the input string


– Returns the number of matched patterns (0 = no match)

• Useful options
– Use -nocase for case-insensitive search
– Use -all to replace ALL matched patterns (global substitution)

regsub syntax

regsub ?switches? exp string subSpec varName


Inserting Matched Sub-Strings
• regsub can re-insert the matched sub-strings
– Uses special positional substitution “commands”:
\0 or & insert the entire matched string
\1 insert the first matched sub-string
\2 insert the second matched sub-string
etc.

• Example: changing the bit width


first sub-pattern = \1 second sub-pattern = \2

%% regsub
regsub --
-- {[0-9]+
{[0-9]+ +([a-z]+)
+([a-z]+) +([0-9]+)} "vector(7 downto
+([0-9]+)} "vector(7 downto 0)"
0)" \\
{(n-1) \1 \2} new_str
{(n-1) \1 \2} new_str
11
%% set
set new_str
new_str
vector((n-1) downto
vector((n-1) downto 0)
0)
Using REs for Complex Substitutions
• Two-pass processing (collect & substitute)
– regexp to collect the information
– regsub to substitute

• Consider converting all std_logic_vector(0 downto 0)


signals/ports to std_logic
– First we need to find all 1-bit vector signals/ports
– Then substitute
ports/signals: std_logic_vector(0 downto 0) to std_logic
signal assignments: a(0) to a
a <= (others => '0') to a <= '0'
– See examples/vector_to_bit.tcl
Quiz 8
file: examples/quiz8.tcl
set line "a_in: in std_logic_vector(31 downto 0);"

regsub {\(([0-9]+) +(.*) +([0-9]+)\);} \


$line {(\3 to \1);} new_line

puts $new_line

• What is the value of new_line ?


(no options, sorry!)

Answer
LAB 4: VHDL Netlist Hacking
• Write a procedure find_vector_port which will identify the
FIRST bus port in the VHDL design entity
– An example of a VHDL design file is in adder.vhdl
entity add is
port (
cin : in std_logic;
a : in std_logic_vector(7 downto 0); Stage 2: modify the port names
b : in std_logic_vector(7 do wnto 0);
entity add is
cout: out std_logic;
sum : out port (
std_logic_vector(7 do wnto 0);
cin : in std_logic;
)
a_bus : in std_logic_vector(7 downto 0);
end add;
b_bus : in std_logic_vector(7 downto 0);
cout : out std_logic;
sum_bus : out std_logic_vector(7 downto 0);
)
end add;
• Example:
%% find_vector_port
find_vector_port adder.vhdl
adder.vhdl
First
First bus
bus port is aa
port is
%%
LAB 4: VHDL Netlist Hacking (2)
• Stage 1
– Open and read in the entire adder.vhdl file into a variable
– Use regexp to extract the first entity port name, which is a vector
• Construct a regular expression to identify the port name with the
std_logic_vector type
– Print the port name on the terminal

• Stage 2
– Replace regexp with regsub to append _bus string to ALL vector port
names and save the new adder entity into a new file
– Include port indices into the port names, e.g. ain_bus_7_0
– Replace the port bus signals with a number of single-bit signals
labelled with their respective indices, e.g. ain_7, ain_6, etc.
– Replace ALL design bus signals (in entity and architecture)
with single-bit signals (use adder_full.vhdl)
TCL Scripting for SoC Design

TCL in SoC Design Tools


Aims and Topics
• Aim
— To gain understanding about how TCL is used in
contemporary SoC Design tools

• Topics
— Where you can find TCL interpreters in SoC Design tools
— Typical uses of TCL with various SoC Design tools
Where is My TCL Interpreter?
• TCL interpreter is typically embedded in your SoC
Design tool command console (GUI or command line)

HERE
HERE

HERE
HERE

HERE
HERE
Finding out More about your SoC Design Tool
• Check the version of the TCL interpreter
info tclversion
%% info tclversion
8.0
8.0
info patchlevel
%% info patchlevel
8.0.5
8.0.5

• Check for SoC Design tool-specific commands and variables


— For example MTI’s simulator-specific commands and variables start
with the mti_ prefix
info commands
%% info commands mti_*
mti_*
...
...
info globals
%% info globals mti_*
mti_*
...
...

• Examine the SoC Design tool-specific TCL


documentation for tool-specific TCL functionality
and data structures
info tclversion provides an alternative way to examining the version
of the TCL interpreter. The same information can be obtained by examining
global variables tcl_version and tcl_patchLevel.
Examples of TCL-based SoC Design Tools
• HDL simulation
— MTI/Mentor Graphics ModelSim /NCSim
—...

• HDL synthesis / Placement & Routing / Static Timing Analysis


— Synopsys DC, ICC, PT etc.
— Exemplar Logic LeonardoSpectrum
— Cadence RC, Encounter, Genus, Innovus, Tempus
— Synplify Pro
—...
LAB 5: Working with a TCL-enabled SoC Design

Tool

• Please refer to your exercise book for your tool specific


laboratories.
TCL Scripting for SoC Design

Next Steps
What this Course Covered...
• Main topics
— TCL scripting basics
— TCL data structures (strings, lists and arrays)
— File I/O, multi-process communication and simple networking
— Regular expressions
— Building TCL applications
— EDA TCL scripting
— Appendix:
• Using expect for interacting with command-line programs

• Following the course...


— Several months “hands-on” work to become experienced
Suggested Follow-on Training
TCL for EDA •
Scripting
TCL for SoC Design Scripting
— This course!
Building
Applications • Building Applications with
with TCL/TK
TCL/TK — Using TK graphics toolkit to add complex multi-
platform GUI's to TCL scripts with the
minimum of code
Effective
• Effective TCL/TK Programming
TCL/TK
Programming — More advanced application development using
TCL/TK
• Object Orientated Programming with [incr_TCL]
Object
Orientated — Adding object orientated features to TCL
Programming applications using the [incr_TCL]
with extension
[incr_TCL]

Building Applications with TCL/TK


3 day workshop covering the the use of TCL with TK - the graphics toolkit
extensions to TCL. TK allows the designer to add complex multi-platform
Graphical User Inferfaces (GUI's) to TCL scripts, using the minimum of code. TK
is used by many SoC Design companies to define their tool GUI's.
Effective TCL/TK Programming
2 day workshop covering advanced design and coding techniques for creating
complete and effective TCL/TK applications
Object Orientated Programming with [incr_TCL]
[incr_TCL] is the object orientated extension to TCL. This workshop examines
the features of [incr_TCL] and shows how to take advantage of them in your
applications.
What About TK ?

• TK is a simple but powerful Tool Kit for GUI programming


• Supports different window systems UNIX (Solaris)

— UNIX
— Windows 95/98/NT/2000
— Macintosh

• Try this:
Windows 2000
$$ wish
wish
%% button
button .b
.b -text
-text "Hello
"Hello World!"
World!" -command
-command exit
exit
.b
.b
%% pack
pack .b
.b -padx
-padx 44 -pady
-pady 66
%%

• TK provides a set of TCL commands to create window


“widgets”
TCL/TK Resources
• Internet
— TCL distributions (source & binary), contributed software
archive, discussion lists, books, documentation, tutorials, etc.
• dev.scriptics.com (tcl.activestate.com)
• cui.unige.ch/eao/www/TCLTK.html
• www.sco.com/Technology/tcl/TCL.html
• www.tcltk.com
• www.neosoft.com/tcl
• expect.nist.gov
• www.tclforeda.net
— newsgroup
• comp.lang.tcl

• Books
– tcl.activestate.com/resource/doc/books

There are many resources available to TCL application developers. Some of the popular
websites are listed here. Feel free to use your favourite Internet search engine to discover
more.
comp.lang.tcl is an on-line discussion forum for TCL scripting related issues. If your
company does not provide a news server access, you might want to use one of the public
news services, e.g. try Google at
http://groups.google.com/groups?group=comp.lang.tcl
TCL Scripting for SoC Design

Appendix A:
From Scripts to Applications
Aims and Topics
• Aim
– Expand the knowledge of TCL to enable building complex,
robust and portable scripting applications

• Topics
– TCL scripts versus applications
– Command-line arguments & environment variables
– Advanced procedures
– Variable scope
– Error handling
– Date & time in TCL
– Scheduling and delaying command execution
– Script profiling
– Distributing TCL scripts
TCL Script versus TCL Application
• TCL script is simply a collection of TCL commands, which
do something more or less useful

• TCL application includes one or more TCL scripts, which can


be used as a robust stand-alone application
– Invoked similarly to “ordinary” programs
– Handles command-line arguments
– Provides access to native platform’s environment
– Easily distributed and installed
Executing TCL Scripts as Ordinary Programs
• MSWindows/Macintosh TCL Scripts
– Double-click a TCL source file to execute it

• UNIX TCL Scripts


– Use the #!<pathname> to specify the full path to the interpreter...

full path to the TCL


interpreter which will execute #!/usr/local/bin/tclsh
#!/usr/local/bin/tclsh
this TCL script puts
puts "Hello
"Hello World!"
World!"

– ...or for better portability use the UNIX shell to search the $PATH
IMPORTATNT!
full path to the UNIX shell (escaped newline)
which will invoke the
#!/bin/sh
#!/bin/sh
TCL interpreter on this ## DO
DO NOT REMOVE: \\
NOT REMOVE:
script exec
exec tclsh "$0"
tclsh "$0" "$@"
"$@"
TCL script starts puts
puts "Hello World!"
"Hello World!"
here

On Windows all .tcl files are associated with a TCL/TK interpreter called wish. If
you want to use only the plain TCL interpreter, you may re-define this file
association using the Windows Explorer (File Manager) application.
Command-Line Arguments
• Very useful for customizing TCL script behavior
from a command-line
• Command-line arguments passed to TCL scripts are
stored in the following special global variables
argv TCL list of all command-line arguments
argc number of command-line arguments (= llength $argv)
argv0 script name

• Example argv0 argv

tclsh examples/cmd_line_args
%% tclsh examples/cmd_line_args -file
-file mp3.vhdl
mp3.vhdl -dir
-dir synth_run.12
synth_run.12
argv
argv == -file
-file mp3.vhdl
mp3.vhdl -dir
-dir synth_run.12
synth_run.12
argc =
argc = 44
argv0
argv0 == examples/cmd_line_args
examples/cmd_line_args
%%
Dealing with Platform-Specific Code
• Use the global tcl_platform array to obtain information
about the host platform
file: examples/platform_details.tcl

proc platform_details
proc platform_details {}
{} {{
global tcl_platform
global tcl_platform
puts "Machine:\t $tcl_platform(machine)"
puts "Machine:\t $tcl_platform(machine)"
puts "Platform:\t $tcl_platform(platform)"
puts "Platform:\t $tcl_platform(platform)"
puts "OS:\t\t $tcl_platform(os)
puts "OS:\t\t $tcl_platform(os) $tcl_platform(osVersion)"
$tcl_platform(osVersion)"
puts
puts "Byte order:\t $tcl_platform(byteOrder)"
"Byte order:\t $tcl_platform(byteOrder)"
}}

file: examples/edit.tcl
• Typical proc edit
proc edit {filename}
{filename} {{
global
global tcl_platform
example tcl_platform
switch $tcl_platform(platform)
switch $tcl_platform(platform) {{
windows
windows {exec
{exec notepad.exe
notepad.exe $filename
$filename &}
&}
unix
unix - linux {exec nedit $filename &}
- linux {exec nedit $filename &}
}}
}}
Accessing Environment Variables
• Use global env array to access system environment variables
set env(PATH)
%% set env(PATH)
/usr/bin:/bin/:/usr/local/bin
/usr/bin:/bin/:/usr/local/bin
set env(LM_LICENSE_FILE)
%% set env(LM_LICENSE_FILE)
/nfs/cad/mentor/licenses/license.dat
/nfs/cad/mentor/licenses/license.dat

%% info
info exists
exists env(EDITOR)
env(EDITOR) check for existence of an environment variable
00
%% set
set env(EDITOR)
env(EDITOR) "nedit"
"nedit" modify the value of an environment variable
nedit
nedit

• Processes started from the current TCL interpreter


will inherit the environment variables
– TCL can be used to customise system variables for
invoked external programs
Procedures Revisited
• Procedures can have optional arguments
– Possible to write one procedure for many uses
default value for fid default value for prefix

proc print_log
proc {{fid stdout}
print_log {{fid {prefix LOG:}}
stdout} {prefix LOG:}} {{
global log
global log
foreach
foreach line
line $log
$log {{
puts
puts $fid
$fid "$prefix
"$prefix $line"
$line"
}}
}}

• Using procedures with optional arguments


%% print_log
print_log print_log can have 0, 1 or 2 arguments
LOG:
LOG: ...
...
...
...
%% print_log
print_log $open_fid
$open_fid Use optional procedure arguments
%% print_log
print_log $open_fid SYNTH:
$open_fid SYNTH: to improve TCL code re-use,
readability and maintainability.
Variable Number of Arguments
• Use special argument args to absorb all argument values not
matched by the preceding arguments
– Useful for parsing command switches, reusing procedure code, etc.
– args is an ordinary TCL list
args must be the LAST argument
file: examples/print_log.tcl

proc print_log_args
proc print_log_args {fid{fid args}
args} {{
global
global log
log
set
set prefix
prefix "LOG:";
"LOG:"; set
set header
header "";
""; default option values
foreach
foreach {option value} $args {{
{option value} $args parsing command options stored in the args list
switch -- $option
switch -- $option { {
-prefix
-prefix {set
{set prefix
prefix $value}
$value}
-header
-header {set
{set header
header $value}
$value}
default
default {puts
{puts "ERROR:
"ERROR: Unknown
Unknown option
option \"$option\".";
\"$option\"."; return;}
return;}
}}
}}
if
if {$header
{$header !=!= ""}
""} {puts
{puts $fid
$fid $header}
$header}
foreach
foreach line
line $log
$log {puts
{puts $fid
$fid "$prefix
"$prefix $line"}
$line"}
}}
Variable Number of Arguments (2)
• Using print_log with variable arguments

fid args (0 elements)

%% print_log_args
print_log_args stdout
stdout
LOG:
LOG: ...
... args (2 elements)
...
...
%% print_log_args
print_log_args stdout
stdout -prefix
-prefix "PLACE
"PLACE && ROUTE:"
ROUTE:"
PLACE
PLACE && ROUTE:
ROUTE: ...
... args (4 elements)
...
...
%% print_log_args
print_log_args stdout
stdout -prefix
-prefix "PLACE
"PLACE && ROUTE:"
ROUTE:" -header
-header "Design
"Design P&R
P&R Log"
Log"
Design
Design P&R
P&R Log
Log
PLACE
PLACE && ROUTE:
ROUTE: ...
...
... args (1 element)
...
%% print_log_args
print_log_args stdout
stdout -bad_option
-bad_option
Unknown
Unknown option
option "-bad_option"
"-bad_option"
Variable Scope
• global command provides access to variables at global
level only
• upvar command allows accessing variables at ANY level
– typically used for passing variables by reference
file: examples/print_log_upvar.tcl

proc print_log_upvar
proc print_log_upvar {fid
{fid log_var
log_var args}
args} {{
upvar
upvar 11 $log_var
$log_var log
log variable $log_var becomes visible via a local variable log

sets visibility level, 1 = one level UP (default)


...
...
foreach
foreach line
line $log
$log {puts
{puts $fid
$fid "$prefix
"$prefix $line"}
$line"}
}}

variable sim_log becomes visible inside print_log_upvar

%% print_log_upvar
print_log_upvar stdout
stdout sim_log
sim_log
LOG:
LOG: ...
...
...
...
Generating Application Errors
• Error messages can be generated with puts
• TCL also provides a robust error reporting mechanism
using the error TCL command
errorInfo global variable which stores the stack trace
after an error occurred
errorCode global variable which holds the error code
of the last error
file: examples/print_log_error.tcl

proc print_log_error
proc print_log_error {fid log_var args}
{fid log_var args} {{
...
...
switch
switch --
-- $option
$option {{
-prefix
-prefix {set
{set prefix
prefix $value}
$value}
-header
-header {set
{set header
header $value}
$value}
default
default {error
{error "ERROR:
"ERROR: Unknown
Unknown option
option \"$option\".";}
\"$option\".";}
}}
}} terminates immediately and returns the error message.
errorInfo and errorCode variables are set appropriately
...
...
}
Handling Date and Time
• Query the current time
%% clock
clock seconds
seconds
1004945376
1004945376 time measured as seconds from fixed starting time
(usually January 1, 1970)

• Convert date strings to seconds (mm/dd/yy)


%% clock
clock scan
scan "10/17/00"
"10/17/00" clock scan understands many different formats
971733600
971733600

• Convert seconds to date strings:


%% clock
clock format
format 971733600
971733600
Tue
Tue Oct
Oct 17
17 00:00:00
00:00:00 Romance
Romance Daylight
Daylight Time
Time 2000
2000
%% clock
clock format
format 971733600
971733600 -format
-format "%B
"%B %d,
%d, %Y
%Y is
is in
in week
week #%U"
#%U"
October
October 17,
17, 2000
2000 is
is in
in week
week #42
#42
%% clock
clock format
format [clock
[clock seconds]
seconds]
Thu
Thu Oct
Oct 12
12 16:49:22
16:49:22 Romance
Romance Daylight
Daylight Time
Time 2000
2000
Inserting Delays
• Use after command to insert delays or to schedule scripts
for execution in the future
• Typical uses
– Wait for another process to complete
– Periodic tasks
– Simulated user input

• Examples
%% after
after 1000
1000 sleep for 1000 milliseconds, then return
%% after
after 5000
5000 {puts
{puts "Job
"Job done."}
done."} returns immediately, but schedules execution of
after#1
after#1 a TCL script 5000 milliseconds from now
%% vwait
vwait event-loop
event-loop
Job tclsh must enter the EVENT LOOP in order to
Job done.
done. execute all pending scripts
Script Performance Profiling
• Use time command to evaluate the average execution time
over 1 or more iterations
• Typical uses
– Performance profiling
– Collecting timing statistics

• Examples
%% time
time {my_command}
{my_command} time command execution over 1 iteration (default)
180000
180000 microseconds
microseconds per
per iteration
iteration
%% time {my_command} 100
time {my_command} 100 time command execution over 100 iterations
256310
256310 microseconds
microseconds per
per iteration
iteration
TCL Application Distribution
• TCL application includes the following elements
– TCL script files
– Any other files (data, setup, etc.)
– TCL interpreter (?)

• TCL application can be easily packaged with TCLPro


• No need to distribute the TCL interpreter if a
compatible interpreter is available on the target
platform
– Check the TCL version to guard against unexpected errors
global variable with TCL version string (e.g. 8.0)
if {![string match
if {![string match 8.*
8.* $tcl_version]}
$tcl_version]} {{
puts
puts "Error:
"Error: incompatible
incompatible TCL
TCL version
version $tcl_version"
$tcl_version"
exit
exit
}}
TCL Packages
• Rather than source-ing each script required for the
application, the scripts can be put into a package
— Request access to the package commands using package require
% package require tool
1.0
% to_bits 9 use to_bits from the tool package
1001

• Defining packages
— Insert package provide tool 1.0 in each TCL script to
become part of the tool package
— Run pkg_mkIndex . *.tcl in the package directory to create the
package index file (pkgIndex.tcl)
— Update auto_path global variable to include the package directory

All TCL scripts in the examples directory, which define procedures were included in
the tool TCL package.
For an example of the package index file, look in examples/pkglndex.tcl
Quiz 9
file: examples/quiz9.tcl
proc cell_count {args} {
return [llength $args]
}

set cells [list and2 or2 xor2 inv]


puts "Number of cells: [cell_count $cells]"

• What is the number printed by puts ?


(a) none (empty string)
(b) 0
(c) 1
(d) 4
(e) 5
(f) this will generate a syntax error!

Answer
TCL Scripting for SoC Design

Appendix B:
Binary Files and Strings
Aims and Topics
• Aim
— Learn about handling binary data using
TCL

• Topics
— Reading and writing binary files
— Binary strings
Reading and Writing Binary Files
• When accessing binary files, the automatic end-of-line
conversion must be switched off!
file: examples/bitstream.tcl
set
set fid
fid [open
[open "bitstream.bit"
"bitstream.bit" r]
r] change the translation
fconfigure
fconfigure $fid
$fid -translation
-translation binary
binary mode for $fid channel to
BINARY (i.e. no newline
set
set bitstream
bitstream [read
[read $fid]
$fid] conversion)
binary
binary scan $bitstream H*
scan $bitstream H* bitstream
bitstream
close
close $fid
$fid
• Use fconfigure to change properties 10 1 1 0
of an open channel 1 0 1
1 1 10
— Automatic end-of-line conversion 1 0
0
— End-of-file character 1
0
— Channel blocking and buffering
⇒ Channel properties can be changed
at ANY TIME during channel access

When accessing binary files in TCL, it is important to remember to switch off


the default automatic end-of-line translation.
Binary Strings
• Binary strings can hold characters of ANY value
— Similar to “normal” TCL strings
— Some string commands don’t work with binary strings
— Use backslash substitution to specify binary values or ...

remember me?
%% set
set binary_data
binary_data "\x03\x04\x05"
"\x03\x04\x05"
♥♦♣
ε φχ
output will vary depending on the terminal & platform

Binary strings can be manipulated in the same way as “usual” text strings, i.e. they
can be constructed using substitution or using the append command and
compared using ==.
However, only the following string commands are guaranteed to work with binary
strings:
string index, string range, string length
It is therefore sometimes desirable to convert binary strings into normal
TCL strings.
Converting Binary Strings
• ... use the binary TCL command to convert binary
values to/from their equivalent string representation

string → binary conversion %% set


set binary_data [binary format
binary_data [binary format H*
H* "030405"]
"030405"]
♥♦♣
ε φχ
binary → string conversion %% binary
binary scan "\x03\x04\x05" H*
scan "\x03\x04\x05" H* hex_data
hex_data
11
returns the number %% set
set hex_data
hex_data hex conversion specifier
of conversions performed 030405
030405 (high-to-low order)

binary command can be used to convert binary strings into a variety of text
strings.
binary format syntax:

binary format formatString ?arg arg ...?


The Power of binary
• binary command simplifies manipulation of binary values
— Converts binary values to different ASCII formats
• character, string, decimal, hexadecimal, octal, bit
— Converts between different representations of binary values
• little ↔ big endian

• Generic to_bits (LAB 1) using binary


32-bit integer conversion specifier
(big endian order)
file: examples/to_bits.tcl

proc
proc to_bits
to_bits {num}
{num} {{
binary scan [binary format
binary scan [binary format II $num]
$num] B*
B* bits
bits
return
return [string
[string trimleft
trimleft $bits
$bits 0]
0]
}}
trims away unnecessary leading bit conversion specifier
O’s (high-to-low order)

binary scan syntax

binary scan string formatString ?varName varName ...?

Use hexdump (provided in examples/hexdump.tcl) to visualize the contents of a


binary string.
TCL Scripting for SoC Design

Appendix C:
Client-Server Applications
and Networking
Aims and Topics
• Aim
— Expand the knowledge of TCL multi-process communication to
include client-server and networking applications

• Topics
— Client-server applications
— Safe interpreters
— Simple networking
Multi-Process Communication
CLIENT SERVER

commands
HHDDLL H
Haarrddw
waarree
SSimmuulaatoorr results tteessttrrigg

external program
(can be another TCL read/write mode (bi-directional communication)
script!)
%% set
set fid [open "|
fid [open test_rig" r+]
"| test_rig" r+] IMPORTANT: set-up LINE buffering
file24 (FULL buffering is the default for files)
file24
%% fconfigure
fconfigure $fid -buffering line
$fid -buffering line
%% puts $fid "test1 100"
puts $fid "test1 100"
%% gets
gets $fid
$fid
test1:
test1: 1000
1000 H
Haarrddw
waarree
%% puts
puts $fid
$fid "test2
"test2 200"
200" tteessttrrigg
%% gets
gets $fid
$fid
test2:
test2: 400
400
%% close
close $fid
$fid

The above is the example of SYNCHRONOUS communication, i.e. the client


application always waits for the response from the server before proceeding
further.
TCL can be also used to build ASYNCHRONOUS communication channels,
which are typically used in servers and GUI applications.
Server Application in TCL
file: examples/test_rig.tcl
while
while {[gets
{[gets stdin
stdin line]
line] >=
>= 0}
0} {{
set
set cmd [lindex $line 0]; set
cmd [lindex $line 0]; set data
data [lindex
[lindex $line$line 1] 1]
switch
switch --
-- $cmd
$cmd {{
command-line parsing
test1
test1 {{
## perform
perform test1
test1 test1 procedure goes here
set result [expr $data *
set result [expr $data * 10] 10]
puts
puts "test1:
"test1: $result"
$result"
}}
test2
test2 {{
## perform
perform test2
test2 test2 procedure goes here
set
set result
result [expr
[expr $data
$data ** 2]
2]
puts "test2: $result"
puts "test2: $result"
}}
default
default {{
puts
puts "Error:
"Error: unrecognized
unrecognized command"
command"
}}
}} Always handle unrecognized
input to avoid server locking.
}}

Notice that in the above example a considerable amount of TCL code is used to
parse server commands. In order to improve efficiency, it would be better to define
all server commands as TCL commands and then use TCL parsing and error
checking capabilities.
Using TCL as a Command Parser
file: examples/test_rig2.tcl

proc test1
proc test1 {data}
{data} {{
## perform Use TCL interpreter to parse
perform test1
test1 commands to improve efficiency
set
set result [expr
result [expr $data
$data ** 10]
10]
return "test1: $result"
return "test1: $result"
}}
proc test2
proc test2 {data}
{data} {{
## perform
perform test2
test2
set
set result
result [expr
[expr $data
$data ** 2]
2] catch will evaluate the
return
return "test2:
"test2: $result"
$result" TCL script in $line and
}} store its
result in result. Returns 0 on
success, 1 otherwise.

while
while {[gets
{[gets stdin
stdin line]
line] >=
>= 0}
0} {{
if
if {[catch $line result] !=
{[catch $line result] != 0}
0} {{
puts "Error: $result"
puts "Error: $result"
}} else
else {{
puts
puts $result
$result there is no need to change the
}} server's parsing code when new
commands are added
}}

catch syntax catch script ?varName?


But How Safe is your TCL Interpreter?

cd ~; file delete -force .

C
CLLIIEEN
NTT SSEERRVVEERR

• SAFE TCL interpreters provide protection against


harmful scripts
— Create safe interpreters using the interp command

%% interp mmaainin
interp create
create -safe
-safe safe_parser
safe_parser TTcclininteerrpprreeteerr
safe_parser
safe_parser $script
%% safe_parser
safe_parser eval
eval $script
$script
...
... safe_parser
TTcclininteerrpprreeteerr
hides all “dangerous” commands

interp create syntax interp create ?-safe? ?--? ?path?

slave eval syntax slave eval arg ?arg?

When attempting to invoke a “dangerous” TCL command (e.g. exec, file, open)
in a safe interpreter, the command is simply not recognized and the interpreter
will return an error.
It is always a good idea to examine TCL scripts you receive from your friends
and colleagues by running them in a safe TCL interpreter. You can use
check_script command from examples/check_script.tcl to do this for you.

%% source
source examples/check_script.tcl
examples/check_script.tcl
%% check_script
check_script unknown_script.tcl
unknown_script.tcl
invalid
invalid command
command name
name "file"
"file"
Safe Server Command Parser
file: examples/test_rig_safe.tcl
proc
proc test1
test1 {data}
{data} {{
... When receiving TCL commands
... from another process or machine,
}} always use SAFE interpreters
proc
proc test2
test2 {data}
{data} {{
...
...
}}

interp
interp create
create -safe
-safe safe_parser
safe_parser
safe_parser
safe_parser alias test1
alias test1 test1
test1
safe_parser alias test2 test2
safe_parser alias test2 test2

while
while {[gets
{[gets stdin
stdin line]
line] >=
>= 0}
0} {{
if {[catch {safe_parser
if {[catch {safe_parser eval
eval $line}
$line} result]
result] !=
!= 0}
0} {{
puts "Error: $result"
puts "Error: $result"
}} else
else {{
puts
puts $result
$result
}}
}}

slave alias syntax

slave alias srcCmd targetCmd ?arg ...?


Introduction to TCP IP Networking

computer's unique IP address

129.14.234.2 10.140.131.21
ports

80
33
80
8111

33 8111

unique
port number
More on Networking
• Port numbers
— < 1024 are reserved
— Other ports are available, but could be used by other applications
(e.g. SoC Design license servers)
— Port numbers between 8100-9999 are usually OK

• Typical uses of TCL networking in EDA


— Remote design testing and prototyping
— Co-simulation and co-prototyping
— EDA tool servers, priority-based job queuing
— Interaction with Web servers (with http TCL package)
Client-Server Networking in TCL
• Networking connections are similar to bi-directional pipes
• Setting-up client/server networking
— Use socket to create network connections (server & client)
TCL procedure to be invoked for each client connection

SERVER: socket
socket -server server_accept 8111
-server server_accept 8111 port numbers
CLIENT: set
set ch_id
ch_id [socket $host 8111]
[socket $host 8111]
hostname or IP address of the destination server

— Use fileevent to bind TCL commands to network channel


events
(server & client) channel condition
TCL procedure to be invoked each time
there is something to be READ from
$ch_id
fileevent
fileevent $ch_id
$ch_id readable
readable "server_handle
"server_handle $ch_id"
$ch_id"

— Use vwait enter-mainloop to start the server (server only)


enter an indefinite loop
vwait
vwait enter-mainloop
enter-mainloop (process events until the value of a non-existent
variable enter-mainloop is changed)

Syntax for the commands above:

socket ?-sever? command ?options? port

socket ?options? host port

fileevent channelId readable ?script?

fileevent channelId writable ?script?

vwait varName
Example: A Networked Server
file: examples/test_rig_net.tcl
...
...
interp
interp create
create -safe
-safe safe_parser
safe_parser
...
...

invoked each time a client connects


proc server_accept
proc server_accept {ch_id
{ch_id addr
addr port}
port} {{ to the server
fileevent $ch_id readable "server_handle
fileevent $ch_id readable "server_handle $ch_id" $ch_id"
fconfigure
fconfigure $ch_id
$ch_id -buffering
-buffering line
line
}}
proc server_handle
proc server_handle {ch_id}
{ch_id} {{ invoked when there is something
if
if {[gets
{[gets $ch_id
$ch_id line]
line] << 0}
0} {{ to be read from the channel
close
close $ch_id
$ch_id
}} else
else {{
if
if {[catch
{[catch {safe_parser
{safe_parser eval
eval $line}
$line} result]
result] !=
!= 0}
0} {{
puts $ch_id "Error: $result"
puts $ch_id "Error: $result"
}} else
else {{
puts
puts $ch_id
$ch_id $result
$result
}}
}}
}} start the server to listen
on port 8111
socket -server server_accept
socket -server server_accept 8111
8111
vwait vwait enter-mainloop
enter-mainloop enter an indefinite loop
TCL Shell as a Networked Client
• Very similar to using bi-directional pipes
open a network connection to the
%% set
set ch_id [socket 127.0.0.1
ch_id [socket 127.0.0.1 8111]
8111] server with IP address 127.0.0.1
sock148
sock148 at port number 8111
%% fconfigure
fconfigure $ch_id -buffering line
$ch_id -buffering line
%% puts
puts $ch_id "test1 100"
$ch_id "test1 100"
%% gets
gets $ch_id
$ch_id
test1:
test1: 1000
1000
%% puts
puts $ch_id
$ch_id "test2
"test2 200"
200"
%% gets $ch_id
gets $ch_id
test2:
test2: 400
400

• TCP/IP server can be tested using any telnet client


— Easy to test & maintain
— Easy to provide various server front-ends
TCL Scripting for SoC Design

Appendix D:
Interacting with
Command-Line Programs
Aims and Topics
• Aim
– To learn about using Expect for as a tool for communicating between
interactive command-line programs and a TCL interpreter

• Topics
– What is Expect?
– Simple communication with an interactive program
– Handling errors and loops
– Regular expressions with Expect
– Expect in SoC Design scripting
What is the Problem?
• Some useful tools exists only as interactive
command-line programs
– Limited command set (e.g. no loops or conditionals)
– Require user input
– Difficult to use for repetitive jobs

• Ever tried using command-line ftp or telnet?


Expect
• Automates tasks normally performed
through a terminal TCL
– Removes blocking and buffering problems script
by emulating an interactive user session

• Provides TCL scripting to non-TCL


tools
– Networking, hardware testing, software
and machine administration, etc.

EExxppeecct
Example: FTP session

expect this type this

expect this secret password type this

expect this type this


Talking to an FTP client with Expect
file: examples/any_ftp.tcl

if
if {[llength
{[llength $argv]
$argv] << 1}
1} {{
puts
puts stderr
stderr "Usage:
"Usage: expect
expect any_ftp.tcl
any_ftp.tcl <hostname>"
<hostname>"
}}
set
set host
host [lindex
[lindex $argv
$argv 0]
0]

exp_spawn
exp_spawn ftp
ftp $host
$host start an ftp client, but redirect its
I/O through expect

expect
expect "Name"
"Name"
exp_send
exp_send "anonymous\r"
"anonymous\r"
use \r to simulate a raw carriage
return
expect
expect "Password:"
"Password:"
exp_send
exp_send "secret
"secret password\r"
password\r"
expect "ftp>"
expect "ftp>"
exp_send "cd pub\r"
exp_send "cd pub\r"
expect "ftp>"
expect "ftp>"
exp_interact let user interact with the ftp client
exp_interact at this point
Handling Errors
file: examples/any_ftp2.tcl

...
...
set
set host
host [lindex
[lindex $argv
$argv 0]
0]
set timeout 10
set timeout 10 controls how long expect waits for
a match (in seconds)

exp_spawn
exp_spawn ftp
ftp $host
$host

expect
expect {{
"Name"
"Name" {exp_send
{exp_send "anonymous\r"}
"anonymous\r"}
if matches this... ...then do this

"unknown host"
"unknown host" {return
{return 0}
0}
if matches this... ...then do this

timeout {return
timeout {return 0}
0}
no match ...then do this
after 10 seconds?
}
}
...
...
Example: Changing Password Remotely

expect this type this

expect this secret old password type this


expect this secret new password type this
secret new password type this
expect this
expect this
Regular Expressions in Expect
file: examples/rpasswd.tcl
proc
proc change_remote_passwd
change_remote_passwd {machine
{machine user
user old_pass
old_pass new_pass}
new_pass} {{
...
...
set
set prompt
prompt "\#|\\\$|%|>"
"\#|\\\$|%|>"
>
matches any of these
% prompt characters

expect
expect {{ $
-re $prompt {exp_send "passwd\r"} start up UNIX
-re $prompt {exp_send "passwd\r"}
#
passwd program

treat $prompt as a regular expression

timeout {return 0}
timeout {return 0}
}
}
expect {
expect {
"assword:" {exp_send "$old_pass\r"} type in the old password
"assword:" {exp_send "$old_pass\r"}
timeout {return 0}
timeout {return 0}
}
}
...
...
Looping in Expect
file: examples/rpasswd.tcl

proc
proc change_remote_passwd
change_remote_passwd {machine
{machine user
user old_pass
old_pass new_pass}
new_pass} {{
...
...
set
set times
times 00
expect
expect {{
"new
"new \[Pp\]assword:"
\[Pp\]assword:" {{
glob-style search pattern
incr
incr times
times
if {$times >> 2}
if {$times 2} {{
return
return 00
}}
exp_send
exp_send "$new_pass\r"
"$new_pass\r" type in new password TWICE

exp_continue
exp_continue repeat the pattern search
}}
"tokens
"tokens updated
updated successfully\r\n"
successfully\r\n" {return
{return 1}
1} success!
timeout {return 0}
timeout {return 0}
}}
}}
Expect in SoC Design Scripting
• Many SoC Design tools and utilities are command-line
driven
– HDL simulation
– HDL synthesis
– Placement & routing
– Generation & customization of IP cores
– File format conversion, back-annotation, etc.
– Programs for driving test beds, prototyping boards, etc.

• With Expect is it easy to integrate all these tools


– Integrate design & test flows
– Combine SoC Design tools with standard OS utilities (networking,
system monitoring, backup, job management, etc.)
LAB 6: Interaction with a Synthesis Server
• Write a procedure submit_synthesis_job which will FTP the
design file design.vhdl and its synthesis script
design_synthesis.tcl to a server, directory ~/incoming.

• Stage 1
– Choose an FTP server on your local network to which you have access
(localhost will do) and:
• Create directories ~/incoming and ~/results
• Start examples/synth_server on this server
– Test the operation of the FTP client first by hand
• Upload the design files using
ftp> put design_*
• Collect any useful messages you EXPECT
– Write an Expect TCL script for this job
LAB 6: Interaction with a Synth. Server (2)
• Stage 2
— Check in 60-second intervals whether the ~/results directory contains
design_results.log. Once present, download all design_* files from
the /results directory.
• Check for design_results.log using
ftp> get design_results.log
• Use after 60000 to delay script execution for 60 seconds
— After the files were received, start-up an editor with received
design_results.log
— Send user an e-mail message that the job was completed
Index
Note: the course is structured such that information on a particular construct is usually
spread over several consecutive pages. Where this occurs, only the first page of the set is
listed in this index

args, ll-9, ll- lO


Symbols argv, ll- 5 argvO,
"" quotes ll- 5 array, 6-l7
grouping, 2-5, 3-l4 multi-dimensional, 6-2O, 6-22
use of, 3-l5 versus list, 6-23
$ dollar array exists, 6-2l
variable substitution, 2 - ll array get, 6-l9
& ampersand array names, 6-2l
process, 7-l9 array set, 6-l9, 6-22
() parentheses array size, 6-2l
expressions, 3-5 auto_noexec, 7-l5
math functions, 3-7 auto_path
regular expression, 8-8, 8-9 package, ll- l 7
* asterisk
regular expression, 8-5
/ slash B
directory separator, 3-l2 backslash
[] brackets substitution, 2-l3
command substitution, 2-l6 binary, l2-5
grouping, 2-l8 file, l2-3
regular expression, 8-5 string, l2-4
\ backslash bit-wise
\b backspace, 2-l4 operators, 3-5
\n newline, 2-l4, 7-l2 break, 4-3, 4-l4, 4-l5
regular expression, 8-9 buffering, 7-l3
special characters, 2-l4 process, 7-2O, l3-3
substitution, 2-l3
{} braces C
grouping, 2-5, 3-l4
if, 4-l6 catch, 7-5, l3-5
use of, 3-l5 cd, 3-l2
| pipe channel
process, 7-l9 buffering, 7-l3
regular expression, 8-8, 8-9 identifier, 7-4
characters
special, 2-l4
A client-server, l3-lO
after, l l - l 4 clock, ll- l 3
append, 5-4 close, 7-4
argc, ll- 5 command
evaluation, 2-9, 2-l9, 2-2O flush, 7-l4
substitution, 2-l6 for, 4-3, 4-lO, 4-ll, 4-l5
comparison foreach, 4-3, 4-ll, 4-l2, 4-l5
operators, 3-5 format
concat, 6-8 clock, ll- l 3
continue, 4-3, 4-l4, 4-l5 string, 5-lO
functions
D mathematical, 3-7
decrement, 3-8
default, 4-7 G
gets, 7-8
E glob, 3-l2, 5-7, 7-l6, 7-l7
else, 4-5, 4-6 lsearch, 6-l2, 6-l3
elseif, 4-6 switch, 4-8
end of file (eof), 7 - ll global variable, 3-ll, l l - l l
env, ll- 7 grouping
eof, 7 - ll "", 2-5, 3-l4
error, l l - l 2 [], 2-l8
eval, 7-l6, 7-l7 {}, 2-5, 3-l4
exact use of "" and {}, 3-l5
lsearch, 6-l2, 6-l3
switch, 4-8 I
exec, 7-l5, 7-l6, 7-l7 if, 4-3, 4-4, 4-5, 4-6, 4-l5
exp_interact, l4-6 incr, 3-8
exp_send, l4-6 increment, 3-8
exp_spawn, l4-6 index file
expect, l4-4, l4-6, l4 - l l package, ll- l 7
loop, l4-lO indices
regular expressions, l4-9 regular expression, 8-l2
expr, 3-4 info, l- l l , 9-4
expression interp, l3-6
regular, 8-3 interpretation, 2-4, 3-l3

F J
fconfigure, 7-l4, 7-2O, l2-3, l3-3 join, 6 - ll
file
binary, l2-3 L
command, 7-3 lappend, 6-7
descriptor, 7-4 lindex, 6-4
id, 7-4 linsert, 6-9
pointer, 7-7 list, 6-3, 6-6
portability, 7-l2 nested, 6-5
read, 7-8, 7-lO reversal, 6-lO
translation, l2-3 summary, 6-l6
write, 7-6 versus array, 6-23
fileevent, l3-lO
llength, 6-4 read, 7-lO
logical real numbers, 3-4
operators, 3-5 redirection, 7-l8
lrange, 6-4 regexp, 8-6, 8-l7
lreplace, 6-9 indices, 8-l2
lsearch, 6-l2, 6-l3 lsearch, 6-l2, 6-l3
lsort, 6-l4, 6-l5 nocase, 8-6
switch, 4-8
M regsub, 8-l5, 8-l7
regular expression, 8-3
mathematical
sub-expression, 8-lO
functions, 3-7
regular expressions
operators, 3-3, 3-5
expect, l4-9
N require
package, ll- l 7
networking, l3-8 resources, lO-5
newline, 2-l4, 7-l2 result, 7-5
nonewline, 7-6
S
O
safe interpreter, l3-6
open, 7-4, 7-l9, 7-2O,l3-3 scan
operators, 3-5 clock, ll- l 3
bit-wise, 3-5 string, 5 - ll
comparison, 3-5 script, l-8, l-9
logical, 3-5 scripts, ll- 3
mathematical, 3-3 seconds, l l - l 3
Seek, 7-7
P set, 2-7, 5-4
package, ll- l 7 shift
pid, 7-l9 operators, 3-5
pipe, 7-l8 socket, l3-lO
pipe |, 7-l9 split, 6 - ll
precision, 3-9 stderr, 7-6
procedure, ll- 8 stdin, 7-6
arguments, ll-9 , ll- lO stdout, 7-6
procedures, 3-lO string, 5-3
process, 7-l9 binary, l2-4
communication, 7-2O, l3-3 formatting, 5-lO
provide scanning, 5 - ll
package, ll- l 7 string compare, 5-5, 5-9
puts, 2-5 string first, 5-l2
write to file, 7-6 string index, 5-l2
pwd, 3-l2 string last, 5-l2
string length, 5-l2
R string match, 5-6, 5-9
string range, 5-l2
random numbers, 3-8
string tolower, 5-8 U
string toupper, 5-8
unset, 2-7
string trim, 5-8
upvar, l l - l l
substitution, 2-9, 2-lO, 2-l2, 2-l7
backslash, 2-l3 V
command, 2-l6
variable, 2 - ll variable, 2-7
switch, 4-9 environmental, ll- 7
switch, 4-3, 4-7, 4-l5 global, 3-ll, l l - l l
multiple pattern match, 4-8 name, 2-8
options, 4-8 substitution, 2 - ll
variable substitution, 4-9 switch, 4-9
upvar, l l - l l
T value, 2-8
vwait, ll- l4 , l3-lO
tcl_platform, ll- 6
tcl_precision, 3-9 W
tcp/ip, l3-8
time, l l - l 5 while, 4-3, 4-l3, 4-l5
TK, lO-4
TCL Scripting for SoC Design

TCL Lab Exercises and Case


Studies
Contents
INTRODUCTION 1
Tool Specific Information 1
Conventions 2
Icons 2
Overview of Labs 3
Lab Summary 3

LAB 1 —GENERIC TCL, SYNTHESIS REPORT FILE PARSING 4


Looking at the script design 5
Modifying the get_message procedure 5

LAB 2 —GENERIC TCL, TEST HARNESS BUILDER 6


Looking at the script design 9
Adding the ‘findPorts’ procedure 9
Modifying the ‘entity’ pattern 10

LAB 3 —MODELSIM DYNAMIC POWER ESTIMATION 11


Looking at the script design 14
Adding the ‘monitorSingnals’ procedure 15
Optional 15

LAB 3 —LEONARDO MULTI-PASS SYNTHESIS 16


Looking at the script design 20
Completing the procedures 21

LAB 4 —SYNPLIFY MULTI-PASS SYNTHESIS 22


Looking at the script design 25
Completing the procedures 26
Imtroductiom

These lab exercises are designed to make you more familiar with TCL scripting
by using it in some typical SoC Design scripting situations. They are organixed
in a way that takes you step by step through what to do first, and then let you
alter the code to achieve the desired functionality.

Tool Specific Imformatiom

The Lab exercises are designed to suit individual requirements. A number of


SoC Design tools are proposed with corresponding Labs. You can choose
which tool you want to use when you attend a TCL Workshop. Alternatively
you can choose to work on one of the SoC Design tool-independent Labs. The
later Labs will illustrate the powers of TCL for file/data processing.
Conventions

Gertain conventions are followed in the exercises, that are worth mentioning
before you start.

Icoms

Each exercise starts on a new page and is divided into separate clear sections
using icons:

5oals The aims of the exercise.

Explains the function of the


Scemario
script to be created.

Discusses specific TCL language


Backgroumd Imfo issues that you will need to
understand to write the model.

Explains how to go about writing


Recommemdatioms the procedures in terms of
arguments, types, etc. Read these
before you move on to.....

This is what you actually do!!


Actiom

Two additional symbols are used i Additional information


within the main text, to represent: ? A question to be answered.
Overview of Labs

The labs are not in any specific sequence. Choose a specific lab according to
your requirements. If time permits, you are welcomed to experiment with any
of the other labs presented in this lab book.

The labs will involve, understanding of the supplied code and the addition of
new functionalities to the existing code. The data structure as well as the
subprograms’ functionality will be explained inside the ‘background info’ and
‘recommendation’ sections of each individual lab.

Lab Summary

Lab 1 : 5emeric TCL, synthesis report file parsimg - an example of the use
of TCL to parse a simple report file and log the error, warning and note
messages.

Lab 2 : 5emeric TCL, test karmess builder - automatically creating a VHDL


test harness template from a top level design.

Lab 3 : ModelSim, dymamic power estimatiom - performing an analysis of


internal signal toggle count during a simulation.

Lab 4 : Leomardo Spectrum - executing a multi-pass synthesis

Lab 5 : Symplify - executing a multi-pass synthesis


Lab 1 – Generic TCL, synthesis report file parsimg

Goals

The goals of the lab exercise are to familiarixe yourself with a typical example
file parsing and information gathering. This example uses a Synplify ‘.srr’ file
however this example can be extended to any synthesis tool with a limited
amount of alterations.

Scenario

Commonly, SoC Design tools generate lengthy ASCII report files summarixing
their activity. Although the created reports are very thorough, the amount of
information available is often overwhelming for the human eye. As a result, the
user at times overlooks important messages.

The proposed lab example consists in creating a procedure that will be used to
extract specific information from a report file and display them on the screen.

message_type

standard output
get_message

file_name

The output value is displayed on the screen (standard output). Alternatively,


the output strings can be directed to a result file.
Recommendations

Data types:
- message_type : (string) notes, warnings, errors
- file_name : (string) filtercore.srr
- standard output : (string)

‘Notes’ patterm sample:


@N:"thresh_mux.vhd":106:15:106:26|Removed redundant assignment

‘Warmimgs’ patterm sample:


@W:"nsmask.vhd":31:11:31:19|Input middle_in is unused

‘Errors’ patterm sample:


@E:"nsmask.vhd":31:11:31:19|Expecting <=

Procedure usage: get_message filtercore.srr warnings

Action

Lookimg at the script desigm


❏Files Locatiom: the lab files will are stored in the following directories:

Workstation Users:
<install_path>/tclscript/labs/generictcl

PC Users:
<install_path>\tclscript\labs\generictcl

Your trainer will tell you the location of the lab files installation
<install_path>

❏We will work on the file warnings_errors.tcl. Take a look at the file's
contents using a text editor. Check with your instructor to see which text
editors are available, or use your favorite editor.

Modifying the get_message procedure

❏Complete the ‘get_message’ procedure and test it on the ‘filtercore.srr’


synthesis report file.

❏Add to the ‘get_message’ procedure a routine that will prevent the same
message to be printed more than once.
Lab 2 – Generic TCL, test karmess builder

Goals

The goal of this exercise is to become familiar with how to create complex
parsing patterns for language processing. This example uses a VHDL design as
a source. Once the principles of language processing are understood, the same
techniques can be used for a variety of other languages such as Verilog, EDIF,
and HTML.

No prior knowledge of the VHDL language is required for this lab.

Scenario

Hardware programming languages like VHDL or Verilog require the creation of


test harnesses for the verification of specific designs. The designer usually
creates those test harnesses manually. However, in most cases a large part of
the creation process of a test harness can be automated by gathering
information contained inside the design to be tested.

The proposed lab example consists in improving an existing script to extend its
semantics coverage and the creation of a procedure used to find the ports of a
given design. The general structure of the script is as follows:

(ports)
findPorts
(line)

(entity)
status vhdlDesign
createTb

(entity)
(line)
(ports)
(line)
findEntity buildTestBench

filtercore.vhd

Procedure call :

Data transfer :
t_filtercore.vhd
The ‘createTb’ procedure is the top-level procedure. It implements a state
machine that directs the text line ($line) read from the input file to ether the
procedure ‘findEntity’ or the procedure ‘findPorts’ according to the state, the
state machine is in. The variable ‘status’ is the state variable. The values held
in the variable ‘status’ can be : ‘entity’ ‘ports’ ‘finish’.

The procedure ‘findEntity’, searches the ‘line’ variable for the entity name of the
design. Once the name has been found, it is stored in the variable
‘vhdlDesign(entity)’.

The procedure ‘findPorts’ searches the line variable for ports patterns. Once
ports have been identified, the procedure append the variable list
‘vhdlDesign(ports)’ with the following information: name, direction and type of
the port . For more information, see the ‘Data structure’ topic in the
‘Recommendations’ section.

The procedure ‘buildTestBench’ simply creates the output file from the
information gathered inside the ‘vhdlDesign’ variable. You are welcomed to look
at this procedure although, you will not be asked to do any work on it.

Recommemdatioms
Data structures:
The main data structure used in this script is called: ‘vhdlDesign’. This variable
is used to hold the name of the entity declared in the original design file
(filtercore.vhd) as well as the port details. The following diagram represents
how the design information is stored inside the vhdlDesign variable.

# Variable declaration
global vhdlDesign
set vhdlDesign(entity) {}
set vhdlDesign(ports) {}

# Variable assignment
set vhdlDesign(entity) “decoder”
lappend vhdlDesign(ports) “a in integer”
lappend vhdlDesign(ports) “b out bit”

vhdlDesign

(entity) decoder
entity decoder is
port (a : in integer;
(ports) a in integer
b : out bit);
end decoder;

b out bit
VHDL Tokems:
Tokens are commonly used in scanners/parsers to facilitate the building of
complex regular expressions. Here are the tokens defined for this TCL script:
set separator {\s}
set nameIdentifier {[a-z][_a-z0-9]*}
set typeIdentifier {[a-z][a-z0-9_ ]*(\([a-z0-9_ ]*\))*}
set portMode "in|out|inout|buffer"

VHDL 5rammar:
The grammar part of a scanner/parser is used to define a valid set of token
sequences. This is used in regular expressions to extract specific information
from code. Here are the grammar rules defined in the TCL script.

set portPattern
"($nameIdentifier)$separator*:$separator*
($portMode)+$separator+($typeIdentifier)"

This pattern is used to match VHDL port declarations such as :


clk4 : IN STD_LOGIC;
edge_fs : OUT STD_LOGIC;
fs : IN STD_LOGIC;
ack : OUT STD_LOGIC;
enable : IN STD_LOGIC;
wr_nrd : IN STD_LOGIC;
edge : OUT STD_LOGIC;
coef : IN bit_vector(14 downto 0)

Other patterns used in this script are used to detect entity declarations such as:

set entityHead
"^$separator*entity$separator+
($nameIdentifier)$separator+is"

set entityEnd1 "$separator+$nameIdentifier"


set entityEnd "^$separator*end($entityEnd1)?$separator*;"

These patterns will respectively match the following declarations:

entityHead

entityEnd
Actiom

Lookimg at the script desigm


❏Files Locatiom: the lab files will are stored in the following directories:

Workstation Users:
<install_path>/tclscript/labs/generictcl

PC Users:
<install_path>\tclscript\labs\generictcl

Your trainer will tell you the location of the lab files installation
<install_path>

❏We will work on the file testbench.tcl. Take a look at the file's
contents using a text editor. Check with your instructor to see which text
editors are available, or use your favorite editor.

❏Familiarixe yourself with the script. Before modifying the script, you can
execute it to see what it does (look at the generated ‘t_filtercore.vhd’).

Adding the ‘fimdPorts’ procedure

❏The first part of this lab consists in adding a procedure called ‘findPorts’
that will be used to store the ports information inside the variable
‘vhdlDesign’. The following diagram represents the data flow for that
function:

(line) (ports)
findPorts vhdlDesign

status

The ‘line’ variable is passed from the procedure ‘createTb’. Its value is a
text line (ASCII) extracted from input file currently processed
(filtercore.vhd).
In this procedure you will have to process the ‘line’ to define if it is a port
declaration or not. If so, you will have to store the ports information inside
the variable ‘vhdlDesign’. The processing information has been described
in the recommendation section.

The second operation performed by the ‘findPorts’ procedure is to set the


value of the ‘status’ variable to: ‘finish’ when it detects the end of the
entity declaration such as:

...
ls : IN STD_LOGIC; portPattern
reset : IN STD_LOGIC;
);
entityEnd
END filtercore;

By setting the value of ‘status’ to ‘finish’, this will force the state machine
implemented inside the procedure ‘createTb’ to stop.

❏One you have made the modifications, run the script and observe the
differences in the resut file ‘t_filtercore.vhd’.

Modifying the ‘emtity’ patterm

❏Although the current ‘entityEnd’ pattern works with the current example,
this grammar can only match two type of entity ending:

‘END;' Or ‘END filtercore;'

The VHDL language reference manual defines that an entity ending can
also be of the following form:

‘END ENTITY;' Or ‘END ENTITY filtercore;'

❏ Modify the ‘entityEnd’ pattern to include those two extra kinds of endings.

❏Modify the ‘filtercore’ entity ending inside the ‘filtercore.vhd’ file to be:
‘END ENTITY;’ or END ENTITY filtercore;’ and validate your new
script.

... ...
ls : IN STD_LOGIC; ls : IN STD_LOGIC;
reset : IN STD_LOGIC; reset : IN STD_LOGIC;
); );
END filtercore; END ENTITY filtercore;
Lab 3 – ModelSim Dymamic Power Estimatiom

Goals

The goal of this exercise is to become familiar with some of the features of
ModelSim’s API. This example is based on a VHDL simulation; this script will
be used to log signal activity during a simulation and report the results of its
analysis.

No prior knowledge of the VHDL language is required for this lab.

Scenario

A large number of current ASIC/FPGA designs require careful considerations of


power consumption aspects. Although a number of specialized SoC Design tools
are available for dynamic and static power analysis, a simple script run during
simulation can already indicate what are the critical areas of a design. This
estimation is based on the principles of CMOS transistors consumption. The
theory tells us that CMOS based circuit only consume energy during a charge
transfer; in other words during a change of state.

The proposed lab example consists in creating a procedure that will be used to
monitor signals activity at a given hierarchical level of the design during a
simulation. Once the simulation is over the script will display the results using
a graph.

The procedure ‘monitorSignal’ is the top level procedure. It is called with an


argument ‘hierarchy’ that indicates the hierarchy level you want to monitor
inside the design. The procedure ‘monitorSignal’ will extract all the signal
names contained at the specified hierarchical level using the ‘find’ API
command. Once the signal names have been extracted, the procedure will
create an array of counters ‘expendedList’ that will be used to record all the
signals toggle activity. Lastly the procedure will set an individual ‘when’
command for each of the signals encountered at the specified hierarchical level.
This ‘when command is used to record all the signals toggle activity
(concurrently).

The procedure ‘reportSignals’ is used to query the variable ‘expendedList’ and


display the ten most toggled signals.

The following diagram illustrates the script’s architecture:


(hierarchy)

monitorSignals

(signal)
signalList signalType

(hierarchy)

find describe

when
expendedList

(maxValue)
(mostLeast)

reportSignals

sortedList (toggled ignal) resultList


s

result.txt graph.tcl

Procedure call :

Data transfer :

API Procedure :
API
Recommemdatioms

ModelSim’s API:
ModelSim features a large amount of TCL API commands described in
detail in the simulator’s documentation. This script will only feature a few
of those to give you a feel for what you can achieve with scripting.

This is the list of ModelSim commands used in this lab:

- fimd : This command is used to find objects in the design


o ‘find signal <path>/*’ will return a list of all the
signals at the specified level of hierarchy.
o ‘find signal –r /*’ will extract all the signals of the
design, recursively.
o ‘find nets –in /top/clk*’ will extract all the input
signals at the ‘top’ level starting with a ‘clk’.

- wkem : Allows to perform commands when a specific condition is


met.
o ‘when { result = “1100”} {puts “error”}’ prints
the message ‘error’ when the value of result reaches
“1100”.
o ‘when {clk'event} {incr a}' increases the value
of ‘a' when the signal ‘clk’ has had an event.

- mowkem : This command disable when commands.


o ‘nowhen *’ disables all whens
o ‘nowhen xxx’ disable the ‘when’ labeled xxx

- discribe : Displays information about a specific VHDL item.


o ‘describe clk’ will return the string:

Enum: ('U','X','0','1','Z','W','L','H','-')

When clk is of a std_logic type.

o ‘desicribe dataio' will return :

Array(15 downto 0) of
Enum: ('U','X','0','1','Z','W','L','H','-')

When dataio is of a std_logic_vector(15 downto 0) type;

Data types:
- signalList : (list of strings) signal names.
- signalType : (string) type information of a signal (see previous
section ‘describe’ command).
- expendedList : (array) Signal names are used as indexes whilst
the toggle amount is the value.
- resultList: (list of ‘toggle value/ signal’ name pair) a list version of
the values contained in the variable ‘expendedList’.
- sortedList : numerically sorted version of the variable ‘resultList’.

ExpendedList()

(a) 0
signal a : integer := 0;
signal b : std_logic := ‘0'; (b) 0
signal c : Boolean := false;
(c) 0

counter

Activity on signal ‘a’ results in an increase of its toggle count.

ExpendedList()

wait for 10 ns; (a) 1


a <= not a;
wait; incr expendedList(a)
(b) 0

(c) 0

Actiom

Lookimg at the script desigm


❏Files Locatiom: the lab files will are stored in the following directories:

Workstation Users:
<install_path>/tclscript/labs/modelsimtcl

PC Users:
<install_path>\tclscript\labs\modelsimtcl

Your trainer will tell you the location of the lab files installation
<install_path>

❏We will work on the file signalcount.tcl. Take a look at the file's
contents using a text editor. Check with your instructor to see which text
editors are available, or use your favorite editor.
Adding the ‘momitorSigmals’ procedure

❏ Complete the ‘monitorSignals’ procedure using the comments found inside


the script file.

❏ Test the resulting script on the filtercore.srr synthesis report file.

❏ Add to the get_message procedure a routine that will prevent the same
message to be printed more than once.

Optiomal

❏If you have some time left, try to improve the ‘monitorSignals’ procedure by
checking if a signal (inside the ‘signalList’ variable) is of an array type; if
so, expend the signal into individual values so that you can create
individual counters for each of the bits of a vector. The following diagram
explains the procedure.

signalList

sig_a describe dataio

Array(3 downto 0) of
dataio Enum:
('U','X','0','1','Z','W','L','H','-')

clk

ExpendedList()

(sig_a) 0
(dataio(0)) 0
(dataio(1)) 0
Added
(dataio(2)) 0
(dataio(3)) 0
(dataio) 0
(clk) 0
Lab 3 – Leomardo Multi-pass Synthesis

5oals

The goal of this exercise is to become familiar with some of the features of
Leonardo’s API. This example is based on a VHDL synthesis; this script will be
used to perform a multi-pass synthesis and report the results of its analysis.

No prior knowledge of the VHDL language is required for this lab.

Scemario

Synthesis is often viewed as a simple push-button process. In most cases this


approach is sufficient to achieve the required results. However when dealing
with designs with tight constrains such as area or timing, synthesis becomes a
more involved process. Commonly designers find themselves engaged in
countless synthesis runs involving different sets of synthesis constraints.
Unfortunately, due to the increasing level of complexity of synthesis
algorithms, synthesis constraints combinations that used to lead to specific
improvements are no longer valid.

The proposed lab example consists in creating a procedure that will be used to
initiate synthesis runs over a range of constraint variations. This type of script
would typically run overnight since they are inherently long. Once the multi-
pass synthesis is complete, the script will display the results using a graph. The
following diagram illustrates the script’s architecture:
vhdlFileList

maxFreq

read
args compile

load_library

config Leonardo’s
variables pre_optimixe

optimixe

optimixe_timing
newRun

result.txt delay.txt area.txt

report_delay report_area

synResult
Procedure call :

Data transfer :

API Procedure :
API
The ‘compile’ procedure is the top-level procedure. This procedure reads all the
files located inside the current directory and initiate successive synthesis runs
on each of those files. When calling the procedure, the user has to specify a
required frequency value in MHx. Optionally, if the VHDL files require
packages to be analyxed prior to synthesis, the user will specify the required
files as part of the procedure’s arguments.

The procedure ‘newRun’ is invoked by the procedure ‘compile’ whenever there is


a new synthesis run to perform. This procedure will configure the synthesis
tool’s variables from the information located inside the ‘config’ variable. Once
the variable have been set-up, the procedure ‘newRun’ will call a number of
Leonardo’s API functions to perform a synthesis. Finally, the procedure will
browse the report files to create a concise summary file ‘result.txt’.

Recommemdatioms

Leomardo Spectrum’s API:


Leonardo Spectrum features a large amount of TCL API commands
described in detail in the synthesis tool’s documentation. This script will
only feature a few of those to give you a feel for what you can achieve with
scripting.

This is the list of Leonardo Spectrum’s commands used in this lab:

- read : This command is used to analyxe an HDL file


o ‘read -format vhdl <file name>’ will analyxe the
given file and return any errors or warning related to the
semantics of that file.

- load_library : This command loads a pre-compiled technology


library.
o ‘load_library flex10’ will load the Altera Flex 10K
primitive library.

- pre-optimixe : This procedure does a number of high level


optimixations, such as: operator sharing, redundant logic
removal, macros extraction.
o ‘pre_optimize –common_logic –unused_logic
–boudary –xor_comparator_optimize –extract'
will use all the pre optimixation options.

- optimixe : Optimixes and map a design to a target technology.


o ‘optimize' will run the optimixation process, using the
constraint information located inside the synthesis tool’s
global variables (see Leonardo’s global variables).

- optimixe_timimg : Performs critical path optimixation on the


design.
o ‘optimize_timing': Optimixe the critical paths using
the timing constraints found in Leonardo’s global
variables (see Leonardo’s global variables).

- report_delay : Writes out a report file containing timing


information.

- report_area : Writes out a report file containing area


information.

Leomardo Spectrum’s global variables:


Leonardo Spectrum features a large amount of variables used to configure
the synthesis engine. This script will only feature a few of those.

This is the list of Leonardo Spectrum’s global variables used in this lab:

- output_file : This variable indicates the name of the resulting


netlist.
o ‘set output_file decode.edf’ will assign the name
‘decode.edf’ to the resulting netlist.

- part : This variable indicates the part name in the chosen target
family.
o ‘set part EPF10K30RC208' will set the part to the
specified value.

- process : This indicates the grade of the device.


o ‘set process 3' will set the process to 3

- register2register : This variable indicates the delay


requirement (ns) between registers inside your design.
o ‘set register2register 25' will force Leonardo
Spectrum to try to meet a 25 ns delay between any
register in the design.

- imput2register : This variable indicates the delay requirement


(ns) between any input and register inside your design.
o ‘set input2register 25' will force Leonardo
Spectrum to try to meet a 25 ns delay between any input
and register in the design.

- output2register : This variable indicates the delay requirement


(ns) between any output and register inside your design.
o ‘set output2register 25' will force Leonardo
Spectrum to try to meet a 25 ns delay between any output
and register in the design.

- resource_skarimg : This indicate if the synthesis tool tries to


resource share operators or not.
o ‘set resource_sharing TRUE' will force Leonardo
Spectrum to try to implement resource sharing.
- emcodimg : This variable is used to set the encoding style of state
machines.
o ‘set encoding Binary' will force Leonardo Spectrum
to use the binary style for the state machines contained
inside the current design.

If you require more information about specific variables, you can type the
command ‘help –v’ inside the Leonardo Spectrum’s console window.

Data types:
- config : (array) Constraint names are used as indexes.

config()

nano seconds
(register2register) 100

(input2register) 100

(output2register) 100

(resource_sharing)
TRUE

(encoding) Binary

- vhdlFileList : (list of stings) List of all the vhdl files contained


inside the current directory.

Actiom

Lookimg at the script desigm


❏Files Locatiom: the lab files will are stored in the following directories:

Workstation Users:
<install_path>/tclscript/labs/leonardotcl

PC Users:
<install_path>\tclscript\labs\leonardotcl

Your trainer will tell you the location of the lab files installation
<install_path>
❏We will work on the file complile.tcl. Take a look at the file's contents using a
text editor. Check with your instructor to see which text editors are available, or
use your favorite editor.

Completing the procedures

❏ Complete the procedures using the comments found inside the script file.

❏Test the resulting script on the vhdl files found in the lab directory. This can be
achieved by typing the following commands in Leonardo Spectrum.

cd <install_path>/tclscript/labs/leonardotcl
source compile.tcl
compile 40 mask_types.vhd
Lab 4 – Symplify Multi-pass Synthesis

5oals

The goal of this exercise is to become familiar with some of the features of
Synplify’s API. This example is based on a VHDL synthesis; this script will be
used to perform a multi-pass synthesis and report the results of its analysis.

No prior knowledge of the VHDL language is required for this lab.

Scemario

Synthesis is often viewed as a simple push-button process. In most cases this


approach is sufficient to achieve the required results. However when dealing
with designs with tight constrains such as area or timing, synthesis become a
more involved process. Commonly designers find themselves engaged in
countless synthesis runs involving different sets of synthesis constraints.
Unfortunately, due to the increasing level of complexity of synthesis
algorithms, synthesis constraints combinations that used to lead to specific
improvements are no longer valid.

The proposed lab example consists in creating a procedure that will be used to
initiate synthesis runs over a range of constraint variations. This type of script
would typically run overnight since they are inherently long. Once the multi-
pass synthesis is complete, the script will display the results using a graph. The
following diagram illustrates the script’s architecture:
vhdlFileList

maxFreq

add_file
args compile

set_option

newRun config

project

<name>.srr result.txt

Procedure call :

Data transfer :

API Procedure :
API
The ‘compile’ procedure is the top-level procedure. This procedure reads all the
files located inside the current directory and initiate successive synthesis runs
on each of those files. When calling the procedure, the user has to specify a
required frequency value in MHx. Optionally, if the VHDL files require
packages to be analyxed prior to synthesis, the user will specify the required
files as part of the procedure’s arguments.

The procedure ‘newRun’ is invoked by the procedure ‘compile’ whenever there is


a new synthesis run to perform. This procedure will configure the synthesis
tool’s variables from the information located inside the ‘config’ variable. Once
the variable has been set-up, the procedure ‘newRun’ will call a Synplify API
functions to perform a synthesis. Finally, the procedure will browse the report
files to create a concise summary file ‘result.txt’.

Recommemdatioms

Symplify’s API:
Synplify features a large amount of TCL API commands described in
detail in the synthesis tool’s documentation. This script will only feature a
few of those to give you a feel for what you can achieve with scripting.

This is the list of Synplify ’s commands used in this lab:

- project : This command is used by Synplify for a number of


applications. In this script, ‘project’ is used to set-up a new
project, specify a log file and run the synthesis engine.
o ‘project -new’ will initialixe the synthesis tool and
prepare a new project.
o ‘project –log_file <name>.srr’ will specify the
name of the log file to be generated after synthesis.
o ‘project –run synthesis’ will initiate a synthesis run.

- add_file : This command is used to analyxe an HDL file.


o ‘add_file –vhdl decode.vhd' will compile the
decode.vhd file.

- set_optiom : This procedure is used to set the design constraints


as well as synthesis options.
o ‘set_option –technology FLEX10K' will select the
Altera FLEX technology.
o ‘set_option –part EFP10K30' will specify the part to
be used within the Altera FLEX family
o ‘set_option frequency 40' will specify the required
frequency for the current design (in MHx).
o ‘set_option resource_sharing 1'will indicate to the
synthesis engine to try to resource share logic.
o ‘set_option symbolic_fsm_compiler 1' will to the
synthesis engine to use dedicated algorithms for state
machine optimixation.
o ‘set_option default_enum_encoding sequential'
will indicate Synplify to use a sequential (binary) encoding
style for the state machines inside the current design.
Alternatively, the user can specify ‘onehot’ for a one-hot
coding style.

Data types:
- config : (array) Constraint names are used as indexes.

config()

sequential
(default_enum_encoding)

0
(symbolic_fsm_compiler)

0
(resource_sharing)

0
(frequency)

- vhdlFileList : (list of stings) List of all the vhdl files contained


inside the current directory.

Actiom

Lookimg at the script desigm


❏Files Locatiom: the lab files will are stored in the following directories:

Workstation Users:
<install_path>/tclscript/labs/Synplifytcl

PC Users:
<install_path>\tclscript\labs\Synplifytcl

Your trainer will tell you the location of the lab files installation
<install_path>

❏We will work on the file complile.tcl. Take a look at the file's contents
using a text editor. Check with your instructor to see which text editors
are available, or use your favorite editor.
Completing the procedures

❏ Complete the procedures using the comments found inside the script file.

❏ Test the resulting script on the vhdl files found in the lab directory. This
can be achieved by performing the following steps.

Click on: run > run script


Select: compile.tcl

You might also like