XILINX之约束篇

        本篇文章简单总结使用XILINX FPGA时常用的约束文件添加方式以及语法格式,分别以及ISE14.7以及VIVADO19.1为例,进行说明。

        需要注意的是,FPGA中的约束文件只能起到辅助作用,而设计才是保证功能的关键。以时序约束中的伪路径为例,电路设计中必须进行跨时钟域处理,保证电路功能的正确性,而伪路径约束只是告诉工具我们的意图,让工具在这条路径之间不做时序分析。但若跨时钟域处理不当,那么无论时序约束给的多么好,也无法将一个有问题的设计纠正。

1、ISE14.7如何生成约束文件

        在ISE中,约束文件的名字以.ucf的形式存在,ucf即user constraints files,可以通过两种方式生成,一种是通过ISE的图形化界面进行向导式生成,另一种则是直接通过文本编译的方式来生成。

1.1 使用图形化界面向导生成UCF文件

        对于新手来说,采用这种图形化界面生成约束文件会更容易理解和学习,但其相对比较好使。

        具体操作方法如下:

         以管脚约束为例,可以在ISE左侧界面中依次展开1并且选择2进入管脚约束界面,进入之后可以看到我们设计中顶层的信号,需要对这些信号选择合适的管脚以及电平,具体应该选择哪一个管脚需要根据自己的设计需要以及所使用FPGA芯片手册来选择,而对应的电平也应该与手册保持一致。生成后进行保存,工程路径下会多出一个.ucf的文件。

        打开文件会看到文件内容为端口相关的管脚约束,如:NET "reset"         LOC = D16;代表将reset信号连接到FPGA的D16引脚上。

1.2 使用文本编译的方式生成UCF文件

        虽说图形化界面非常直观和容易理解,但为了提升效率,大多数情况下我们使用文本编译的方式进行UCF文件生成。

        操作方法如下:

        右击空白处1,然后选择2新生成一个源文件。         然后选择3,生成一个UCF文件,然后打开它,然后我们通过文本编译的方式,通过语法来完成管脚约束以及时序约束。这里有一个技巧,就是可以复制之前工程的UCF文件,然后修改它,进行新的设计的约束。具体语法的含义在下节介绍。

1.3 UCF文件的语法格式和含义

1.3.1 语法

{NET|INST|PIN} "signal_name" Attribute;

        “signal_name”是指所约束对象的名字,包含了对象所在层次的描述;“Attribute”为约束的具体描述;语句必须以分号“;”结束。可以用“#”或“/* */”添加注释。需要注意的是:UCF文件是大小写敏感的,信号名必须和设计中保持大小写一致,但约束的关键字可以是大写、小写甚至大小写混合。

1.3.2 通配符

        在UCF文件中,通配符指的是“*”和“?”。“*”可以代表任何字符串以及空,“?”则代表一个字符。在编辑约束文件时,使用通配符可以快速选择一组信号,当然这些信号都要包含部分共有的字符串。例如:NET "*CLK?" FAST;  #作用:将包含“CLK”字符并以一个字符结尾的所有信号,并提高了其速率。在位置约束中,可以在行号和列号中使用通配符。例如:INST "/CLK_logic/*" LOC = CLB_r*c7;  #作用:把CLK_logic层次中所有的实例放在第7列的CLB中。

1.3.3 定义设计层次   

        在UCF文件中,通过通配符*可以指定信号的设计层次。其语法规则为:" * " 遍历所有层次

Level1/*    遍历level1及以下层次中的模块;Level1/*/   遍历level1种的模块,但不遍历更低层的模块。

1.3.4 引脚和区域约束语法

        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的常用属性。

2、在VIVADO中生成约束文件

        与ISE相似,VIVADO也可以通过图形化界面和文本编译两种方式完成约束文件的生成,但在VIVDAO中,我们把约束文件称为XDC文件。

2.1 图形化界面生成XDC

        可以通过PROJECT MANAGER的Open Elaborated Design或Open Synthesis Design来打开综合前设计或综合后设计。如下图中1和2处所示。

打开后在右上角选择I/O planning进行管脚约束。 

        在3处选择I/O Planning,在会打开上图所示界面,在4处选择相应的管脚和电平即可,选择完记得保存。

