| 1 | --#############################################################
|
|---|
| 2 | -- Author : Boris Keil, Stefan Ritt
|
|---|
| 3 | -- Contents : Use external 33 MHz to generate internal clocks
|
|---|
| 4 | -- via DCMs
|
|---|
| 5 | -- $Id: usr_clocks.vhd 8369 2007-07-06 14:47:25Z ritt@PSI.CH $
|
|---|
| 6 | --#############################################################
|
|---|
| 7 |
|
|---|
| 8 | library ieee;
|
|---|
| 9 | use ieee.std_logic_1164.ALL;
|
|---|
| 10 | -- use ieee.std_logic_arith.all;
|
|---|
| 11 | use ieee.std_logic_unsigned.all;
|
|---|
| 12 | use ieee.numeric_std.ALL;
|
|---|
| 13 | -- synopsys translate_off
|
|---|
| 14 | library UNISIM;
|
|---|
| 15 | use UNISIM.Vcomponents.ALL;
|
|---|
| 16 | -- synopsys translate_on
|
|---|
| 17 |
|
|---|
| 18 | entity usr_clocks is
|
|---|
| 19 | port (
|
|---|
| 20 | P_I_CLK33 : in std_logic;
|
|---|
| 21 | P_I_CLK66 : in std_logic;
|
|---|
| 22 | O_CLK33 : out std_logic;
|
|---|
| 23 | O_CLK33_NODLL : out std_logic;
|
|---|
| 24 | O_CLK66 : out std_logic;
|
|---|
| 25 | O_CLK132 : out std_logic;
|
|---|
| 26 | O_CLK264 : out std_logic;
|
|---|
| 27 | O_CLK66_PS : out std_logic;
|
|---|
| 28 | O_LOCKED : out std_logic
|
|---|
| 29 | );
|
|---|
| 30 | end usr_clocks;
|
|---|
| 31 |
|
|---|
| 32 | architecture arch of usr_clocks is
|
|---|
| 33 | attribute BOX_TYPE : STRING ;
|
|---|
| 34 |
|
|---|
| 35 | -- xilinx cores
|
|---|
| 36 |
|
|---|
| 37 | component IBUFGDS_LVDS_25
|
|---|
| 38 | port(
|
|---|
| 39 | O : out std_ulogic;
|
|---|
| 40 | I : in std_ulogic;
|
|---|
| 41 | IB : in std_ulogic
|
|---|
| 42 | );
|
|---|
| 43 | end component;
|
|---|
| 44 | attribute BOX_TYPE of IBUFGDS_LVDS_25 : component is "PRIMITIVE";
|
|---|
| 45 |
|
|---|
| 46 | component BUFG
|
|---|
| 47 | port(
|
|---|
| 48 | O : out std_ulogic;
|
|---|
| 49 | I : in std_ulogic
|
|---|
| 50 | );
|
|---|
| 51 | end component;
|
|---|
| 52 | attribute BOX_TYPE of BUFG : component is "PRIMITIVE";
|
|---|
| 53 |
|
|---|
| 54 | -- !!! WARNING !!! : The Virtex2Pro has a bug in the DCM
|
|---|
| 55 | -- (a silicon bug, i.e. real hardware), the PLL does not
|
|---|
| 56 | -- lock properly if the CLK2x output is used for
|
|---|
| 57 | -- feedback -> always use CLK1x !!! (Call from Memec,
|
|---|
| 58 | -- C. Grivet, 17.12.03)
|
|---|
| 59 |
|
|---|
| 60 | component DCM
|
|---|
| 61 | generic (
|
|---|
| 62 | CLKDV_DIVIDE : real := 2.0;
|
|---|
| 63 | CLKFX_DIVIDE : integer := 1;
|
|---|
| 64 | CLKFX_MULTIPLY : integer := 4;
|
|---|
| 65 | CLKIN_DIVIDE_BY_2 : boolean := false;
|
|---|
| 66 | CLKIN_PERIOD : real := 0.0; --non-simulatable, in nanoseconds
|
|---|
| 67 | CLKOUT_PHASE_SHIFT : string := "NONE";
|
|---|
| 68 | CLK_FEEDBACK : string := "1X";
|
|---|
| 69 | DESKEW_ADJUST : string := "SYSTEM_SYNCHRONOUS"; --non-simulatable
|
|---|
| 70 | DFS_FREQUENCY_MODE : string := "LOW";
|
|---|
| 71 | DLL_FREQUENCY_MODE : string := "LOW";
|
|---|
| 72 | DSS_MODE : string := "NONE"; --non-simulatable
|
|---|
| 73 | DUTY_CYCLE_CORRECTION : boolean := true;
|
|---|
| 74 | -- MAXPERCLKIN : time := 1000000 ps; --simulation parameter
|
|---|
| 75 | -- MAXPERPSCLK : time := 100000000 ps; --simulation parameter
|
|---|
| 76 | PHASE_SHIFT : integer := 0;
|
|---|
| 77 | -- SIM_CLKIN_CYCLE_JITTER : time := 300 ps; --simulation parameter
|
|---|
| 78 | -- SIM_CLKIN_PERIOD_JITTER : time := 1000 ps; --simulation parameter
|
|---|
| 79 | STARTUP_WAIT : boolean := false --non-simulatable
|
|---|
| 80 | );
|
|---|
| 81 | port (
|
|---|
| 82 | CLK0 : out std_ulogic := '0';
|
|---|
| 83 | CLK180 : out std_ulogic := '0';
|
|---|
| 84 | CLK270 : out std_ulogic := '0';
|
|---|
| 85 | CLK2X : out std_ulogic := '0';
|
|---|
| 86 | CLK2X180 : out std_ulogic := '0';
|
|---|
| 87 | CLK90 : out std_ulogic := '0';
|
|---|
| 88 | CLKDV : out std_ulogic := '0';
|
|---|
| 89 | CLKFX : out std_ulogic := '0';
|
|---|
| 90 | CLKFX180 : out std_ulogic := '0';
|
|---|
| 91 | LOCKED : out std_ulogic := '0';
|
|---|
| 92 | PSDONE : out std_ulogic := '0';
|
|---|
| 93 | STATUS : out std_logic_vector(7 downto 0) := "00000000";
|
|---|
| 94 |
|
|---|
| 95 | CLKFB : in std_ulogic := '0';
|
|---|
| 96 | CLKIN : in std_ulogic := '0';
|
|---|
| 97 | DSSEN : in std_ulogic := '0';
|
|---|
| 98 | PSCLK : in std_ulogic := '0';
|
|---|
| 99 | PSEN : in std_ulogic := '0';
|
|---|
| 100 | PSINCDEC : in std_ulogic := '0';
|
|---|
| 101 | RST : in std_ulogic := '0'
|
|---|
| 102 | );
|
|---|
| 103 | end component;
|
|---|
| 104 | attribute BOX_TYPE of DCM : component is "PRIMITIVE";
|
|---|
| 105 |
|
|---|
| 106 | signal clk33_i, clk33, clk66_dcm1, clk66_dcm2, clk132, clk264, clk33_ps, clk66_ps : std_logic;
|
|---|
| 107 | signal clk33_tmp, clk66_dcm1_tmp, clk66_dcm2_tmp, clk132_tmp, clk264_tmp, clk33_ps_tmp, clk66_ps_tmp : std_logic;
|
|---|
| 108 | signal locked_dcm1, locked_dcm2, locked_dcm3 : std_logic;
|
|---|
| 109 | signal dcm2_reset, dcm2_reset_n: std_logic;
|
|---|
| 110 | signal dcm2_reset_delay_n: std_logic_vector(4 downto 0);
|
|---|
| 111 | signal GND: std_logic;
|
|---|
| 112 | signal VCC: std_logic;
|
|---|
| 113 |
|
|---|
| 114 | begin
|
|---|
| 115 | GND <= '0';
|
|---|
| 116 | VCC <= '1';
|
|---|
| 117 |
|
|---|
| 118 | -- Drive clock buffer with input pad oscillator signal
|
|---|
| 119 |
|
|---|
| 120 | inst_bufg_clk33_i: BUFG
|
|---|
| 121 | port map (
|
|---|
| 122 | I => P_I_CLK33,
|
|---|
| 123 | O => clk33_i
|
|---|
| 124 | );
|
|---|
| 125 |
|
|---|
| 126 | O_CLK33_NODLL <= clk33_i;
|
|---|
| 127 |
|
|---|
| 128 | -- Use clock buffers for DCM outputs
|
|---|
| 129 |
|
|---|
| 130 | inst_bufg_clk33_dcm1: BUFG
|
|---|
| 131 | port map (
|
|---|
| 132 | I => clk33_tmp,
|
|---|
| 133 | O => clk33
|
|---|
| 134 | );
|
|---|
| 135 |
|
|---|
| 136 | inst_bufg_clk66_dcm1: BUFG
|
|---|
| 137 | port map (
|
|---|
| 138 | I => clk66_dcm1_tmp,
|
|---|
| 139 | O => clk66_dcm1
|
|---|
| 140 | );
|
|---|
| 141 |
|
|---|
| 142 | inst_bufg_clk66_dcm2: BUFG
|
|---|
| 143 | port map (
|
|---|
| 144 | I => clk66_dcm2_tmp,
|
|---|
| 145 | O => clk66_dcm2
|
|---|
| 146 | );
|
|---|
| 147 |
|
|---|
| 148 | inst_bufg_clk132: BUFG
|
|---|
| 149 | port map (
|
|---|
| 150 | I => clk132_tmp,
|
|---|
| 151 | O => clk132
|
|---|
| 152 | );
|
|---|
| 153 |
|
|---|
| 154 | inst_bufg_clk264: BUFG
|
|---|
| 155 | port map (
|
|---|
| 156 | I => clk264_tmp,
|
|---|
| 157 | O => clk264
|
|---|
| 158 | );
|
|---|
| 159 |
|
|---|
| 160 | inst_bufg_clk33_ps: BUFG
|
|---|
| 161 | port map (
|
|---|
| 162 | I => clk33_ps_tmp,
|
|---|
| 163 | O => clk33_ps
|
|---|
| 164 | );
|
|---|
| 165 |
|
|---|
| 166 | inst_bufg_clk66_ps: BUFG
|
|---|
| 167 | port map (
|
|---|
| 168 | I => clk66_ps_tmp,
|
|---|
| 169 | O => clk66_ps
|
|---|
| 170 | );
|
|---|
| 171 |
|
|---|
| 172 | Inst_dcm1_clk132: DCM
|
|---|
| 173 | generic map (
|
|---|
| 174 | CLKDV_DIVIDE => 2.0,
|
|---|
| 175 | CLKFX_DIVIDE => 1,
|
|---|
| 176 | CLKFX_MULTIPLY => 4,
|
|---|
| 177 | CLKIN_DIVIDE_BY_2 => false,
|
|---|
| 178 | CLKIN_PERIOD => 30.0, -- in nanoseconds
|
|---|
| 179 | CLKOUT_PHASE_SHIFT => "NONE",
|
|---|
| 180 | CLK_FEEDBACK => "1X", -- 2X has a silicon bug ...
|
|---|
| 181 | DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS", -- OK ?? non-simulatable
|
|---|
| 182 | DFS_FREQUENCY_MODE => "LOW",
|
|---|
| 183 | DLL_FREQUENCY_MODE => "LOW",
|
|---|
| 184 | DSS_MODE => "NONE", --non-simulatable
|
|---|
| 185 | DUTY_CYCLE_CORRECTION => true,
|
|---|
| 186 | -- MAXPERCLKIN => 1000000 ps, --simulation parameter
|
|---|
| 187 | -- MAXPERPSCLK => 100000000 ps, --simulation parameter
|
|---|
| 188 | PHASE_SHIFT => 0,
|
|---|
| 189 | -- SIM_CLKIN_CYCLE_JITTER => 300 ps, --simulation parameter
|
|---|
| 190 | -- SIM_CLKIN_PERIOD_JITTER => 1000 ps, --simulation parameter
|
|---|
| 191 | STARTUP_WAIT => true --non-simulatable
|
|---|
| 192 | )
|
|---|
| 193 | port map (
|
|---|
| 194 | -- inputs
|
|---|
| 195 | CLKFB => clk33,
|
|---|
| 196 | CLKIN => clk33_i,
|
|---|
| 197 | DSSEN => GND,
|
|---|
| 198 | PSCLK => GND,
|
|---|
| 199 | PSEN => GND,
|
|---|
| 200 | PSINCDEC => GND,
|
|---|
| 201 | RST => GND,
|
|---|
| 202 | -- outputs
|
|---|
| 203 | CLK0 => clk33_tmp,
|
|---|
| 204 | CLK180 => open,
|
|---|
| 205 | CLK270 => open,
|
|---|
| 206 | CLK2X => clk66_dcm1_tmp,
|
|---|
| 207 | CLK2X180 => open,
|
|---|
| 208 | CLK90 => open,
|
|---|
| 209 | CLKDV => open,
|
|---|
| 210 | CLKFX => clk132_tmp,
|
|---|
| 211 | CLKFX180 => open,
|
|---|
| 212 | LOCKED => locked_dcm1,
|
|---|
| 213 | PSDONE => open,
|
|---|
| 214 | STATUS => open
|
|---|
| 215 |
|
|---|
| 216 | );
|
|---|
| 217 |
|
|---|
| 218 | Inst_dcm2_clk264: DCM
|
|---|
| 219 | generic map (
|
|---|
| 220 | CLKDV_DIVIDE => 2.0,
|
|---|
| 221 | CLKFX_DIVIDE => 1,
|
|---|
| 222 | CLKFX_MULTIPLY => 4,
|
|---|
| 223 | CLKIN_DIVIDE_BY_2 => false,
|
|---|
| 224 | CLKIN_PERIOD => 15.0, -- in nanoseconds
|
|---|
| 225 | CLKOUT_PHASE_SHIFT => "NONE",
|
|---|
| 226 | CLK_FEEDBACK => "1X", -- 2X has a silicon bug ...
|
|---|
| 227 | DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS", -- OK ?? non-simulatable
|
|---|
| 228 | DFS_FREQUENCY_MODE => "LOW",
|
|---|
| 229 | DLL_FREQUENCY_MODE => "HIGH",
|
|---|
| 230 | DSS_MODE => "NONE", --non-simulatable
|
|---|
| 231 | DUTY_CYCLE_CORRECTION => true,
|
|---|
| 232 | -- MAXPERCLKIN => 1000000 ps, --simulation parameter
|
|---|
| 233 | -- MAXPERPSCLK => 100000000 ps, --simulation parameter
|
|---|
| 234 | PHASE_SHIFT => 0,
|
|---|
| 235 | -- SIM_CLKIN_CYCLE_JITTER => 300 ps, --simulation parameter
|
|---|
| 236 | -- SIM_CLKIN_PERIOD_JITTER => 1000 ps, --simulation parameter
|
|---|
| 237 | STARTUP_WAIT => false --non-simulatable
|
|---|
| 238 | )
|
|---|
| 239 | port map (
|
|---|
| 240 | -- inputs
|
|---|
| 241 | CLKFB => clk66_dcm2,
|
|---|
| 242 | CLKIN => P_I_CLK66,
|
|---|
| 243 | DSSEN => GND,
|
|---|
| 244 | PSCLK => GND,
|
|---|
| 245 | PSEN => GND,
|
|---|
| 246 | PSINCDEC => GND,
|
|---|
| 247 | RST => dcm2_reset,
|
|---|
| 248 | -- outputs
|
|---|
| 249 | CLK0 => clk66_dcm2_tmp,
|
|---|
| 250 | CLK180 => open,
|
|---|
| 251 | CLK270 => open,
|
|---|
| 252 | CLK2X => open,
|
|---|
| 253 | CLK2X180 => open,
|
|---|
| 254 | CLK90 => open,
|
|---|
| 255 | CLKDV => open,
|
|---|
| 256 | CLKFX => clk264_tmp,
|
|---|
| 257 | CLKFX180 => open,
|
|---|
| 258 | LOCKED => locked_dcm2,
|
|---|
| 259 | PSDONE => open,
|
|---|
| 260 | STATUS => open
|
|---|
| 261 |
|
|---|
| 262 | );
|
|---|
| 263 |
|
|---|
| 264 | Inst_dcm3_clk_ps: DCM
|
|---|
| 265 | generic map (
|
|---|
| 266 | CLKDV_DIVIDE => 2.0,
|
|---|
| 267 | CLKFX_DIVIDE => 1,
|
|---|
| 268 | CLKFX_MULTIPLY => 2,
|
|---|
| 269 | CLKIN_DIVIDE_BY_2 => false,
|
|---|
| 270 | CLKIN_PERIOD => 30.0, -- in nanoseconds
|
|---|
| 271 | CLKOUT_PHASE_SHIFT => "FIXED", -- turn on phase shifting
|
|---|
| 272 | CLK_FEEDBACK => "1X", -- 2X has a silicon bug ...
|
|---|
| 273 | DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS", -- OK ?? non-simulatable
|
|---|
| 274 | DFS_FREQUENCY_MODE => "LOW",
|
|---|
| 275 | DLL_FREQUENCY_MODE => "LOW",
|
|---|
| 276 | DSS_MODE => "NONE", -- non-simulatable
|
|---|
| 277 | DUTY_CYCLE_CORRECTION => true,
|
|---|
| 278 | -- MAXPERCLKIN => 1000000 ps, -- simulation parameter
|
|---|
| 279 | -- MAXPERPSCLK => 100000000 ps, -- simulation parameter
|
|---|
| 280 | --PHASE_SHIFT => -32, -- adjust for FADC
|
|---|
| 281 | PHASE_SHIFT => 120, -- adjust for FADC
|
|---|
| 282 | --PHASE_SHIFT => 0, -- for simulation
|
|---|
| 283 | -- SIM_CLKIN_CYCLE_JITTER => 300 ps, -- simulation parameter
|
|---|
| 284 | -- SIM_CLKIN_PERIOD_JITTER => 1000 ps, -- simulation parameter
|
|---|
| 285 | STARTUP_WAIT => true -- non-simulatable
|
|---|
| 286 | )
|
|---|
| 287 | port map (
|
|---|
| 288 | -- inputs
|
|---|
| 289 | CLKFB => clk33_ps,
|
|---|
| 290 | CLKIN => clk33_i,
|
|---|
| 291 | DSSEN => GND,
|
|---|
| 292 | PSCLK => GND,
|
|---|
| 293 | PSEN => GND,
|
|---|
| 294 | PSINCDEC => GND,
|
|---|
| 295 | RST => GND,
|
|---|
| 296 | -- outputs
|
|---|
| 297 | CLK0 => clk33_ps_tmp,
|
|---|
| 298 | CLK180 => open,
|
|---|
| 299 | CLK270 => open,
|
|---|
| 300 | CLK2X => clk66_ps_tmp,
|
|---|
| 301 | CLK2X180 => open,
|
|---|
| 302 | CLK90 => open,
|
|---|
| 303 | CLKDV => open,
|
|---|
| 304 | CLKFX => open,
|
|---|
| 305 | CLKFX180 => open,
|
|---|
| 306 | LOCKED => locked_dcm3,
|
|---|
| 307 | PSDONE => open,
|
|---|
| 308 | STATUS => open
|
|---|
| 309 |
|
|---|
| 310 | );
|
|---|
| 311 |
|
|---|
| 312 | -- DCM2 is reset while DCM1 is not locked, because DCM1 feeds DCM2.
|
|---|
| 313 | -- A shift register guarantees a decent (i.e. long) reset pulse.
|
|---|
| 314 | proc_delayed_reset: process (P_I_CLK33)
|
|---|
| 315 | begin
|
|---|
| 316 | if rising_edge(P_I_CLK33) then
|
|---|
| 317 | if (locked_dcm1 = '0') then
|
|---|
| 318 | dcm2_reset_delay_n <= (others => '0');
|
|---|
| 319 | dcm2_reset_n <= '0';
|
|---|
| 320 | else
|
|---|
| 321 | dcm2_reset_delay_n <= dcm2_reset_delay_n(dcm2_reset_delay_n'high-1 downto 0) & '1';
|
|---|
| 322 | dcm2_reset_n <= dcm2_reset_delay_n(dcm2_reset_delay_n'high);
|
|---|
| 323 | dcm2_reset <= not dcm2_reset_n;
|
|---|
| 324 | end if;
|
|---|
| 325 | end if;
|
|---|
| 326 | end process;
|
|---|
| 327 |
|
|---|
| 328 | -- DCM outputs
|
|---|
| 329 | O_CLK33 <= clk33;
|
|---|
| 330 | O_CLK66 <= clk66_dcm1;
|
|---|
| 331 | O_CLK132 <= clk132;
|
|---|
| 332 | O_CLK264 <= clk264;
|
|---|
| 333 | O_CLK66_PS <= clk66_ps;
|
|---|
| 334 | O_LOCKED <= locked_dcm1 and locked_dcm2 and locked_dcm3;
|
|---|
| 335 | end arch;
|
|---|