MMCM与PLL
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.设置。
下图代码中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。
代码如下:
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之间时钟偏差。