时序约束进阶三: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》

相关推荐
szxinmai主板定制专家1 小时前
【国产NI替代】基于FPGA的32通道(24bits)高精度终端采集核心板卡
大数据·人工智能·fpga开发
HIZYUAN6 小时前
AGM FPGA如何配置上拉或者下拉电阻
fpga开发
∑狸猫不是猫6 小时前
(13)CT137A- 简易音乐盒设计
fpga开发
ThreeYear_s12 小时前
基于FPGA 的4位密码锁 矩阵键盘 数码管显示 报警仿真
fpga开发·矩阵·计算机外设
Anin蓝天(北京太速科技-陈)18 小时前
252-8路SATAII 6U VPX高速存储模块
fpga开发
如何学会学习?21 小时前
2. FPGA基础了解--全局网络
fpga开发
Anin蓝天(北京太速科技-陈)21 小时前
271-基于XC7V690T的12路光纤PCIe接口卡
嵌入式硬件·fpga开发
碎碎思1 天前
FPGA新闻速览-WiMi开发基于FPGA的数字量子计算机验证技术
fpga开发·量子计算
hi942 天前
Vivado - 远程调试 + 远程综合实现 + vmWare网络配置 + NFS 文件共享 + 使用 VIO 核
嵌入式硬件·fpga开发·vivado 远程开发·vmware网络配置
乘风~&2 天前
基于发FPGA 练手智能小车顶层文件
fpga开发