在FPGA VI中可使用组件级IP(CLIP)时钟。下列代码为使用CLIP内部的Xilinx DCM生成衍生时钟及使用诸如相位偏移等功能的范例。代码还显示了锁定和重置DCM和将BUFGCE用于可能停止的时钟的方法。

提示    如要使用此代码,可将代码复制至文本文件并另存为ClipGenerateClks.vhd。然后通过配置组件级IP向导,由ClipGenerateClks.vhd自动生成声明XML文件。
------------------------------------------------------------------------------- 
-- 
-- File: ClipGenerateClks.vhd 
-- Author: National Instruments Corporation 
-- Date: April 2009 
-- 
------------------------------------------------------------------------------- 
-- 
-- Purpose: 
-- 
-- This CLIP component generates clocks using a Xilinx DCM. A 40 Mhz clock is 
-- used to derive an 80 Mhz clock, and a phase shifted version of 80Mhz clock 
-- that is shifted by 180 degrees. 
-- 
-- This example illustrates to use other Xilinx DCM features 
-- such as phase shifting. 
-- 
-- Signal naming convention: 
-- 
-- All asynchronous signals are pre-fixed with a. 
-- All Clk40 synchronous signals are pre-fixed with c40. 
-- All Clk80FromDcm0 synchronous signals are pre-fixed with c80. 
-- All metastable signals are suffixed with _ms. 
-- 
-- Ports: 
-- 
-- aDiagramReset : This is the LabVIEW FPGA asynchronous diagram reset. 
-- 
-- Clk40 : This is the LabVIEW FPGA generated 40 Mhz clock. This 
-- clock is stable and free-running only when aDiagramReset 
-- is low. 
-- 
-- ClkOut80 : This is an 80 Mhz clock generated from Xilinx DCM. 
-- 
-- ClkOut80P180 : This is an 80 Mhz clock phase shifted by 180 degrees 
-- generated by Xilinx DCM. 
-- 
------------------------------------------------------------------------------- 

library ieee; 
  use ieee.std_logic_1164.all; 
  use ieee.numeric_std.all; 

entity ClipGenerateClks is 
  port ( 
    aDiagramReset : in std_logic; 
    Clk40 : in std_logic; 
    ClkOut80 : out std_logic; 
    ClkOut80P180 : out std_logic 
  ); 
end ClipGenerateClks; 

architecture rtl of ClipGenerateClks is 

  -- BUFG component declaration 
  component BUFG 
    port ( 
       I : in std_logic; 
       O : out std_logic); 
  end component; 

  -- BUFGCE component declaration 
  component BUFGCE 
    port ( 
       I : in std_logic; 
       CE : in std_logic; 
       O : out std_logic); 
  end component; 

  -- DCM component declaration 
  component DCM 
    generic ( 
       CLKIN_PERIOD : real; 
       CLK_FEEDBACK : string; 
       CLKDV_DIVIDE : real; 
       CLKFX_DIVIDE : integer; 
       CLKFX_MULTIPLY : integer; 
       CLKIN_DIVIDE_BY_2 : boolean; 
       CLKOUT_PHASE_SHIFT : string; 
       DESKEW_ADJUST : string; 
       DFS_FREQUENCY_MODE : string; 
       DLL_FREQUENCY_MODE : string; 
       DSS_MODE : string; 
       DUTY_CYCLE_CORRECTION : Boolean; 
       PHASE_SHIFT : integer; 
       STARTUP_WAIT : boolean 
    ); 
    port ( 
       CLKIN, CLKFB, RST, DSSEN, PSINCDEC, PSEN, PSCLK : in std_logic; 
       CLK0, CLK90, CLK180, CLK270, 
       CLK2X, CLK2X180, CLKDV, CLKFX, CLKFX180 : out std_logic; 
       LOCKED : out std_logic; 
       STATUS : out std_logic_vector(7 downto 0); 
       PSDONE : out std_logic 
    ); 
  end component; 

  constant kDcmResetDuration : positive := 3; 
  signal c40ResetToDcm0_ms : std_logic := '1'; 
  signal c40ResetToDcm0 : std_logic_vector(kDcmResetDuration downto 1) := (others => '1'); 
  signal Clk0FromDcm0, ClkFbToDcm0 : std_logic; 
  signal Clk80FromDcm0, Clk80P180FromDcm0, Clk80ThruBufg : std_logic; 
  signal aLockedFromDcm0 : std_logic; 
  signal c80Locked_ms, c80Locked : std_logic := '0'; 

