时序约束进阶三:Create_clock与Create_Generated_Clock详解

目录

一、前言

二、生成时钟

[2.1 示例设计](#2.1 示例设计)

[2.2 主时钟约束](#2.2 主时钟约束)

1)约束对象解析

2)约束到非时钟位置

[2.3 生成时钟约束](#2.3 生成时钟约束)

1)无约束

2)倍频约束

3)生成时钟的主时钟约束不正确

4)使能时钟控制的约束

5)通过时钟边沿设置生成时钟

6)非整数倍频生成时钟

三、参考资料


一、前言

时序约束中,使用Create_clock约束来生成主时钟,主时钟可以说是设计的心脏。主时钟是来自FPGA芯片外部的时钟,通过时钟输入端口或高速收发器GT的输出引脚进入FPGA内部。对于赛灵思7系列的器件,主时钟必须手动定义到GT的输出,对于Ultrascale和Ultrascale+系列的器件,定时器会自动地接入到GT的输出

生成时钟通常来源于设计内部的时钟管理单元,如MMCM,PLL等,生成时钟是与主时钟(使用create_clock创建的时钟)相关,其来源来自主时钟或其他生成时钟。因此,需先定义主时钟,再定义生成时钟。优点是主时钟变化时生成时钟会同步进行变化

生成时钟与主时钟关系可以是分频,倍频,非整数倍频率,相移,占空比切换,以及上述关系的组合。

二、生成时钟

2.1 示例设计

下面用于示例的设计代码如下

module all_timing(CLKIN1,CLKIN2,CLKINSEL,CLKFBIN,clk1,rst,d1,ff2,ff2_pll);
input CLKIN1,CLKIN2,CLKINSEL,CLKFBIN,clk1,rst,d1;
output ff2,ff2_pll;
reg ff1,ff2,ff1_pll,ff2_pll;
wire CLKOUT0;
PLLE2_ADV #(
      .BANDWIDTH("OPTIMIZED"),  // OPTIMIZED, HIGH, LOW
      .CLKFBOUT_MULT(2),        // 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(4),
      .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("INTERNAL"),   // 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(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
        ff1_pll<=1'b0;
    end
    else begin
        ff1_pll<=d1;
    end

always@(posedge CLKOUT0,negedge rst)
    if(!rst)
        ff2_pll<=1'b0;
    else begin
        ff2_pll<=ff1_pll;
    end


always@(posedge clk1,negedge rst)
    if(!rst)
        ff1<=1'b0;
    else begin
        ff1<=d1;
    end
always@(posedge clk1,negedge rst)
    if(!rst)
        ff2<=1'b0;
    else begin
        ff2<=ff1;
    end

endmodule 

2.2 主时钟约束

主时钟的约束较为简单,设置时钟名Clock name,约束对象Source objects,波形设置Waveform,同一个对象设置多条约束是否不被覆盖Add this clock to the existing clock。

1)约束对象解析

约束对象可为port,net,pin三种类型,当约束在input为时钟的port上时,port和net效果相同,约束在pin上时,则port和net上的约束会失效。

如对clk1的port和net同时约束

create_clock -period 10.000 -name clk1_port -waveform {0.000 5.000} -add [get_ports clk1]
create_clock -period 10.000 -name clk1_net -waveform {0.000 5.000} -add [get_nets clk1]

查看时序分析结果,两者的分析结果一致

在上述约束的基础上,在添加对pin的约束,约束如下

create_clock -period 4.000 -name clk1_port -waveform {0.000 2.000} -add [get_ports clk1]
create_clock -period 10.000 -name clk1_net -waveform {0.000 5.000} -add [get_nets clk1]
create_clock -period 10.000 -name clk1_pin -waveform {0.000 5.000} -add [get_pins clk1_IBUF_inst/I]

时序分析结果此时只有clk1_pin,不存在clk1_port和clk1_net,原因是clk1_pin在前两者传输的路径上,因此前面两者的时钟传播中断到clk1_IBUF_inst/I

2)约束到非时钟位置

create_clock -period 10.000 -name port_d1 -waveform {0.000 5.000} -add [get_ports d1]

此时约束不生效,但不会有相关提示

2.3 生成时钟约束

1)无约束

对于设计中有PLL、MMCM单元时,如果用户未设置生成时钟约束,软件会自动创建生成时钟,以上述工程为例,如果没有对clkout设置create_generated_clock约束时,查看时序报告,对于clkout0存在2个生成时钟CLKOUT0_1和CLKOUT0,对应的主时钟分别是clkin2和clkin1,同时在Intra-clock Paths中有对应的时序路径

对应自动生成的生成时钟,看频率都是主时钟的二分频,该配置怎么来的?查看设计会发现在配置中存在,集CLKOUT0_DIVIDE和CLKBOUT_MULT,分别是分频系数和倍频系数,先4分频再2倍频,最终是2分频

除了示例中的pll外,MMCM/BUFR,以及在UltraScale器件中,还包括GT_COMMON/GT_CHANNEL/IBUFDS_GTE3,ISERDESE3,BITSLICE_CONTROL / RX*_BITSLICE的时钟输出端口都能自动产生生成时钟

