Accessing Files - 2020.2 English

Vivado Design Suite User Guide: Using Tcl Scripting (UG894)

Document ID
UG894
Release Date
2021-03-30
Version
2020.2 English

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, or socket.
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, or fileID, used to access the file. It is a standard practice to capture the fileID 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 of perms and the process umask. The access mode determines whether you can read to or write to the open file. Some common access modes are:
r
Read only. The file must exist; it will not be created. This is the default access mode if one is not specified.
w
Write only. This will create the specified file if it does not already exist. The data is written to the front of the file, truncating or overwriting the content of an existing file.
a
Append only. This will create the specified file if it does not already exist. The data is written at the end of the file, appending to any existing file content.
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, the read command will read the entire file at once.
read fileId numBytes
Read the specified number of bytes, numBytes, from fileId. 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 the gets 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 of gets, without specifying a Tcl variable to capture the output. In this case the output is returned to stdout. The second form of the command assigns the output to a variable called $line, and the gets command returns the number of characters it has read, 28.

Note: You can assign the return of the gets 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 default fileId for the puts command is stdout.
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.

Note: It is not recommended to read large files in a single operation due to performance and memory considerations.

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.