Because the Vivado Design Suite provides a full Tcl interpreter built into the tool, creating new custom commands and procedures is a simple task. You can write Tcl scripts that can be loaded and run from the Vivado IDE, or you can write procedures, to act like new Tcl commands, taking arguments, checking for errors, and returning results.
A Tcl procedure is defined with the proc
command which takes three arguments: the procedure name, the list of arguments, and the body of code to be executed. The following code provides a simple example of a procedure definition:
proc helloProc { arg1 } {
# This is a comment inside the body of the procedure
puts "Hello World! Arg1 is $arg1"
}
A procedure usually has predefined arguments. Each of them can optionally have a default value. When an argument has a default value, it does not need to be specified when calling the procedure if all the mandatory preceding arguments are specified. A procedure returns an empty string unless the return
command is used to return a different value.
The following example defines a procedure, reportWorstViolations
, with three arguments:
proc reportWorstViolations { nbrPaths corner delayType } {
report_timing -max_paths $nbrPaths -corner $corner -delay_type $delayType -nworst 1
}
When running the procedure, all the arguments must be specified as shown:
%> reportWorstViolations 2 Slow max
%> reportWorstViolations 10 Fast min
The next example is a different form of the same procedure, where the last two of the three arguments have a default value. The default value for corner
is Slow
, and the default value for delayType
is Max
. With default values specified in the definition of the procedure, the corner
and delayType
arguments are optional when calling the procedure.
proc reportWorstViolations { nbrPaths { corner Slow } { delayType Max } } {
report_timing -max_paths $nbrPaths -corner $corner -delay_type $delayType -nworst 1
}
When running this procedure, all of the following calls of the command are valid:
%> reportWorstViolations 2
%> reportWorstViolations 10 Fast
%> reportWorstViolations 10 Slow Min
The following example is an illustration of a procedure that has one mandatory argument, nbrPath
, but that can also accept any number of additional arguments. This uses the Tcl keyword args
in the list of arguments when defining the procedure. The args
keyword is a Tcl list that can have any number of elements, including none.
proc reportWorstViolations { nbrPaths args } {
eval report_timing -max_paths $nbrPaths $args
}
When executing a Tcl command, you can use variable substitution to replace some of the command line arguments accepted or required by the Tcl command. In this case, you must use the Tcl eval
command to evaluate the command line with the Tcl variable as part of the command. In the preceding example, the variable list of arguments ($args
) is passed to the encapsulated report_timing
command as a variable, and so requires the use of the eval
command.
When running this procedure, any of the following forms of the command will work:
%> reportWorstViolations 2
%> reportWorstViolations 1 -to [get_ports]
%> reportWorstViolations 10 -delay_type min_max -nworst 2
In the first example, the number 2 is passed to the $nbrPaths
argument, and applied to -max_paths
. In the second and third examples, the numbers 1 and 10 respectively are applied to -max_paths
, and all the subsequent characters are assigned to $args
.
The following example provides the procedure definition for the reportCriticalPaths
command that was previously used in the Non-Project mode example script. The procedure takes a single argument, $filename
, and has been commented to explain each section:
#------------------------------------------------------------------------
# reportCriticalPaths
#------------------------------------------------------------------------
# This function generates a CSV file that provides a summary of the first
# 50 violations for both Setup and Hold analysis. So a maximum number of
# 100 paths are reported.
#------------------------------------------------------------------------
proc reportCriticalPaths { fileName } {
# Open the specified output file in write mode
set FH [open $fileName w]
# Write the current date and CSV format to a file header
puts $FH "#\n# File created on [clock format [clock seconds]]\n#\n"
puts $FH "Startpoint,Endpoint,DelayType,Slack,#Levels,#LUTs"
# Iterate through both Min and Max delay types
foreach delayType {max min} {
# Collect details from the 50 worst timing paths for the current analysis
# (max = setup/recovery, min = hold/removal)
# The $path variable contains a Timing Path object.
foreach path [get_timing_paths -delay_type $delayType -max_paths 50 -nworst 1] {
# Get the LUT cells of the timing paths
set luts [get_cells -filter {REF_NAME =~ LUT*} -of_object $path]
# Get the startpoint of the Timing Path object
set startpoint [get_property STARTPOINT_PIN $path]
# Get the endpoint of the Timing Path object
set endpoint [get_property ENDPOINT_PIN $path]
# Get the slack on the Timing Path object
set slack [get_property SLACK $path]
# Get the number of logic levels between startpoint and endpoint
set levels [get_property LOGIC_LEVELS $path]
# Save the collected path details to the CSV file
puts $FH "$startpoint,$endpoint,$delayType,$slack,$levels,[llength $luts]"
}
}
# Close the output file
close $FH
puts "CSV file $fileName has been created.\n"
return 0
}; # End PROC