AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Variables
daqlink_7s_tx_startup_fsm.vhd
1 --////////////////////////////////////////////////////////////////////////////////
2 --// ____ ____
3 --// / /\/ /
4 --// /___/ \ / Vendor: Xilinx
5 --// \ \ \/ Version : 2.7
6 --// \ \ Application : 7 Series FPGAs Transceivers Wizard
7 --// / / Filename :daqlink_7s_tx_startup_fsm.vhd
8 --// /___/ /\
9 --// \ \ / \
10 --// \___\/\___\
11 --//
12 --//
13 -- Description : This module performs TX reset and initialization.
14 --
15 --
16 --
17 -- Module DAQLINK_7S_tx_startup_fsm
18 -- Generated by Xilinx 7 Series FPGAs Transceivers Wizard
19 --
20 --
21 -- (c) Copyright 2010-2012 Xilinx, Inc. All rights reserved.
22 --
23 -- This file contains confidential and proprietary information
24 -- of Xilinx, Inc. and is protected under U.S. and
25 -- international copyright and other intellectual property
26 -- laws.
27 --
28 -- DISCLAIMER
29 -- This disclaimer is not a license and does not grant any
30 -- rights to the materials distributed herewith. Except as
31 -- otherwise provided in a valid license issued to you by
32 -- Xilinx, and to the maximum extent permitted by applicable
33 -- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
34 -- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
35 -- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
36 -- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
37 -- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
38 -- (2) Xilinx shall not be liable (whether in contract or tort,
39 -- including negligence, or under any other theory of
40 -- liability) for any loss or damage of any kind or nature
41 -- related to, arising under or in connection with these
42 -- materials, including for any direct, or any indirect,
43 -- special, incidental, or consequential loss or damage
44 -- (including loss of data, profits, goodwill, or any type of
45 -- loss or damage suffered as a result of any action brought
46 -- by a third party) even if such damage or loss was
47 -- reasonably foreseeable or Xilinx had been advised of the
48 -- possibility of the same.
49 --
50 -- CRITICAL APPLICATIONS
51 -- Xilinx products are not designed or intended to be fail-
52 -- safe, or for use in any application requiring fail-safe
53 -- performance, such as life-support or safety devices or
54 -- systems, Class III medical devices, nuclear facilities,
55 -- applications related to the deployment of airbags, or any
56 -- other applications that could lead to death, personal
57 -- injury, or severe property or environmental damage
58 -- (individually and collectively, "Critical
59 -- Applications"). Customer assumes the sole risk and
60 -- liability of any use of Xilinx products in Critical
61 -- Applications, subject only to applicable laws and
62 -- regulations governing limitations on product liability.
63 --
64 -- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
65 -- PART OF THIS FILE AT ALL TIMES.
66 
67 
68 --*****************************************************************************
69 
70 library IEEE;
71 use IEEE.STD_LOGIC_1164.ALL;
72 use IEEE.NUMERIC_STD.ALL;
73 
75  Generic( GT_TYPE : string := "GTX";
76  STABLE_CLOCK_PERIOD : integer range 4 to 250 := 8; --Period of the stable clock driving this state-machine, unit is [ns]
77  RETRY_COUNTER_BITWIDTH : integer range 2 to 8 := 8;
78  TX_QPLL_USED : boolean := False; -- the TX and RX Reset FSMs must
79  RX_QPLL_USED : boolean := False; -- share these two generic values
80  PHASE_ALIGNMENT_MANUAL : boolean := True -- Decision if a manual phase-alignment is necessary or the automatic
81  -- is enough. For single-lane applications the automatic alignment is
82  -- sufficient
83  );
84  Port ( STABLE_CLOCK : in STD_LOGIC; --Stable Clock, either a stable clock from the PCB
85  --or reference-clock present at startup.
86  TXUSERCLK : in STD_LOGIC; --TXUSERCLK as used in the design
87  SOFT_RESET : in STD_LOGIC; --User Reset, can be pulled any time
88  QPLLREFCLKLOST : in STD_LOGIC; --QPLL Reference-clock for the GT is lost
89  CPLLREFCLKLOST : in STD_LOGIC; --CPLL Reference-clock for the GT is lost
90  QPLLLOCK : in STD_LOGIC; --Lock Detect from the QPLL of the GT
91  CPLLLOCK : in STD_LOGIC; --Lock Detect from the CPLL of the GT
92  TXRESETDONE : in STD_LOGIC;
93  MMCM_LOCK : in STD_LOGIC;
94  GTTXRESET : out STD_LOGIC:='0';
95  MMCM_RESET : out STD_LOGIC:='1';
96  QPLL_RESET : out STD_LOGIC:='0'; --Reset QPLL
97  CPLL_RESET : out STD_LOGIC:='0'; --Reset CPLL
98  TX_FSM_RESET_DONE : out STD_LOGIC; --Reset-sequence has sucessfully been finished.
99  TXUSERRDY : out STD_LOGIC:='0';
100  RUN_PHALIGNMENT : out STD_LOGIC:='0';
101  RESET_PHALIGNMENT : out STD_LOGIC:='0';
102  PHALIGNMENT_DONE : in STD_LOGIC;
103 
104  RETRY_COUNTER : out STD_LOGIC_VECTOR (RETRY_COUNTER_BITWIDTH-1 downto 0):=(others=>'0')-- Number of
105  -- Retries it took to get the transceiver up and running
106  );
107 end DAQLINK_7S_TX_STARTUP_FSM;
108 
109 --Interdependencies:
110 -- * Timing depends on the frequency of the stable clock. Hence counters-sizes
111 -- are calculated at design-time based on the Generics
112 --
113 -- * if either of PLLs is reset during TX-startup, it does not need to be reset again by RX
114 -- => signal which PLL has been reset
115 -- *
116 
117 
118 
119 architecture RTL of DAQLINK_7S_TX_STARTUP_FSM is
120 
121  component DAQLINK_7S_sync_block
122  generic (
123  INITIALISE : bit_vector(1 downto 0) := "00"
124  );
125  port (
126  clk : in std_logic;
127  data_in : in std_logic;
128  data_out : out std_logic
129  );
130  end component;
131 
132  type tx_rst_fsm_type is(
133  INIT, ASSERT_ALL_RESETS, RELEASE_PLL_RESET,
134  RELEASE_MMCM_RESET, WAIT_RESET_DONE, DO_PHASE_ALIGNMENT,
135  RESET_FSM_DONE);
136 
137  signal tx_state : tx_rst_fsm_type := INIT;
138 
139  constant MMCM_LOCK_CNT_MAX : integer := 1024;
140  constant STARTUP_DELAY : integer := 500;--AR43482: Transceiver needs to wait for 500 ns after configuration
141  constant WAIT_CYCLES : integer := STARTUP_DELAY / STABLE_CLOCK_PERIOD; -- Number of Clock-Cycles to wait after configuration
142  constant WAIT_MAX : integer := WAIT_CYCLES + 10; -- 500 ns plus some additional margin
143 
144  constant WAIT_TIMEOUT_2ms : integer := 2000000 / STABLE_CLOCK_PERIOD;-- 2 ms time-out
145  constant WAIT_TLOCK_MAX : integer := 100000 / STABLE_CLOCK_PERIOD;--100 us time-out
146  constant WAIT_TIMEOUT_500us : integer := 500000 / STABLE_CLOCK_PERIOD;--100 us time-out
147 
148  signal init_wait_count : integer range 0 to WAIT_MAX:=0;
149  signal init_wait_done : std_logic := '0';
150  signal pll_reset_asserted : std_logic := '0';
151 
152  signal tx_fsm_reset_done_int : std_logic := '0';
153  signal tx_fsm_reset_done_int_s2 : std_logic := '0';
154  signal tx_fsm_reset_done_int_s3 : std_logic := '0';
155 
156  signal txresetdone_s2 : std_logic := '0';
157  signal txresetdone_s3 : std_logic := '0';
158 
159  constant MAX_RETRIES : integer := 2**RETRY_COUNTER_BITWIDTH-1;
160  signal retry_counter_int : integer range 0 to MAX_RETRIES;
161  signal time_out_counter : integer range 0 to WAIT_TIMEOUT_2ms := 0;
162 
163  signal reset_time_out : std_logic := '0';
164  signal time_out_2ms : std_logic := '0';--\Flags that the various time-out points
165  signal time_tlock_max : std_logic := '0';--|have been reached.
166  signal time_out_500us : std_logic := '0';--/
167 
168  signal mmcm_lock_count : integer range 0 to MMCM_LOCK_CNT_MAX-1:=0;
169  signal mmcm_lock_int : std_logic := '0';
170  signal mmcm_lock_i : std_logic := '0';
171  signal mmcm_lock_reclocked : std_logic := '0';
172 
173  signal run_phase_alignment_int : std_logic := '0';
174  signal run_phase_alignment_int_s2 : std_logic := '0';
175  signal run_phase_alignment_int_s3 : std_logic := '0';
176  constant MAX_WAIT_BYPASS : integer := 25344; --110000 TXUSRCLK cycles is the max time for Multi lane designs
177 
178 
179 
180  signal wait_bypass_count : integer range 0 to MAX_WAIT_BYPASS-1;
181  signal time_out_wait_bypass : std_logic := '0';
182  signal time_out_wait_bypass_s2 : std_logic := '0';
183  signal time_out_wait_bypass_s3 : std_logic := '0';
184  signal refclk_lost : std_logic;
185 
186  signal cplllock_sync: std_logic := '0';
187  signal qplllock_sync: std_logic := '0';
188  signal cplllock_prev: std_logic := '0';
189  signal qplllock_prev: std_logic := '0';
190  signal cplllock_ris_edge: std_logic := '0';
191  signal qplllock_ris_edge: std_logic := '0';
192 
193 begin
194  --Alias section, signals used within this module mapped to output ports:
195  RETRY_COUNTER <= STD_LOGIC_VECTOR(TO_UNSIGNED(retry_counter_int,RETRY_COUNTER_BITWIDTH));
196  RUN_PHALIGNMENT <= run_phase_alignment_int;
197  TX_FSM_RESET_DONE <= tx_fsm_reset_done_int;
198 
199  process(STABLE_CLOCK)
200  begin
201  if rising_edge(STABLE_CLOCK) then
202  -- The counter starts running when configuration has finished and
203  -- the clock is stable. When its maximum count-value has been reached,
204  -- the 500 ns from Answer Record 43482 have been passed.
205  if init_wait_count = WAIT_MAX then
206  init_wait_done <= '1';
207  else
208  init_wait_count <= init_wait_count + 1;
209  end if;
210  end if;
211  end process;
212 
213 
214  timeouts:process(STABLE_CLOCK)
215  begin
216  if rising_edge(STABLE_CLOCK) then
217  -- One common large counter for generating three time-out signals.
218  -- Intermediate time-outs are derived from calculated values, based
219  -- on the period of the provided clock.
220  if reset_time_out = '1' then
221  time_out_counter <= 0;
222  time_out_2ms <= '0';
223  time_tlock_max <= '0';
224  time_out_500us <= '0';
225  else
226  if time_out_counter = WAIT_TIMEOUT_2ms then
227  time_out_2ms <= '1';
228  else
229  time_out_counter <= time_out_counter + 1;
230  end if;
231 
232  if time_out_counter = WAIT_TLOCK_MAX then
233  time_tlock_max <= '1';
234  end if;
235 
236  if time_out_counter = WAIT_TIMEOUT_500us then
237  time_out_500us <= '1';
238  end if;
239  end if;
240  end if;
241  end process;
242 
243  mmcm_lock_wait:process(STABLE_CLOCK)
244  begin
245  if rising_edge(STABLE_CLOCK) then
246  if mmcm_lock_i = '0' then
247  mmcm_lock_count <= 0;
248  mmcm_lock_reclocked <= '0';
249  else
250  if mmcm_lock_count < MMCM_LOCK_CNT_MAX - 1 then
251  mmcm_lock_count <= mmcm_lock_count + 1;
252  else
253  mmcm_lock_reclocked <= '1';
254  end if;
255  end if;
256  end if;
257  end process;
258 
259 
260 
261  -- Clock Domain Crossing
262 
263  sync_run_phase_alignment_int : DAQLINK_7S_sync_block
264  port map
265  (
266  clk => TXUSERCLK,
267  data_in => run_phase_alignment_int ,
268  data_out => run_phase_alignment_int_s2
269  );
270 
271  sync_tx_fsm_reset_done_int : DAQLINK_7S_sync_block
272  port map
273  (
274  clk => TXUSERCLK,
275  data_in => tx_fsm_reset_done_int,
276  data_out => tx_fsm_reset_done_int_s2
277  );
278 
279  process(TXUSERCLK)
280  begin
281  if rising_edge(TXUSERCLK) then
282  run_phase_alignment_int_s3 <= run_phase_alignment_int_s2;
283 
284  tx_fsm_reset_done_int_s3 <= tx_fsm_reset_done_int_s2;
285  end if;
286  end process;
287 
288  sync_TXRESETDONE : DAQLINK_7S_sync_block
289  port map
290  (
291  clk => STABLE_CLOCK,
292  data_in => TXRESETDONE,
293  data_out => txresetdone_s2
294  );
295 
296  sync_time_out_wait_bypass : DAQLINK_7S_sync_block
297  port map
298  (
299  clk => STABLE_CLOCK,
300  data_in => time_out_wait_bypass,
301  data_out => time_out_wait_bypass_s2
302  );
303 
304  sync_mmcm_lock_reclocked : DAQLINK_7S_sync_block
305  port map
306  (
307  clk => STABLE_CLOCK,
308  data_in => MMCM_LOCK,
309  data_out => mmcm_lock_i
310  );
311 
312  process(STABLE_CLOCK)
313  begin
314  if rising_edge(STABLE_CLOCK) then
315  txresetdone_s3 <= txresetdone_s2;
316 
317  time_out_wait_bypass_s3 <= time_out_wait_bypass_s2;
318  cplllock_prev <= cplllock_sync;
319  qplllock_prev <= qplllock_sync;
320  end if;
321  end process;
322 
323  sync_CPLLLOCK : DAQLINK_7S_sync_block
324  port map
325  (
326  clk => STABLE_CLOCK,
327  data_in => CPLLLOCK,
328  data_out => cplllock_sync
329  );
330 
331  sync_QPLLLOCK : DAQLINK_7S_sync_block
332  port map
333  (
334  clk => STABLE_CLOCK,
335  data_in => QPLLLOCK,
336  data_out => qplllock_sync
337  );
338 
339 
340  process (STABLE_CLOCK)
341  begin
342  if rising_edge(STABLE_CLOCK) then
343  if(SOFT_RESET = '1' ) then
344  cplllock_ris_edge <= '0';
345  elsif((cplllock_prev = '0') and (cplllock_sync = '1')) then
346  cplllock_ris_edge <= '1';
347  elsif(tx_state = ASSERT_ALL_RESETS or tx_state = RELEASE_PLL_RESET) then
348  cplllock_ris_edge <= cplllock_ris_edge;
349  else
350  cplllock_ris_edge <= '0';
351  end if;
352  end if;
353  end process;
354 
355  process (STABLE_CLOCK)
356  begin
357  if rising_edge(STABLE_CLOCK) then
358  if(SOFT_RESET = '1' ) then
359  qplllock_ris_edge <= '0';
360  elsif((qplllock_prev = '0') and (qplllock_sync = '1')) then
361  qplllock_ris_edge <= '1';
362  elsif(tx_state = ASSERT_ALL_RESETS or tx_state = RELEASE_PLL_RESET) then
363  qplllock_ris_edge <= qplllock_ris_edge;
364  else
365  qplllock_ris_edge <= '0';
366  end if;
367  end if;
368  end process;
369 
370 
371  timeout_buffer_bypass:process(TXUSERCLK)
372  begin
373  if rising_edge(TXUSERCLK) then
374  if run_phase_alignment_int_s3 = '0' then
375  wait_bypass_count <= 0;
376  time_out_wait_bypass <= '0';
377  elsif (run_phase_alignment_int_s3 = '1') and (tx_fsm_reset_done_int_s3 = '0') then
378  if wait_bypass_count = MAX_WAIT_BYPASS - 1 then
379  time_out_wait_bypass <= '1';
380  else
381  wait_bypass_count <= wait_bypass_count + 1;
382  end if;
383  end if;
384  end if;
385  end process;
386 
387  refclk_lost <= '1' when ((TX_QPLL_USED and QPLLREFCLKLOST='1') or (not TX_QPLL_USED and CPLLREFCLKLOST='1')) else '0';
388 
389 
390  --FSM for resetting the GTX/GTH/GTP in the 7-series.
391  --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
392  --
393  -- Following steps are performed:
394  -- 1) Only for GTX - After configuration wait for approximately 500 ns as specified in
395  -- answer-record 43482
396  -- 2) Assert all resets on the GT and on an MMCM potentially connected.
397  -- After that wait until a reference-clock has been detected.
398  -- 3) Release the reset to the GT and wait until the GT-PLL has locked.
399  -- 4) Release the MMCM-reset and wait until the MMCM has signalled lock.
400  -- Also signal to the RX-side which PLL has been reset.
401  -- 5) Wait for the RESET_DONE-signal from the GT.
402  -- 6) Signal to start the phase-alignment procedure and wait for it to
403  -- finish.
404  -- 7) Reset-sequence has successfully run through. Signal this to the
405  -- rest of the design by asserting TX_FSM_RESET_DONE.
406 
407  reset_fsm:process(STABLE_CLOCK)
408  begin
409  if rising_edge(STABLE_CLOCK) then
410  if(SOFT_RESET = '1' or (not(tx_state = INIT) and not(tx_state = ASSERT_ALL_RESETS) and refclk_lost = '1')) then
411  tx_state <= INIT;
412  TXUSERRDY <= '0';
413  GTTXRESET <= '0';
414  MMCM_RESET <= '1';
415  tx_fsm_reset_done_int <= '0';
416  QPLL_RESET <= '0';
417  CPLL_RESET <= '0';
418  pll_reset_asserted <= '0';
419  reset_time_out <= '0';
420  retry_counter_int <= 0;
421  run_phase_alignment_int <= '0';
422  RESET_PHALIGNMENT <= '1';
423  else
424 
425  case tx_state is
426  when INIT =>
427  --Initial state after configuration. This state will be left after
428  --approx. 500 ns and not be re-entered.
429  if init_wait_done = '1' then
430  tx_state <= ASSERT_ALL_RESETS;
431  reset_time_out <= '1';
432  end if;
433 
434  when ASSERT_ALL_RESETS =>
435  --This is the state into which the FSM will always jump back if any
436  --time-outs will occur.
437  --The number of retries is reported on the output RETRY_COUNTER. In
438  --case the transceiver never comes up for some reason, this machine
439  --will still continue its best and rerun until the FPGA is turned off
440  --or the transceivers come up correctly.
441  if TX_QPLL_USED then
442  if pll_reset_asserted = '0' then
443  QPLL_RESET <= '1';
444  pll_reset_asserted <= '1';
445  else
446  QPLL_RESET <= '0';
447  end if;
448  else
449  if pll_reset_asserted = '0' then
450  CPLL_RESET <= '1';
451  pll_reset_asserted <= '1';
452  else
453  CPLL_RESET <= '0';
454  end if;
455  end if;
456  TXUSERRDY <= '0';
457  GTTXRESET <= '1';
458  MMCM_RESET <= '1';
459  reset_time_out <= '0';
460  run_phase_alignment_int <= '0';
461  RESET_PHALIGNMENT <= '1';
462 
463  if (TX_QPLL_USED and (QPLLREFCLKLOST = '0') and pll_reset_asserted = '1') or
464  (not TX_QPLL_USED and (CPLLREFCLKLOST = '0') and pll_reset_asserted = '1') then
465  tx_state <= RELEASE_PLL_RESET;
466  end if;
467 
468  when RELEASE_PLL_RESET =>
469  --PLL-Reset of the GTX gets released and the time-out counter
470  --starts running.
471  pll_reset_asserted <= '0';
472 
473  if (TX_QPLL_USED and (qplllock_ris_edge = '1')) or
474  (not TX_QPLL_USED and (cplllock_ris_edge = '1')) then
475  tx_state <= RELEASE_MMCM_RESET;
476  reset_time_out <= '1';
477  end if;
478 
479  if time_out_2ms = '1' then
480  if retry_counter_int = MAX_RETRIES then
481  -- If too many retries are performed compared to what is specified in
482  -- the generic, the counter simply wraps around.
483  retry_counter_int <= 0;
484  else
485  retry_counter_int <= retry_counter_int + 1;
486  end if;
487  tx_state <= ASSERT_ALL_RESETS;
488  end if;
489 
490  when RELEASE_MMCM_RESET =>
491  GTTXRESET <= '0';
492  reset_time_out <= '0';
493  --Release of the MMCM-reset. Waiting for the MMCM to lock.
494  MMCM_RESET <= '0';
495  if mmcm_lock_reclocked = '1' then
496  tx_state <= WAIT_RESET_DONE;
497  reset_time_out <= '1';
498  end if;
499 
500  if (time_tlock_max = '1' and mmcm_lock_reclocked = '0' and reset_time_out = '0') then
501  if retry_counter_int = MAX_RETRIES then
502  -- If too many retries are performed compared to what is specified in
503  -- the generic, the counter simply wraps around.
504  retry_counter_int <= 0;
505  else
506  retry_counter_int <= retry_counter_int + 1;
507  end if;
508  tx_state <= ASSERT_ALL_RESETS;
509  end if;
510 
511  when WAIT_RESET_DONE =>
512  TXUSERRDY <= '1';
513  reset_time_out <= '0';
514  if txresetdone_s3 = '1' then
515  tx_state <= DO_PHASE_ALIGNMENT;
516  reset_time_out <= '1';
517  end if;
518 
519  if (time_out_500us = '1' and reset_time_out = '0') then
520  if retry_counter_int = MAX_RETRIES then
521  -- If too many retries are performed compared to what is specified in
522  -- the generic, the counter simply wraps around.
523  retry_counter_int <= 0;
524  else
525  retry_counter_int <= retry_counter_int + 1;
526  end if;
527  tx_state <= ASSERT_ALL_RESETS;
528  end if;
529 
530  when DO_PHASE_ALIGNMENT =>
531  --The direct handling of the signals for the Phase Alignment is done outside
532  --this state-machine.
533  RESET_PHALIGNMENT <= '0';
534  run_phase_alignment_int <= '1';
535  reset_time_out <= '0';
536 
537  if PHALIGNMENT_DONE = '1' then
538  tx_state <= RESET_FSM_DONE;
539  end if;
540 
541  if time_out_wait_bypass_s3 = '1' then
542  if retry_counter_int = MAX_RETRIES then
543  -- If too many retries are performed compared to what is specified in
544  -- the generic, the counter simply wraps around.
545  retry_counter_int <= 0;
546  else
547  retry_counter_int <= retry_counter_int + 1;
548  end if;
549  tx_state <= ASSERT_ALL_RESETS;
550  end if;
551 
552  when RESET_FSM_DONE =>
553  reset_time_out <= '1';
554  tx_fsm_reset_done_int <= '1';
555 
556  when OTHERS =>
557  tx_state <= INIT;
558 
559  end case;
560  end if;
561  end if;
562  end process;
563 
564 end RTL;
565