When you are optimizing a design, it is useful to view information about levels of logic between registers. The following script generates a Comma Separated Value (.csv) file with the number of paths with different levels of logic in your design. You can chart this data or create a histogram in Excel showing the distribution of paths by levels of logic.
If two registers have multiple logic paths between them, only the path with the most levels of logic is counted by this script. For example, two registers with one four-level and one two-level path would be counted as one four-level path.
The script generates a CSV file named <revision name>.levels_of_logic.csv.
Assuming you save the script in a file named report_levels_of_logic.tcl, you can run it with the following command:
quartus_tan -t report_levels_of_logic.tcl -project <project name> [-revision <revision name>] [-name_pattern <string to match>]
You can use the -name_pattern option to restrict path counting to a specific hierarchy in your design. Specify a string to match with tool command language (Tcl) wildcard matching. If you do not specify a value for the -name_pattern option, it defaults to *. For example, if you want to report levels of logic between registers in the mult:inst6|lpm_mult:lpm_mult_component hierarchy of your design, specify mult:inst6|lpm_mult:lpm_mult_component* for the value of the -name_pattern option.
load_package advanced_timing package require cmdline set options {\ { "project.arg" "" "Project name" } \ { "revision.arg" "" "Revision name" } \ { "name_pattern.arg" "*" "Restrict to registers matching this pattern"} } array set opts [::cmdline::getoptions quartus(args) $options] array set num_levels [list] # Open the project and get the revision name if { [string equal "" $opts(revision)] } { project_open $opts(project) -current_revision } else { project_open $opts(project) -revision $opts(revision) } set rev [get_current_revision] # Prepare the timing netlist if { [catch { create_timing_netlist; create_p2p_delays } res] } { post_message -type error $res project_close qexit -error } # Iterate through every register in the design foreach_in_collection dest [get_timing_nodes -type reg] { # Get a list of keepers (registers, pins, clocks) # that feed to the register node set delays_from_keepers [get_delays_from_keepers $dest] # If the destination register name doesn't match the pattern, # simply go on to the next one. set dest_name [get_timing_node_info -info name $dest] if { ! [string match $opts(name_pattern) $dest_name] } { continue } # Walk through all keepers feeding the register node foreach delay $delays_from_keepers { set src [lindex $delay 0] # Keeper can include pins and clocks, and we want only registers. if { ! [string equal "reg" [get_timing_node_info -info type $src]] } { continue } # If the source register name doesn't match the pattern, # simply go on to the next one set src_name [get_timing_node_info -info name $src] if { ! [string match $opts(name_pattern) $src_name] } { continue } # At this point, both the source and destination names # match the pattern, and it's a register-to-register path. # The get_delay_path command returns a list of nodes on # a path. The length of the path is the length of the list. # The list includes the source and destination registers, # so the levels of logic between registers is - 2 set path [get_delay_path -type longest -from $src -to $dest] set levels_of_logic [expr { [llength $path] - 2 } ] # Save the information in an array if { [info exists num_levels($levels_of_logic)] } { incr num_levels($levels_of_logic) } else { set num_levels($levels_of_logic) 1 } } } project_close # Write the information out to a file if { [catch {open ${rev}.levels_of_logic.csv w} fh] } { post_message -type error $fh } else { # Write a descriptive header into the file puts $fh "Levels of logic for project $opts(project) revision $rev" puts $fh "File generated by Quartus® II $quartus(version) on \ [clock format [clock seconds]]" puts $fh "\nReporting paths for register names matching $opts(name_pattern)" puts $fh "Levels of logic,Number in design" foreach level [lsort -integer [array names num_levels]] { if { [catch { puts $fh "$level,$num_levels($level)" } res] } { post_message -type error $res break } } catch { close $fh } }