如果在项目中采用模块化 LogicLock 区域设计流程,可以选择将模块中的所有 I/O 引脚设置为虚拟 I/O 引脚,以便于在顶层设计中轻松导入模块。此外,如果想要编译 IP 核并查看它使用了多少资源,但发现它使用了目标设备过多的引脚,将引脚虚拟化可以使核与设计相匹配。
以下简单程序将设计中的所有引脚设置为虚拟 I/O 引脚。首先对设计进行综合,确定哪些节点是引脚。接下来,将名称 ID 集合设置为与设计中的引脚相对应,然后对每个引脚应用 VIRTUAL_PIN 赋值。最后,export_assignments 命令将所有新赋值写入项目的 Quartus II 设置文件 (.qsf)。
此示例使用 get_names 和 get_name_info 命令,这些命令适用于 Quartus II 软件 4.0 版及更高版本(::quartus::project 包 2.0 版及更高版本)。有关适用于 Quartus II 软件 3.0 版及更高版本并具有更多高级功能的代码,请参阅此页面的最后一个示例。
load_package flow proc make_all_pins_virtual {} { execute_module -tool map set name_ids [get_names -filter * -node_type pin] foreach_in_collection name_id $name_ids { set pin_name [get_name_info -info full_path $name_id] post_message "Making VIRTUAL_PIN assignment to $pin_name" set_instance_assignment -to $pin_name -name VIRTUAL_PIN ON } export_assignments }
改进示例代码
可通过多种方法改进示例代码。
移除现有 VIRTUAL_PIN 赋值
可以将以下命令添加到此程序的开头,以便移除所有现有 VALUAL_PIN 赋值。这是确保赋值处于已知状态的有效步骤。将此命令添加到 execute_module 命令前面。
remove_all_instance_assignments -name VIRTUAL_PIN
手动排除特定引脚,例如时钟
为了使 Quartus II 软件在与设计相匹配的情况下执行时序优化,时钟必须连接到目标设备中的顶层 I/O 引脚,并且时钟必须应用了时钟设置。即使设计中的所有其它引脚都是虚拟 I/O 引脚,情况也是如此。因此,以上基本示例阻止 Quartus II 软件在编译期间优化时序,因为所有引脚(包括时钟)都应用了 VIRTUAL_PIN 赋值。
可以在程序中添加一个参数,接受要从 VIRTUAL_PIN 赋值中排除的信号列表。此列表通常是设计中的时钟引脚名称。以下示例接受要排除的名称列表。它还包括上述移除任何现有 VIRTUAL_PIN 赋值的命令。
load_package flow package require cmdline proc make_all_pins_virtual { args } { set options {\ { "exclude.arg" "" "List of signals to exclude" } \ } array set opts [::cmdline::getoptions quartus(args) $options] remove_all_instance_assignments -name VIRTUAL_PIN execute_module -tool map set name_ids [get_names -filter * -node_type pin] foreach_in_collection name_id $name_ids { set pin_name [get_name_info -info full_path $name_id] if { -1 == [lsearch -exact $opts(excludes) $pin_name] } { post_message "Making VIRTUAL_PIN assignment to $pin_name" set_instance_assignment -to $pin_name -name VIRTUAL_PIN ON } else { post_message "Skipping VIRTUAL_PIN assignment to $pin_name" } } export_assignments }
可以使用此命令调用此程序。此示例假设设计中有两个时钟,分别名为 clk_a 和 clk_b。
make_all_pins_virtual -exclude { clk_a clk_b }
自动识别和处理时钟
上一个排除特定信号的示例的缺点在于必须手动输入这些信号。可以使用 ::quartus::advanced_timing 包中的命令确定时钟信号。此包仅可在 quartus_tan 可执行文件中加载,因此,必须使用 quartus_tan 运行以下示例的脚本。Quartus II 软件 3.0 版及更高版本支持此示例中的所有命令。
自动识别时钟的优点在于可以自动应用 USE_CLK_FOR_VIRTUAL_PIN 赋值。可以将 USE_CLK_FOR_VIRTUAL_PIN 赋值与 VIRTUAL_PIN 赋值配合使用,从而将时钟设置与设计中的时钟相关联。在使用虚拟 I/O 引脚编译设计时,这将为 Quartus II Fitter 提供有关时序要求的准确信息。有关此赋值的更多信息,请参阅“Quartus II 帮助”中的“虚拟引脚时钟逻辑选项”主题。
以下示例程序将设计中的所有 I/O 引脚都设置为虚拟 I/O 引脚。此外,还在适当的情况下进行虚拟引脚时钟设置赋值。
示例代码首先对设计进行综合。然后,它尝试在创建新的时序网表之前删除所有现有时序网表。get_timing_nodes 命令从时序网表中创建两个节点集合:pin_ids 和 clk_ids。这两个集合都具有互斥性;即使时钟可能位于 I/O 引脚上,clk_ids 集合中的所有节点都不在 pin_ids 集合中。
第一个 foreach_in_collection 循环获取设计中每个引脚的名称(不包括时钟引脚),并对其进行 VIRTUAL_PIN 赋值。
第二个 foreach_in_collection 循环获取设计中每个时钟的名称。get_instance_assignment 命令检索相应的时钟设置(如果存在)。如果时钟的时钟设置存在(字符串不为空),脚本将使用时钟设置名称的值对时钟名称进行 USE_CLOCK_FOR_VIRTUAL_PIN 赋值。
load_package flow load_package timing load_package advanced_timing proc make_all_pins_virtual { } { remove_all_instance_assignments -name VIRTUAL_PIN remove_all_instance_assignments -name USE_CLK_FOR_VIRTUAL_PIN execute_module -tool map catch { delete_timing_netlist } create_timing_netlist -post_map set pin_ids [get_timing_nodes -type pin] set clk_ids [get_timing_nodes -type clk] # 对设计中的每个引脚进行 VIRTUAL_PIN 赋值 foreach_in_collection pin_id $pin_ids { set pin_name [get_timing_node_info -info name $pin_id] post_message "Making VIRTUAL_PIN assignment to $pin_name" set_instance_assignment -to $pin_name -name VIRTUAL_PIN ON } # 对于设计中的每个时钟,请检查它是否有 # 相应的 CLOCK_SETTINGS 赋值。 foreach_in_collection clk_id $clk_ids { set clk_name [get_timing_node_info -info name $clk_id] set clk_stgs [get_instance_assignment -to $clk_name -name \ CLOCK_SETTINGS] # 如果此时钟有时钟设置,进行 # USE_CLK_FOR_VIRTUAL_PIN 赋值 if { ![string equal "" $clk_stgs] } { post_message "Making USE_CLK_FOR_VIRTUAL_PIN assignment \ to $clk_name with value $clk_stgs" set_instance_assignment -to $clk_name \ -name USE_CLK_FOR_VIRTUAL_PIN $clk_stgs } } export_assignments }