【Xilinx Vivado 时序分析/约束系列11】FPGA开发时序分析/约束-FPGA DDR-PLL接口的 input delay 约束优化方法

18 篇文章 11 订阅
11 篇文章 103 订阅

目录

DDR-PLL 简述

实际操作

实际工程

顶层代码

PLL配置

添加时钟约束

添加 input delay 约束

添加 False Path

Setup Time

Hold Time

Multicycle约束

解决办法

PLL配置

发现问题

建立时间中

保持时间中

添加 False Path

 总结

往期系列博客


 

DDR-PLL 简述

在之前介绍了 DDR-Direct 的时序模型,也就是不带有 PLL 的普通时序模型,这节重点介绍带有 PLL 的模型,在SDR采样模型中也介绍到这两种时序模型,因此同样的也会带有 PLL 的时序模型,PLL 的功能也是一样,可以对时钟进行偏移,可以正偏移也可以负偏移,对应的是时钟的延时增大和减小。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

在分析时,默认PCB数据路径延迟Td_bd和PCB时钟路径延迟Tc_bd是一致的,因此在分析到达FPGA管脚的时钟和数据的状态时,只需要知道在上游器件的管脚的时钟和数据的状态,就可以对FPGA的时钟和数据进行约束,分析时钟和数据的相位关系即可。

以下是时序图,在DDR-Direct中有详细的分析,这里不多介绍。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

这种时序模型可以用在input带有 PLL 的情况和不带有 PLL 的情况,带有 PLL 情况下采样时钟相移为正时需要进行 false path + Multicycle 约束,否则分析报告不正确。

实际操作

这次依然以索尼的一款CMOS器件的手册为例。

时钟频率为54Mhz,即周期为18.519ns,半周期为9.259ns。在参数表中可以看到Max skew为2ns,因此,从图中可以看出第一个下降沿作为采样沿时的数据是由上一个上升沿发射出来的,此时图中箭头1所指的时刻为input delay的最小值,而箭头2的时刻为input delay的最大值;同样的,当第一个下降沿作为发射沿发射数据时,下一个上升沿作为采样沿,此时的input delay的最大、最小值分别为箭头3、4所指的时刻。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

这里需要注意的是,由于这里采用的是PLL对时钟进行移相,所以会产生一个新的时钟,因此要对时序约束工具进行多一些的操作,让时序工具能够正确的识别到,以免给出错误的时序报告。

实际工程

依然是 DDR-Direct 的实验工程,只需对顶层文件做个小改动。

顶层代码

将上一节加入的IDELAY2原语注释或删除,并例化PLL,将rx_clk作为输入,rx_clk_90作为输出。

module top_ioddr(
    input wire        rx_clk,
    input wire        rx_ctrl,
    input wire    [3:0] rx_dat,
  //tx
    output  wire    tx_clk,
    output  wire [3:0]  tx_d,
    output  wire    tx_dv,
    input	wire 	sdrclk,
    input	wire 	[3:0]	sdrdata,
    input	wire 	sdrden,
    input	wire 	sysclk,
    output	reg 	tout 	
	);
wire RDY;
wire rst;
wire rx_clk_90;
wire rx_en;
wire [7:0] rx_data;

