在优化设计时,查看寄存器之间的逻辑级数信息是很有用的。下面的脚本生成一个逗号分隔值 (.csv) 文件,其中包含设计中具有不同逻辑级数的路径数量。可以在 Excel 中绘制此数据的图表或创建直方图,按逻辑级数显示路径分布。
如果两个寄存器之间有多个逻辑路径,此脚本以逻辑级数最多的路径为准。例如,如果两个寄存器之间有一个四级路径和一个两级路径,将被视为一个四级路径。
此脚本生成一个名为 <revision name>.levels_of_logic.csv 的 CSV 文件。
假设将脚本保存到名为 report_levels_of_logic.tcl 的文件中,可以使用以下命令运行此脚本:
quartus_tan -t report_levels_of_logic.tcl -project <project name> [-revision <revision name>] [-name_pattern <string to match>]
可以使用 -name_pattern 选项将路径计数限制为设计中的特定层次结构。使用工具命令语言 (Tcl) 通配符匹配,指定匹配的字符串。如果不指定 -name_pattern 选项的值,则默认为 *。例如,如果要报告设计的 mult:inst6|lpm_mult:lpm_mult_component 层次结构中寄存器之间的逻辑级数,请将 -name_pattern 选项的值指定为 mult:inst6|lpm_mult:lpm_mult_component*。
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] # 打开项目,获取修订版名称 if { [string equal "" $opts(revision)] } { project_open $opts(project) -current_revision } else { project_open $opts(project) -revision $opts(revision) } set rev [get_current_revision] # 准备时序网表 if { [catch { create_timing_netlist; create_p2p_delays } res] } { post_message -type error $res project_close qexit -error } # 对设计中的每个寄存器进行迭代 foreach_in_collection dest [get_timing_nodes -type reg] { # 获取馈入寄存器节点的 # 保持器(寄存器、引脚、时钟)列表 set delays_from_keepers [get_delays_from_keepers $dest] # 如果目标寄存器名称与模式不匹配, # 继续下一个。 set dest_name [get_timing_node_info -info name $dest] if { ! [string match $opts(name_pattern) $dest_name] } { continue } # 对馈入寄存器节点的所有保持器进行遍历 foreach delay $delays_from_keepers { set src [lindex $delay 0] # 保持器可以包括引脚和时钟,此处仅包括寄存器。 if { ! [string equal "reg" [get_timing_node_info -info type $src]] } { continue } # 如果源寄存器名称与模式不匹配, # 继续下一个 set src_name [get_timing_node_info -info name $src] if { ! [string match $opts(name_pattern) $src_name] } { continue } # 此时,源寄存器名称和目标寄存器名称均与模式匹配, # 构成了寄存器到寄存器路径。 # get_delay_path 命令返回路径上的 # 节点列表。路径的长度就是列表的长度。 # 此列表包含源寄存器和目标寄存器, # 因此寄存器之间的逻辑级数为 - 2 set path [get_delay_path -type longest -from $src -to $dest] set levels_of_logic [expr { [llength $path] - 2 } ] # 将信息保存到一个阵列中 if { [info exists num_levels($levels_of_logic)] } { incr num_levels($levels_of_logic) } else { set num_levels($levels_of_logic) 1 } } } project_close # 将信息写入一个文件 if { [catch {open ${rev}.levels_of_logic.csv w} fh] } { post_message -type error $fh } else { # 将描述性标题写入文件 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 } }