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

目录

时序分析实操

分析数据手册

实验工程

输入部分

输出部分

顶层部分

设计层次

综合布线

时序约束

时钟约束

输入延时约束

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

数据中间采样

最小延时约束

最大延时约束

结果分析

数据边缘采样

添加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的工程,代码如下

输入部分

`timescale 1ns / 1ps
module iddr_ctrl(
	(* clock_buffer_type = "none" *)     input	wire			rx_clk_90,
	input	wire 			rst,
	input	wire 	[3:0]	rx_dat,
	input	wire 			rx_ctrl,
	output	wire 			rx_en,
	output	wire 	[7:0]	rx_data
    );

wire	[7:0]	rxd;
wire 			rxdv,rxerr;
reg 			rxdv_r;
reg             rxerr_r;
reg 	[7:0]	rxd_r;

assign rx_en = rxdv_r;
assign  rx_data	=rxd_r ;

always @(posedge rx_clk_90) begin
	if (rst == 1'b1) begin
		rxdv_r <= 1'b0;
		rxerr_r <= 1'b0;
		rxd_r <= 'd0;
	end
	else begin
		rxdv_r <= rxdv;
		rxerr_r <= rxerr;
		rxd_r <= rxd;
	end
end

generate
	genvar i;
	for(i=0;i<4;i=i+1) begin
		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[i]),   // 1-bit DDR data input
      .R(1'b0),   // 1-bit reset
      .S(1'b0)    // 1-bit set
   );
	end
endgenerate


	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_rxctrl_inst (
      .Q1(rxdv), // 1-bit output for positive edge of clock
      .Q2(rxerr), // 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_ctrl),   // 1-bit DDR data input
      .R(1'b0),   // 1-bit reset
      .S(1'b0)    // 1-bit set
   );
   
endmodule

输出部分

module	oddr_ctrl(
	input	wire		sclk,
	input	wire	[7:0]	tx_dat,	
	input	wire		tx_en,
	input	wire		tx_c,//相移时钟
	
	output	wire	[3:0]	tx_data,
	output	wire		tx_dv,
	output	wire		tx_clk
);
ODDR #(
      .DDR_CLK_EDGE("SAME_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE" 
      .INIT(1'b0),    // Initial value of Q: 1'b0 or 1'b1
      .SRTYPE("ASYNC") // Set/Reset type: "SYNC" or "ASYNC" 
   ) ODDR_DV_inst (
      .Q(tx_dv),   // 1-bit DDR output
      .C(sclk),   // 1-bit clock input
      .CE(1'b1), // 1-bit clock enable input
      .D1(tx_en), // 1-bit data input (positive edge)
      .D2(tx_en), // 1-bit data input (negative edge)
     .R(1'b0),  // 1-bit reset
     .S(1'b0)    // 1-bit set
   );	
 ODDR #(
      .DDR_CLK_EDGE("SAME_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE" 
      .INIT(1'b0),    // Initial value of Q: 1'b0 or 1'b1
      .SRTYPE("ASYNC") // Set/Reset type: "SYNC" or "ASYNC" 
   ) ODDR_CLK_inst (
      .Q(tx_clk),   // 1-bit DDR output
      .C(tx_c),   // 1-bit clock input
      .CE(1'b1), // 1-bit clock enable input
      .D1(1'b1), // 1-bit data input (positive edge)
      .D2(1'b0), // 1-bit data input (negative edge)
     .R(1'b0),  // 1-bit reset
     .S(1'b0)    // 1-bit set
   );	   
 genvar j;
generate
	for(j=0;j<4;j=j+1)
		begin
ODDR #(
      .DDR_CLK_EDGE("SAME_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE" 
      .INIT(1'b0),    // Initial value of Q: 1'b0 or 1'b1
      .SRTYPE("ASYNC") // Set/Reset type: "SYNC" or "ASYNC" 
) ODDR_DATA_inst (
      .Q(tx_data[j]),   // 1-bit DDR output
      .C(sclk),   // 1-bit clock input
      .CE(1'b1), // 1-bit clock enable input
      .D1(tx_dat[j]), // 1-bit data input (positive edge)
      .D2(tx_dat[j+4]), // 1-bit data input (negative edge)
     .R(1'b0),  // 1-bit reset
     .S(1'b0)    // 1-bit set
   );	
end 
endgenerate 
endmodule

顶层部分

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,
    output	reg 	tout 	
	);

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;
assign rst =0;
assign rx_clk_90 = rx_clk;
/*
 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

*/
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 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

设计层次

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,并将其例化进顶层。

具体代码例化

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,
    output	reg 	tout 	
	);

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;
/*
 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

*/
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)
		);
	clk_wiz_0 pll_inst
   		(
   		 	// 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 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 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提供。

set_property IOSTANDARD LVCMOS33 [get_ports rx_clk]
set_property PACKAGE_PIN J19 [get_ports rx_clk]
set_property PACKAGE_PIN H22 [get_ports rx_ctrl]
set_property IOSTANDARD LVCMOS33 [get_ports rx_ctrl]
set_property PACKAGE_PIN K22 [get_ports {rx_dat[0]}]
set_property PACKAGE_PIN K21 [get_ports {rx_dat[1]}]
set_property PACKAGE_PIN J22 [get_ports {rx_dat[2]}]
set_property PACKAGE_PIN J20 [get_ports {rx_dat[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {rx_dat[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {rx_dat[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {rx_dat[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {rx_dat[0]}]


set_property PACKAGE_PIN M18 [get_ports tx_dv]
set_property IOSTANDARD LVCMOS33 [get_ports tx_dv]
set_property PACKAGE_PIN K18 [get_ports tx_clk]
set_property IOSTANDARD LVCMOS33 [get_ports tx_clk]

set_property PACKAGE_PIN M22 [get_ports {tx_d[0]}]
set_property PACKAGE_PIN L18 [get_ports {tx_d[1]}]
set_property PACKAGE_PIN L19 [get_ports {tx_d[2]}]
set_property PACKAGE_PIN L20 [get_ports {tx_d[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {tx_d[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {tx_d[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {tx_d[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {tx_d[0]}]

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]

综合布线

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

打开编辑时序约束,并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时序约束实操

猜你喜欢

转载自blog.csdn.net/m0_61298445/article/details/123672178