reg tx_en1,tx_en2;
reg [7:0] tx_data1,tx_data2;
wire	sdrclk1;
assign rst =0;
//assign rx_clk_90 = rx_clk;

 IDELAYCTRL IDELAYCTRL_inst (
.RDY(RDY),       // 1-bit output: Ready output
.REFCLK(sysclk), // 1-bit input: Reference clock input
.RST(1'b0)        // 1-bit input: Active high reset input
);


clk_wiz_0 clk_gen0
   (
    // Clock out ports
    .clk_out1(rx_clk_90),     // output clk_out1
   // Clock in ports
    .clk_in1(rx_clk));      // input clk_in1

assign sdrclk1 = sdrclk;

always @(posedge rx_clk_90 or posedge rst) begin
	if (rst == 1'b1) begin
		tx_data1 <= 'd0;
	end
	else if (rx_en == 1'b1) begin
		tx_data1 <= rx_data+ rx_data -1;
	end
end

always @(posedge rx_clk_90 or posedge rst) begin
	if (rst == 1'b1) begin
		tx_data2 <= 'd0;
	end
	else if (tx_en1 == 1'b1) begin
		tx_data2 <= tx_data1+ tx_data1 -5;
	end
end

always @(posedge rx_clk_90 ) begin
	tx_en1 <= rx_en;
end

always @(posedge rx_clk_90 ) begin
	tx_en2 <= tx_en1;
end

	iddr_ctrl inst_iddr_ctrl
		(
			.rx_clk_90 (rx_clk_90),
			.rst       (rst),
			.rx_dat    (rx_dat),
			.rx_ctrl   (rx_ctrl),
			.rx_en     (rx_en),
			.rx_data   (rx_data)
		);

	oddr_ctrl inst_oddr_ctrl
		(
			.sclk    (rx_clk_90),
			.tx_dat  (tx_data2),
			.tx_en   (tx_en2),
			.tx_c    (rx_clk_90),
			.tx_data (tx_d),
			.tx_dv   (tx_dv),
			.tx_clk  (tx_clk)
		);

//sdr clock domain

reg [3:0] sdrdata_r1,sdrdata_r2;
reg 	sdrden_r1,sdrden_r2;

always @(posedge sdrclk1 ) begin
	{sdrdata_r2,sdrdata_r1} <= {sdrdata_r1,sdrdata};
end
always @(posedge sdrclk1 ) begin
	{sdrden_r2,sdrden_r1} <= {sdrden_r1,sdrden};
end

always @(posedge sdrclk1) begin
	if(sdrden_r2 == 1'b1) begin
		tout <= (&sdrdata_r1)|(&sdrdata_r2);
	end
	else begin
		tout <= (^sdrdata_r2);
	end
end

endmodule

PLL配置

设置向右相移30°,也就是1/12个周期,大约为1.543ns。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

对工程布局布线,完成之后可以打开布线设计,并编辑时序约束。

添加时钟约束

对 rx_clk 进行约束,周期为18.518ns

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

添加 input delay 约束

需要对四个 input delay 进行约束,分别为上升沿的Max、Min,下降沿的Max、Min。

以上升沿的Max作为示例,最大为2ns

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

下降沿的 Max 设定为2ns,并勾选 no overwrite

注意!在对下降沿进行约束时,在图中箭头所指的参数需要勾选,表示此约束是否会覆盖之前上升沿所做的约束,因为本次实验是DDR双沿采样,上升沿和下降沿既作发射沿也作采样沿,因此在定义下降沿约束时,需要作不覆盖之前约束的操作,而之前的SDR则不需要。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

input delay 约束汇总如图

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

CTRL+S 保存点开XDC约束文件即可看到刚刚添加的约束信息

create_clock -period 18.518 -name sdrclk -waveform {0.000 9.259} [get_ports sdrclk]
set_input_delay -clock [get_clocks rx_clk] -rise -max 2.000 [get_ports {rx_ctrl {rx_dat[0]} {rx_dat[1]} {rx_dat[2]} {rx_dat[3]}}]
set_input_delay -clock [get_clocks rx_clk] -rise -min -2.000 [get_ports {rx_ctrl {rx_dat[0]} {rx_dat[1]} {rx_dat[2]} {rx_dat[3]}}]
set_input_delay -clock [get_clocks rx_clk] -clock_fall -fall -max -add_delay 2.000 [get_ports {rx_ctrl {rx_dat[0]} {rx_dat[1]} {rx_dat[2]} {rx_dat[3]}}]
set_input_delay -clock [get_clocks rx_clk] -clock_fall -fall -min -add_delay -2.000 [get_ports {rx_ctrl {rx_dat[0]} {rx_dat[1]} {rx_dat[2]} {rx_dat[3]}}]

从下图可以看到,在不对时序作false path的约束时,约束工具会把一些不必要的路径,在对下表的内容做约束后,上升沿与上升沿之间是不需要分析建立时间的,上升沿和下降沿之间也不需要做保持时间。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

添加 False Path

在timing constraints中的exceptions中的set false path添加

Setup Time

首先对两个上升沿之间的建立时间做false path,From是rx_clk的上升沿,To是PLL输出的时钟的上升沿。

下降沿同理

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

并在options中设定为上升沿rise的mark

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

Hold Time

再对保持时间做false path,From是rx_clk的上升沿,To是PLL输出的时钟的下降沿。

另一个From是rx_clk的下降沿,To是PLL输出的时钟的上升沿。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

在options中设定为hold time的mark

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

Multicycle约束

这时候就会避免掉一些错误的时序报告,但是仍然有一些错误的报告,比如rx_clk的上升沿与PLL输出的时钟的上升沿之间(L1r与C2r之间)作保持时间的分析。这时候就需要做另外一种约束Multicycle约束。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

同样的,在Exceptions中添加Multicycle,需要让PLL的上升沿左移一个,即让C2r变成C0r,设置成-1即可

下降沿的设置也是一样的。不多赘述。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

options中设定为hold time。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

保存后就可以看到XDC文件中有了 false path 和 Multicycle 的约束文件

set_false_path -setup -rise_from [get_clocks rx_clk] -rise_to [get_clocks [get_clocks -of_objects [get_pins clk_gen0/inst/mmcm_adv_inst/CLKOUT0]]]
set_false_path -setup -fall_from [get_clocks rx_clk] -fall_to [get_clocks [get_clocks -of_objects [get_pins clk_gen0/inst/mmcm_adv_inst/CLKOUT0]]]
set_false_path -hold -rise_from [get_clocks rx_clk] -fall_to [get_clocks [get_clocks -of_objects [get_pins clk_gen0/inst/mmcm_adv_inst/CLKOUT0]]]
set_false_path -hold -fall_from [get_clocks rx_clk] -rise_to [get_clocks [get_clocks -of_objects [get_pins clk_gen0/inst/mmcm_adv_inst/CLKOUT0]]]
set_multicycle_path -hold -rise_from [get_clocks rx_clk] -rise_to [get_clocks [get_clocks -of_objects [get_pins clk_gen0/inst/mmcm_adv_inst/CLKOUT0]]] -1
set_multicycle_path -hold -fall_from [get_clocks rx_clk] -fall_to [get_clocks [get_clocks -of_objects [get_pins clk_gen0/inst/mmcm_adv_inst/CLKOUT0]]] -

重新reload一下时序报告可以看到,时序出现了违例,通过看时序报告可以得出这个时序报告是正确的。只有在时序报告是正确的情况下,再去做时序约束才是有意义的,如果时序报告给的是错的,那时序约束也是无用功。时序报告是正确的,即使是违例的,我们再去调整也不麻烦。因此学会让时序工具给出正确的时序报告比懂得如何约束更重要!

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

report timing可以看到保持时间出现了违例

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

解决办法

现在得到了正确的时序报告,如何去修正时序呢,利用PLL的移相的功能就可以实现,既然是保持时间出现了违例,就说明是时钟的延时过大,只需要将PLL向左相移60°,即可恢复时序正常。

PLL配置

双击打开PLL配置界面,将相移改成-60即可

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

重新布局布线,由于这次是将PLL向左相移,所以在刚刚向右移的PLL所设定的Falsh Path和Multicycle删除掉,然后重新 reload 并 report time 查看时序报告。

发现问题

这时候看可以看到时序恢复了正常。但是有些余量是不正常的

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

建立时间中

rx_clk的rise到PLL的rise是不对的

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

rx_clk的fall到PLL的fall是不对的

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

保持时间中

rx_clk的fall到PLL的rise是不对的

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

rx_clk的rise到PLL的fall是不对的

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

添加 False Path

这四种情况所得到的建立时间和保持时间是不对的,因此需要把他们利用false path进行剔除。

添加四个false path

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

另外,不需要添加Multicycle,因为在使用PLL时,向右相移时才需要添加Multicycle,而向左相移则不需要添加。

重新reload可以看到给出的是正确的时序,并且时序恢复了正常。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

 总结

如何得到正确的时序报告比如何解决时序违例更重要,知道问题的根,才能更好的解决问题!在用PLL进行时序优化时,注意看是否需要添加 False Path 和 Multicycle,以及怎么添加这些约束。

往期系列博客

 【Xilinx Vivado时序分析/约束系列1】FPGA开发时序分析/约束-寄存器间时序分析

 【Xilinx Vivado时序分析/约束系列2】FPGA开发时序分析/约束-建立时间

 ​​​​​​【Xilinx Vivado时序分析/约束系列3】FPGA开发时序分析/约束-保持时间

 【Xilinx Vivado时序分析/约束系列4】FPGA开发时序分析/约束-实验工程上手实操

 【Xilinx Vivado时序分析/约束系列5】FPGA开发时序分析/约束-IO时序分析

 【Xilinx Vivado时序分析/约束系列6】FPGA开发时序分析/约束-IO时序输入延时

 【Xilinx Vivado时序分析/约束系列7】FPGA开发时序分析/约束-FPGA单沿采样数据input delay时序约束实操

 【Xilinx Vivado时序分析/约束系列8】FPGA开发时序分析/约束-FPGA数据中间采样、边缘采样PLL时序优化实操

 【Xilinx Vivado时序分析/约束系列9】FPGA开发时序分析/约束-FPGA单沿数据input delay边沿对齐,不同时序模型实操练习

 【Xilinx Vivado 时序分析/约束系列10】FPGA开发时序分析/约束-FPGA DDR-Direct接口的 input delay 约束优化方法

 

 

  • 5
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
Vivado中,时序约束(或时钟约束)是用来指定时钟的特性和限制的。对于PLL(Phase-Locked Loop,锁相环)时钟,可以通过以下步骤进行约束设置: 1. 首先,在约束文件(.xdc文件)中定义PLL时钟对象。可以使用set_clocks命令来定义PLL时钟,指定时钟名称、时钟源、时钟频率等相关属性。 2. 如果在约束文件中已经定义了PLL时钟对象,那么Vivado将不会自动生成相同对象上的时钟。 3. 在时序约束中,可以使用时钟延迟约束来指定时钟的上升沿或下降沿延迟。可以使用-add_delay选项来避免下降沿延迟覆盖上升沿延迟。 总之,通过在约束文件中定义和设置PLL时钟对象,可以对PLL时钟进行时序约束的设置。 需要注意的是,在进行时序分析时,同步时钟可以安全地进行时序分析,而异步时钟和不可扩展时钟的时序分析结果可能不可靠。对于异步时钟和不可扩展时钟,可以通过设置时钟组来忽略其时序路径的分析。 在7系列FPGA中,CMB单元包括MMCM、PLL、BUFR和PHASER等,而UltraScale系列FPGA的CMB单元种类更多。具体的CMB单元种类和数量可以根据实际情况查阅相关文档,这里不一一列举。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [vivado时序约束](https://blog.csdn.net/qq_42322644/article/details/118311470)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Vivado使用技巧(31):时钟的约束方法](https://blog.csdn.net/FPGADesigner/article/details/82871624)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Linest-5

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

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

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

打赏作者

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

抵扣说明:

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

余额充值