begin 

  -- Dcm0RstShiftReg ---------------------------------------------------------- 
  -- This shift register makes sure that when the DCM reset asserts, it 
  -- remains asserted for at least three clock cycles of DCM CLKIN. This 
  -- is required for correct DCM locking sequence. Refer to the Xilinx FPGA 
  -- user guide for more information. 
  -- 
  -- The DCM should be reset when aDiagramReset asserts. This is important 
  -- because some LabVIEW FPGA generated clocks (base or derived clocks) may 
  -- not be valid when aDiagramReset is asserted. All LabVIEW FPGA clocks 
  -- (in this case Clk40) are guaranteed to be stable and free-running 
  -- immediately following the de-assertion of aDiagramReset. 
  -- However, if externally generated clocks are used to source the DCM, other 
  -- reset schemes would have to be used so that the DCM is kept in reset until 
  -- the external clock is stable and free-running. 
  ----------------------------------------------------------------------------- 
  Dcm0RstShiftReg : process (aDiagramReset, Clk40) 
  begin 
    if aDiagramReset = '1' then 
       c40ResetToDcm0_ms <= '1'; 
       c40ResetToDcm0 <= (others => '1'); 
    elsif rising_edge(Clk40) then 
       c40ResetToDcm0_ms <= '0'; 
       c40ResetToDcm0(1) <= c40ResetToDcm0_ms; 
       for i in 1 to kDcmResetDuration-1 loop 
           c40ResetToDcm0(i+1) <= c40ResetToDcm0(i); 
       end loop; 
    end if; 
  end process Dcm0RstShiftReg; 
  -- DCM0: -------------------------------------------------------------------- 
  -- This DCM generates a 80 Mhz and a phase shifted version of the 80 Mhz 
  -- clock shifted by 180 degrees. 
  ----------------------------------------------------------------------------- 
  DCM0: DCM 
    generic map( 
       CLKIN_PERIOD => 25.0, 
       CLK_FEEDBACK => "1X", 
       CLKDV_DIVIDE => 2.0, 
       CLKFX_DIVIDE => 1, 
       CLKFX_MULTIPLY => 4, 
       CLKIN_DIVIDE_BY_2 => FALSE, 
       CLKOUT_PHASE_SHIFT => "NONE", 
       DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS", 
       DFS_FREQUENCY_MODE => "LOW", 
       DLL_FREQUENCY_MODE => "LOW", 
       DSS_MODE => "NONE", 
       DUTY_CYCLE_CORRECTION => TRUE, 
       PHASE_SHIFT => 0, 
       STARTUP_WAIT => FALSE 
    ) 
    port map ( 
       RST => c40ResetToDcm0(kDcmResetDuration), 
       CLKIN => Clk40, 
       CLKFB => ClkFbToDcm0, 
       CLK0 =>Clk0FromDcm0, 
       CLK180 =>OPEN, 
       CLK270 =>OPEN, 
       CLK2X =>Clk80FromDcm0, 
       CLK2X180 =>Clk80P180FromDcm0, 
       CLK90 =>OPEN, 
       CLKDV =>OPEN, 
       CLKFX =>OPEN, 
       CLKFX180 =>OPEN, 
       DSSEN =>'0', 
       PSCLK =>'0', 
       PSEN =>'0', 
       PSINCDEC =>'0', 
       LOCKED =>aLockedFromDcm0, 
       PSDONE =>OPEN, 
       STATUS =>OPEN); 
  -- BufgClkFbofDcm0: --------------------------------------------------------- 
  -- This BUFG is used to drive the feedback clock input of DCM0. 
  ----------------------------------------------------------------------------- 
  BufgClkFbofDcm0: BUFG 
    port map ( 
       I =>Clk0FromDcm0, 
       O =>ClkFbToDcm0); 
  -- BufgClk80: --------------------------------------------------------------- 
  -- This BUFG is used to drive the clock used by the synchronizer on locked 
  -- signal from DCM0. 
  ----------------------------------------------------------------------------- 
  BufgClk80: BUFG 
    port map ( 
       I => Clk80FromDcm0, 
       O => Clk80ThruBufg); 
  -- DblSyncLocked: ----------------------------------------------------------- 
  -- This double synchronizer synchronizes the asynchronous locked signal from 
  -- DCM0 to the Clk80FromDcm0 clock domain. This signal will be used to drive 
  -- the CE pin of the BUFGCE. This is because CE must not change during a short 
  -- setup window just prior to the rising clock edge on the BUFGCE input I. 
  -- Violating this setup time requirement can result in glitchy output pulse. 
  -- Refer to the Xilinx FPGA user guide for more information. 
  -- 
  -- However, when aDiagramReset asserts, c80Locked could violate the setup 
  -- time requirement of Clk80FromDcm0, and it could result in a glitchy output 
  -- pulse at output O of BUFGCE. This glitch is acceptable because the FPGA VI 
  -- will be in an asynchronous reset. However, if this clock is being used for 
  -- other circuitry not reset by aDiagramReset, that circuitry should be 
  -- disabled before this reset asserts. 
  ----------------------------------------------------------------------------- 
  DblSyncLocked : process (aDiagramReset, Clk80ThruBufg) 
  begin 
    if aDiagramReset = '1' then 
       c80Locked_ms <= '0'; 
       c80Locked <= '0'; 
    elsif rising_edge(Clk80ThruBufg) then 
       c80Locked_ms <= aLockedFromDcm0; 
       c80Locked <= c80Locked_ms; 
    end if; 
  end process DblSyncLocked; 

  -- BufgceClk80: ------------------------------------------------------------- 
  -- This BUFGCE remains disabled until DCM0 achieves lock. This ensures that 
  -- the global clock network is driven only when the 80 Mhz derived clock is 
  -- valid and glitch free. 
  -----------------------------------------------------------------------------
  BufgceClk80: BUFGCE 
    port map ( 
       I =>Clk80FromDcm0, 
       CE =>c80Locked, 
       O =>ClkOut80); 

  -- BufgceClk80P180: --------------------------------------------------------- 
  -- This BUFGCE remains disabled until DCM0 achieves lock. This ensures that 
  -- the global clock network is driven only when the phase shifted 80 Mhz 
  -- derived clock is valid and glitch free. 
  ----------------------------------------------------------------------------- 
  BufgceClk80P180: BUFGCE 
    port map ( 
       I =>Clk80P180FromDcm0, 
       CE =>c80Locked, 
       O =>ClkOut80P180); 

end rtl;