SURF  1.0
Gtx7RecClkMonitor.vhd
Go to the documentation of this file.
1 --////////////////////////////////////////////////////////////////////////////////
2 --// ____ ____
3 --// / /\/ /
4 --// /___/ \ / Vendor: Xilinx
5 --// \ \ \/ Version : 2.2
6 --// \ \ Application : 7 Series FPGAs Transceivers Wizard
7 --// / / Filename : kintexgtxlowlat_recclk_monitor.vhd
8 --// /___/ /\
9 --// \ \ / \
10 --// \___\/\___\
11 --//
12 --//
13 -- Description : This module is the ppm monitor between the
14 -- GT RxRecClk and the reference clock
15 --
16 -- This module will declare that the Rx RECCLK is stable if the
17 -- recovered clock is within +/-5000PPM of the reference clock.
18 --
19 --
20 -- There are 3 counters running on local clocks for both
21 -- recovered clocks and one for the reference clock. The
22 -- COUNTER_UPPER_VALUE parameter is the width of these
23 -- counters. The PPM offset is checked when these counters
24 -- roll over.
25 --
26 -- There is also a counter running on the system clock.
27 -- This can be running at a much lower frequency and is
28 -- running on a BUFG.
29 --
30 -- To set the parameters correctly here is what you need to
31 -- do. Lets assume taht the reference and recovered
32 -- clocks are running at 156MHz and the system clock is
33 -- running at 50MHz.
34 --
35 -- To ensure that the interval is long enough we want to
36 -- to make the COUNTER_UPPER_VALUE to be reasonable. The
37 -- CLOCK_PULSES is the number of sytem clock cycles we can
38 -- expect to be off based on these frequencies:
39 --
40 -- Example: Rec Clk and Ref Clk 156MHz, System clock 50MHz
41 -- PPM Offset to tolerate +/- 5000PPM
42 --
43 -- COUNTER_UPPER_VALUE = 15 -> 2^15 counter = 32768
44 -- GCLK_COUNTER_UPPER_VALUE = 15 -> 2^15 counter = 32768
45 --
46 -- PPM OFFSET = 5000 => 32768 * 5000/1000000 = 164
47 --
48 -- Now we are using the system clock to do the
49 -- calculations, therfore we need to scale the PPM_OFFSET
50 -- accordingly.
51 --
52 -- CLOCK_PULSES = PPM_OFFSET * sysclk_freq/refclk_freq
53 -- = 164 * 50/156 = 52
54 --
55 --
56 -- When the counters are checked if they are off by less
57 -- than 52, we can delcare that the particular RECCLK is
58 -- stable.
59 --
60 -- All FFs that have the _meta are metastability FFs and
61 -- can be ignored from a timing perspective. The following
62 -- constraint can be added to the UCF to ensure that they
63 -- are ignored:
64 --
65 -- INST "*_meta" TNM = "METASTABILITY_FFS";
66 -- TIMESPEC "TS_METASTABILITY" = FROM FFS TO "METASTABILITY_FFS" TIG;
67 --
68 -- Module KintexGtxLowLat_RECCLK_MONITOR
69 -- Generated by Xilinx 7 Series FPGAs Transceivers Wizard
70 --
71 --
72 -- (c) Copyright 2010-2012 Xilinx, Inc. All rights reserved.
73 --
74 -- This file contains confidential and proprietary information
75 -- of Xilinx, Inc. and is protected under U.S. and
76 -- international copyright and other intellectual property
77 -- laws.
78 --
79 -- DISCLAIMER
80 -- This disclaimer is not a license and does not grant any
81 -- rights to the materials distributed herewith. Except as
82 -- otherwise provided in a valid license issued to you by
83 -- Xilinx, and to the maximum extent permitted by applicable
84 -- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
85 -- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
86 -- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
87 -- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
88 -- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
89 -- (2) Xilinx shall not be liable (whether in contract or tort,
90 -- including negligence, or under any other theory of
91 -- liability) for any loss or damage of any kind or nature
92 -- related to, arising under or in connection with these
93 -- materials, including for any direct, or any indirect,
94 -- special, incidental, or consequential loss or damage
95 -- (including loss of data, profits, goodwill, or any type of
96 -- loss or damage suffered as a result of any action brought
97 -- by a third party) even if such damage or loss was
98 -- reasonably foreseeable or Xilinx had been advised of the
99 -- possibility of the same.
100 --
101 -- CRITICAL APPLICATIONS
102 -- Xilinx products are not designed or intended to be fail-
103 -- safe, or for use in any application requiring fail-safe
104 -- performance, such as life-support or safety devices or
105 -- systems, Class III medical devices, nuclear facilities,
106 -- applications related to the deployment of airbags, or any
107 -- other applications that could lead to death, personal
108 -- injury, or severe property or environmental damage
109 -- (individually and collectively, "Critical
110 -- Applications"). Customer assumes the sole risk and
111 -- liability of any use of Xilinx products in Critical
112 -- Applications, subject only to applicable laws and
113 -- regulations governing limitations on product liability.
114 --
115 -- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
116 -- PART OF THIS FILE AT ALL TIMES.
117 
118 
119 --*******************************************************************************
120 
121 library IEEE;
122 use IEEE.STD_LOGIC_1164.ALL;
123 use IEEE.STD_LOGIC_ARITH.ALL;
124 use IEEE.STD_LOGIC_UNSIGNED.ALL;
125 
126 --! @see entity
127  --! @ingroup xilinx_7Series_gtx7
129  generic(
130  COUNTER_UPPER_VALUE : integer := 20; --ppm counter. For 2^20 cntr.
131  GCLK_COUNTER_UPPER_VALUE : integer := 20; --ppm counter. For 2^20 cntr.
132  CLOCK_PULSES : integer := 5000;
133  EXAMPLE_SIMULATION : integer := 0 --The simulation-only constructs are not used but the
134  --full HW-circuitry gets simulated.
135  --NOTE OF CARE: This can extend the necessary simulation-
136  --time to beyond 600 ?s (six-hundred, sic!)
137 
138  );
139  port (
140  GT_RST : in std_logic;
141  REF_CLK : in std_logic;
142  RX_REC_CLK0 : in std_logic;
143  SYSTEM_CLK : in std_logic; -- This would be your System Clock;
144  PLL_LK_DET : in std_logic; -- This signal is verified in the Rx-FSM,
145  -- it can be tied high as the PLL-LK has already been
146  -- verified in the previous state.
147  RECCLK_STABLE : out std_logic;
148  EXEC_RESTART : out std_logic
149  );
150 end ENTITY Gtx7RecClkMonitor;
151 
152 
153 ARCHITECTURE RTL of Gtx7RecClkMonitor is
154 
155 --------------------------------------------------------------------------------
156 -- Declaration of wires/regs
157 --------------------------------------------------------------------------------
158 type FSM is (WAIT_FOR_LOCK,REFCLK_EVENT,CALC_PPM_DIFF,CHECK_SIGN,COMP_CNTR,RESTART);
159 signal state : FSM;
160 
161 
162 attribute syn_keep : boolean;
163 signal ref_clk_cnt : std_logic_vector (COUNTER_UPPER_VALUE-1 downto 0);
164 signal rec_clk0_cnt : std_logic_vector (COUNTER_UPPER_VALUE-1 downto 0) := (others => '0');
165 signal rec_clk0_msb : std_logic_vector (2 downto 1);
166 signal ref_clk_msb : std_logic_vector (2 downto 1);
167 signal rec_clk_0_msb_meta : std_logic;
168 attribute syn_keep of rec_clk_0_msb_meta : signal is true;
169 signal ref_clk_msb_meta : std_logic;
170 attribute syn_keep of ref_clk_msb_meta : signal is true;
171 
172 signal sys_clk_counter : std_logic_vector (GCLK_COUNTER_UPPER_VALUE-1 downto 0);
173 signal rec_clk0_compare_cnt_latch : std_logic_vector (GCLK_COUNTER_UPPER_VALUE-1 downto 0);
174 signal ref_clk_compare_cnt_latch : std_logic_vector (GCLK_COUNTER_UPPER_VALUE-1 downto 0);
175 
176 signal g_clk_rst_meta : std_logic;
177 attribute syn_keep of g_clk_rst_meta : signal is true;
178 signal g_clk_rst_sync : std_logic;
179 signal gt_pll_locked_meta : std_logic;
180 attribute syn_keep of gt_pll_locked_meta : signal is true;
181 signal gt_pll_locked_sync : std_logic;
182 
183 signal reset_logic_rec0_meta : std_logic;
184 attribute syn_keep of reset_logic_rec0_meta : signal is true;
185 signal reset_logic_rec0_sync : std_logic;
186 signal reset_logic_ref_meta : std_logic;
187 attribute syn_keep of reset_logic_ref_meta: signal is true;
188 signal reset_logic_ref_sync : std_logic;
189 
190 signal rec_clk0_edge_event : std_logic;
191 signal ref_clk_edge_event : std_logic_vector (1 downto 0);
192 
193 signal ppm0 : std_logic_vector (GCLK_COUNTER_UPPER_VALUE-1 downto 0);
194 
195 signal recclk_stable0 : std_logic;
196 signal reset_logic : std_logic_vector (3 downto 0);
197 signal ref_clk_edge_rt : std_logic_vector (1 downto 0);
198 
199 signal g_clk_rst : std_logic;
200 signal gt_pll_locked : std_logic;
201 signal rec_clk0_edge : std_logic;
202 signal ref_clk_edge : std_logic;
203 signal recclk_stable0_int : std_logic := '0';
204 
205 
206  function simulation_func return boolean is
207  --This function detects at compile-time whether the design
208  --is synthesised or simulated. For Simulation the Pragma-
209  --constructs below are just comments and the variable "sim"
210  --is set to True.
211  --For synthesis the Pragma-constructs turn off the translation
212  --between the _off and _on part and hence only the value false
213  --is returned for the function.
214  variable sim: boolean := false;
215  begin
216  sim := false;
217  --pragma translate_off
218  sim := true;
219  --pragma translate_on
220  return sim;
221  end function;
222 
223  constant simulation: boolean := simulation_func;
224 
225 --------------------------------------------------------------------------------
226 -- Main Logic
227 --------------------------------------------------------------------------------
228 begin
229 
230 HW_circuitry: if not simulation or (EXAMPLE_SIMULATION = 0) generate
231 process (RX_REC_CLK0) begin
232  if rising_edge(RX_REC_CLK0) then
235  end if;
236 end process;
237 
238 process (RX_REC_CLK0) begin
239  if rising_edge(RX_REC_CLK0) then
240  if (reset_logic_rec0_sync = '1') then
241  rec_clk0_cnt <= (others => '0');
242  else
244  end if;
245  end if;
246 end process;
247 
248 
249 process (REF_CLK) begin
250  if rising_edge(REF_CLK) then
253  end if;
254 end process;
255 
256 process (REF_CLK) begin
257  if rising_edge(REF_CLK) then
258  if (reset_logic_ref_sync = '1') then
259  ref_clk_cnt <= (others => '0');
260  else
261  ref_clk_cnt <= ref_clk_cnt +1;
262  end if;
263  end if;
264 end process;
265 
266 
267 --------------------------------------------------------------------------------
268 -- PPM Monitor
269 --
270 --We will also need 3 counters running on a global clock, one corresponding to
271 --each of the local counters. For this example I will use a 50MHz clock, but it
272 --can be anything. We use the global clock to sample the 20th bit of the local
273 --counter, it has to be sampled twice for metastability. Whenever we detect a
274 --falling edge on that signal, it means that the counter has rolled over. We
275 --use this to latch the current count value to FFs and reset the counter. Now
276 --you have the amount of time it took to count ~1M clock cycles. In an ideal
277 --world, this would be 6.7ms or 335,602 50MHz clock periods. You would do the
278 --same for the reference clock and then you could compare both counts and ensure
279 --that the difference is less than 1,678 (33.55us), if its not then you know
280 --you?ve exceeded your PPM limit. All the counts could be set as parameters and
281 --could easily be adjusted based on the global clock frequency and the PPM offset
282 --required.
283 --------------------------------------------------------------------------------
284 
285 -- Synchronize reset to global Clock domain
286 process (SYSTEM_CLK) begin
287  if rising_edge(SYSTEM_CLK) then
290 
293  end if;
294 end process;
295 
298 
299 
300 -- Main FSM
301 process (SYSTEM_CLK) begin
302  if rising_edge(SYSTEM_CLK) then
303  if (g_clk_rst = '1') then
304  state <= WAIT_FOR_LOCK;
305  ppm0 <= (others => '1');
306  recclk_stable0 <= '0';
307  EXEC_RESTART <= '0';
308  else
309  EXEC_RESTART <= '0';
310  case (state) is
311  when WAIT_FOR_LOCK =>
312  if ( (gt_pll_locked= '1')) then
313  if (ref_clk_edge_event = "01") then
314  state <= REFCLK_EVENT;
315  else
316  state <= WAIT_FOR_LOCK;
317  end if;
318  else
319  state <= WAIT_FOR_LOCK;
320  end if;
321  when REFCLK_EVENT =>
322  if (ref_clk_edge_event = "11") then -- two reference couter periods
323  state <= CALC_PPM_DIFF;
324  else
325  state <= REFCLK_EVENT;
326  end if;
327  when CALC_PPM_DIFF =>
328  if (rec_clk0_edge_event = '1') then
330  end if;
331  state <= CHECK_SIGN;
332  when CHECK_SIGN =>
333  --check the sign bit - if 1'b1, then convert to binary.
334  if (ppm0(GCLK_COUNTER_UPPER_VALUE-1) = '1') then
335  ppm0 <= not ppm0 + 1;
336  end if;
337  state <= COMP_CNTR;
338  when COMP_CNTR =>
339  if (ppm0 < CLOCK_PULSES) then
340  recclk_stable0 <= '1';
341  else
342  recclk_stable0 <= '0';
343  end if;
344  state <= RESTART;
345  when RESTART =>
346  state <= WAIT_FOR_LOCK;
347  EXEC_RESTART <= '1';
348  when others =>
349  state <= WAIT_FOR_LOCK;
350  ppm0 <= (others => '1');
351  recclk_stable0 <= '0';
352  end case;
353  end if;
354  end if;
355 end process;
356 
357 
358 
359 -- On clock roll-over, latch counter value once and event occurance.
360 process (SYSTEM_CLK) begin
361  if rising_edge(SYSTEM_CLK) then
362  if (reset_logic(3) = '1') then
363  rec_clk0_edge_event <= '0';
364  ref_clk_edge_event <= "00";
365  rec_clk0_compare_cnt_latch <= (others => '0');
366  ref_clk_compare_cnt_latch <= (others => '0');
367  ref_clk_edge_rt <= "00";
368  else
369  if ((rec_clk0_edge='1') and(rec_clk0_edge_event='0')) then
370  rec_clk0_edge_event <= '1';
372  end if;
373  if (ref_clk_edge='1') then
375  --only latch it the first time around
376  if (ref_clk_edge_event(0)='0') then
378  end if;
380  --take the 2's complement number after we latched it
381  if ((ref_clk_edge_event = "01") and (ref_clk_edge_rt= "01")) then
383  end if;
384  end if;
385  end if;
386  end if;
387 end process;
388 
389 -- increment clock counters'
390 process (SYSTEM_CLK) begin
391  if rising_edge(SYSTEM_CLK) then
392  if (reset_logic(3) = '1') then
393  sys_clk_counter <= (others => '0');
394  else
396  end if;
397  end if;
398 end process;
399 
400 process (SYSTEM_CLK) begin
401  if rising_edge(SYSTEM_CLK) then
402  if (reset_logic(3) = '1') then
403  rec_clk_0_msb_meta <= '0';
404  ref_clk_msb_meta <= '0';
405  rec_clk0_msb <= "00";
406  ref_clk_msb <= "00";
407  else -- double flop msb count bit to system clock domain
410 
413  end if;
414  end if;
415 end process;
416 
417 --falling edge detect
418 rec_clk0_edge <= '1' when ((rec_clk0_msb(2)='1')and (rec_clk0_msb(1)='0')) else '0';
419 ref_clk_edge <= '1' when ((ref_clk_msb(2)='1')and (ref_clk_msb(1)='0')) else '0';
420 
421 -- Manage counter reset/restart
422 process (SYSTEM_CLK) begin
423  if rising_edge(SYSTEM_CLK) then
424  if (g_clk_rst = '1') then
425  reset_logic <= "1111";
426  else
427  if (state = RESTART) then
428  reset_logic <= "1111";
429  else
430  reset_logic <= reset_logic(2 downto 0) & '0';
431  end if;
432  end if;
433  end if;
434 end process;
435 
436 
437 
439  end generate;
440 
441  SIM_shortcut: if simulation and (EXAMPLE_SIMULATION = 1)generate
442  --This Generate-branch is ONLY FOR SIMULATION and is not implemented in HW.
443  --The whole purpose of this shortcut-branch is to avoid huge simulation-
444  --times.
445  process(SYSTEM_CLK)
446  begin
447  if rising_edge(SYSTEM_CLK) then
448  if GT_RST = '1' then
449  recclk_stable0_int <= '0';
450  else
452  end if;
453  end if;
454  end process;
456 
457  end generate;
458 
459 
460 
461 end RTL;
462 
463 
std_logic_vector( 1 downto 0) ref_clk_edge_rt
std_logic_vector( GCLK_COUNTER_UPPER_VALUE- 1 downto 0) ppm0
out RECCLK_STABLEstd_logic
out EXEC_RESTARTstd_logic
_library_ IEEEIEEE
Definition: StdRtlPkg.vhd:18
std_logic_vector( 2 downto 1) ref_clk_msb
std_logic_vector( 2 downto 1) rec_clk0_msb
std_logic_vector( COUNTER_UPPER_VALUE- 1 downto 0) :=( others => '0') rec_clk0_cnt
in RX_REC_CLK0std_logic
std_logic_vector( GCLK_COUNTER_UPPER_VALUE- 1 downto 0) sys_clk_counter
std_logic_vector( GCLK_COUNTER_UPPER_VALUE- 1 downto 0) ref_clk_compare_cnt_latch
std_logic_vector( GCLK_COUNTER_UPPER_VALUE- 1 downto 0) rec_clk0_compare_cnt_latch
GCLK_COUNTER_UPPER_VALUEinteger := 20
std_logic_vector( 3 downto 0) reset_logic
std_logic_vector( COUNTER_UPPER_VALUE- 1 downto 0) ref_clk_cnt
COUNTER_UPPER_VALUEinteger := 20
(WAIT_FOR_LOCK,REFCLK_EVENT,CALC_PPM_DIFF,CHECK_SIGN,COMP_CNTR,RESTART) FSM
CLOCK_PULSESinteger := 5000
boolean := simulation_func simulation
std_logic_vector( 1 downto 0) ref_clk_edge_event
EXAMPLE_SIMULATIONinteger := 0
std_logic := '0' recclk_stable0_int