Input delay 时序约束实例
概述: 对Input delay时序约束做以描述以及实例分析。
文章目录
1、 IO时序分析的基本模型
我们要想进行FPGA内部IO的时序分析,就要明确外部信号到达FPGA引脚时数据和时钟的相位关系(就是知道何时外部数据和时钟到达FPGA引脚端)。引出以下两个系统模型进行分析
模型一:系统同步FPGA输入模型:由一个时钟源驱动上下游器件。(基本上被淘汰,不适合高速传输)
System clock为晶振。
模型二:源同步FPGA输入模型:上游器件提供同步时钟和同步数据。(逐渐被高速串行协议PCIE、SATA等等取代,但是还是被广泛的应用比如低速的AD、DA器件)
System clock为晶振,为上游器件的两个寄存器提供时钟,Reg2在时钟的上升沿输出高电平,在时钟的下降沿输出低电平,其实输出的就是同步的时钟。
2、引出Input delay
以模型二为例分析:
数据延时:
Tco : 数据在上游器件接口的延迟
Td_bd:数据路径延迟
Td_fi : 数据在FPGA内部到寄存器D端的延迟
时钟延时:
Tc_d : 时钟在上游器件的延迟
Tc_bd:时钟路径延迟
Tc_fi : 时钟在FPGA内部到寄存器C端的延迟
模型二的传输延迟图如下所示:(参考建立时间与保持时间会看的更清楚)
针对FPGA内部的寄存器Reg3:
数据要求到达的时间为:Tc_d +Tc_bd +Tc_fi(时钟采样沿到达的时间)
数据实际到达的时间为:Tco +Td_bd +Td_fi
FPGA内部Tc_fi、Td_fi的延时是知道的,但是外部延时Tc_d +Tc_bd、Tco +Td_bd FPGA是不知道的,那么FPGA不知道怎么这段延时,怎么正确的进行时序分析呢,就引入了input delay约束来告诉FPGA外部器件的时钟和数据的关系。
input delay = 数据到达FPGA引脚时间 - 时钟发射沿到达FPGA引脚时间 = Tco +Td_bd - Tc_d -Tc_bd。
以下是Vivado时序约束中描述的Input delay:
由于数据线不止一根,而且布线有长有短(短快长慢)、线宽不一、阻抗不一等因素,数据延迟就会有最大最小。就会出现 LrMax、LrMin,如下图所示
如果DATA0(看数据到达FPGA引脚的图)往右偏,也就延时更大,则数据到达FPGA内部寄存器也会往右偏,这样就会压缩建立时间余量(Tus_Slack)。
建立时间余量(Setup Slack): 要求数据到达时间和数据实际到达时间的差值。
如果DATA0(看数据到达FPGA引脚的图)往左偏,也就延时更小,则数据到达FPGA内部寄存器也会往左偏,这样就会压缩保持时间余量(Th_Slack)。
保持时间余量(Hold Slack): 数据实际结束位置和要求数据结束位置的差值。
如果建立时间余量或保持时间余量出现负值就会引起时序违例。
3、Input delay时序约束实例以及时序报告解读
通过Vivado进行input delay约束实现FPGA管脚处时钟上升沿到达之后3ns数据到达(时序图中时钟发射沿在左数据在右)并查看时序报告。
顶层设计如下所示:
顶层代码:
(参考B站尤老师代码)
module top_ioddr(
input wire sdrclk,
input wire [3:0] sdrdata,
input wire sdrden,
output reg tout
);
//sdr clock domain
reg [3:0] sdrdata_r1,sdrdata_r2;
reg sdrden_r1,sdrden_r2;
always @(posedge sdrclk ) begin
{
sdrdata_r2,sdrdata_r1} <= {
sdrdata_r1,sdrdata};
end
always @(posedge sdrclk ) begin
{
sdrden_r2,sdrden_r1} <= {
sdrden_r1,sdrden};
end
always @(posedge sdrclk) begin
if(sdrden_r2 == 1'b1) begin
tout <= (&sdrdata_r1)|(&sdrdata_r2);
end
else begin
tout <= (^sdrdata_r2);
end
end
endmodule
约束:
set_property PACKAGE_PIN W19 [get_ports sdrclk]
set_property PACKAGE_PIN Y22 [get_ports sdrden]
set_property PACKAGE_PIN V20 [get_ports {
sdrdata[0]}]
set_property PACKAGE_PIN U20 [get_ports {
sdrdata[1]}]
set_property PACKAGE_PIN AB22 [get_ports {
sdrdata[2]}]
set_property PACKAGE_PIN AB21 [get_ports {
sdrdata[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports sdrclk]
set_property IOSTANDARD LVCMOS33 [get_ports {
sdrdata[*]}]
set_property IOSTANDARD LVCMOS33 [get_ports sdrden]
set_property PACKAGE_PIN Y21 [get_ports tout]
set_property IOSTANDARD LVCMOS33 [get_ports tout]
首先不做任何约束查看时序报告:
因为只查看输入信号,所以只选From,选择数据sdrdata[0]、sdrdata[1]、sdrdata[2]、sdrdata[3]、sdrden
查看时序报告,余量都显示无穷,这是因为我们没有添加任何约束,Vivado为了防止报时序警告就设置为了无穷。
我们添加主时钟约束:
ok保存,查看约束文件,约束已经被添加
设置input delay
数据:(哪些信号相对于时钟的关系要描述就添加谁)
时钟到达3ns后数据到达,则设置max、min均为3ns
Apply 保存,查看约束文件,约束已经添加
重新打开report就能看到时序打印信息
双击Path6,查看详细信号路径延时(图中第二行注释的Max、Min 改为 Fast和Slow)
下图input delay为3ns,详细解读看图
4、以传感器送数据到FPGA为例分析input delay
以SONY的一款CMOS传感器IMX222LQJ-C传输数据到FPGA为例进行input delay分析。
传感器时序图如下所示
从以上时序图以及描述中我们可以得到以下信息:
①、传感器数据传输工作模式有两种
模式一:数据起始与时钟的下降沿对齐。
模式二:数据起始与时钟的上升沿对齐。
②、数据相对时钟沿,往右最大延时2ns。
数据相对时钟沿,往左最大延时2ns
③、时钟可以工作在54MHz或者37.125Hz,我们选择54MHz进行分析。
下图中红框处代表传感器的输出引脚,蓝框处代表FPGA输入引脚,知道上图的时序关系,就知道了红框处即传感器输出引脚的时钟和数据的相位关系,通过PCB工程师以及一些材料介质等计算会得到中间PCB布线延时(一般会做等延时处理),所以蓝框处即FPGA输入引脚处的时钟和数据的相位关系也就知道了,从而就可以约束input delay。
4.1 、传感器在模式一(数据起始与时钟的下降沿对齐)下时序分析
传感器在模式一下,数据起始与时钟的下降沿对齐。
因为
input delay = 数据到达FPGA引脚时间 - 时钟发射沿到达FPGA引脚时间 。
所以
从上图Data1处可以看出的Input delay Min和Input delay Max。
Input delay Min:周期/2 - 2ns。
Input delay Max:周期/2 + 2ns。
时钟频率为54MHz,时钟周期为18.5185,做主时钟约束
约束input delay(min=周期/2-2ns;max=周期/2+2ns)
约束文件
综合实现后打开时序报告,在数据的中心对数据进行采样时,没有时序违例。
仔细观察:发现相同的路径有两个报告
分别打开Path11和Path16:两种不同的报告是软件在不同的环境下分析的。
比如CPU温度高了就会降频,CPU为低压版本工作频率就相对低,FPGA也一样,就会导致信号延时增加。
4.2 、传感器在模式二(数据起始与时钟的上升沿对齐)下时序分析
传感器在模式二下,数据起始与时钟的上升沿对齐。
因为
input delay = 数据到达FPGA引脚时间 - 时钟发射沿到达FPGA引脚时间 。
所以
从上图Data0处可以看出的Input delay Min和Input delay Max。
Input delay Min: - 2ns。
Input delay Max: + 2ns。
更改时序约束
查看约束文件:
直接rerun时序(不综合布局布线):hold Time出现了时序违例
便是以下模型,建立时间余量很大,保持时间余量成为了负值
建立时间余量:要求数据到达的时间 - 实际数据到达的时间(②-①)。
保持时间余量:数据实际结束的时间 - 要求数据结束的时间(④-③)。
但是如果重新布局布线就会发现,上面的违例消失了,这是因为在布局布线的时候,综合工具会增加数据的走线延时,来得到正确的建立时间余量个保持时间余量。
4.2.3 利用PLL相移消除时序违例
但是如果时序违例严重,我们可以通过PLL具有调相的功能来实现时钟的移位使之消除建立时间余量和保持时间余量的违例。以下为加入PLL的系统模型:
加入PLL调整时钟相位使之出现正值的保持时间余量(图中是将上图时序中的时钟左移)。
但是实际PLL具体该怎么加入呢?
步骤1: 加入PLL IP,先不设置相移查看一次时序报告,删除XDC之前的时钟约束,主时钟的约束也删除,因为PLL会生成主时钟的约束。
top代码:
module top_ioddr(
input wire sdrclk,
input wire [3:0] sdrdata,
input wire sdrden,
output reg tout
);
clk_wiz_0 clk_gen0
(
// Clock out ports
.clk_out1(sdrclk1), // output clk_out1
// Clock in ports
.clk_in1(sdrclk)); // input clk_in1
//sdr clock domain
reg [3:0] sdrdata_r1,sdrdata_r2;
reg sdrden_r1,sdrden_r2;
always @(posedge sdrclk ) begin
{
sdrdata_r2,sdrdata_r1} <= {
sdrdata_r1,sdrdata};
end
always @(posedge sdrclk ) begin
{
sdrden_r2,sdrden_r1} <= {
sdrden_r1,sdrden};
end
always @(posedge sdrclk) begin
if(sdrden_r2 == 1'b1) begin
tout <= (&sdrdata_r1)|(&sdrdata_r2);
end
else begin
tout <= (^sdrdata_r2);
end
end
endmodule
打开时序约束窗口:
以下是PLL自动约束的
添加 input delay约束
保存
打开report timing
报告如下:
保持时间出现违例(和不加PLL一样,因为我们没有做相移),要么是数据延时太小,要么是时钟延时太大。
打开建立时间路径,查看采样沿为18.5185(第二个上升沿):
打开保持时间路径,查看数据和时钟到达的时间
所以保持时间余量为 -1.386 -(-0.389)=-0.997ns
所以要想保持时间余量成为正值,则时钟要往左移(上面算式的减数更小),但是要小多少的,也就是时钟应该怎么相移,移多少呢,这就得计算一下了。
所以为了保持时间余量成为正值,被减数继续往负值走,比如为 -1.389
-1.386 -(-1.389)=0.003ns 近似于刚好称为正值。
时钟到达的时间为-0.389变为-1.389,相当于向左偏移了1ns
换算成相位:
时钟频率:54MHz
时钟周期:18.518 ns;相位对应360度
时间为:1ns ;相位对应 1/18.518=x/360 所以x=19.440度。
又因为时钟是向左移,所以通过PLL将时钟左移大概20度就会使保持时间余量称为正值。
步骤二: 设置IP核相移为-20:
时钟左移会使保持时间余量(④-③)成为正值:
综合实现,打开report timing查看时序报告:
打开建立时间路径
再次查看采样沿为17.486ns(近似左移了1ns)
保持时间余量成为了正值,满组时序要求
完成了以上的验证。
★★★如有错误,欢迎指导!!!