Output接口类型和约束
FPGA 做Output 的接口时序同样也可以分为系统同步和源同步。在设置XDC约束时,总体思路与Input类似,只是换成要考虑下游期间的时序模型。另外,在源同步接口中,定义接口约束之前,需要用create_generated_clock先定义送出的随路时钟。
与Input 的系统同步接口一样,FPGA做Output接口的系统同步设计,新偏见只传递数据信号,时钟信号的同步完全依靠板级设计来对齐。所以设置约束时候要考虑的仅仅是下游期间的Tsu/Th和数据在板级的延时。
上图是一个SDR上升沿采样系统同步接口的Output约束示例。其中,-max后的数值是板级延时的最大值与下游器件的Tsu想加而得出,-min后的数值则是板级延时的最小值减去下游期间的Th而来。
与源同步接口的Input约束设置类似,FPGA做源同步接口的Output也有两种方法可以设置约束。
方法一我们称作setup/hold based method,与上述系统同步接口的设置思路基本一致,仅需要了解下游器件用来锁存数据的触发器的Tsu与Th值与系统板级的延时便可以设置。
方法二长做Skew Based Method,此时需要了解FPGA送出的数据相对于时钟沿的关系,根据Skew的大小和时钟频率来计算如何设置Output约束。
具体约束时可以根据已知条件的不同,选用不同的约束方式。一般而言,FPGA作为输出接口时,数据相对时钟的Skew关系是已知的,所以方法二更常见。
Setup/Hold Based Method的计算公式如下,可以看出其跟系统同步输出接口的设置方法完全一样。如果换成DDR方式,则可以参考Input源同步DDR接口的约束,用两个可选项-clock_fall与-add_delay来添加针对时钟下降沿的约束值。
Set_output_delay -max:Ttrace(max)+Dest Register Tsu
Set_output_delay -min:Ttrace(min)+Dest Register Th
如果板级延时的最小值(在源同步接口中,因为时钟与信号同步传递,所以板级延时常常可以视作为0)小于接收端寄存器Th,这样计算出的接口就会在-min后出现负数值,很多时候会让人觉得设置错误。其实这里的负数并不表示负的延迟,而代表最小的延时情况下,数据是在时钟采样沿之后才有效。同样的,-max后的证书,表示最大的延迟情况爱,数据是在时钟采样沿之前就有效了。
如果我们在纸上画一下接收端的波形图,就会很容易理解:用于setup分析的-max之后跟着正数,表示数据在时钟采样沿之前就到达,用于hold分析的-min之后跟着负数,表示数据在时钟采样沿之后还保持了一段时间。只有这样才能满足接收端用于锁存接口数据的触发器的Tsu和Th要求。
为了把同步数据相对于时钟沿的Skew限定在一定范围内,我们可以基于Skew的大小来设置源同步输出接口的约束。此时可以不考虑下游采样器件的Tsu与Th值。
我们可以通过波形图再次验证set_output_delay中的-max/-min的定义,即时钟采样沿之前最大与最小的数据有效窗口。
DDR 接口的约束设置
DDR接口的约束稍许复杂,需要将上升沿和下降沿分别考虑和约束,以下以源同步接口为例,分别就Setup/Hold Based方法和Skew Based方法举例。
方法一Setup/Hold Based Method
已知条件下:
ü 时钟信号src_sync_ddr_clk的频率:100MHz
ü 随路送出的时钟src_sync_ddr_clk_out的频率:100MHz
ü 数据总线:src_sync_ddr_dout[3:0]
ü 接收端的上升沿建立时间要求(tsu_r):0.7ns
ü 接收端的上升沿保持时间要求(thd_r):0.3ns
ü 接收端的下降沿建立时间要求(tsu_f):0.6ns
ü 接收端的下降沿保持时间要求(thd_f):0.4ns
ü 板级走线延时:0ns
可以这样计算输出接口约束:已知条件包含接收端上升沿和下降沿的建立与保持时间要求,所以可以分别独立计算。
上升沿采样数据的-max是板级延时的最大值加上接收端的上升沿建立时间要求(tsu_r)
对应的-min就应该是板级延时的最小值减去接收端的上升沿保持时间要求(thd_r)
下降沿采样数据的-max是板级延时的最大值加上接收端的下降沿建立时间要求(tsu_f)
对应的-min就应该是板级延时的最小值减去接收端下降沿保持时间要求(thd_f)
create_clock -period 10.0 -name clk [get_ports src_sync_ddr_clk];
create_generated_clock -name clk_out [get_ports ddr_src_clk_out] \
-source [get_ports src_sync_ddr_clk] -divide_by 1;
set_output_delay -clock clk_out -max 0.7 [get_ports src_sync_ddr_dout[*]];
set_output_delay -clock clk_out -min 0.3 [get_ports src_sync_ddr_dout[*]];
set_output_delay -clock clk_out -max 0.6 [get_ports src_sync_ddr_dout[*]];
-clock_fall -add_delay
set_output_delay -clock clk_out -min 0.4 [get_ports src_sync_ddr_dout[*]];
-clock_fall -add_delay
方法二 Skew Based method
已知条件下:
ü 时钟信号src_sync_ddr_clk的频率:100MHz
ü 随路送出的时钟src_sync_ddr_clk_out的频率:100MHz
ü 数据总线:src_sync_ddr_dout[3:0]
ü 上升沿之前的数据skew(bre_skew):0.4ns
ü 上升沿之后的数据skew(are_skew):0.6ns
ü 下降沿之前的数据skew(bre_skew):0.7ns
ü 下降沿之后的数据skew(are_skew):0.2ns
可以这样计算输出接口约束:时钟周期是10ns,因为是DDR方式,所以数据实际的采样周期是时钟周期的一半
上升沿采样的数据-max应该是采样周期减去这个数据的发送沿(下降沿)之后的数据skew即afe_skew
上升沿采样的数据-min应该是上升沿之前的数据skew值bre_skew
下降沿采样数据的-max应该是采样周期减去这个数据的发送沿(上升沿)之后的数据skew值are_skew
下降沿采样数据的-min就应该是下降沿之前的数据skew值bre_skew
所以最终写入XDC的output约束应该如下:
set period 10.0;
create_clock -period $period -name clk [get_ports src_sync_ddr_clk];
create_generated_clock -name clk_out [get_ports ddr_src_sync_clk_out] \
-source [get_ports src_sync_ddr_clk] -divide_by 1;
set_output_delay -clock clk_out -max [expr $period/2-0.2] \
[get_ports src_sync_ddr_dout[*]] ;
set_output_delay -clock clk_out -min 0.4 [get_ports src_sync_ddr_dout[*]] ;
set_output_delay -clock clk_out -max [expr $period/2 – 0.6] \
[get_ports src_sync_ddr_dout[*]] -clock_fall -add_delay ;
set_output_delay -clock clk_out -min 0.7
[get_ports src_sync_ddr_dout[*]] -clock_fall -add_delay;
对以上两种方法稍作总结,就会发现在设置DDR源同步输出接口时,送出的数据是中心对齐的情况下,用setup/hold based方法来写约束比较容易,而如果是边沿对齐的情况,则推荐使用skew based方法来写约束。