时序约束(5):源同步约束:input和output
一、input约束
1、理论计算
![](https://img2020.cnblogs.com/blog/1536533/202008/1536533-20200806193551289-1544960850.png)
但是数据手册没有提供数据线之间的 skew,我们假设一个 0.2ns 的偏移范围,因为专用芯片之间的数据 skew 很像,几乎是数据周期的 1/40 左右,比如125Mhz时钟是8ns的周期,data skew = 8/40 = 0.2ns。由此我们可以绘制出本次约束的时序图:
之前章节的计算方法 : dMax = 2+skew/2 = 2.1 Xilinx 官方计算方法: dMax = Tcycle/2 - dv_bfe = 4 – (2-0.1) =2.1 ------------------------------------------------------------------------- 之前章节的计算方法 : dMin = 2 – skew/2 = 1.9 Xilinx 官方计算方法: dMin = dv_bre=2 – 0.1=1.9
2、查看未约束时的报告
在打开 implementation design 下 在 tcl console 里边输入如下命令:
report_timing -from [get_ports {rx_ctrl rx_dat[0] rx_dat[1] rx_dat[2] rx_dat[3]}] -delay_type min_max -max_paths 100 -sort_by group -input_pins -routable_nets -name timing_1
当然也可以通过 gui 界面 的 report timing 界面打印 rx_data 路径时序信息,如下所示:
3、input约束步骤
(1)设置 input delay约束:max = 2.1,min = 1.9。
(2)设置上升沿的 max delay 用于建立时间分析这里要设置时钟和数据源端口,时钟为 PLL 移相之后的时钟 rx_clk_90。
(3)设置上升沿的 min delay 用于保持时间分析 这里必须额外增加 add delay (意思就是不覆盖之前设置的 max delay)
(4)上面只是约束了上升沿,但我们的 IDDR 是双沿传递,因此做完这两个还得再来两个,只是 rise 改成 fall。
(5)保存约束文件
(6)rerun一下Timing,看看效果,现在是约束前的网表。
(7)重新综合工程和布局布线工程,再打开时序报告,会发现时序变得更好了。
4、input约束的优化:indelay control
目前设计是通过 PLL 调整相位来达到时序要求,也可以时钟不通过PLL,而通过对数据进行【延时链】相移来达到目的。
(1)找到原语 IDELAYCTRL,例化到顶层模块,给其引入一个 200Mhz 时钟和复位。
IDELAYCTRL IDELAYCTRL_inst ( .RDY (RDY ), // 1-bit output: Ready output,反接到IDDR_trans的复位中,不用也行 .REFCLK (DDR3_200m ), // 1-bit input: Reference clock input .RST (DDR3_rst ) // 1-bit input: Active high reset input );
generate genvar i; for(i=0;i<4;i=i+1) begin IDELAYE2 #( .CINVCTRL_SEL("FALSE"), // Enable dynamic clock inversion (FALSE, TRUE) .DELAY_SRC("IDATAIN"), // Delay input (IDATAIN, DATAIN) .HIGH_PERFORMANCE_MODE("FALSE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE") .IDELAY_TYPE("FIXED"), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE .IDELAY_VALUE(18), // Input delay tap setting (0-31) .PIPE_SEL("FALSE"), // Select pipelined mode, FALSE, TRUE .REFCLK_FREQUENCY(200.0), // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0). .SIGNAL_PATTERN("DATA") // DATA, CLOCK input signal ) IDELAYE2_inst_data ( .CNTVALUEOUT(), // 5-bit output: Counter value output .DATAOUT(rx_dat_t[i]), // 1-bit output: Delayed data output .C(1'b0), // 1-bit input: Clock input .CE(1'b0), // 1-bit input: Active high enable increment/decrement input .CINVCTRL(1'b0), // 1-bit input: Dynamic clock inversion input .CNTVALUEIN(5'd0), // 5-bit input: Counter value input .DATAIN(1'b0), // 1-bit input: Internal delay data input .IDATAIN(rx_dat[i]), // 1-bit input: Data input from the I/O .INC(1'b0), // 1-bit input: Increment / Decrement tap delay input .LD(1'b0), // 1-bit input: Load IDELAY_VALUE input .LDPIPEEN(1'b0), // 1-bit input: Enable PIPELINE register to load data input .REGRST(1'b0) // 1-bit input: Active-high reset tap-delay input ); IDDR #( .DDR_CLK_EDGE("SAME_EDGE_PIPELINED"), // "OPPOSITE_EDGE", "SAME_EDGE" // or "SAME_EDGE_PIPELINED" .INIT_Q1(1'b0), // Initial value of Q1: 1'b0 or 1'b1 .INIT_Q2(1'b0), // Initial value of Q2: 1'b0 or 1'b1 .SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC" ) IDDR_rxd_inst ( .Q1(rxd[i]), // 1-bit output for positive edge of clock .Q2(rxd[i+4]), // 1-bit output for negative edge of clock .C(rx_clk_90), // 1-bit clock input .CE(1'b1), // 1-bit clock enable input .D(rx_dat_t[i]), // 1-bit DDR data input .R(1'b0), // 1-bit reset .S(1'b0) // 1-bit set ); end endgenerate
(3)时钟没有经过PLL,所以要进行基准时钟约束。
(4)数据属于input,再对数据进行 input 约束。
(5)补充,关于原语中 IDELAY2 的.IDELAY_VALUE的解释:该信号的值映射为延迟,具体每一级别延迟多少请参考 select IO 文档,每个器件不一样。![](https://img2020.cnblogs.com/blog/1536533/202008/1536533-20200806201153720-87187810.png)
经过查找手册得到 Fref=200,那么该信号的分度值为 78.125ps 左右,可以通过修改该信号的值来调整分辨率(本工程18很合适),使数据达到时序要求。
二、output约束
1、理论计算
时钟和数据从ODDR到管脚这一段需要进行约束:
建立时间余量计算
Data Required time = Tcycle + Tc_d
Data Arrival time = Tco+askew
Setup Slack = Data Required time - Data Arrival time
= Tcycle + Tc_d – Tco – askew
= Tc_d – Tco + (Tcycle - askew)
dMax = Tcycle - askew
保持时间余量计算
Data finish time = Tco + Tcycle - bskew
Data Required finish time = Tcycle + Tc_d
Hold Slack = Data finish time - Data Required finish time
= Tco + Tcycle - bskew - (Tcycle + Tc_d)
= Tco –Tc_d -(bskew)
dMin = bskew
(Xilinx官方计算方法和上面一样)
这里设置的 bskew 和 askew 和 input delay 是不一样的思想,input delay 是根据上游器件的参数决定的,而 output delay 是我们设置约束使得我们的时钟不要落到 skew 的区间内,这样我们可以通过调整 skew 的值使时钟在一个中心位置。
通过约束 askew 和 bskew 的值,综合工具会调整布线长度使得时钟落在 a/bskew 之间红色箭头指示的区间,如果落在了bskew 和 askew 范围内就会出现时序违例。
2、生成时钟约束
ODDR的时钟到管脚这一段需要进行生成时钟约束,源为PLL的输出,目的为芯片的 tx_clk 引脚。
3、output约束步骤
和 input 约束步骤类似,安装上面计算的理论值,填入 max 和 min 值即可,注意双沿传输既要设置 rise 也要设置 fall。
4、output约束的优化:outdelay control
output delay 也有【延时链】原语来达到数据的约束,和 input delay 类似。但是《ug471_7Series_SelectIO》说该原语在 HR banks 中是无效的,只在 HP banks 中有效。
打开《ug475_7Series_Pkg_Pinout》,看到我的 A7 板子正是 HR banks,所以不能用哦。
A7 系列板卡都是在 HR banks中,因此在 Language template 中选择 A7 也会搜不到 output delay 的原语,选择 K7 就可以看到了。
参考资料:V3学院FPGA教程