After a file has been written to the file system, Tcl provides many useful commands for working with the files. You can extract elements of a file, such as the file path, file name and file extension. Some of the Tcl commands available to examine information about file include:
-
file exists
<filename>
- A boolean test that returns 1 if
filename
exists, and you have permission to read its location; returns 0 otherwise. Use this to determine if the file you are looking for already exists. -
file type
<filename>
- Returns the type of filename as a string with one of the following values:
file
,directory
,characterSpecial
,blockSpecial
,fifo
,link
, orsocket
.
-
file dirname
<filename>
- This returns the directory structure of the
fileName
, up to but not including the last slash. -
file rootname
<filename>
- Returns all the characters in
filename
up to but not including last dot. -
file tail
<filename>
- Return all characters in
filename
after the last slash. -
file extension
<filename>
- Returns all characters in
filename
after, and including, the last dot.
The following examples illustrates some of the Tcl commands:
set filePath {C:/Data/carry_chain.txt}
file dirname $filePath ; # Returns C:/Data
file tail $filePath ; # Returns carry_chain.txt
file extension $filePath ; # Returns .txt
After the Vivado tools have created a file, through a report_*
command, or write_*
command, you can open the file from within a Tcl script to read
its contents, or to write additional content. To open, read from, write to, and close a
file, you can use some of the following Tcl commands:
-
open
<filename>
[
access
] [
perms
]
- Opens the
filename
and returns the file handle, orfileID
, used to access the file. It is a standard practice to capture thefileID
in a Tcl variable, so that you can refer to the file handle when needed. The file permissions of a new file are set to the conjunction ofperms
and the process umask. Theaccess
mode determines whether you can read to or write to the open file. Some common access modes are: -
read [-nonewline]
fileId
- Read all remaining bytes from
fileId
, optionally discarding the last character if it is a newline,\n
. When used in this form right after opening the file, theread
command will read the entire file at once. -
read
fileId
numBytes
- Read the specified number of bytes,
numBytes
, fromfileId
. Use this form of the command to read blocks of the file, up to the end of the file. -
eof
fileId
- Returns 1 if an end-of-file (EOF) has occurred on
fileId
, 0 otherwise. -
gets
fileId
[
varName
]
- Read the next line from
fileId
, discarding the newline character. Places the characters of line in$varName
if given, otherwise returns them to the command shell. The following are different forms of thegets
commands:gets $fileHandle Append line 4 of file. gets $fileHandle line 28 puts $line Append line 5 of file. set line [gets $fileHandle] Append line 6 of file. puts $line Append line 6 of file.
In the preceding example,
$fileHandle
is the file handle returned when the file was opened. The first line uses the simple form ofgets
, without specifying a Tcl variable to capture the output. In this case the output is returned tostdout
. The second form of the command assigns the output to a variable called$line
, and thegets
command returns the number of characters it has read, 28.Note: You can assign the return of thegets
command to a Tcl variable, but depending on which form you are using you may capture the contents of the file, or the number of characters the gets command has read. -
puts [-nonewline] [
fileId
]
string
- Write a string to the specified
fileId
, optionally omitting the newline character,\n
. The defaultfileId
for theputs
command isstdout
. -
close
fileId
- Close the open file channel
fileId
. It is very important to close any files your Tcl scripts have opened, or you may develop memory leaks in the Vivado application, or encounter other undesirable effects.
The following example opens a file in read access mode, storing the file handle as $FH
, reads the contents of the file in a single operation, assigning it to $content
, and splits the contents into a Tcl list. The file is closed upon completion.
Rather than reading the entire file at once, and then parsing the results, the following example reads the file line-by-line until the end of the file has been reached, and writes the line number and line content to stdout
. The file is closed upon completion:
set FH [open C:/Data/carry_chains.txt r]
set i 1
while {![eof $FH]} {
# Read a line from the file, and assign it to the $line variable
set line [gets $FH]
puts "Line $i: $line"
incr i
}
close $FHset FH [open C:/Data/carry_chains.txt r]
set content [read $FH]; # The entire file content is saved to $content
foreach line [split $content \n] {
# The current line is saved inside $line variable
puts $line
}
close $FH
The example below writes to a file, ports.rpt
, saving all the I/O ports from the design, with the port direction, sorted by name:
set FH [open C:/Data/ports.rpt w]
foreach port [lsort [get_ports *]] {
puts $FH [format "%-18s %-4s" $port [get_property DIRECTION $port]]
}
close $FH
In the example above, the file is opened in write mode. Unlike read mode, the write mode will create the file if it does not exist, or overwrite the file if it does exist. To write new content to the end of an existing file, you should open the file in append mode instead.