2.2 使用文本编译的方式生成XDC文件

        如上图所示,依次点击1和2,选择创建 一个约束文件,打开后可以根据自己的需求,进行管脚约束或时序约束。常用的语法和功能由下节介绍。

2.3 XDC文件中的常用语法和功能

2.3.1 管脚约束

##将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}]



 2.3.2 时序约束

##外部输入时钟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则是逻辑上独立。

2.3.3 其他补充

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工具给出的时序约束模版。

  • 16
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
这些代码是针对 Vivado 工具对 FPGA 设计进行约束(constraints)的语句,用于指定 FPGA 设备的引脚映射、时钟、电平标准等信息,以保证设计在硬件上能够正确工作。 具体来说,这些语句的含义如下: 1. `set_property -dict { PACKAGE_PIN H16 IOSTANDARD LVCMOS33 } [get_ports { clk }];` - `set_property` 是 Vivado 工具中的约束命令,用于设置约束属性。 - `-dict { PACKAGE_PIN H16 IOSTANDARD LVCMOS33 }` 表示设置一个字典类型的属性,其中 `PACKAGE_PIN` 表示引脚的物理位置,`H16` 是该引脚的位置,`IOSTANDARD` 表示引脚的电平标准,`LVCMOS33` 表示使用 LVCMOS33 标准。 - `[get_ports { clk }]` 表示获取名为 `clk` 的端口对象,将 `PACKAGE_PIN` 和 `IOSTANDARD` 属性设置为上面指定的值。 2. `create_clock -add -name sys_clk_pin -period 8.00 -waveform {0 4} [get_ports { clk }];` - `create_clock` 命令用于创建时钟对象。 - `-add` 表示将新的时钟添加到已有的时钟列表中。 - `-name sys_clk_pin` 表示设置时钟的名称为 `sys_clk_pin`。 - `-period 8.00` 表示时钟周期为 8ns。 - `-waveform {0 4}` 表示时钟波形为持续 0ns,然后持续 4ns。 - `[get_ports { clk }]` 表示获取名为 `clk` 的时钟端口对象,将其设置为新建时钟的源。 3. `set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[7]}]`、`set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[6]}]`、`set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[5]}]`、`set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[4]}]`、`set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[3]}]`、`set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[2]}]`、`set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[1]}]`、`set_property IOSTANDARD LVCMOS33 [get_ports {ad_data[0]}]` - 这些语句用于设置名为 `ad_data[7]`、`ad_data[6]`、`ad_data[5]`、`ad_data[4]`、`ad_data[3]`、`ad_data[2]`、`ad_data[1]`、`ad_data[0]` 的端口使用 LVCMOS33 电平标准。 4. `set_property PACKAGE_PIN T14 [get_ports {ad_data[7]}]`、`set_property PACKAGE_PIN U12 [get_ports {ad_data[6]}]`、`set_property PACKAGE_PIN U13 [get_ports {ad_data[5]}]`、`set_property PACKAGE_PIN V13 [get_ports {ad_data[4]}]`、`set_property PACKAGE_PIN V15 [get_ports {ad_data[3]}]`、`set_property PACKAGE_PIN T15 [get_ports {ad_data[2]}]`、`set_property PACKAGE_PIN R16 [get_ports {ad_data[1]}]`、`set_property PACKAGE_PIN U17 [get_ports {ad_data[0]}]` - 这些语句用于将 `ad_data[7]`、`ad_data[6]`、`ad_data[5]`、`ad_data[4]`、`ad_data[3]`、`ad_data[2]`、`ad_data[1]`、`ad_data[0]` 端口映射到具体的 FPGA 引脚上,分别为 `T14`、`U12`、`U13`、`V13`、`V15`、`T15`、`R16` 和 `U17`。 5. `set_property IOSTANDARD LVCMOS33 [get_ports {ad_clk}]`、`set_property PACKAGE_PIN V17 [get_ports {ad_clk}]` - 这些语句用于设置名为 `ad_clk` 的端口使用 LVCMOS33 电平标准,并将其映射到引脚 `V17` 上。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小靴子是社牛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值