使用示例
3.1 获取总线类对象
看以下例子。在进行物理约束的时候,为一个总线设置信号类型,如果一个一个的写即慢又可能犯错。使用正则可以将这类信号全部提取出来。以一个从0到31共32路的总线为例。
set_property IOSTANDARD SSTL18_I_DCI [get_ports -regexp {c2c_sync[.*]}]
以上指令可以获取所有名字为c2c_sync[]的端口,方括号内可能是任意多个数字。这种写法不够准确,在文字处理程序里面会出大问题,但是在FPGA工程中足够了。当然也可以写的稍微严格点,比如:
set_property IOSTANDARD SSTL18_I_DCI [get_ports -regexp {c2c_sync[[0-9]{1,2}]}]
这个表达式比上一个更进一步的约束了中括号内的内容。这里的[是为了匹配“[”本身,而里面的[0-9]则定义了一个从数字0到数字9的字符集,[0-9]后面的{1,2}则表示[0-9]中的任意数字将出现1次,或以任意两个数字的组合出现1次。对于我们的应用,做到这一步就够了。
3.2 简化匹配表达式
工程中会有一些名字很特殊的信号,比如全局复位信号,这种信号在工程中往往只会出现一次,我用更加简单粗暴的方式来获得。
set_false_path -from [get_cells -regexp -hierarchical .*rst_global_reg.*]
比如上面的例子。通过使用-hierarchical搜索所有层次,通过在rst_global_reg的前后都使用.*来匹配任何可能出现的字符。其中。表示匹配任何非换行符的字符,*表示。可以出现任意次。当然并不推荐这种写法,因为会增加编译时匹配对象的负担。可以使用更精准的匹配。
对于层次很深的信号,只要保证列出的匹配字符能够找到我们所要的对象即可。比如某工程有下图的层次结构。
比如设计者发现A_i0模块内部的D_i0内的某个关键信号的位置需要优化,且设计者知道该信号在D_i0中唯一。为了拿到这个关键信号,可以使用正则表达式,并且可以略过中间层次的所有模块。
get_cells -regexp -hierarchical {A_i0/.*/D_i0/start_reg}
3.3 特殊字符的获取
前面提到过一些特殊字符,比如?、。、/、[等等,如果需要匹配这些字符,需要用到转义符“”。比如“。”表示“。”这个字符本身,而不再是匹配符。。
比如在上文提到的get_ports -regexp {c2c_sync[[0-9]{1,2}]}。这个总线的完整名称是c2c_sync[0]、c2c_sync[1]。..。..,此处的“[”就是表示左方括号这个字符本身。而[0-9]中单独使用的[]就表示一个字符集合。这里有个需要注意的地方,作为字符使用的左方括号左侧加了转义符““,而右方括号则不需要加”“。
另外一个需要注意的是上文中提到的get_cells -regexp -hierarchical ConfigRegs_i/bus_hsio_dly.*_fine_sel.*。这里面bus_hsio_dly是一个systemverilog中的interface,获取的对象是bus_hsio_dly接口中的cmph_fine_sel_reg信号,其表达方式应该是bus_hsio_dly.cmph_fine_sel_reg。此处我使用”.*“来匹配任何非换行字符,所以可以匹配”。“字符。
更合适一点的匹配表达式应该是ConfigRegs_i/bus_hsio_dly。.*_fine_sel_reg。第一处修改是明确使用。来匹配”。“,第二处修改时添加了_reg后缀(Vivado会给寄存器变量默认添加_reg后缀)。如果不添加该后缀,可能会获取一些不期望的对象。比如使用get_cells时,可能或获取带_fine_sel的LUT,比如_fine_sel_i_1等等。
再进一步,我们可能注意到上述匹配获得的对象打印出来是:
bus_hsio_dly\.cmph_fine_sel_reg
打印结果不是。,而是\。。对于这种情况,我猜想是\用来表示转义符”“。而”\“表示的转义符则作用于特殊字符”。“,用来表示普通字符”。“。
这是个人猜测,但是为什么会这样?如果哪位清楚原因,不吝赐教。
使用示例
3.1 获取总线类对象
看以下例子。在进行物理约束的时候,为一个总线设置信号类型,如果一个一个的写即慢又可能犯错。使用正则可以将这类信号全部提取出来。以一个从0到31共32路的总线为例。
set_property IOSTANDARD SSTL18_I_DCI [get_ports -regexp {c2c_sync[.*]}]
以上指令可以获取所有名字为c2c_sync[]的端口,方括号内可能是任意多个数字。这种写法不够准确,在文字处理程序里面会出大问题,但是在FPGA工程中足够了。当然也可以写的稍微严格点,比如:
set_property IOSTANDARD SSTL18_I_DCI [get_ports -regexp {c2c_sync[[0-9]{1,2}]}]
这个表达式比上一个更进一步的约束了中括号内的内容。这里的[是为了匹配“[”本身,而里面的[0-9]则定义了一个从数字0到数字9的字符集,[0-9]后面的{1,2}则表示[0-9]中的任意数字将出现1次,或以任意两个数字的组合出现1次。对于我们的应用,做到这一步就够了。
3.2 简化匹配表达式
工程中会有一些名字很特殊的信号,比如全局复位信号,这种信号在工程中往往只会出现一次,我用更加简单粗暴的方式来获得。
set_false_path -from [get_cells -regexp -hierarchical .*rst_global_reg.*]
比如上面的例子。通过使用-hierarchical搜索所有层次,通过在rst_global_reg的前后都使用.*来匹配任何可能出现的字符。其中。表示匹配任何非换行符的字符,*表示。可以出现任意次。当然并不推荐这种写法,因为会增加编译时匹配对象的负担。可以使用更精准的匹配。
对于层次很深的信号,只要保证列出的匹配字符能够找到我们所要的对象即可。比如某工程有下图的层次结构。
比如设计者发现A_i0模块内部的D_i0内的某个关键信号的位置需要优化,且设计者知道该信号在D_i0中唯一。为了拿到这个关键信号,可以使用正则表达式,并且可以略过中间层次的所有模块。
get_cells -regexp -hierarchical {A_i0/.*/D_i0/start_reg}
3.3 特殊字符的获取
前面提到过一些特殊字符,比如?、。、/、[等等,如果需要匹配这些字符,需要用到转义符“”。比如“。”表示“。”这个字符本身,而不再是匹配符。。
比如在上文提到的get_ports -regexp {c2c_sync[[0-9]{1,2}]}。这个总线的完整名称是c2c_sync[0]、c2c_sync[1]。..。..,此处的“[”就是表示左方括号这个字符本身。而[0-9]中单独使用的[]就表示一个字符集合。这里有个需要注意的地方,作为字符使用的左方括号左侧加了转义符““,而右方括号则不需要加”“。
另外一个需要注意的是上文中提到的get_cells -regexp -hierarchical ConfigRegs_i/bus_hsio_dly.*_fine_sel.*。这里面bus_hsio_dly是一个systemverilog中的interface,获取的对象是bus_hsio_dly接口中的cmph_fine_sel_reg信号,其表达方式应该是bus_hsio_dly.cmph_fine_sel_reg。此处我使用”.*“来匹配任何非换行字符,所以可以匹配”。“字符。
更合适一点的匹配表达式应该是ConfigRegs_i/bus_hsio_dly。.*_fine_sel_reg。第一处修改是明确使用。来匹配”。“,第二处修改时添加了_reg后缀(Vivado会给寄存器变量默认添加_reg后缀)。如果不添加该后缀,可能会获取一些不期望的对象。比如使用get_cells时,可能或获取带_fine_sel的LUT,比如_fine_sel_i_1等等。
再进一步,我们可能注意到上述匹配获得的对象打印出来是:
bus_hsio_dly\.cmph_fine_sel_reg
打印结果不是。,而是\。。对于这种情况,我猜想是\用来表示转义符”“。而”\“表示的转义符则作用于特殊字符”。“,用来表示普通字符”。“。
这是个人猜测,但是为什么会这样?如果哪位清楚原因,不吝赐教。
举报