MMCME4_ADV与PLL4_ADV原语

本文转载自:硬码农二毛哥的微信公众号

UltraScale器件中时钟管理模块(CMT)包含mixed-mode clock manager (MMCM) 和phase-locked loops (PLLs) 。PLL主要用来生成I/O时钟,也包含一部分MMCM的功能。

其中MMCM输出时钟相位调整语VCO频率相关。

MMCME4_ADV原语

MMCM原语包含MMCME3_BASE和MMCME3_ADV,在UltraScale+ 器件中MMCME4替代MMCME3。UltraScale+ 器件MMCM原语包含MMCME4_BASE和MMCME4_ADV。

MMCME4_BASE实现基本MMCM功能。MMCME4_ADV除了能实现MMCME4_BASE功能外,还可以实现动态可重配等功能。

计算输出时钟频率

时钟输出频率和VCO输出频率计算公式如下,其中M值通过CLKFBOUT_MULT_F设置,D值通过DIVLK_DIVIDE设置,O的值为通过CLKOUT_DIVIDE.设置。

代码1.png

下图代码中CLKFBOUT_MULT_F设置成8,DIVCLK_DIVIDE设置成1,CLKOUT0_DIVIDE_F设置成4,输入时钟频率CLKIN1_PERIOD等于10,为100Mhz。通过公式计算CLKOUT0输出为100*8/4=200Mhz。

