URL
https://opencores.org/ocsvn/pcie_ds_dma/pcie_ds_dma/trunk
Subversion Repositories pcie_ds_dma
[/] [pcie_ds_dma/] [trunk/] [core/] [ds_dma64/] [pcie_src/] [pcie_core64_m1/] [source_virtex6/] [pcie_clocking_v6.vhd] - Rev 2
Compare with Previous | Blame | View Log
------------------------------------------------------------------------------- -- -- (c) Copyright 2009-2011 Xilinx, Inc. All rights reserved. -- -- This file contains confidential and proprietary information -- of Xilinx, Inc. and is protected under U.S. and -- international copyright and other intellectual property -- laws. -- -- DISCLAIMER -- This disclaimer is not a license and does not grant any -- rights to the materials distributed herewith. Except as -- otherwise provided in a valid license issued to you by -- Xilinx, and to the maximum extent permitted by applicable -- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND -- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES -- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING -- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- -- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and -- (2) Xilinx shall not be liable (whether in contract or tort, -- including negligence, or under any other theory of -- liability) for any loss or damage of any kind or nature -- related to, arising under or in connection with these -- materials, including for any direct, or any indirect, -- special, incidental, or consequential loss or damage -- (including loss of data, profits, goodwill, or any type of -- loss or damage suffered as a result of any action brought -- by a third party) even if such damage or loss was -- reasonably foreseeable or Xilinx had been advised of the -- possibility of the same. -- -- CRITICAL APPLICATIONS -- Xilinx products are not designed or intended to be fail- -- safe, or for use in any application requiring fail-safe -- performance, such as life-support or safety devices or -- systems, Class III medical devices, nuclear facilities, -- applications related to the deployment of airbags, or any -- other applications that could lead to death, personal -- injury, or severe property or environmental damage -- (individually and collectively, "Critical -- Applications"). Customer assumes the sole risk and -- liability of any use of Xilinx products in Critical -- Applications, subject only to applicable laws and -- regulations governing limitations on product liability. -- -- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS -- PART OF THIS FILE AT ALL TIMES. -- ------------------------------------------------------------------------------- -- Project : Virtex-6 Integrated Block for PCI Express -- File : pcie_clocking_v6.vhd -- Version : 2.3 ---- Description: Clocking module for Virtex6 PCIe Block ---- ---- ---- ---------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; library unisim; use unisim.vcomponents.all; entity pcie_clocking_v6 is generic ( IS_ENDPOINT : boolean := TRUE; CAP_LINK_WIDTH : integer := 8; -- 1 - x1 , 2 - x2 , 4 - x4 , 8 - x8 CAP_LINK_SPEED : integer := 1; -- 1 - Gen1 , 2 - Gen2 REF_CLK_FREQ : integer := 0; -- 0 - 100 MHz , 1 - 125 MHz , 2 - 250 MHz USER_CLK_FREQ : integer := 3 -- 0 - 31.25 MHz , 1 - 62.5 MHz , 2 - 125 MHz , 3 - 250 MHz , 4 - 500Mhz ); port ( sys_clk : in std_logic; gt_pll_lock : in std_logic; sel_lnk_rate : in std_logic; sel_lnk_width : in std_logic_vector(1 downto 0); sys_clk_bufg : out std_logic; pipe_clk : out std_logic; user_clk : out std_logic; block_clk : out std_logic; drp_clk : out std_logic; clock_locked : out std_logic ); end pcie_clocking_v6; architecture v6_pcie of pcie_clocking_v6 is -- MMCM Configuration function clkin_prd( constant REF_CLK_FREQ : integer) return real is variable CLKIN_PERD : real := 0.0; begin -- clkin_prd if (REF_CLK_FREQ = 0) then CLKIN_PERD := 10.0; elsif (REF_CLK_FREQ = 1) then CLKIN_PERD := 8.0; elsif (REF_CLK_FREQ = 2) then CLKIN_PERD := 4.0; else CLKIN_PERD := 0.0; end if; return CLKIN_PERD; end clkin_prd; constant mmcm_clockin_period : real := clkin_prd(REF_CLK_FREQ); function clkfb_mul( constant REF_CLK_FREQ : integer) return real is variable CLKFB_MULT : real := 0.0; begin -- clkfb_mul if (REF_CLK_FREQ = 0) then CLKFB_MULT := 10.0; elsif (REF_CLK_FREQ = 1) then CLKFB_MULT := 8.0; elsif (REF_CLK_FREQ = 2) then CLKFB_MULT := 8.0; else CLKFB_MULT := 0.0; end if; return CLKFB_MULT; end clkfb_mul; constant mmcm_clockfb_mult : real := clkfb_mul(REF_CLK_FREQ); function divclk_div( constant REF_CLK_FREQ : integer) return integer is variable DIVCLK_DIVIDE : integer := 0; begin -- divclk_div if (REF_CLK_FREQ = 0) then DIVCLK_DIVIDE := 1; elsif (REF_CLK_FREQ = 1) then DIVCLK_DIVIDE := 1; elsif (REF_CLK_FREQ = 2) then DIVCLK_DIVIDE := 2; else DIVCLK_DIVIDE := 0; end if; return DIVCLK_DIVIDE; end divclk_div; constant mmcm_divclk_divide : integer := divclk_div(REF_CLK_FREQ); constant mmcm_clock0_div : real := 4.0; constant mmcm_clock1_div : integer := 8; constant TCQ : integer := 1; function clk2_div( constant LNK_WDT : integer; constant LNK_SPD : integer; constant USR_CLK_FREQ : integer) return integer is variable CLK_DIV : integer := 1; begin -- clk2_div if ((LNK_WDT = 1) and (LNK_SPD = 1) and (USR_CLK_FREQ = 0)) then CLK_DIV := 32; elsif ((LNK_WDT = 1) and (LNK_SPD = 1) and (USR_CLK_FREQ = 1)) then CLK_DIV := 16; elsif ((LNK_WDT = 1) and (LNK_SPD = 2) and (USR_CLK_FREQ = 1)) then CLK_DIV := 16; elsif ((LNK_WDT = 2) and (LNK_SPD = 1) and (USR_CLK_FREQ = 1)) then CLK_DIV := 16; else CLK_DIV := 2; end if; return CLK_DIV; end clk2_div; constant mmcm_clock2_div : integer := clk2_div(CAP_LINK_WIDTH, CAP_LINK_SPEED, USER_CLK_FREQ); constant mmcm_clock3_div : integer := 2; signal mmcm_locked : std_logic; signal mmcm_clkfbin : std_logic; signal mmcm_clkfbout : std_logic; signal mmcm_reset : std_logic; signal clk_500 : std_logic; signal clk_250 : std_logic; signal clk_125 : std_logic; signal user_clk_prebuf : std_logic; signal sel_lnk_rate_d : std_logic; signal reg_clock_locked : std_logic_vector(1 downto 0) := "11"; -- Declare intermediate signals for referenced outputs signal sys_clk_bufg_v6pcie3 : std_logic; signal pipe_clk_v6pcie : std_logic; signal user_clk_v6pcie4 : std_logic; signal block_clk_v6pcie0 : std_logic; signal drp_clk_v6pcie1 : std_logic; signal clock_locked_int : std_logic; begin -- Drive referenced outputs sys_clk_bufg <= sys_clk_bufg_v6pcie3; pipe_clk <= pipe_clk_v6pcie; user_clk <= user_clk_v6pcie4; block_clk <= block_clk_v6pcie0; drp_clk <= drp_clk_v6pcie1; clock_locked <= clock_locked_int; clock_locked_int <= (not(reg_clock_locked(1))) and mmcm_locked; -- MMCM Reset mmcm_reset <= '0'; -- PIPE Clock BUFG. GEN1_LINK : if (CAP_LINK_SPEED = 1) generate pipe_clk_bufg : BUFG port map (O => pipe_clk_v6pcie, I => clk_125 ); end generate; GEN2_LINK : if (CAP_LINK_SPEED = 2) generate sel_lnk_rate_delay : SRL16E generic map ( INIT => X"0000" ) port map ( Q => sel_lnk_rate_d, D => sel_lnk_rate, CLK => pipe_clk_v6pcie, CE => clock_locked_int, A3 => '1', A2 => '1', A1 => '1', A0 => '1' ); pipe_clk_bufgmux : BUFGMUX port map ( O => pipe_clk_v6pcie, I0 => clk_125, I1 => clk_250, S => sel_lnk_rate_d ); end generate; ILLEGAL_LINK_SPEED : if ((CAP_LINK_SPEED /= 1) and (CAP_LINK_SPEED /= 2)) generate --$display("Confiuration Error : CAP_LINK_SPEED = %d, must be either 1 or 2.", CAP_LINK_SPEED); --$finish; end generate; -- User Clock BUFG. x1_GEN1_31_25 : if ((CAP_LINK_WIDTH = 1) and (CAP_LINK_SPEED = 1) and (USER_CLK_FREQ = 0)) generate user_clk_bufg : BUFG port map ( O => user_clk_v6pcie4, I => user_clk_prebuf ); end generate; x1_GEN1_62_50 : if ((CAP_LINK_WIDTH = 1) and (CAP_LINK_SPEED = 1) and (USER_CLK_FREQ = 1)) generate user_clk_bufg : BUFG port map ( O => user_clk_v6pcie4, I => user_clk_prebuf ); end generate; x1_GEN1_125_00 : if ((CAP_LINK_WIDTH = 1) and (CAP_LINK_SPEED = 1) and (USER_CLK_FREQ = 2)) generate user_clk_bufg : BUFG port map ( O => user_clk_v6pcie4, I => clk_125 ); end generate; x1_GEN1_250_00 : if ((CAP_LINK_WIDTH = 1) and (CAP_LINK_SPEED = 1) and (USER_CLK_FREQ = 3)) generate user_clk_bufg : BUFG port map ( O => user_clk_v6pcie4, I => clk_250 ); end generate; x1_GEN2_62_50 : if ((CAP_LINK_WIDTH = 1) and (CAP_LINK_SPEED = 2) and (USER_CLK_FREQ = 1)) generate user_clk_bufg : BUFG port map ( O => user_clk_v6pcie4, I => user_clk_prebuf ); end generate; x1_GEN2_125_00 : if ((CAP_LINK_WIDTH = 1) and (CAP_LINK_SPEED = 2) and (USER_CLK_FREQ = 2)) generate user_clk_bufg : BUFG port map ( O => user_clk_v6pcie4, I => clk_125 ); end generate; x1_GEN2_250_00 : if ((CAP_LINK_WIDTH = 1) and (CAP_LINK_SPEED = 2) and (USER_CLK_FREQ = 3)) generate user_clk_bufg : BUFG port map ( O => user_clk_v6pcie4, I => clk_250 ); end generate; x2_GEN1_62_50 : if ((CAP_LINK_WIDTH = 2) and (CAP_LINK_SPEED = 1) and (USER_CLK_FREQ = 1)) generate user_clk_bufg : BUFG port map ( O => user_clk_v6pcie4, I => user_clk_prebuf ); end generate; x2_GEN1_125_00 : if ((CAP_LINK_WIDTH = 2) and (CAP_LINK_SPEED = 1) and (USER_CLK_FREQ = 2)) generate user_clk_bufg : BUFG port map ( O => user_clk_v6pcie4, I => clk_125 ); end generate; x2_GEN1_250_00 : if ((CAP_LINK_WIDTH = 2) and (CAP_LINK_SPEED = 1) and (USER_CLK_FREQ = 3)) generate user_clk_bufg : BUFG port map ( O => user_clk_v6pcie4, I => clk_250 ); end generate; x2_GEN2_125_00 : if ((CAP_LINK_WIDTH = 2) and (CAP_LINK_SPEED = 2) and (USER_CLK_FREQ = 2)) generate user_clk_bufg : BUFG port map ( O => user_clk_v6pcie4, I => clk_125 ); end generate; x2_GEN2_250_00 : if ((CAP_LINK_WIDTH = 2) and (CAP_LINK_SPEED = 2) and (USER_CLK_FREQ = 3)) generate user_clk_bufg : BUFG port map ( O => user_clk_v6pcie4, I => clk_250 ); end generate; x4_GEN1_125_00 : if ((CAP_LINK_WIDTH = 4) and (CAP_LINK_SPEED = 1) and (USER_CLK_FREQ = 2)) generate user_clk_bufg : BUFG port map ( O => user_clk_v6pcie4, I => clk_125 ); end generate; x4_GEN1_250_00 : if ((CAP_LINK_WIDTH = 4) and (CAP_LINK_SPEED = 1) and (USER_CLK_FREQ = 3)) generate user_clk_bufg : BUFG port map ( O => user_clk_v6pcie4, I => clk_250 ); end generate; x4_GEN2_250_00 : if ((CAP_LINK_WIDTH = 4) and (CAP_LINK_SPEED = 2) and (USER_CLK_FREQ = 3)) generate user_clk_bufg : BUFG port map ( O => user_clk_v6pcie4, I => clk_250 ); end generate; x8_GEN1_250_00 : if ((CAP_LINK_WIDTH = 8) and (CAP_LINK_SPEED = 1) and (USER_CLK_FREQ = 3)) generate user_clk_bufg : BUFG port map ( O => user_clk_v6pcie4, I => clk_250 ); end generate; x8_GEN2_250_00 : if ((CAP_LINK_WIDTH = 8) and (CAP_LINK_SPEED = 2) and (USER_CLK_FREQ = 4)) generate user_clk_bufg : BUFG port map ( O => user_clk_v6pcie4, I => clk_250 ); block_clk_bufg : BUFG port map ( O => block_clk_v6pcie0, I => clk_500 ); end generate; -- v6pcie42 : if (not((CAP_LINK_WIDTH = 8) and (CAP_LINK_SPEED = 2) and (USER_CLK_FREQ = 4))) generate --$display("Confiuration Error : Unsupported Link Width, Link Speed and User Clock Frequency Combination"); --$finish; -- end generate; -- DRP clk drp_clk_bufg_i : BUFG port map ( O => drp_clk_v6pcie1, I => clk_125 ); -- Feedback BUFG. Required for Temp Compensation clkfbin_bufg_i : BUFG port map ( O => mmcm_clkfbin, I => mmcm_clkfbout ); -- sys_clk BUFG. sys_clk_bufg_i : BUFG port map ( O => sys_clk_bufg_v6pcie3, I => sys_clk ); mmcm_adv_i : MMCM_ADV generic map ( -- 5 for 100 MHz , 4 for 125 MHz , 2 for 250 MHz CLKFBOUT_MULT_F => mmcm_clockfb_mult, DIVCLK_DIVIDE => mmcm_divclk_divide, CLKFBOUT_PHASE => 0.0, -- 10 for 100 MHz, 4 for 250 MHz CLKIN1_PERIOD => mmcm_clockin_period, CLKIN2_PERIOD => mmcm_clockin_period, -- 500 MHz / mmcm_clockx_div CLKOUT0_DIVIDE_F => mmcm_clock0_div, CLKOUT0_PHASE => 0.0, CLKOUT1_DIVIDE => mmcm_clock1_div, CLKOUT1_PHASE => 0.0, CLKOUT2_DIVIDE => mmcm_clock2_div, CLKOUT2_PHASE => 0.0, CLKOUT3_DIVIDE => mmcm_clock3_div, CLKOUT3_PHASE => 0.0 ) port map ( clkfbout => mmcm_clkfbout, clkout0 => clk_250, -- 250 MHz for pipe_clk clkout1 => clk_125, -- 125 MHz for pipe_clk clkout2 => user_clk_prebuf, -- user clk clkout3 => clk_500, clkout4 => open, clkout5 => open, clkout6 => open, do => open, drdy => open, clkfboutb => open, clkfbstopped => open, clkinstopped => open, clkout0b => open, clkout1b => open, clkout2b => open, clkout3b => open, psdone => open, locked => mmcm_locked, clkfbin => mmcm_clkfbin, clkin1 => sys_clk, clkin2 => '0', clkinsel => '1', daddr => "0000000", dclk => '0', den => '0', di => "0000000000000000", dwe => '0', psen => '0', psincdec => '0', pwrdwn => '0', psclk => '0', rst => mmcm_reset ); -- Synchronize MMCM locked output process (pipe_clk_v6pcie, gt_pll_lock) begin if ((not(gt_pll_lock)) = '1') then reg_clock_locked <= "11" after (TCQ)*1 ps; elsif (pipe_clk_v6pcie'event and pipe_clk_v6pcie = '1') then reg_clock_locked <= (reg_clock_locked(0) & '0') after (TCQ)*1 ps; end if; end process; end v6_pcie;