Vivado时序报告之Check_timing详解

目录

一、前言

二、Check_Timing

[2.1 含义解释](#2.1 含义解释)

[2.2 工程代码](#2.2 工程代码)

[2.3 时序约束](#2.3 时序约束)

[2.4 Check_timing报告](#2.4 Check_timing报告)

[no clock](#no clock)

pulse_width_clock

unconstrained_internal_endpoints

no_input_delay

no_output_delay

multiple_clock

generated_clocks

loops

partial_input_delay

partial_output_delay

latch_loops

三、参考文档


一、前言

​Vivado使用中会涉及到各种报告,内容也较多,很多初学者可能对其中一些内容感到困惑,下面将结合实际工程示例对report_timing_summary中的Check_timing部分进行说明,帮助大家理解报告。

二、Check_Timing

​Check_timing报告主要显示一些时钟约束类的检查结果,以Vivado2022.1为例,检查项有以下12项

2.1 含义解释

no_clock:检查出没有时钟信号的寄存器

constant_clock:检查出连接到常量信号(如VSS、接地、数据信号)的时钟信号

pulse_width_clock:检查出只有脉冲宽度检查的时钟引脚,该时钟引脚没有setup/hold/recovery/removal检查

unconstrained_internal_endpoints:检查出以寄存器数据引脚为时序路径终点,但引脚没有约束

no_input_delay:检查出没有设置输入延时的输入端口

no_output_delay:检查出没有设置输出延时的输出端口

multiple_clock:检查出有多个时钟的时钟引脚,在检查出存在这样的时钟引脚时,建议使用set_case_analysis约束来限制只有一个时钟在该引脚上传输

generated_clocks:检查生成时钟是否存在环路或循环定义,如果生成时钟的源时钟也是生成时钟将报错

loops:检查组合逻辑中是否存在环路

**partial_input_delay:**检查出输入端口中设置了输入时延input_delay,但只设置了max或min,或者延时值只有rise或fall边沿触发

partial_output_delay:检查出输出端口中设置了输出时延output_delay,但只设置了max或min,或者延时值只有rise或fall边沿触发

**latch_loops:**检查设计中组合逻辑是否存在latch环路

2.2 工程代码

注意:此设计中在综合后会报错,因为PLL的参数COMPENSATION("ZHOLD")为ZHOLD,如果需要跑通,需设置为EXTERNAL或INTERNAL,之所以这样设置是为了看到pulse_width_clock检查

复制代码
`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/02/24 14:18:11
// Design Name: 
// Module Name: Check_timing
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module Check_timing(clk1,clk2,clk3,rst,d1,d2,S,CLKIN1,CLKIN2,CLKINSEL,CLKFBIN,CLKFBOUT,o_clk,o_lut,O,Q1,Q2,Q3,out_syn,pll_out,ff2);
input clk1,clk2,clk3,rst,d1,S;
input [4:0] d2;
input CLKIN1,CLKIN2,CLKINSEL,CLKFBIN;
output O,Q1,Q2,Q3,out_syn,pll_out,CLKFBOUT,o_clk,o_lut;
reg ff1,pll_ff1,pll_ff2,ff_syn;
output reg [4:0] ff2;
wire o_fdce;



always@(posedge clk1,negedge rst)
     if(!rst)
     begin
         ff1<=1'b0;
         ff2<=1'b0;
     end
     else begin
         ff1<=d1;
         ff2<=d2;
     end
//constant_clock
   (*DONT_TOUCH="YES"*)LUT2 #(
      .INIT(4'b0101)  // Specify LUT Contents
   ) LUT2_inst4 (
      .O(o_lut),   // LUT general output
      .I0(clk3),// LUT input
      .I1(d1) // LUT input
   );
   (*DONT_TOUCH="YES"*) FDCE #(
      .INIT(1'b0) // Initial value of register (1'b0 or 1'b1)
   ) FDCE_inst (
      .Q(o_clk),      // 1-bit Data output
      .C(clk3),      // 1-bit Clock input
      .CE(S),    // 1-bit Clock enable input
      .CLR(rst),  // 1-bit Asynchronous clear input
      .D(d1)       // 1-bit Data input
   );

 assign sum12=ff1+o_fdce;
 always@(posedge clk2,negedge rst)
     if(!rst)
         ff_syn<=1'b0;
     else begin
         ff_syn<=sum12;
     end
 assign out_syn=ff_syn;


//latch_loop
LDCE #(
      .INIT(1'b1)
   )
   LDCE_inst2 (
      .Q(Q2),     // 1-bit output: Data
      .CLR(rst), // 1-bit input: Asynchronous clear
      .D(Q3),     // 1-bit input: Data
      .G(1'b1),     // 1-bit input: Gate
      .GE(S)    // 1-bit input: Gate enable
   );

   LUT1 #(
      .INIT(2'b01)  // Specify LUT Contents
   ) LUT1_inst3 (
      .O(Q3),   // LUT general output
      .I0(Q2)  // LUT input
   );

//loop
LUT1 #(
      .INIT(2'b01)  // Specify LUT Contents
   ) LUT1_inst1 (
      .O(O),   // LUT general output
      .I0(Q0)  // LUT input
   );
LUT1 #(
      .INIT(2'b01)  // Specify LUT Contents
   ) LUT1_inst2 (
      .O(Q0),   // LUT general output
      .I0(O)  // LUT input
   );

 PLLE2_ADV #(
      .BANDWIDTH("OPTIMIZED"),  // OPTIMIZED, HIGH, LOW
      .CLKFBOUT_MULT(8),        // Multiply value for all CLKOUT, (2-64)
      .CLKFBOUT_PHASE(0.0),     // Phase offset in degrees of CLKFB, (-360.000-360.000).
      // CLKIN_PERIOD: Input clock period in nS to ps resolution (i.e. 33.333 is 30 MHz).
      .CLKIN1_PERIOD(0.0),
      .CLKIN2_PERIOD(0.0),
      // CLKOUT0_DIVIDE - CLKOUT5_DIVIDE: Divide amount for CLKOUT (1-128)
      .CLKOUT0_DIVIDE(1),
      .CLKOUT1_DIVIDE(2),
      .CLKOUT2_DIVIDE(4),
      .CLKOUT3_DIVIDE(5),
      .CLKOUT4_DIVIDE(1),
      .CLKOUT5_DIVIDE(1),
      // CLKOUT0_DUTY_CYCLE - CLKOUT5_DUTY_CYCLE: Duty cycle for CLKOUT outputs (0.001-0.999).
      .CLKOUT0_DUTY_CYCLE(0.4),
      .CLKOUT1_DUTY_CYCLE(0.5),
      .CLKOUT2_DUTY_CYCLE(0.5),
      .CLKOUT3_DUTY_CYCLE(0.5),
      .CLKOUT4_DUTY_CYCLE(0.5),
      .CLKOUT5_DUTY_CYCLE(0.5),
      // CLKOUT0_PHASE - CLKOUT5_PHASE: Phase offset for CLKOUT outputs (-360.000-360.000).
      .CLKOUT0_PHASE(0.0),
      .CLKOUT1_PHASE(0.0),
      .CLKOUT2_PHASE(0.0),
      .CLKOUT3_PHASE(0.0),
      .CLKOUT4_PHASE(0.0),
      .CLKOUT5_PHASE(0.0),
      .COMPENSATION("ZHOLD"),   // ZHOLD, BUF_IN, EXTERNAL, INTERNAL
      .DIVCLK_DIVIDE(1),        // Master division value (1-56)
      // REF_JITTER: Reference input jitter in UI (0.000-0.999).
      .REF_JITTER1(0.0),
      .REF_JITTER2(0.0),
      .STARTUP_WAIT("FALSE")    // Delay DONE until PLL Locks, ("TRUE"/"FALSE")
   )
   PLLE2_ADV_inst (
      // Clock Outputs: 1-bit (each) output: User configurable clock outputs
      .CLKOUT0(CLKOUT0),   // 1-bit output: CLKOUT0
      .CLKOUT1(CLKOUT1),   // 1-bit output: CLKOUT1
      .CLKOUT2(CLKOUT2),   // 1-bit output: CLKOUT2
      // Feedback Clocks: 1-bit (each) output: Clock feedback ports
      .CLKFBOUT(), // 1-bit output: Feedback clock

      // Clock Inputs: 1-bit (each) input: Clock inputs
      .CLKIN1(CLKIN1),     // 1-bit input: Primary clock
      .CLKIN2(CLKIN2),     // 1-bit input: Secondary clock
      // Control Ports: 1-bit (each) input: PLL control ports
      .CLKINSEL(CLKINSEL), // 1-bit input: Clock select, High=CLKIN1 Low=CLKIN2
      .RST(rst),           // 1-bit input: Reset
      // Feedback Clocks: 1-bit (each) input: Clock feedback ports
      .CLKFBIN(CLKFBIN)    // 1-bit input: Feedback clock
   );
   // End of PLLE2_ADV_inst instantiation

always@(posedge CLKOUT0,negedge rst)
    if(!rst)
    begin
        pll_ff1<=1'b0;
        pll_ff2<=1'b0;
    end
    else begin
        pll_ff1<=d1;
        pll_ff2<=S;
    end
assign pll_out=pll_ff1*pll_ff2;

wire sum12;
assign sum12=pll_ff1+pll_ff2;
always@(posedge CLKOUT1,negedge rst)
    if(!rst)
        ff_syn<=1'b0;
    else begin
        ff_syn<=sum12;
    end
assign out_syn=ff_syn;

endmodule

2.3 时序约束

复制代码
create_clock -period 4.000 -name clk1 -waveform {0.000 2.000} -add [get_ports clk1]
create_clock -period 6.000 -name clk1_a -waveform {0.000 3.000} -add [get_ports clk1]
create_clock -period 6.000 -name clkin1 -waveform {0.000 3.000} -add [get_ports CLKIN1]
create_generated_clock -name gen_clk -source [get_pins PLLE2_ADV_inst/CLKOUT1] -multiply_by 2 -add -master_clock clkin2 [get_pins PLLE2_ADV_inst/CLKOUT0]
set_input_delay -clock [get_clocks clk1] -rise 0.111 [get_ports {{d2[0]} {d2[1]}}]
set_output_delay -clock [get_clocks clk1] -min 0.222 [get_ports {ff2[0]}]
create_clock -period 9.000 -name clkin2 -waveform {0.000 4.500} -add [get_ports CLKIN2]
create_generated_clock -name gen_clk -source [get_ports CLKIN1] -multiply_by 2 -add -master_clock clkin2 [get_pins PLLE2_ADV_inst/CLKOUT1]
create_clock -period 10.000 -name clk3 -waveform {0.000 5.000} -add [get_ports clk3]
set_case_analysis 1 [get_ports clk3]

2.4 Check_timing报告

no clock

no_clock中触发器ff_syn无时钟信号,因为ff_syn的时钟clk2无create_clock约束,后面的serverity表示影响大小,High表示影响大

pulse_width_clock

对PLL的反馈输入端口进行脉冲宽度检查

unconstrained_internal_endpoints

unconstrained_internal_endpoints中high级别的端口未设置最大时延,级别为medium表示由于连接常量时钟而无最大延时

no_input_delay

未设置input_delay约束的端口

no_output_delay

未设置output_delay约束的端口,设置了约束的端口不会出现

multiple_clock

时钟引脚存在多个时钟的触发器,之所以存在多个时钟是因为这些触发器由时钟clk1驱动,而clk1端口上定义了2各时钟信号clk1和clk1_a

generated_clocks

生成时钟约束问题,因为generate_clock约束中master pin和master clock是无关联的。

loops

设计中组合路径存在环路LUT1_inst1和LUT1_inst2的输入输出首尾相连了

partial_input_delay

设计中d20,d21中的set_input_delay约束中使用了-rise,注意,如果再添加一条set_input_delay,使用-fall,则端口不会出现在partial_input_delay中,此时延时约束完整

partial_output_delay

设计中ff20中的set_output_delay约束中使用了-min,注意:如果再添加一条约束使用-max,则不会partial_output_delay中

latch_loops

设计中LDCE_inst2的输入和输出首尾相连,因此出现latch的环路

三、参考文档

用户手册《ug835-vivado-tcl-commands-en-us-2023.1.pdf》

相关推荐
仲南音1 天前
Xilinx FPGA——时钟IP核MMCM、PLL
fpga开发
I'm a winner2 天前
基于Xilinx FPGA的LVDS高速串行通信系统(三)--数据训练及握手机制【文末源码】
fpga开发
upper20202 天前
coremark移植坑之-nostartfiles -nostdlib参数
学习·fpga开发·coremark移植·riscv设计
Eloudy2 天前
Vivado 纯命令行构建 FPGA 项目教程
fpga开发
Rambo.xia2 天前
AXI跨时钟域与数据一致性——CDC FIFO深度不够、写后读冒险、多Master仲裁、乱序返回,出了Bug根本查不出来
fpga开发·bug
upper20202 天前
FPGA部署卷积神经网络识别MINST图片
fpga开发·卷积神经网络·minst·minst识别·部署神经网络·神经网络识别图片
你是我的解忧王子3 天前
嵌入式 ADC采样 原始数据分析上层(平均值 波动率 正态分布 线性补偿 系统误差)
fpga开发·数据挖掘·数据分析
9527华安3 天前
FPGA纯verilog代码ISP图像处理培训教程,基于IMX214,提供工程源码+视频教程+FPGA开发板
图像处理·fpga开发·isp·imx214·mipi
千寻xun4 天前
二、实战篇-NVME SSD控制之ZYNQ实现(六)-读写NVME SSD硬盘数据
fpga开发·nvme·nvme ssd
千寻xun4 天前
二、实战篇-NVME SSD控制之ZYNQ实现(三)
fpga开发·nvme ssd·nvme协议