MMCME4_ADV #(
    .BANDWIDTH("OPTIMIZED"),       // Jitter programming
    .CLKFBOUT_MULT_F(8),         // Multiply value for all CLKOUT
    .CLKFBOUT_PHASE(0.0),           // Phase offset in degrees of CLKFB
    .CLKFBOUT_USE_FINE_PS("FALSE"), // Fine phase shift enable (TRUE/FALSE)
    .CLKIN1_PERIOD(10),           // Input clock period in ns to ps resolution (i.e., 33.333 is 30 MHz).
    .CLKIN2_PERIOD(0.0),           // Input clock period in ns to ps resolution (i.e., 33.333 is 30 MHz).
    .CLKOUT0_DIVIDE_F(4),         // Divide amount for CLKOUT0
    .CLKOUT0_DUTY_CYCLE(0.5),       // Duty cycle for CLKOUT0
    .CLKOUT0_PHASE(0.0),           // Phase offset for CLKOUT0
    .CLKOUT0_USE_FINE_PS("FALSE"), // Fine phase shift enable (TRUE/FALSE)
    .CLKOUT1_DIVIDE(1),             // Divide amount for CLKOUT (1-128)
    .CLKOUT1_DUTY_CYCLE(0.5),       // Duty cycle for CLKOUT outputs (0.001-0.999).
    .CLKOUT1_PHASE(0.0),           // Phase offset for CLKOUT outputs (-360.000-360.000).
    .CLKOUT1_USE_FINE_PS("FALSE"), // Fine phase shift enable (TRUE/FALSE)
    .CLKOUT2_DIVIDE(1),             // Divide amount for CLKOUT (1-128)
    .CLKOUT2_DUTY_CYCLE(0.5),       // Duty cycle for CLKOUT outputs (0.001-0.999).
    .CLKOUT2_PHASE(0.0),           // Phase offset for CLKOUT outputs (-360.000-360.000).
    .CLKOUT2_USE_FINE_PS("FALSE"), // Fine phase shift enable (TRUE/FALSE)
    .CLKOUT3_DIVIDE(1),             // Divide amount for CLKOUT (1-128)
    .CLKOUT3_DUTY_CYCLE(0.5),       // Duty cycle for CLKOUT outputs (0.001-0.999).
    .CLKOUT3_PHASE(0.0),           // Phase offset for CLKOUT outputs (-360.000-360.000).
    .CLKOUT3_USE_FINE_PS("FALSE"), // Fine phase shift enable (TRUE/FALSE)
    .CLKOUT4_CASCADE("FALSE"),     // Divide amount for CLKOUT (1-128)
    .CLKOUT4_DIVIDE(1),             // Divide amount for CLKOUT (1-128)
    .CLKOUT4_DUTY_CYCLE(0.5),       // Duty cycle for CLKOUT outputs (0.001-0.999).
    .CLKOUT4_PHASE(0.0),           // Phase offset for CLKOUT outputs (-360.000-360.000).
    .CLKOUT4_USE_FINE_PS("FALSE"), // Fine phase shift enable (TRUE/FALSE)
    .CLKOUT5_DIVIDE(8),             // Divide amount for CLKOUT (1-128)
    .CLKOUT5_DUTY_CYCLE(0.5),       // Duty cycle for CLKOUT outputs (0.001-0.999).
    .CLKOUT5_PHASE(0.0),           // Phase offset for CLKOUT outputs (-360.000-360.000).
    .CLKOUT5_USE_FINE_PS("FALSE"), // Fine phase shift enable (TRUE/FALSE)
    .CLKOUT6_DIVIDE(1),             // Divide amount for CLKOUT (1-128)
    .CLKOUT6_DUTY_CYCLE(0.5),       // Duty cycle for CLKOUT outputs (0.001-0.999).
    .CLKOUT6_PHASE(0.0),           // Phase offset for CLKOUT outputs (-360.000-360.000).
    .CLKOUT6_USE_FINE_PS("FALSE"), // Fine phase shift enable (TRUE/FALSE)
    .COMPENSATION("AUTO"),         // Clock input compensation
    .DIVCLK_DIVIDE(1),             // Master division value
    .IS_CLKFBIN_INVERTED(1'b0),     // Optional inversion for CLKFBIN
    .IS_CLKIN1_INVERTED(1'b0),     // Optional inversion for CLKIN1
    .IS_CLKIN2_INVERTED(1'b0),     // Optional inversion for CLKIN2
    .IS_CLKINSEL_INVERTED(1'b0),   // Optional inversion for CLKINSEL
    .IS_PSEN_INVERTED(1'b0),       // Optional inversion for PSEN
    .IS_PSINCDEC_INVERTED(1'b0),   // Optional inversion for PSINCDEC
    .IS_PWRDWN_INVERTED(1'b0),     // Optional inversion for PWRDWN
    .IS_RST_INVERTED(1'b0),         // Optional inversion for RST
    .REF_JITTER1(0.0),             // Reference input jitter in UI (0.000-0.999).
    .REF_JITTER2(0.0),             // Reference input jitter in UI (0.000-0.999).
    .SS_EN("FALSE"),               // Enables spread spectrum
    .SS_MODE("CENTER_HIGH"),       // Spread spectrum frequency deviation and the spread type
    .SS_MOD_PERIOD(10000),         // Spread spectrum modulation period (ns)
    .STARTUP_WAIT("FALSE")         // Delays DONE until MMCM is locked
  )
  MMCME4_ADV_inst (
    .CDDCDONE(),         // 1-bit output: Clock dynamic divide done
    .CLKFBOUT(clk_fb),         // 1-bit output: Feedback clock
    .CLKFBOUTB(),       // 1-bit output: Inverted CLKFBOUT
    .CLKFBSTOPPED(), // 1-bit output: Feedback clock stopped
    .CLKINSTOPPED(), // 1-bit output: Input clock stopped
    .CLKOUT0(clkout0),           // 1-bit output: CLKOUT0
    .CLKOUT0B(),         // 1-bit output: Inverted CLKOUT0
    .CLKOUT1(clkout1),           // 1-bit output: CLKOUT1
    .CLKOUT1B(),         // 1-bit output: Inverted CLKOUT1
    .CLKOUT2(clkout2),           // 1-bit output: CLKOUT2
    .CLKOUT2B(),         // 1-bit output: Inverted CLKOUT2
    .CLKOUT3(clkout3),           // 1-bit output: CLKOUT3
    .CLKOUT3B(),         // 1-bit output: Inverted CLKOUT3
    .CLKOUT4(clkout4),           // 1-bit output: CLKOUT4
    .CLKOUT5(clkout5),           // 1-bit output: CLKOUT5
    .CLKOUT6(clkout6),           // 1-bit output: CLKOUT6
    .DO(),                     // 16-bit output: DRP data output
    .DRDY(),                 // 1-bit output: DRP ready
    .LOCKED(lock),             // 1-bit output: LOCK
    .PSDONE(),             // 1-bit output: Phase shift done
    .CDDCREQ(1'b0),           // 1-bit input: Request to dynamic divide clock
    .CLKFBIN(clk_fb_g),           // 1-bit input: Feedback clock
    .CLKIN1(clk_in),             // 1-bit input: Primary clock
    .CLKIN2(1'b0),             // 1-bit input: Secondary clock
    .CLKINSEL(1'b1),         // 1-bit input: Clock select, High=CLKIN1 Low=CLKIN2
    .DADDR(7'b0),               // 7-bit input: DRP address
    .DCLK(1'b0),                 // 1-bit input: DRP clock
    .DEN(1'b0),                   // 1-bit input: DRP enable
    .DI(16'b0),                     // 16-bit input: DRP data input
    .DWE(1'b0),                   // 1-bit input: DRP write enable
    .PSCLK(1'b0),               // 1-bit input: Phase shift clock
    .PSEN(1'b0),                 // 1-bit input: Phase shift enable
    .PSINCDEC(1'b0),         // 1-bit input: Phase shift increment/decrement
    .PWRDWN(1'b0),             // 1-bit input: Power-down
    .RST(rst)                   // 1-bit input: Reset
  );

使用全局时钟网络

如下图所示,CLKOUT0输出要经过全局时钟网络BUFG,CLKFBOUT通过BUFG反馈到CLKFBIN。

代码2.png

代码如下:

BUFG u_clkout0
  (
  .O (clk_out0_g),
  .I (clkout0)  
  );
BUFG u_clk_fb
  (
  .O (clk_fb_g),
  .I (clk_fb)  
  );

PLL4_ADV

UltraScale+ 器件包含PLL4_BASE和PLL4_ADV。

PLL4_ADV原语输出时钟频率计算方式与MMCME4_ADV一样。输入时钟周期为5ns,频率200Mhz,CLKFBOUT_MULT_F设置成4,DIVCLK_DIVIDE设置成1,CLKOUT0_DIVIDE_F设置成4,CLKOUT0输出依然为200Mhz。

PLLE4_ADV #(
    .CLKFBOUT_MULT(4),         // Multiply value for all CLKOUT
    .CLKFBOUT_PHASE(0.0),       // Phase offset in degrees of CLKFB
    .CLKIN_PERIOD(5),         // Input clock period in ns to ps resolution (i.e., 33.333 is 30 MHz).
    .CLKOUT0_DIVIDE(4),         // Divide amount for CLKOUT0
    .CLKOUT0_DUTY_CYCLE(0.5),   // Duty cycle for CLKOUT0
    .CLKOUT0_PHASE(0.0),       // Phase offset for CLKOUT0
    .CLKOUT1_DIVIDE(1),         // Divide amount for CLKOUT1
    .CLKOUT1_DUTY_CYCLE(0.5),   // Duty cycle for CLKOUT1
    .CLKOUT1_PHASE(0.0),       // Phase offset for CLKOUT1
    .CLKOUTPHY_MODE("VCO_2X"), // Frequency of the CLKOUTPHY
    .COMPENSATION("AUTO"),     // Clock input compensation
    .DIVCLK_DIVIDE(1),         // Master division value
    .IS_CLKFBIN_INVERTED(1'b0), // Optional inversion for CLKFBIN
    .IS_CLKIN_INVERTED(1'b0),   // Optional inversion for CLKIN
    .IS_PWRDWN_INVERTED(1'b0), // Optional inversion for PWRDWN
    .IS_RST_INVERTED(1'b0),     // Optional inversion for RST
    .REF_JITTER(0.0),           // Reference input jitter in UI
    .STARTUP_WAIT("FALSE")     // Delays DONE until PLL is locked
  )
  PLLE4_ADV_inst (
    .CLKFBOUT(clk_fb),       // 1-bit output: Feedback clock
    .CLKOUT0(clk0),         // 1-bit output: General Clock output
    .CLKOUT0B(),       // 1-bit output: Inverted CLKOUT0
    .CLKOUT1(clk1),         // 1-bit output: General Clock output
    .CLKOUT1B(),       // 1-bit output: Inverted CLKOUT1
    .CLKOUTPHY(),     // 1-bit output: Bitslice clock
    .DO(),                   // 16-bit output: DRP data output
    .DRDY(),               // 1-bit output: DRP ready
    .LOCKED(lock),           // 1-bit output: LOCK
    .CLKFBIN(clk_fb_g),         // 1-bit input: Feedback clock
    .CLKIN(clk_in),             // 1-bit input: Input clock
    .CLKOUTPHYEN(1'b1), // 1-bit input: CLKOUTPHY enable
    .DADDR(7'b0),             // 7-bit input: DRP address
    .DCLK(1'b0),               // 1-bit input: DRP clock
    .DEN(1'b0),                 // 1-bit input: DRP enable
    .DI(16'b0),                   // 16-bit input: DRP data input
    .DWE(1'b0),                 // 1-bit input: DRP write enable
    .PWRDWN(1'b0),           // 1-bit input: Power-down
    .RST(rst)                 // 1-bit input: Reset
  );

使用方法

OSERDESE3 时钟

当MMCME4_ADV输出时钟作为OSERDESE3输入时钟是,MMCME4_ADV输出时钟通过BUFGCE和BUFGCE_DIV后,进入OSERDESE3。通过BUFGCE和BUFGCE_DIV来减少CLK与CLKDIV之间时钟偏差。

代码3.png

最新文章