2)倍频约束

clkin2的周期为5ns,占空比为80%,gen_clkout0为clkin2的2倍频时钟

create_clock -period 5.000 -name clkin2 -waveform {0.000 4.000} -add [get_nets CLKIN2]
create_generated_clock -name gen_clkout0 -source [get_pins PLLE2_ADV_inst/CLKOUT1] -multiply_by 2 -add -master_clock clkin2 [get_pins PLLE2_ADV_inst/CLKOUT0]

查看结果,gen_clkout0为clkin2的等比例缩小

3)生成时钟的主时钟约束不正确

下面对Pll的clkin2输入端口设置生成时钟,源时钟为clk1,但实际设计中clk1和clkin2完全是独立的

create_generated_clock -name gen_clkin2 -source [get_ports clk1] -multiply_by 2 -add -master_clock clk1_port [get_ports CLKIN2]

如果生成时钟的主时钟非实际主时钟,在Tcl Console窗口将会有如下告警提示,下方还有相应的解决方法Resolution

CRITICAL WARNING: [Timing 38-249] Generated clock gen_clkin2 has no logical paths from master clock clk1_port.

4)使能时钟控制的约束

对于下图所示,触发器的输出作为时钟,来源都是clk1,这种结构的优点是时钟和数据的路径相同,从而传输延迟相同。此时对于下一级的时钟需要设置生成时钟约束,同时需勾选-combinational。

create_generated_clock -name ff_genclk -source [get_ports clk1] -multiply_by 1 -combinational -add -master_clock clk1_port [get_pins clk_div_reg/Q]

时钟报告中ff_genclk如下

5)通过时钟边沿设置生成时钟

通过源时钟的边沿设置生成时钟,以下图为例。

对应的命令为create_generated_clock -name gen_clk -source [get_pins clk_IBUF_BUFG_inst/O] -edges {1 3 4} -edge_shift {2.0 0.0 1.0} -add -master_clock [get_clocks "*"] [get_pins {shiftr_reg[13]/C}]

含义解释:-edge {1,3,4}即生成时钟的第1个上升沿位置,第1个下降沿位置,第2个上升沿位置分别对应源时钟的第1,3,4个变化边沿,-edge_shift的3个值为在源时钟基础上的偏移。假设源时钟clk周期为10ns,占空比为50%,从0时刻开始,统计了边沿变化的数目,-edge {1,3,4}如中间波形所示,对应了clk第1,3,4的边沿;Generate clk即为各个边沿的偏移值,分别是0+2,10+0,15+1,即为Generate clk的波形。

示例如下图

a.二分频的生成时钟实现用寄存器实现

主时钟周期为10ns,对应的约束命令为

create_clock -name clkin -period 10 [get_ports clkin] #创建主时钟 create_generated_clock -name clkdiv2 -source [get_ports clkin] -divide_by 2 [get_pins REGA/Q] #创建生成时钟

b.边沿生成时钟

时钟边沿设置生成时钟,对应命令为,由波形可看出生成时钟的3个边沿刚好对应主时钟的第1,3,5,因为无偏移,故不需要-edge_shift,

create_generated_clock -name clkdiv2 -source [get_pins REGA/C] -edges {1 3 5}  [get_pins REGA/Q]

生成时钟的波形clkdiv2如下图所示

6)非整数倍频生成时钟

通过同时设置倍频和分频可以设置非整数倍的生成时钟频率,如果需要生成一个4/3倍频的生成时钟,先用倍频参数multiply_by 4,再用分频参数divide_by 3。

create_generated_clock -name clk43 -source [get_pins mmcm0/CLKIN] -multiply_by 4 -divide_by 3 [get_pins mmcm0/CLKOUT]

三、参考资料

《ug903-vivado-using-constraints-en-us-20232.pdf》

相关推荐
DS小龙哥1 小时前
基于Zynq FPGA的雷龙SD NAND存储芯片性能测试
fpga开发·sd nand·雷龙·spi nand·spi nand flash·工业级tf卡·嵌入式tf卡
上理考研周导师11 小时前
第二章 虚拟仪器及其构成原理
fpga开发
FPGA技术实战12 小时前
《探索Zynq MPSoC》学习笔记(二)
fpga开发·mpsoc
bigbig猩猩1 天前
FPGA(现场可编程门阵列)的时序分析
fpga开发
Terasic友晶科技1 天前
第2篇 使用Intel FPGA Monitor Program创建基于ARM处理器的汇编或C语言工程<二>
fpga开发·汇编语言和c语言
码农阿豪1 天前
基于Zynq FPGA对雷龙SD NAND的测试
fpga开发·sd nand·spi nand·spi nand flash·工业级tf卡·嵌入式tf卡
江山如画,佳人北望1 天前
EDA技术简介
fpga开发
淘晶驰AK1 天前
电子设计竞赛准备经历分享
嵌入式硬件·fpga开发
最好有梦想~1 天前
FPGA时序分析和约束学习笔记(4、IO传输模型)
笔记·学习·fpga开发