当前位置:   article > 正文

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

vivado 时序优化 实例

目录

时序分析实操

分析数据手册

实验工程

输入部分

输出部分

顶层部分

设计层次

综合布线

时序约束

时钟约束

输入延时约束

分析输入延时的约束如何设计

数据中间采样

最小延时约束

最大延时约束

结果分析

数据边缘采样

添加input delay约束

时序报告

解决方法

PLL IP配置参数

综合布线

改变PLL IP中的相移参数

综合布线

结果分析

 往期系列博客


 

时序分析实操

本实验根据数据手册分析,对时序进行约束,分为两种情况:数据中间采样和数据边缘采样,并且在边缘采样的情况下,还利用PLL进行时序的优化。

分析数据手册

分析图中信息,分别是数据中心采样和数据边缘采样,在边缘采样的情况下,对于时钟对数据采样,时钟沿与数据到来之间的偏差最大为2ns,最小为-2ns。

时钟的频率为54Mhz,也就是周期为18.519ns。

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

实验工程

这次仍然采用上次分析input delay的工程,代码如下

输入部分

  1. `timescale 1ns / 1ps
  2. module iddr_ctrl(
  3. (* clock_buffer_type = "none" *) input wire rx_clk_90,
  4. input wire rst,
  5. input wire [3:0] rx_dat,
  6. input wire rx_ctrl,
  7. output wire rx_en,
  8. output wire [7:0] rx_data
  9. );
  10. wire [7:0] rxd;
  11. wire rxdv,rxerr;
  12. reg rxdv_r;
  13. reg rxerr_r;
  14. reg [7:0] rxd_r;
  15. assign rx_en = rxdv_r;
  16. assign rx_data =rxd_r ;
  17. always @(posedge rx_clk_90) begin
  18. if (rst == 1'b1) begin
  19. rxdv_r <= 1'b0;
  20. rxerr_r <= 1'b0;
  21. rxd_r <= 'd0;
  22. end
  23. else begin
  24. rxdv_r <= rxdv;
  25. rxerr_r <= rxerr;
  26. rxd_r <= rxd;
  27. end
  28. end
  29. generate
  30. genvar i;
  31. for(i=0;i<4;i=i+1) begin
  32. IDDR #(
  33. .DDR_CLK_EDGE("SAME_EDGE_PIPELINED"), // "OPPOSITE_EDGE", "SAME_EDGE"
  34. // or "SAME_EDGE_PIPELINED"
  35. .INIT_Q1(1'b0), // Initial value of Q1: 1'b0 or 1'b1
  36. .INIT_Q2(1'b0), // Initial value of Q2: 1'b0 or 1'b1
  37. .SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC"
  38. ) IDDR_rxd_inst (
  39. .Q1(rxd[i]), // 1-bit output for positive edge of clock
  40. .Q2(rxd[i+4]), // 1-bit output for negative edge of clock
  41. .C(rx_clk_90), // 1-bit clock input
  42. .CE(1'b1), // 1-bit clock enable input
  43. .D(rx_dat[i]), // 1-bit DDR data input
  44. .R(1'b0), // 1-bit reset
  45. .S(1'b0) // 1-bit set
  46. );
  47. end
  48. endgenerate
  49. IDDR #(
  50. .DDR_CLK_EDGE("SAME_EDGE_PIPELINED"), // "OPPOSITE_EDGE", "SAME_EDGE"
  51. // or "SAME_EDGE_PIPELINED"
  52. .INIT_Q1(1'b0), // Initial value of Q1: 1'b0 or 1'b1
  53. .INIT_Q2(1'b0), // Initial value of Q2: 1'b0 or 1'b1
  54. .SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC"
  55. ) IDDR_rxctrl_inst (
  56. .Q1(rxdv), // 1-bit output for positive edge of clock
  57. .Q2(rxerr), // 1-bit output for negative edge of clock
  58. .C(rx_clk_90), // 1-bit clock input
  59. .CE(1'b1), // 1-bit clock enable input
  60. .D(rx_ctrl), // 1-bit DDR data input
  61. .R(1'b0), // 1-bit reset
  62. .S(1'b0) // 1-bit set
  63. );
  64. endmodule

输出部分

  1. module oddr_ctrl(
  2. input wire sclk,
  3. input wire [7:0] tx_dat,
  4. input wire tx_en,
  5. input wire tx_c,//相移时钟
  6. output wire [3:0] tx_data,
  7. output wire tx_dv,
  8. output wire tx_clk
  9. );
  10. ODDR #(
  11. .DDR_CLK_EDGE("SAME_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE"
  12. .INIT(1'b0), // Initial value of Q: 1'b0 or 1'b1
  13. .SRTYPE("ASYNC") // Set/Reset type: "SYNC" or "ASYNC"
  14. ) ODDR_DV_inst (
  15. .Q(tx_dv), // 1-bit DDR output
  16. .C(sclk), // 1-bit clock input
  17. .CE(1'b1), // 1-bit clock enable input
  18. .D1(tx_en), // 1-bit data input (positive edge)
  19. .D2(tx_en), // 1-bit data input (negative edge)
  20. .R(1'b0), // 1-bit reset
  21. .S(1'b0) // 1-bit set
  22. );
  23. ODDR #(
  24. .DDR_CLK_EDGE("SAME_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE"
  25. .INIT(1'b0), // Initial value of Q: 1'b0 or 1'b1
  26. .SRTYPE("ASYNC") // Set/Reset type: "SYNC" or "ASYNC"
  27. ) ODDR_CLK_inst (
  28. .Q(tx_clk), // 1-bit DDR output
  29. .C(tx_c), // 1-bit clock input
  30. .CE(1'b1), // 1-bit clock enable input
  31. .D1(1'b1), // 1-bit data input (positive edge)
  32. .D2(1'b0), // 1-bit data input (negative edge)
  33. .R(1'b0), // 1-bit reset
  34. .S(1'b0) // 1-bit set
  35. );
  36. genvar j;
  37. generate
  38. for(j=0;j<4;j=j+1)
  39. begin
  40. ODDR #(
  41. .DDR_CLK_EDGE("SAME_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE"
  42. .INIT(1'b0), // Initial value of Q: 1'b0 or 1'b1
  43. .SRTYPE("ASYNC") // Set/Reset type: "SYNC" or "ASYNC"
  44. ) ODDR_DATA_inst (
  45. .Q(tx_data[j]), // 1-bit DDR output
  46. .C(sclk), // 1-bit clock input
  47. .CE(1'b1), // 1-bit clock enable input
  48. .D1(tx_dat[j]), // 1-bit data input (positive edge)
  49. .D2(tx_dat[j+4]), // 1-bit data input (negative edge)
  50. .R(1'b0), // 1-bit reset
  51. .S(1'b0) // 1-bit set
  52. );
  53. end
  54. endgenerate
  55. endmodule

顶层部分

  1. module top_ioddr(
  2. input wire rx_clk,
  3. input wire rx_ctrl,
  4. input wire [3:0] rx_dat,
  5. //tx
  6. output wire tx_clk,
  7. output wire [3:0] tx_d,
  8. output wire tx_dv,
  9. input wire sdrclk,
  10. input wire [3:0] sdrdata,
  11. input wire sdrden,
  12. output reg tout
  13. );
  14. wire rst;
  15. wire rx_clk_90;
  16. wire rx_en;
  17. wire [7:0] rx_data;
  18. reg tx_en1,tx_en2;
  19. reg [7:0] tx_data1,tx_data2;
  20. assign rst =0;
  21. assign rx_clk_90 = rx_clk;
  22. /*
  23. clk_wiz_0 clk_gen0
  24. (
  25. // Clock out ports
  26. .clk_out1(rx_clk_90), // output clk_out1
  27. // Clock in ports
  28. .clk_in1(rx_clk)); // input clk_in1
  29. */
  30. always @(posedge rx_clk_90 or posedge rst) begin
  31. if (rst == 1'b1) begin
  32. tx_data1 <= 'd0;
  33. end
  34. else if (rx_en == 1'b1) begin
  35. tx_data1 <= rx_data+ rx_data -1;
  36. end
  37. end
  38. always @(posedge rx_clk_90 or posedge rst) begin
  39. if (rst == 1'b1) begin
  40. tx_data2 <= 'd0;
  41. end
  42. else if (tx_en1 == 1'b1) begin
  43. tx_data2 <= tx_data1+ tx_data1 -5;
  44. end
  45. end
  46. always @(posedge rx_clk_90 ) begin
  47. tx_en1 <= rx_en;
  48. end
  49. always @(posedge rx_clk_90 ) begin
  50. tx_en2 <= tx_en1;
  51. end
  52. iddr_ctrl inst_iddr_ctrl
  53. (
  54. .rx_clk_90 (rx_clk_90),
  55. .rst (rst),
  56. .rx_dat (rx_dat),
  57. .rx_ctrl (rx_ctrl),
  58. .rx_en (rx_en),
  59. .rx_data (rx_data)
  60. );
  61. oddr_ctrl inst_oddr_ctrl
  62. (
  63. .sclk (rx_clk_90),
  64. .tx_dat (tx_data2),
  65. .tx_en (tx_en2),
  66. .tx_c (rx_clk_90),
  67. .tx_data (tx_d),
  68. .tx_dv (tx_dv),
  69. .tx_clk (tx_clk)
  70. );
  71. //sdr clock domain
  72. reg [3:0] sdrdata_r1,sdrdata_r2;
  73. reg sdrden_r1,sdrden_r2;
  74. always @(posedge sdrclk ) begin
  75. {sdrdata_r2,sdrdata_r1} <= {sdrdata_r1,sdrdata};
  76. end
  77. always @(posedge sdrclk ) begin
  78. {sdrden_r2,sdrden_r1} <= {sdrden_r1,sdrden};
  79. end
  80. always @(posedge sdrclk) begin
  81. if(sdrden_r2 == 1'b1) begin
  82. tout <= (&sdrdata_r1)|(&sdrdata_r2);
  83. end
  84. else begin
  85. tout <= (^sdrdata_r2);
  86. end
  87. end
  88. endmodule

设计层次

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

 

综合布线

综合布线完成之后,点击布线的open implemented design中的edit timing constraints,对时序约束进行编辑

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

 

时序约束

时钟约束

点击creat clock中的+号,创建的时钟约束如下,对手册中的时钟进行约束,频率为54Mhz即周期为18.519ns,时钟约束名设定为sdrclk,对应着单边采样时钟的名字,让其对应上。最后点击ok即可。

 

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

 

这样就创建了时钟约束

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

 

输入延时约束

再来添加输入延时约束,同样的点击左侧栏的input delay选择栏的+号添加约束

da526a3af818429882d56cfa8ff69799.png

 

分析输入延时的约束如何设计

数据中间采样

由于是中间采样,所以采样时钟位于数据的中间,而整个数据可以看成一个时钟周期,处于中间则应该是一般的时钟周期,即9.259ns,用Visio简单画了一个示意图方便理解。除此之外,还存在最大最小的延时,分别为max=2ns、min=-2ns,因此,要分别添加最小延时约束以及最大延时约束。

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

 

最小延时约束

最小延时约束=半周期+最小延时=9.259ns-2ns=7.259ns

选择为上升沿,设定延时值为7.259ns

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

 

object对应上,然后点击ok即可

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

 

最大延时约束

同最小延时约束的谁当大致相同,只需将延时值设定为11.259ns,并且改为max,其余不变点击ok。

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

 

这时候点击apply保存,并打开时序报告,report timing

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

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

 

随便点开一条路径,可以计算验证以下

根据前面的介绍,建立时间余量=数据所被要求到达的时间-数据实际达到的时间

代入计算:setup slack = 20.048ns - 12.183ns = 7.865ns

符合设计的结果。

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

 

添加input delay约束

只需要在刚刚的约束改下延时值就行,max = 2ns ,min = -2ns

设置完点击保存即可

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

 

保持时间余量报错,出现红色说明出现了保持时间违例

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

 

可以看出建立时间余量非常充裕,但是保持时间余量出现了负值,这说明数据结束的时间比时钟到达的时间早,就导致了时钟没有采到数据,因此要对其进行约束。

解决方法

解决的方法有两个:

  • 增加数据的延时
  • 减小时钟的延时

显然减小时钟的延时会更简单一些,可以利用PLL实现改变时钟延时,添加一个相移为零的PLL,输入输出时钟频率都为54Mhz,PLL除了有相位偏移和改变时钟频率的作用,还有一个作用就是消除时钟到来之前的延时,也就是输入时钟到达PLL之前是有一段延时的,这段延时PLL是可以消除掉的,前面说了出现保持时间余量的违例的原因是采样时钟的延时大于数据结束的时间,而添加了PLL可以在一定程度的减小时钟延时。

首先在ip catalog中添加PLL IP,并将其例化进顶层。

具体代码例化

  1. module top_ioddr(
  2. input wire rx_clk,
  3. input wire rx_ctrl,
  4. input wire [3:0] rx_dat,
  5. //tx
  6. output wire tx_clk,
  7. output wire [3:0] tx_d,
  8. output wire tx_dv,
  9. input wire sdrclk,
  10. input wire [3:0] sdrdata,
  11. input wire sdrden,
  12. output reg tout
  13. );
  14. wire rst;
  15. wire rx_clk_90;
  16. wire rx_en;
  17. wire [7:0] rx_data;
  18. reg tx_en1,tx_en2;
  19. reg [7:0] tx_data1,tx_data2;
  20. wire sdrclk1;
  21. assign rst =0;
  22. assign rx_clk_90 = rx_clk;
  23. /*
  24. clk_wiz_0 clk_gen0
  25. (
  26. // Clock out ports
  27. .clk_out1(rx_clk_90), // output clk_out1
  28. // Clock in ports
  29. .clk_in1(rx_clk)); // input clk_in1
  30. */
  31. always @(posedge rx_clk_90 or posedge rst) begin
  32. if (rst == 1'b1) begin
  33. tx_data1 <= 'd0;
  34. end
  35. else if (rx_en == 1'b1) begin
  36. tx_data1 <= rx_data+ rx_data -1;
  37. end
  38. end
  39. always @(posedge rx_clk_90 or posedge rst) begin
  40. if (rst == 1'b1) begin
  41. tx_data2 <= 'd0;
  42. end
  43. else if (tx_en1 == 1'b1) begin
  44. tx_data2 <= tx_data1+ tx_data1 -5;
  45. end
  46. end
  47. always @(posedge rx_clk_90 ) begin
  48. tx_en1 <= rx_en;
  49. end
  50. always @(posedge rx_clk_90 ) begin
  51. tx_en2 <= tx_en1;
  52. end
  53. iddr_ctrl inst_iddr_ctrl
  54. (
  55. .rx_clk_90 (rx_clk_90),
  56. .rst (rst),
  57. .rx_dat (rx_dat),
  58. .rx_ctrl (rx_ctrl),
  59. .rx_en (rx_en),
  60. .rx_data (rx_data)
  61. );
  62. oddr_ctrl inst_oddr_ctrl
  63. (
  64. .sclk (rx_clk_90),
  65. .tx_dat (tx_data2),
  66. .tx_en (tx_en2),
  67. .tx_c (rx_clk_90),
  68. .tx_data (tx_d),
  69. .tx_dv (tx_dv),
  70. .tx_clk (tx_clk)
  71. );
  72. clk_wiz_0 pll_inst
  73. (
  74. // Clock out ports
  75. .clk_out1(sdrclk1), // output clk_out1
  76. // Clock in ports
  77. .clk_in1(sdrclk)); // input clk_in1
  78. //sdr clock domain
  79. reg [3:0] sdrdata_r1,sdrdata_r2;
  80. reg sdrden_r1,sdrden_r2;
  81. always @(posedge sdrclk1 ) begin
  82. {sdrdata_r2,sdrdata_r1} <= {sdrdata_r1,sdrdata};
  83. end
  84. always @(posedge sdrclk1 ) begin
  85. {sdrden_r2,sdrden_r1} <= {sdrden_r1,sdrden};
  86. end
  87. always @(posedge sdrclk1) begin
  88. if(sdrden_r2 == 1'b1) begin
  89. tout <= (&sdrdata_r1)|(&sdrdata_r2);
  90. end
  91. else begin
  92. tout <= (^sdrdata_r2);
  93. end
  94. end
  95. endmodule

PLL IP配置参数

输入时钟和输出时钟频率设定为54Mhz,与数据手册中的保持一致,相移0°,其余保持默认即可。

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

 

 

由于利用了PLL进行时钟的约束,因此在XDC文件中应将刚刚添加的时钟约束给删除,时钟由PLL提供。

  1. set_property IOSTANDARD LVCMOS33 [get_ports rx_clk]
  2. set_property PACKAGE_PIN J19 [get_ports rx_clk]
  3. set_property PACKAGE_PIN H22 [get_ports rx_ctrl]
  4. set_property IOSTANDARD LVCMOS33 [get_ports rx_ctrl]
  5. set_property PACKAGE_PIN K22 [get_ports {rx_dat[0]}]
  6. set_property PACKAGE_PIN K21 [get_ports {rx_dat[1]}]
  7. set_property PACKAGE_PIN J22 [get_ports {rx_dat[2]}]
  8. set_property PACKAGE_PIN J20 [get_ports {rx_dat[3]}]
  9. set_property IOSTANDARD LVCMOS33 [get_ports {rx_dat[3]}]
  10. set_property IOSTANDARD LVCMOS33 [get_ports {rx_dat[2]}]
  11. set_property IOSTANDARD LVCMOS33 [get_ports {rx_dat[1]}]
  12. set_property IOSTANDARD LVCMOS33 [get_ports {rx_dat[0]}]
  13. set_property PACKAGE_PIN M18 [get_ports tx_dv]
  14. set_property IOSTANDARD LVCMOS33 [get_ports tx_dv]
  15. set_property PACKAGE_PIN K18 [get_ports tx_clk]
  16. set_property IOSTANDARD LVCMOS33 [get_ports tx_clk]
  17. set_property PACKAGE_PIN M22 [get_ports {tx_d[0]}]
  18. set_property PACKAGE_PIN L18 [get_ports {tx_d[1]}]
  19. set_property PACKAGE_PIN L19 [get_ports {tx_d[2]}]
  20. set_property PACKAGE_PIN L20 [get_ports {tx_d[3]}]
  21. set_property IOSTANDARD LVCMOS33 [get_ports {tx_d[3]}]
  22. set_property IOSTANDARD LVCMOS33 [get_ports {tx_d[2]}]
  23. set_property IOSTANDARD LVCMOS33 [get_ports {tx_d[1]}]
  24. set_property IOSTANDARD LVCMOS33 [get_ports {tx_d[0]}]
  25. set_property PACKAGE_PIN W19 [get_ports sdrclk]
  26. set_property PACKAGE_PIN Y22 [get_ports sdrden]
  27. set_property PACKAGE_PIN V20 [get_ports {sdrdata[0]}]
  28. set_property PACKAGE_PIN U20 [get_ports {sdrdata[1]}]
  29. set_property PACKAGE_PIN AB22 [get_ports {sdrdata[2]}]
  30. set_property PACKAGE_PIN AB21 [get_ports {sdrdata[3]}]
  31. set_property IOSTANDARD LVCMOS33 [get_ports sdrclk]
  32. set_property IOSTANDARD LVCMOS33 [get_ports {sdrdata[*]}]
  33. set_property IOSTANDARD LVCMOS33 [get_ports sdrden]
  34. set_property PACKAGE_PIN Y21 [get_ports tout]
  35. set_property IOSTANDARD LVCMOS33 [get_ports tout]

综合布线

综合布线后的操作和刚刚做的数据中间采样一致。

打开编辑时序约束,并report timing

可以看到建立时间余量处于正常的状态

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

 

保持时间余量依然出现了违例,但是可以发现,相对于刚刚没有添加PLL时,此时添加了PLL后的保持时间余量已经有了改善。

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

 

这说明采样时钟的延时还是过大了,需要进一步缩小延时,利用PLL可以相移的特点,将时钟向左相移60°,一个周期是360°,相当于向左移动了1/6个时钟周期,一个时钟周期是18.519ns,相当于将时钟延时减小了3.0865ns,这样就可以增加保持时间的余量。

改变PLL IP中的相移参数

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

 

综合布线

完成之后reload,重新report timing查看时序报告。

可以看到建立时间余量保持时间余量均恢复正常。

 

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

 

结果分析

随便点开一条路径进行分析,其所得保持时间余量是符合设计要求的,这样就达到了建立时间余量和保持时间余量都恢复正常的目的。

 

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

 

 往期系列博客

 【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时序约束实操

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/539416
推荐阅读
相关标签
  

闽ICP备14008679号