赞
踩
本篇文章简单总结使用XILINX FPGA时常用的约束文件添加方式以及语法格式,分别以及ISE14.7以及VIVADO19.1为例,进行说明。
需要注意的是,FPGA中的约束文件只能起到辅助作用,而设计才是保证功能的关键。以时序约束中的伪路径为例,电路设计中必须进行跨时钟域处理,保证电路功能的正确性,而伪路径约束只是告诉工具我们的意图,让工具在这条路径之间不做时序分析。但若跨时钟域处理不当,那么无论时序约束给的多么好,也无法将一个有问题的设计纠正。
在ISE中,约束文件的名字以.ucf的形式存在,ucf即user constraints files,可以通过两种方式生成,一种是通过ISE的图形化界面进行向导式生成,另一种则是直接通过文本编译的方式来生成。
对于新手来说,采用这种图形化界面生成约束文件会更容易理解和学习,但其相对比较好使。
具体操作方法如下:
以管脚约束为例,可以在ISE左侧界面中依次展开1并且选择2进入管脚约束界面,进入之后可以看到我们设计中顶层的信号,需要对这些信号选择合适的管脚以及电平,具体应该选择哪一个管脚需要根据自己的设计需要以及所使用FPGA芯片手册来选择,而对应的电平也应该与手册保持一致。生成后进行保存,工程路径下会多出一个.ucf的文件。
打开文件会看到文件内容为端口相关的管脚约束,如:NET "reset" LOC = D16;代表将reset信号连接到FPGA的D16引脚上。
虽说图形化界面非常直观和容易理解,但为了提升效率,大多数情况下我们使用文本编译的方式进行UCF文件生成。
操作方法如下:
右击空白处1,然后选择2新生成一个源文件。 然后选择3,生成一个UCF文件,然后打开它,然后我们通过文本编译的方式,通过语法来完成管脚约束以及时序约束。这里有一个技巧,就是可以复制之前工程的UCF文件,然后修改它,进行新的设计的约束。具体语法的含义在下节介绍。
{NET|INST|PIN} "signal_name" Attribute;
“signal_name”是指所约束对象的名字,包含了对象所在层次的描述;“Attribute”为约束的具体描述;语句必须以分号“;”结束。可以用“#”或“/* */”添加注释。需要注意的是:UCF文件是大小写敏感的,信号名必须和设计中保持大小写一致,但约束的关键字可以是大写、小写甚至大小写混合。
在UCF文件中,通配符指的是“*”和“?”。“*”可以代表任何字符串以及空,“?”则代表一个字符。在编辑约束文件时,使用通配符可以快速选择一组信号,当然这些信号都要包含部分共有的字符串。例如:NET "*CLK?" FAST; #作用:将包含“CLK”字符并以一个字符结尾的所有信号,并提高了其速率。在位置约束中,可以在行号和列号中使用通配符。例如:INST "/CLK_logic/*" LOC = CLB_r*c7; #作用:把CLK_logic层次中所有的实例放在第7列的CLB中。
在UCF文件中,通过通配符*可以指定信号的设计层次。其语法规则为:" * " 遍历所有层次
Level1/* 遍历level1及以下层次中的模块;Level1/*/ 遍历level1种的模块,但不遍历更低层的模块。
LOC约束是FPGA设计中最基本的布局约束和综合约束,能够定义基本设计单元在FPGA芯片中的位置,可实现绝对定位、范围定位以及区域定位。此外, LOC还能将一组基本单元约束在特定区域之中。LOC语句既可以书写在约束文件中,也可以直接添加到设计文件中。换句话说,ISE中的FPGA底层工具编辑器(FPGA Editor)、布局规划器(Floorplanner)和引脚和区域约束编辑器的主要功能都可以通过LOC语句完成。
(1)LOC语句语法
基本的LOC语法如下:
INST "instance_name " LOC = location;
其中“location”可以是FPGA芯片中任一或多个合法位置。如果为多个定位,需要用逗号“,”隔开,如下所示:
LOC = location1,location2,...,locationx;
目前,还不支持将多个逻辑置于同一位置以及将多个逻辑至于多个位置上。需要说明的是,多位置约束并不是将设计定位到所有的位置上,而是在布局布线过程中,布局器任意挑选其中的一个作为最终的布局位置。
范围定位的语法为:
INST “instance_name” LOC=location:location [SOFT];
常用的LOC定位语句如下表所示。
使用LOC完成端口定义时,其语法如下:
NET "Top_Module_PORT" LOC = "Chip_Port";
其中,“Top_Module_PORT”为用户设计中顶层模块的信号端口,“Chip_Port”为FPGA芯片的管脚名。
LOC语句中是存在优先级的,当同时指定LOC端口和其端口连线时,对其连线约束的优先级是最高的。例如,在下图中,LOC=11的优先级高于LOC=38。
LOC优先级示意图
(2)LOC属性说明
LOC语句通过加载不同的属性可以约束管脚位置、CLB、Slice、TBUF、块RAM、硬核乘法器、全局时钟、数字锁相环(DLL)以及DCM模块等资源,基本涵盖了FPGA芯片中所有类型的资源。由此可见,LOC语句功能十分强大,下表列出了LOC的常用属性。
与ISE相似,VIVADO也可以通过图形化界面和文本编译两种方式完成约束文件的生成,但在VIVDAO中,我们把约束文件称为XDC文件。
可以通过PROJECT MANAGER的Open Elaborated Design或Open Synthesis Design来打开综合前设计或综合后设计。如下图中1和2处所示。
打开后在右上角选择I/O planning进行管脚约束。
在3处选择I/O Planning,在会打开上图所示界面,在4处选择相应的管脚和电平即可,选择完记得保存。
如上图所示,依次点击1和2,选择创建 一个约束文件,打开后可以根据自己的需求,进行管脚约束或时序约束。常用的语法和功能由下节介绍。
- ##将led1信号放在芯片的W13引脚
- set_property PACKAGE_PIN W13 [get_port led1]
-
- ##将led1所在引脚的电气标准设置为LVCMOS33
- set_property IOSTANDARD LVCMOS33 [get_ports led1]
-
- ##将led1引脚上拉电阻约束为有效
- set_property PULLUP true [get_ports led1]
-
- ##将led1引脚下拉电阻约束为有效
- set_property PULLDOWN true [get_ports led1]
-
- ##IO的驱动能力不够导致线上的电平不能马上到达期望的波形,从而产生抖动。提高电源及时供给能力可以采用在##芯片电源引脚周围加入较大电容储能。默认驱动能力为12mA。驱动能力有< 2 4 6 8 12 16 24 >mA(如果驱动##不上看共地有没有问题)。将led1所在管脚驱动能力设置为16mA:
- set_property DRIVE 16 [get_ports led1]
-
- ##输出(双向)引脚转换速率slew rate可以设置为快fast和慢slow。默认为slow。
- ##将led1所在输出引脚转换速率设置为快:
- set_property SLEW FAST [get_ports led1]
-
- ##高速收发器通道位置约束
- set_property LOC GTXE2_CHANNEL_X0Y8 [get_cells 例化路径/gtx_support_i/gtx_init_i/inst/gtx_i/gt0_gtx_i/gtxe2_i]
-
- ##输入输出模块IOB的约束。(如果在FF输出Q除了到OBUF连线输出外还有其他连接,就无法实现IOB寄存器的布##局,只能用CLB中的寄存器。需要将该信号再按时钟打一拍再单独输出。)
- set_property IOB TRUE [get_ports led1]
- # led1 输出使用IOB
- set_property IOB TRUE [all_inputs]
- # 所有输入使用IOB
-
-
- ##PCIE等、使用GT接口的链路时延需要配置链路参数
- # up_pcie_drive
- set_property TX_RXDETECT_REF 3'b001 [get_cells {例化路径/inst/gt_top_i/pipe_wrapper_i/pipe_lane[0].gt_wrapper_i/gtx_channel.gtx_channel.gtxe2_channel_i}]
- set_property TX_MARGIN_FULL_0 7'b1001010 [get_cells {例化路径/inst/gt_top_i/pipe_wrapper_i/pipe_lane[0].gt_wrapper_i/gtx_channel.gtx_channel.gtxe2_channel_i}]
-
-
-
- ##外部输入时钟clk_in周期为10ns,占空比为25%,相移为90°约束形式为
- create_clock -name clk_in -period 10 -waveform{2.5 5} [get_ports clk_in]
- # {2.5 5} 表示一个周期的波形中2.5ns - 5ns 为高。如果没有指定waveform默认为{0,period/2}为高
-
- ##时钟clk_2由时钟clk_in衍生,clk_2频率为clk_in的频率除以2,clk_2表示modu_2模块的clk_out
- create_generated_clock -name clk_2 -source [get_port clk_in] -divide_by 2 [get_pins modu_2/clk_out]
- # clk_in 0011001100110011001100
- # clk_2 0011110000111100001111
-
- ##时钟clk_3由时钟clk_in衍生,clk_3表示modu_3模块的clk_out
- create_generated_clock -name clk_3 -source [get_ports clk_in] -edges {1 3 5}[get_pins top/modu_3/clk_out]
- # edges{1 3 5}表示从上升沿开始算起,在clk_in的第1、3、5时钟沿clk_3时钟沿变化。
- # clk_in 001110011100111001110011100
- # clk_3 001111100000111110000011111
-
- ##设置clock group来确认各个时钟之间的关系。两个主时钟 clkin_1 和 clkin_2 进入 FPGA由不同的时钟网##络传递,这两个时钟及他们的衍生时钟是一组异步时钟
- set_clock_groups -name async_clk -asynchronous \
- -group [get_clocks -include_generated_clocks clkin_1] \
- -group [get_clocks -include_generated_clocks clkin_2]
- # -asynchronous 表示异步
- # -include_generated_clocks 表示包括衍生时钟
-
- ##有时同一模块在不同模式需要不同时钟来驱动。例如bufgctrl_i/O可由bufgctrl_i/I0和bufgctrl_i/I1衍##生
- create_generated_clock -name clk125_bufgctrl \
- -divide_by 1 [get_pins bufgctrl_i/O] \
- -source [get_ports bufgctrl_i/I0]
- create_generated_clock -name clk250_bufgctrl \
- -divide_by 1 [get_pins bufgctrl_i/O] \
- -source [get_ports bufgctrl_i/I1] \
- -add -master_clock clk125_bufgctrl
- # -add -master_clock表示添加时钟,否则是直接覆盖。
- set_clock_groups –physically_exclusive \
- –group clk125_bufgctrl \
- –group clk250_bufgctrl
- # -physically_exclusive 表示时钟物理意义上不会同时存在,如果为-logically_exclusive则是逻辑上独立。
1.Vivado按照行序从上往下在约束文件中读取XDC的tcl指令,越后面的指令优先级越高,但描述越精确的指令优先级越高(与指令顺序无关)。相同目标属性的约束会向前覆盖。 因为synthesis and implementation algorithms are timing-driven一般把时钟约束放在前面物理位置约束放在后面。物理约束只在implementation时布局器与布线器会使用。
2.一个Vivado工程中可以添加多个XDC文件,XDC文件也是有先后顺序的,可以在界面用鼠标拖拽来调整XDC文件的顺序。工程较大时一般把时钟约束和物理约束放到不同的文件当中,不同IP不同组放到不同文件。VIVADO也可以支持多组XDC文件集合,但是只有1个集合起作用(active)。如果我们一次create多个synthesis或者implementation,我们还可以为它们每一个分别制定一个约束文件。
3.每个XDC约束指令最好单独地完整地写一行(单个命令编写换行时行末加上"\" . "\"后不能有空格)。 注释以“#”开头且与指令不写在同一行。否则指令可能会解析错误。
4.可通过下图所示,获取VIVADO工具给出的时序约束模版。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。