1 | -- |
---|
2 | -- Project: Aurora Module Generator version 2.4 |
---|
3 | -- |
---|
4 | -- Date: $Date: 2005/11/16 00:32:43 $ |
---|
5 | -- Tag: $Name: i+IP+98818 $ |
---|
6 | -- File: $RCSfile: lane_init_sm_vhd.ejava,v $ |
---|
7 | -- Rev: $Revision: 1.1.2.2 $ |
---|
8 | -- |
---|
9 | -- Company: Xilinx |
---|
10 | -- Contributors: R. K. Awalt, B. L. Woodard, N. Gulstone |
---|
11 | -- |
---|
12 | -- Disclaimer: XILINX IS PROVIDING THIS DESIGN, CODE, OR |
---|
13 | -- INFORMATION "AS IS" SOLELY FOR USE IN DEVELOPING |
---|
14 | -- PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY |
---|
15 | -- PROVIDING THIS DESIGN, CODE, OR INFORMATION AS |
---|
16 | -- ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, |
---|
17 | -- APPLICATION OR STANDARD, XILINX IS MAKING NO |
---|
18 | -- REPRESENTATION THAT THIS IMPLEMENTATION IS FREE |
---|
19 | -- FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE |
---|
20 | -- RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY |
---|
21 | -- REQUIRE FOR YOUR IMPLEMENTATION. XILINX |
---|
22 | -- EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH |
---|
23 | -- RESPECT TO THE ADEQUACY OF THE IMPLEMENTATION, |
---|
24 | -- INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR |
---|
25 | -- REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE |
---|
26 | -- FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES |
---|
27 | -- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
---|
28 | -- PURPOSE. |
---|
29 | -- |
---|
30 | -- (c) Copyright 2004 Xilinx, Inc. |
---|
31 | -- All rights reserved. |
---|
32 | -- |
---|
33 | |
---|
34 | -- |
---|
35 | -- LANE_INIT_SM |
---|
36 | -- |
---|
37 | -- Author: Nigel Gulstone |
---|
38 | -- Xilinx - Embedded Networking System Engineering Group |
---|
39 | -- |
---|
40 | -- VHDL Translation: Brian Woodard |
---|
41 | -- Xilinx - Garden Valley Design Team |
---|
42 | -- |
---|
43 | -- Description: This logic manages the initialization of the MGT in 2-byte mode. |
---|
44 | -- It consists of a small state machine, a set of counters for |
---|
45 | -- tracking the progress of initializtion and detecting problems, |
---|
46 | -- and some additional support logic. |
---|
47 | -- |
---|
48 | |
---|
49 | library IEEE; |
---|
50 | use IEEE.STD_LOGIC_1164.all; |
---|
51 | use IEEE.NUMERIC_STD.all; |
---|
52 | use WORK.AURORA.all; |
---|
53 | |
---|
54 | -- synthesis translate_off |
---|
55 | library UNISIM; |
---|
56 | use UNISIM.all; |
---|
57 | -- synthesis translate_on |
---|
58 | |
---|
59 | |
---|
60 | entity LANE_INIT_SM is |
---|
61 | generic ( |
---|
62 | EXTEND_WATCHDOGS : boolean := FALSE |
---|
63 | ); |
---|
64 | port ( |
---|
65 | |
---|
66 | -- MGT Interface |
---|
67 | |
---|
68 | RX_NOT_IN_TABLE : in std_logic_vector(1 downto 0); -- MGT received invalid 10b code. |
---|
69 | RX_DISP_ERR : in std_logic_vector(1 downto 0); -- MGT received 10b code w/ wrong disparity. |
---|
70 | RX_CHAR_IS_COMMA : in std_logic_vector(1 downto 0); -- MGT received a Comma. |
---|
71 | RX_REALIGN : in std_logic; -- MGT had to change alignment due to new comma. |
---|
72 | RX_RESET : out std_logic; -- Reset the RX side of the MGT. |
---|
73 | TX_RESET : out std_logic; -- Reset the TX side of the MGT. |
---|
74 | RX_POLARITY : out std_logic; -- Sets polarity used to interpet rx'ed symbols. |
---|
75 | |
---|
76 | -- Comma Detect Phase Alignment Interface |
---|
77 | |
---|
78 | ENA_COMMA_ALIGN : out std_logic; -- Turn on SERDES Alignment in MGT. |
---|
79 | |
---|
80 | -- Symbol Generator Interface |
---|
81 | |
---|
82 | GEN_K : out std_logic; -- Generate a comma on the MSByte of the Lane. |
---|
83 | GEN_SP_DATA : out std_logic_vector(0 to 1); -- Generate SP data symbol on selected byte(s). |
---|
84 | GEN_SPA_DATA : out std_logic_vector(0 to 1); -- Generate SPA data symbol on selected byte(s). |
---|
85 | |
---|
86 | -- Symbol Decoder Interface |
---|
87 | |
---|
88 | RX_SP : in std_logic; -- Lane rx'ed SP sequence w/ + or - data. |
---|
89 | RX_SPA : in std_logic; -- Lane rx'ed SPA sequence. |
---|
90 | RX_NEG : in std_logic; -- Lane rx'ed inverted SP or SPA data. |
---|
91 | DO_WORD_ALIGN : out std_logic; -- Enable word alignment. |
---|
92 | |
---|
93 | -- Error Detection Logic Interface |
---|
94 | |
---|
95 | ENABLE_ERROR_DETECT : out std_logic; -- Turn on Soft Error detection. |
---|
96 | HARD_ERROR_RESET : in std_logic; -- Reset lane due to hard error. |
---|
97 | |
---|
98 | -- Global Logic Interface |
---|
99 | |
---|
100 | LANE_UP : out std_logic; -- Lane is initialized. |
---|
101 | |
---|
102 | -- System Interface |
---|
103 | |
---|
104 | USER_CLK : in std_logic; -- Clock for all non-MGT Aurora logic. |
---|
105 | RESET : in std_logic -- Reset Aurora Lane. |
---|
106 | |
---|
107 | ); |
---|
108 | |
---|
109 | end LANE_INIT_SM; |
---|
110 | |
---|
111 | architecture RTL of LANE_INIT_SM is |
---|
112 | |
---|
113 | -- Parameter Declarations -- |
---|
114 | |
---|
115 | constant DLY : time := 1 ns; |
---|
116 | |
---|
117 | -- External Register Declarations |
---|
118 | |
---|
119 | signal RX_RESET_Buffer : std_logic; |
---|
120 | signal TX_RESET_Buffer : std_logic; |
---|
121 | signal RX_POLARITY_Buffer : std_logic; |
---|
122 | signal ENA_COMMA_ALIGN_Buffer : std_logic; |
---|
123 | signal GEN_K_Buffer : std_logic; |
---|
124 | signal GEN_SP_DATA_Buffer : std_logic_vector(0 to 1); |
---|
125 | signal GEN_SPA_DATA_Buffer : std_logic_vector(0 to 1); |
---|
126 | signal DO_WORD_ALIGN_Buffer : std_logic; |
---|
127 | signal ENABLE_ERROR_DETECT_Buffer : std_logic; |
---|
128 | signal LANE_UP_Buffer : std_logic; |
---|
129 | |
---|
130 | -- Internal Register Declarations |
---|
131 | |
---|
132 | signal odd_word_r : std_logic := '1'; |
---|
133 | -- counter1 is intitialized to ensure that the counter comes up at some value other than X. |
---|
134 | -- We have tried different initial values and it does not matter what the value is, as long |
---|
135 | -- as it is not X since X breaks the state machine |
---|
136 | signal counter1_r : unsigned(0 to 7) := "00000001"; |
---|
137 | signal counter2_r : std_logic_vector(0 to 15); |
---|
138 | signal counter3_r : std_logic_vector(0 to 3); |
---|
139 | signal counter4_r : std_logic_vector(0 to 15); |
---|
140 | signal counter5_r : std_logic_vector(0 to 15); |
---|
141 | signal rx_polarity_r : std_logic := '0'; |
---|
142 | signal prev_char_was_comma_r : std_logic; |
---|
143 | signal comma_over_two_cycles_r : std_logic; |
---|
144 | signal prev_count_128d_done_r : std_logic; |
---|
145 | signal extend_r : std_logic_vector(0 to 31) := X"00000000"; |
---|
146 | signal extend_n_r : std_logic; |
---|
147 | signal do_watchdog_count_r : std_logic; |
---|
148 | signal reset_count_r : std_logic; |
---|
149 | |
---|
150 | -- FSM states, encoded for one-hot implementation |
---|
151 | |
---|
152 | signal begin_r : std_logic; -- Begin initialization |
---|
153 | signal rst_r : std_logic; -- Reset MGTs |
---|
154 | signal align_r : std_logic; -- Align SERDES |
---|
155 | signal realign_r : std_logic; -- Verify no spurious realignment |
---|
156 | signal polarity_r : std_logic; -- Verify polarity of rx'ed symbols |
---|
157 | signal ack_r : std_logic; -- Ack initialization with partner |
---|
158 | signal ready_r : std_logic; -- Lane ready for Bonding/Verification |
---|
159 | |
---|
160 | -- Wire Declarations |
---|
161 | |
---|
162 | signal send_sp_c : std_logic; |
---|
163 | signal send_spa_r : std_logic; |
---|
164 | signal count_8d_done_r : std_logic; |
---|
165 | signal count_32d_done_r : std_logic; |
---|
166 | signal count_128d_done_r : std_logic; |
---|
167 | signal symbol_error_c : std_logic; |
---|
168 | signal txack_16d_done_r : std_logic; |
---|
169 | signal rxack_4d_done_r : std_logic; |
---|
170 | signal sp_polarity_c : std_logic; |
---|
171 | signal inc_count_c : std_logic; |
---|
172 | signal change_in_state_c : std_logic; |
---|
173 | signal extend_n_c : std_logic; |
---|
174 | signal watchdog_done_r : std_logic; |
---|
175 | signal remote_reset_watchdog_done_r : std_logic; |
---|
176 | |
---|
177 | signal next_begin_c : std_logic; |
---|
178 | signal next_rst_c : std_logic; |
---|
179 | signal next_align_c : std_logic; |
---|
180 | signal next_realign_c : std_logic; |
---|
181 | signal next_polarity_c : std_logic; |
---|
182 | signal next_ack_c : std_logic; |
---|
183 | signal next_ready_c : std_logic; |
---|
184 | |
---|
185 | component FDR |
---|
186 | |
---|
187 | port ( |
---|
188 | D : in std_logic; |
---|
189 | C : in std_logic; |
---|
190 | R : in std_logic; |
---|
191 | Q : out std_logic |
---|
192 | ); |
---|
193 | |
---|
194 | end component; |
---|
195 | |
---|
196 | begin |
---|
197 | |
---|
198 | RX_RESET <= RX_RESET_Buffer; |
---|
199 | TX_RESET <= TX_RESET_Buffer; |
---|
200 | RX_POLARITY <= RX_POLARITY_Buffer; |
---|
201 | ENA_COMMA_ALIGN <= ENA_COMMA_ALIGN_Buffer; |
---|
202 | GEN_K <= GEN_K_Buffer; |
---|
203 | GEN_SP_DATA <= GEN_SP_DATA_Buffer; |
---|
204 | GEN_SPA_DATA <= GEN_SPA_DATA_Buffer; |
---|
205 | DO_WORD_ALIGN <= DO_WORD_ALIGN_Buffer; |
---|
206 | ENABLE_ERROR_DETECT <= ENABLE_ERROR_DETECT_Buffer; |
---|
207 | LANE_UP <= LANE_UP_Buffer; |
---|
208 | |
---|
209 | -- Main Body of Code |
---|
210 | |
---|
211 | -- Main state machine for managing initialization -- |
---|
212 | |
---|
213 | -- State registers |
---|
214 | |
---|
215 | process (USER_CLK) |
---|
216 | |
---|
217 | begin |
---|
218 | |
---|
219 | if (USER_CLK 'event and USER_CLK = '1') then |
---|
220 | |
---|
221 | if ((RESET or HARD_ERROR_RESET) = '1') then |
---|
222 | |
---|
223 | begin_r <= '1' after DLY; |
---|
224 | rst_r <= '0' after DLY; |
---|
225 | align_r <= '0' after DLY; |
---|
226 | realign_r <= '0' after DLY; |
---|
227 | polarity_r <= '0' after DLY; |
---|
228 | ack_r <= '0' after DLY; |
---|
229 | ready_r <= '0' after DLY; |
---|
230 | |
---|
231 | else |
---|
232 | |
---|
233 | begin_r <= next_begin_c after DLY; |
---|
234 | rst_r <= next_rst_c after DLY; |
---|
235 | align_r <= next_align_c after DLY; |
---|
236 | realign_r <= next_realign_c after DLY; |
---|
237 | polarity_r <= next_polarity_c after DLY; |
---|
238 | ack_r <= next_ack_c after DLY; |
---|
239 | ready_r <= next_ready_c after DLY; |
---|
240 | |
---|
241 | end if; |
---|
242 | |
---|
243 | end if; |
---|
244 | |
---|
245 | end process; |
---|
246 | |
---|
247 | -- Next state logic |
---|
248 | |
---|
249 | next_begin_c <= (realign_r and RX_REALIGN) or |
---|
250 | (polarity_r and not sp_polarity_c) or |
---|
251 | (ack_r and watchdog_done_r) or |
---|
252 | (ready_r and remote_reset_watchdog_done_r); |
---|
253 | |
---|
254 | next_rst_c <= begin_r or |
---|
255 | (rst_r and not count_8d_done_r); |
---|
256 | |
---|
257 | next_align_c <= (rst_r and count_8d_done_r) or |
---|
258 | (align_r and not count_128d_done_r); |
---|
259 | |
---|
260 | next_realign_c <= (align_r and count_128d_done_r) or |
---|
261 | ((realign_r and not count_32d_done_r) and not RX_REALIGN); |
---|
262 | |
---|
263 | next_polarity_c <= ((realign_r and count_32d_done_r) and not RX_REALIGN) or |
---|
264 | ((polarity_r and sp_polarity_c) and odd_word_r); |
---|
265 | |
---|
266 | next_ack_c <= ((polarity_r and sp_polarity_c) and not odd_word_r) or |
---|
267 | (ack_r and (not txack_16d_done_r or not rxack_4d_done_r) and not watchdog_done_r); |
---|
268 | |
---|
269 | next_ready_c <= (((ack_r and txack_16d_done_r) and rxack_4d_done_r) and not watchdog_done_r) or |
---|
270 | (ready_r and not remote_reset_watchdog_done_r); |
---|
271 | |
---|
272 | |
---|
273 | -- Output Logic |
---|
274 | |
---|
275 | |
---|
276 | -- Enable comma align when in the ALIGN state. |
---|
277 | |
---|
278 | ENA_COMMA_ALIGN_Buffer <= align_r; |
---|
279 | |
---|
280 | |
---|
281 | -- Hold RX_RESET when in the RST state. |
---|
282 | |
---|
283 | RX_RESET_Buffer <= rst_r; |
---|
284 | |
---|
285 | |
---|
286 | -- Hold TX_RESET when in the RST state. |
---|
287 | |
---|
288 | TX_RESET_Buffer <= rst_r; |
---|
289 | |
---|
290 | |
---|
291 | -- LANE_UP is asserted when in the READY state. |
---|
292 | |
---|
293 | lane_up_flop_i : FDR |
---|
294 | |
---|
295 | port map ( |
---|
296 | D => ready_r, |
---|
297 | C => USER_CLK, |
---|
298 | R => RESET, |
---|
299 | Q => LANE_UP_Buffer |
---|
300 | ); |
---|
301 | |
---|
302 | |
---|
303 | -- ENABLE_ERROR_DETECT is asserted when in the ACK or READY states. Asserting |
---|
304 | -- it earlier will result in too many false errors. After it is asserted, |
---|
305 | -- higher level modules can respond to Hard Errors by resetting the Aurora Lane. |
---|
306 | -- We register the signal before it leaves the lane_init_sm submodule. |
---|
307 | |
---|
308 | process (USER_CLK) |
---|
309 | |
---|
310 | begin |
---|
311 | |
---|
312 | if (USER_CLK 'event and USER_CLK = '1') then |
---|
313 | |
---|
314 | ENABLE_ERROR_DETECT_Buffer <= ack_r or ready_r after DLY; |
---|
315 | |
---|
316 | end if; |
---|
317 | |
---|
318 | end process; |
---|
319 | |
---|
320 | |
---|
321 | -- The Aurora Lane should transmit SP sequences when not ACKing or Ready. |
---|
322 | |
---|
323 | send_sp_c <= not (ack_r or ready_r); |
---|
324 | |
---|
325 | |
---|
326 | -- The Aurora Lane transmits SPA sequences while in the ACK state. |
---|
327 | |
---|
328 | send_spa_r <= ack_r; |
---|
329 | |
---|
330 | |
---|
331 | -- Do word alignment when in the ALIGN state. |
---|
332 | |
---|
333 | DO_WORD_ALIGN_Buffer <= align_r or ready_r; |
---|
334 | |
---|
335 | |
---|
336 | -- Transmission Logic for SP and SPA sequences -- |
---|
337 | |
---|
338 | -- Select either the even or the odd word of the current sequence for transmission. |
---|
339 | -- There is no reset for odd word. It is initialized when the FPGA is configured. |
---|
340 | -- The variable, odd_word_r, is initialized for simulation (See SIGNAL declarations). |
---|
341 | |
---|
342 | process (USER_CLK) |
---|
343 | |
---|
344 | begin |
---|
345 | |
---|
346 | if (USER_CLK 'event and USER_CLK = '1') then |
---|
347 | |
---|
348 | odd_word_r <= not odd_word_r after DLY; |
---|
349 | |
---|
350 | end if; |
---|
351 | |
---|
352 | end process; |
---|
353 | |
---|
354 | |
---|
355 | -- Request transmission of the commas needed for the SP and SPA sequences. |
---|
356 | -- These commas are sent on the MSByte of the lane on all odd bytes. |
---|
357 | |
---|
358 | GEN_K_Buffer <= odd_word_r and (send_sp_c or send_spa_r); |
---|
359 | |
---|
360 | |
---|
361 | -- Request transmission of the SP_DATA sequence. |
---|
362 | |
---|
363 | GEN_SP_DATA_Buffer(0) <= not odd_word_r and send_sp_c; |
---|
364 | GEN_SP_DATA_Buffer(1) <= send_sp_c; |
---|
365 | |
---|
366 | |
---|
367 | -- Request transmission of the SPA_DATA sequence. |
---|
368 | |
---|
369 | GEN_SPA_DATA_Buffer(0) <= not odd_word_r and send_spa_r; |
---|
370 | GEN_SPA_DATA_Buffer(1) <= send_spa_r; |
---|
371 | |
---|
372 | |
---|
373 | -- Counter 1, for reset cycles, align cycles and realign cycles -- |
---|
374 | |
---|
375 | -- Core of the counter |
---|
376 | |
---|
377 | process (USER_CLK) |
---|
378 | |
---|
379 | begin |
---|
380 | |
---|
381 | if (USER_CLK 'event and USER_CLK = '1') then |
---|
382 | |
---|
383 | if (reset_count_r = '1') then |
---|
384 | |
---|
385 | counter1_r <= "00000001" after DLY; |
---|
386 | |
---|
387 | else |
---|
388 | |
---|
389 | if (inc_count_c = '1') then |
---|
390 | |
---|
391 | counter1_r <= counter1_r + "00000001" after DLY; |
---|
392 | |
---|
393 | end if; |
---|
394 | |
---|
395 | end if; |
---|
396 | |
---|
397 | end if; |
---|
398 | |
---|
399 | end process; |
---|
400 | |
---|
401 | |
---|
402 | -- Assert count_8d_done_r when bit 4 in the register first goes high. |
---|
403 | |
---|
404 | count_8d_done_r <= std_bool(counter1_r(4) = '1'); |
---|
405 | |
---|
406 | |
---|
407 | -- Assert count_32d_done_r when bit 2 in the register first goes high. |
---|
408 | |
---|
409 | count_32d_done_r <= std_bool(counter1_r(2) = '1'); |
---|
410 | |
---|
411 | |
---|
412 | -- Assert count_128d_done_r when bit 0 in the register first goes high. |
---|
413 | |
---|
414 | count_128d_done_r <= std_bool(counter1_r(0) = '1'); |
---|
415 | |
---|
416 | |
---|
417 | -- The counter resets any time the RESET signal is asserted, there is a change in |
---|
418 | -- state, there is a symbol error, or commas are not consecutive in the align state. |
---|
419 | |
---|
420 | process (USER_CLK) |
---|
421 | |
---|
422 | begin |
---|
423 | |
---|
424 | if (USER_CLK 'event and USER_CLK = '1') then |
---|
425 | |
---|
426 | reset_count_r <= RESET or change_in_state_c or symbol_error_c or not comma_over_two_cycles_r; |
---|
427 | |
---|
428 | end if; |
---|
429 | |
---|
430 | end process; |
---|
431 | |
---|
432 | |
---|
433 | -- The counter should be reset when entering and leaving the reset state. |
---|
434 | |
---|
435 | change_in_state_c <= std_bool(rst_r /= next_rst_c); |
---|
436 | |
---|
437 | |
---|
438 | -- Symbol error is asserted whenever there is a disparity error or an invalid |
---|
439 | -- 10b code. |
---|
440 | |
---|
441 | symbol_error_c <= std_bool((RX_DISP_ERR /= "00") or (RX_NOT_IN_TABLE /= "00")); |
---|
442 | |
---|
443 | |
---|
444 | -- Previous cycle comma is used to check for consecutive commas. |
---|
445 | |
---|
446 | process (USER_CLK) |
---|
447 | |
---|
448 | begin |
---|
449 | |
---|
450 | if (USER_CLK 'event and USER_CLK = '1') then |
---|
451 | |
---|
452 | prev_char_was_comma_r <= std_bool(RX_CHAR_IS_COMMA /= "00") after DLY; |
---|
453 | |
---|
454 | end if; |
---|
455 | |
---|
456 | end process; |
---|
457 | |
---|
458 | |
---|
459 | -- Check to see that commas are consecutive in the align state. |
---|
460 | |
---|
461 | process (USER_CLK) |
---|
462 | |
---|
463 | begin |
---|
464 | |
---|
465 | if (USER_CLK 'event and USER_CLK = '1') then |
---|
466 | |
---|
467 | comma_over_two_cycles_r <= (prev_char_was_comma_r xor |
---|
468 | std_bool(RX_CHAR_IS_COMMA /= "00")) or not align_r after DLY; |
---|
469 | |
---|
470 | end if; |
---|
471 | |
---|
472 | end process; |
---|
473 | |
---|
474 | |
---|
475 | -- Increment count is always asserted, except in the ALIGN state when it is asserted |
---|
476 | -- only upon the arrival of a comma character. |
---|
477 | |
---|
478 | inc_count_c <= not align_r or (align_r and std_bool(RX_CHAR_IS_COMMA /= "00")); |
---|
479 | |
---|
480 | |
---|
481 | -- Counter 2, for counting tx_acks -- |
---|
482 | |
---|
483 | -- This counter is implemented as a shift register. It is constantly shifting. As a |
---|
484 | -- result, when the state machine is not in the ack state, the register clears out. |
---|
485 | -- When the state machine goes into the ack state, the count is incremented every |
---|
486 | -- cycle. The txack_16d_done signal goes high and stays high after 16 cycles in the |
---|
487 | -- ack state. The signal deasserts only after it has had enough time for all the ones |
---|
488 | -- to clear out after the machine leaves the ack state, but this is tolerable because |
---|
489 | -- the machine will spend at least 8 cycles in reset, 256 in ALIGN and 32 in REALIGN. |
---|
490 | -- |
---|
491 | -- The counter is implemented seperately from the main counter because it is required |
---|
492 | -- to stop counting when it reaches the end of its count. Adding this functionality |
---|
493 | -- to the main counter is more expensive and more complex than implementing it seperately. |
---|
494 | |
---|
495 | -- Counter Logic |
---|
496 | |
---|
497 | process (USER_CLK) |
---|
498 | |
---|
499 | begin |
---|
500 | |
---|
501 | if (USER_CLK 'event and USER_CLK = '1') then |
---|
502 | |
---|
503 | counter2_r <= ack_r & counter2_r(0 to 14) after DLY; |
---|
504 | |
---|
505 | end if; |
---|
506 | |
---|
507 | end process; |
---|
508 | |
---|
509 | |
---|
510 | -- The counter is done when bit 15 of the shift register goes high. |
---|
511 | |
---|
512 | txack_16d_done_r <= counter2_r(15); |
---|
513 | |
---|
514 | |
---|
515 | -- Counter 3, for counting rx_acks -- |
---|
516 | |
---|
517 | -- This counter is also implemented as a shift register. It is always shifting when |
---|
518 | -- the state machine is not in the ack state to clear it out. When the state machine |
---|
519 | -- goes into the ack state, the register shifts only when a SPA is received. When |
---|
520 | -- 4 SPAs have been received in the ACK state, the rxack_4d_done_r signal is triggered. |
---|
521 | -- |
---|
522 | -- This counter is implemented seperately from the main counter because it is required |
---|
523 | -- to increment only when ACKs are received, and then hold its count. Adding this |
---|
524 | -- functionality to the main counter is more expensive than creating a second counter, |
---|
525 | -- and more complex. |
---|
526 | |
---|
527 | -- Counter Logic |
---|
528 | |
---|
529 | process (USER_CLK) |
---|
530 | |
---|
531 | begin |
---|
532 | |
---|
533 | if (USER_CLK 'event and USER_CLK = '1') then |
---|
534 | |
---|
535 | if (RX_SPA = '1' or ack_r = '0') then |
---|
536 | |
---|
537 | counter3_r <= ack_r & counter3_r(0 to 2) after DLY; |
---|
538 | |
---|
539 | end if; |
---|
540 | |
---|
541 | end if; |
---|
542 | |
---|
543 | end process; |
---|
544 | |
---|
545 | |
---|
546 | -- The counter is done when bit 7 of the shift register goes high. |
---|
547 | |
---|
548 | rxack_4d_done_r <= counter3_r(3); |
---|
549 | |
---|
550 | |
---|
551 | -- Counter 4, remote reset watchdog timer -- |
---|
552 | |
---|
553 | -- Another counter implemented as a shift register. This counter puts an upper limit on |
---|
554 | -- the number of SPs that can be received in the Ready state. If the number of SPs |
---|
555 | -- exceeds the limit, the Aurora Lane resets itself. The Global logic module will reset |
---|
556 | -- all the lanes if this occurs while they are all in the lane ready state (i.e. lane_up |
---|
557 | -- is asserted for all. |
---|
558 | |
---|
559 | -- Counter logic |
---|
560 | |
---|
561 | process (USER_CLK) |
---|
562 | |
---|
563 | begin |
---|
564 | |
---|
565 | if (USER_CLK 'event and USER_CLK = '1') then |
---|
566 | |
---|
567 | if (RX_SP = '1' or ready_r = '0') then |
---|
568 | |
---|
569 | counter4_r <= ready_r & counter4_r(0 to 14) after DLY; |
---|
570 | |
---|
571 | end if; |
---|
572 | |
---|
573 | end if; |
---|
574 | |
---|
575 | end process; |
---|
576 | |
---|
577 | |
---|
578 | -- The counter is done when bit 15 of the shift register goes high. |
---|
579 | |
---|
580 | remote_reset_watchdog_done_r <= counter4_r(15); |
---|
581 | |
---|
582 | |
---|
583 | -- Counter 5, internal watchdog timer -- |
---|
584 | |
---|
585 | -- This counter puts an upper limit on the number of cycles the state machine can |
---|
586 | -- spend in the ack state before it gives up and resets. |
---|
587 | -- |
---|
588 | -- The counter is implemented as a shift register extending counter 1. The counter |
---|
589 | -- clears out in all non-ack cycles by keeping CE asserted. When it gets into the |
---|
590 | -- ack state, CE is asserted only when there is a transition on the most |
---|
591 | -- significant bit of counter 1. This happens every 128 cycles. We count out 32 |
---|
592 | -- of these transitions to get a count of approximately 4096 cycles. The actual |
---|
593 | -- number of cycles is less than this because we don't reset counter1, so it starts |
---|
594 | -- off about 34 cycles into its count. |
---|
595 | |
---|
596 | -- Counter logic |
---|
597 | |
---|
598 | process (USER_CLK) |
---|
599 | |
---|
600 | begin |
---|
601 | |
---|
602 | if (USER_CLK 'event and USER_CLK = '1') then |
---|
603 | |
---|
604 | if (do_watchdog_count_r = '1' or ack_r = '0') then |
---|
605 | |
---|
606 | counter5_r <= ack_r & counter5_r(0 to 14) after DLY; |
---|
607 | |
---|
608 | end if; |
---|
609 | |
---|
610 | end if; |
---|
611 | |
---|
612 | end process; |
---|
613 | |
---|
614 | |
---|
615 | -- Store the count_128d_done_r result from the previous cycle. |
---|
616 | |
---|
617 | process (USER_CLK) |
---|
618 | |
---|
619 | begin |
---|
620 | |
---|
621 | if (USER_CLK 'event and USER_CLK = '1') then |
---|
622 | |
---|
623 | prev_count_128d_done_r <= count_128d_done_r after DLY; |
---|
624 | |
---|
625 | end if; |
---|
626 | |
---|
627 | end process; |
---|
628 | |
---|
629 | -- Trigger CE only when the previous 128d_done is not the same as the |
---|
630 | -- current one, and the current value is high. |
---|
631 | |
---|
632 | process (USER_CLK) |
---|
633 | |
---|
634 | begin |
---|
635 | |
---|
636 | if (USER_CLK 'event and USER_CLK = '1') then |
---|
637 | |
---|
638 | do_watchdog_count_r <= count_128d_done_r and not prev_count_128d_done_r after DLY; |
---|
639 | |
---|
640 | end if; |
---|
641 | |
---|
642 | end process; |
---|
643 | |
---|
644 | |
---|
645 | -- The counter is done when bit 15 of the shift register goes high. |
---|
646 | |
---|
647 | watchdog_done_r <= counter5_r(15); |
---|
648 | |
---|
649 | |
---|
650 | -- Polarity Control -- |
---|
651 | |
---|
652 | -- sp_polarity_c, is low if neg symbols received, otherwise high. |
---|
653 | |
---|
654 | sp_polarity_c <= not RX_NEG; |
---|
655 | |
---|
656 | |
---|
657 | -- The Polarity flop drives the polarity setting of the MGT. We initialize it for the |
---|
658 | -- sake of simulation. In hardware, it is initialized after configuration. |
---|
659 | |
---|
660 | process (USER_CLK) |
---|
661 | |
---|
662 | begin |
---|
663 | |
---|
664 | if (USER_CLK 'event and USER_CLK = '1') then |
---|
665 | |
---|
666 | if (polarity_r = '1' and sp_polarity_c = '0') then |
---|
667 | |
---|
668 | rx_polarity_r <= not rx_polarity_r after DLY; |
---|
669 | |
---|
670 | end if; |
---|
671 | |
---|
672 | end if; |
---|
673 | |
---|
674 | end process; |
---|
675 | |
---|
676 | |
---|
677 | -- Drive the rx_polarity register value on the interface. |
---|
678 | |
---|
679 | RX_POLARITY_Buffer <= rx_polarity_r; |
---|
680 | |
---|
681 | end RTL; |
---|