source: PlatformSupport/Deprecated/pcores/linkport_v1_00_a/hdl/vhdl/sym_dec.vhd

Last change on this file was 408, checked in by haijiang, 18 years ago
File size: 27.5 KB
Line 
1--
2--      Project:  Aurora Module Generator version 2.4
3--
4--         Date:  $Date: 2005/11/07 21:30:55 $
5--          Tag:  $Name: i+IP+98818 $
6--         File:  $RCSfile: sym_dec_vhd.ejava,v $
7--          Rev:  $Revision: 1.1.2.4 $
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--  SYM_DEC
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: The SYM_DEC module is a symbol decoder for the 2-byte
44--               Aurora Lane.  Its inputs are the raw data from the MGT.
45--               It word-aligns the regular data and decodes all of the
46--               Aurora control symbols.  Its outputs are the word-aligned
47--               data and signals indicating the arrival of specific
48--               control characters.
49--
50--               This module supports Immediate Mode Native Flow Control.
51--
52
53library IEEE;
54use IEEE.STD_LOGIC_1164.all;
55use WORK.AURORA.all;
56
57entity SYM_DEC is
58
59    port (
60
61    -- RX_LL Interface
62
63            RX_PAD           : out std_logic;                    -- LSByte is PAD.
64            RX_PE_DATA       : out std_logic_vector(0 to 15);    -- Word aligned data from channel partner.
65            RX_PE_DATA_V     : out std_logic;                    -- Data is valid data and not a control character.
66            RX_SCP           : out std_logic;                    -- SCP symbol received.
67            RX_ECP           : out std_logic;                    -- ECP symbol received.
68            RX_SNF           : out std_logic;                    -- SNF symbol received.
69            RX_FC_NB         : out std_logic_vector(0 to 3);     -- Flow Control size code.  Valid with RX_SNF or RX_SUF.
70
71    -- Lane Init SM Interface
72
73            DO_WORD_ALIGN    : in std_logic;                     -- Word alignment is allowed.
74            RX_SP            : out std_logic;                    -- SP sequence received with positive or negative data.
75            RX_SPA           : out std_logic;                    -- SPA sequence received.
76            RX_NEG           : out std_logic;                    -- Intverted data for SP or SPA received.
77
78    -- Global Logic Interface
79
80            GOT_A            : out std_logic_vector(0 to 1);     -- A character received on indicated byte(s).
81            GOT_V            : out std_logic;                    -- V sequence received.
82
83    -- MGT Interface
84
85            RX_DATA          : in std_logic_vector(15 downto 0); -- Raw RX data from MGT.
86            RX_CHAR_IS_K     : in std_logic_vector(1 downto 0);  -- Bits indicating which bytes are control characters.
87            RX_CHAR_IS_COMMA : in std_logic_vector(1 downto 0);  -- Rx'ed a comma.
88
89    -- System Interface
90
91            USER_CLK         : in std_logic;                     -- System clock for all non-MGT Aurora Logic.
92            RESET            : in std_logic
93
94         );
95
96end SYM_DEC;
97
98architecture RTL of SYM_DEC is
99
100-- Parameter Declarations --
101
102    constant DLY            : time := 1 ns;
103
104    constant K_CHAR_0       : std_logic_vector(0 to 3) := X"B";
105    constant K_CHAR_1       : std_logic_vector(0 to 3) := X"C";
106    constant SP_DATA_0      : std_logic_vector(0 to 3) := X"4";
107    constant SP_DATA_1      : std_logic_vector(0 to 3) := X"A";
108    constant SPA_DATA_0     : std_logic_vector(0 to 3) := X"2";
109    constant SPA_DATA_1     : std_logic_vector(0 to 3) := X"C";
110    constant SP_NEG_DATA_0  : std_logic_vector(0 to 3) := X"B";
111    constant SP_NEG_DATA_1  : std_logic_vector(0 to 3) := X"5";
112    constant SPA_NEG_DATA_0 : std_logic_vector(0 to 3) := X"D";
113    constant SPA_NEG_DATA_1 : std_logic_vector(0 to 3) := X"3";
114    constant PAD_0          : std_logic_vector(0 to 3) := X"9";
115    constant PAD_1          : std_logic_vector(0 to 3) := X"C";
116    constant SCP_0          : std_logic_vector(0 to 3) := X"5";
117    constant SCP_1          : std_logic_vector(0 to 3) := X"C";
118    constant SCP_2          : std_logic_vector(0 to 3) := X"F";
119    constant SCP_3          : std_logic_vector(0 to 3) := X"B";
120    constant ECP_0          : std_logic_vector(0 to 3) := X"F";
121    constant ECP_1          : std_logic_vector(0 to 3) := X"D";
122    constant ECP_2          : std_logic_vector(0 to 3) := X"F";
123    constant ECP_3          : std_logic_vector(0 to 3) := X"E";
124    constant SNF_0          : std_logic_vector(0 to 3) := X"D";
125    constant SNF_1          : std_logic_vector(0 to 3) := X"C";
126    constant A_CHAR_0       : std_logic_vector(0 to 3) := X"7";
127    constant A_CHAR_1       : std_logic_vector(0 to 3) := X"C";
128    constant VER_DATA_0     : std_logic_vector(0 to 3) := X"E";
129    constant VER_DATA_1     : std_logic_vector(0 to 3) := X"8";
130
131-- External Register Declarations --
132
133    signal RX_PAD_Buffer       : std_logic;
134    signal RX_PE_DATA_Buffer   : std_logic_vector(0 to 15);
135    signal RX_PE_DATA_V_Buffer : std_logic;
136    signal RX_SCP_Buffer       : std_logic;
137    signal RX_ECP_Buffer       : std_logic;
138    signal RX_SNF_Buffer       : std_logic;
139    signal RX_FC_NB_Buffer     : std_logic_vector(0 to 3);
140    signal RX_SP_Buffer        : std_logic;
141    signal RX_SPA_Buffer       : std_logic;
142    signal RX_NEG_Buffer       : std_logic;
143    signal GOT_A_Buffer        : std_logic_vector(0 to 1);
144    signal GOT_V_Buffer        : std_logic;
145
146-- Internal Register Declarations --
147
148    signal left_aligned_r              : std_logic;
149    signal previous_cycle_data_r       : std_logic_vector(0 to 7);
150    signal previous_cycle_control_r    : std_logic;
151    signal prev_beat_sp_r              : std_logic;
152    signal prev_beat_spa_r             : std_logic;
153    signal word_aligned_data_r         : std_logic_vector(0 to 15);
154    signal word_aligned_control_bits_r : std_logic_vector(0 to 1);
155    signal rx_pe_data_r                : std_logic_vector(0 to 15);
156    signal rx_pe_control_r             : std_logic_vector(0 to 1);
157    signal rx_pad_d_r                  : std_logic_vector(0 to 1);
158    signal rx_scp_d_r                  : std_logic_vector(0 to 3);
159    signal rx_ecp_d_r                  : std_logic_vector(0 to 3);
160    signal rx_snf_d_r                  : std_logic_vector(0 to 1);
161    signal prev_beat_sp_d_r            : std_logic_vector(0 to 3);
162    signal prev_beat_spa_d_r           : std_logic_vector(0 to 3);
163    signal rx_sp_d_r                   : std_logic_vector(0 to 3);
164    signal rx_spa_d_r                  : std_logic_vector(0 to 3);
165    signal rx_sp_neg_d_r               : std_logic_vector(0 to 1);
166    signal rx_spa_neg_d_r              : std_logic_vector(0 to 1);
167    signal prev_beat_v_d_r             : std_logic_vector(0 to 3);
168    signal prev_beat_v_r               : std_logic;
169    signal rx_v_d_r                    : std_logic_vector(0 to 3);
170    signal got_a_d_r                   : std_logic_vector(0 to 3);
171    signal first_v_received_r          : std_logic := '0';
172
173-- Wire Declarations --
174
175    signal got_v_c : std_logic;
176
177begin
178
179    RX_PAD       <= RX_PAD_Buffer;
180    RX_PE_DATA   <= RX_PE_DATA_Buffer;
181    RX_PE_DATA_V <= RX_PE_DATA_V_Buffer;
182    RX_SCP       <= RX_SCP_Buffer;
183    RX_ECP       <= RX_ECP_Buffer;
184    RX_SNF       <= RX_SNF_Buffer;
185    RX_FC_NB     <= RX_FC_NB_Buffer;
186    RX_SP        <= RX_SP_Buffer;
187    RX_SPA       <= RX_SPA_Buffer;
188    RX_NEG       <= RX_NEG_Buffer;
189    GOT_A        <= GOT_A_Buffer;
190    GOT_V        <= GOT_V_Buffer;
191
192-- Main Body of Code --
193
194    -- Word Alignment --
195
196    -- Determine whether the lane is aligned to the left byte (MS byte) or the
197    -- right byte (LS byte).  This information is used for word alignment.  To
198    -- prevent the word align from changing during normal operation, we do word
199    -- alignment only when it is allowed by the lane_init_sm.
200
201    process (USER_CLK)
202
203        variable vec : std_logic_vector(0 to 3);
204
205    begin
206
207        if (USER_CLK 'event and USER_CLK = '1') then
208
209            if ((DO_WORD_ALIGN and not first_v_received_r) = '1') then
210
211                vec := RX_CHAR_IS_COMMA & RX_CHAR_IS_K;
212
213                case vec is
214
215                    when "1010" => left_aligned_r <= '1' after DLY;
216                    when "0101" => left_aligned_r <= '0' after DLY;
217                    when others => left_aligned_r <= left_aligned_r after DLY;
218
219                end case;
220
221            end if;
222
223        end if;
224
225    end process;
226
227
228    -- Store the LS byte from the previous cycle.  If the lane is aligned on
229    -- the LS byte, we use it as the MS byte on the current cycle.
230
231    process (USER_CLK)
232
233    begin
234
235        if (USER_CLK 'event and USER_CLK = '1') then
236
237            previous_cycle_data_r(0) <= RX_DATA(7) after DLY;
238            previous_cycle_data_r(1) <= RX_DATA(6) after DLY;
239            previous_cycle_data_r(2) <= RX_DATA(5) after DLY;
240            previous_cycle_data_r(3) <= RX_DATA(4) after DLY;
241            previous_cycle_data_r(4) <= RX_DATA(3) after DLY;
242            previous_cycle_data_r(5) <= RX_DATA(2) after DLY;
243            previous_cycle_data_r(6) <= RX_DATA(1) after DLY;
244            previous_cycle_data_r(7) <= RX_DATA(0) after DLY;
245
246        end if;
247
248    end process;
249
250
251    -- Store the control bit from the previous cycle LS byte.  It becomes the
252    -- control bit for the MS byte on this cycle if the lane is aligned to the
253    -- LS byte.
254
255    process (USER_CLK)
256
257    begin
258
259        if (USER_CLK 'event and USER_CLK = '1') then
260
261            previous_cycle_control_r <= RX_CHAR_IS_K(0) after DLY;
262
263        end if;
264
265    end process;
266
267
268    -- Select the word-aligned MS byte.  Use the current MS byte if the data is
269    -- left-aligned, otherwise use the LS byte from the previous cycle.
270
271    process (USER_CLK)
272
273    begin
274
275        if (USER_CLK 'event and USER_CLK = '1') then
276
277            if (left_aligned_r = '1') then
278
279                word_aligned_data_r(0) <= RX_DATA(15) after DLY;
280                word_aligned_data_r(1) <= RX_DATA(14) after DLY;
281                word_aligned_data_r(2) <= RX_DATA(13) after DLY;
282                word_aligned_data_r(3) <= RX_DATA(12) after DLY;
283                word_aligned_data_r(4) <= RX_DATA(11) after DLY;
284                word_aligned_data_r(5) <= RX_DATA(10) after DLY;
285                word_aligned_data_r(6) <= RX_DATA(9) after DLY;
286                word_aligned_data_r(7) <= RX_DATA(8) after DLY;
287
288            else
289
290                word_aligned_data_r(0 to 7) <= previous_cycle_data_r after DLY;
291
292            end if;
293
294        end if;
295
296    end process;
297
298
299    -- Select the word-aligned LS byte.  Use the current LSByte if the data is
300    -- right-aligned, otherwise use the current MS byte.
301
302    process (USER_CLK)
303
304    begin
305
306        if (USER_CLK 'event and USER_CLK = '1') then
307
308            if (left_aligned_r = '1') then
309
310                word_aligned_data_r(8)  <= RX_DATA(7) after DLY;
311                word_aligned_data_r(9)  <= RX_DATA(6) after DLY;
312                word_aligned_data_r(10) <= RX_DATA(5) after DLY;
313                word_aligned_data_r(11) <= RX_DATA(4) after DLY;
314                word_aligned_data_r(12) <= RX_DATA(3) after DLY;
315                word_aligned_data_r(13) <= RX_DATA(2) after DLY;
316                word_aligned_data_r(14) <= RX_DATA(1) after DLY;
317                word_aligned_data_r(15) <= RX_DATA(0) after DLY;
318
319            else
320
321                word_aligned_data_r(8)  <= RX_DATA(15) after DLY;
322                word_aligned_data_r(9)  <= RX_DATA(14) after DLY;
323                word_aligned_data_r(10) <= RX_DATA(13) after DLY;
324                word_aligned_data_r(11) <= RX_DATA(12) after DLY;
325                word_aligned_data_r(12) <= RX_DATA(11) after DLY;
326                word_aligned_data_r(13) <= RX_DATA(10) after DLY;
327                word_aligned_data_r(14) <= RX_DATA(9)  after DLY;
328                word_aligned_data_r(15) <= RX_DATA(8)  after DLY;
329
330            end if;
331
332        end if;
333
334    end process;
335
336
337    -- Select the word-aligned MS byte control bit.  Use the current MSByte's
338    -- control bit if the data is left-aligned, otherwise use the LS byte's
339    -- control bit from the previous cycle.
340
341    process (USER_CLK)
342
343    begin
344
345        if (USER_CLK 'event and USER_CLK = '1') then
346
347            if (left_aligned_r = '1') then
348
349                word_aligned_control_bits_r(0) <= RX_CHAR_IS_K(1) after DLY;
350
351            else
352
353                word_aligned_control_bits_r(0) <= previous_cycle_control_r after DLY;
354
355            end if;
356
357        end if;
358
359    end process;
360
361
362    -- Select the word-aligned LS byte control bit.  Use the current LSByte's control
363    -- bit if the data is left-aligned, otherwise use the current MS byte's control bit.
364
365    process (USER_CLK)
366
367    begin
368
369        if (USER_CLK 'event and USER_CLK = '1') then
370
371            if (left_aligned_r = '1') then
372
373                word_aligned_control_bits_r(1) <= RX_CHAR_IS_K(0) after DLY;
374
375            else
376
377                word_aligned_control_bits_r(1) <= RX_CHAR_IS_K(1) after DLY;
378
379            end if;
380
381        end if;
382
383    end process;
384
385
386    -- Pipeline the word-aligned data for 1 cycle to match the Decodes.
387
388    process (USER_CLK)
389
390    begin
391
392        if (USER_CLK 'event and USER_CLK = '1') then
393
394            rx_pe_data_r <= word_aligned_data_r after DLY;
395
396        end if;
397
398    end process;
399
400
401    -- Register the pipelined word-aligned data for the RX_LL interface.
402
403    process (USER_CLK)
404
405    begin
406
407        if (USER_CLK 'event and USER_CLK = '1') then
408
409            RX_PE_DATA_Buffer <= rx_pe_data_r after DLY;
410
411        end if;
412
413    end process;
414
415
416    -- Decode Control Symbols --
417
418    -- All decodes are pipelined to keep the number of logic levels to a minimum.
419
420    -- Delay the control bits: they are most often used in the second stage of
421    -- the decoding process.
422
423    process (USER_CLK)
424
425    begin
426
427        if (USER_CLK 'event and USER_CLK = '1') then
428
429            rx_pe_control_r <= word_aligned_control_bits_r after DLY;
430
431        end if;
432
433    end process;
434
435
436    -- Decode PAD
437
438    process (USER_CLK)
439
440    begin
441
442        if (USER_CLK 'event and USER_CLK = '1') then
443
444            rx_pad_d_r(0) <= std_bool(word_aligned_data_r(8 to 11) = PAD_0) after DLY;
445            rx_pad_d_r(1) <= std_bool(word_aligned_data_r(12 to 15) = PAD_1) after DLY;
446
447        end if;
448
449    end process;
450
451
452    process (USER_CLK)
453
454    begin
455
456        if (USER_CLK 'event and USER_CLK = '1') then
457
458            RX_PAD_Buffer <= std_bool((rx_pad_d_r = "11") and (rx_pe_control_r = "01")) after DLY;
459
460        end if;
461
462    end process;
463
464
465    -- Decode RX_PE_DATA_V
466
467    process (USER_CLK)
468
469    begin
470
471        if (USER_CLK 'event and USER_CLK = '1') then
472
473            RX_PE_DATA_V_Buffer <= not rx_pe_control_r(0) after DLY;
474
475        end if;
476
477    end process;
478
479
480    -- Decode RX_SCP
481
482    process (USER_CLK)
483
484    begin
485
486        if (USER_CLK 'event and USER_CLK = '1') then
487
488            rx_scp_d_r(0) <= std_bool(word_aligned_data_r(0 to 3)   = SCP_0) after DLY;
489            rx_scp_d_r(1) <= std_bool(word_aligned_data_r(4 to 7)   = SCP_1) after DLY;
490            rx_scp_d_r(2) <= std_bool(word_aligned_data_r(8 to 11)  = SCP_2) after DLY;
491            rx_scp_d_r(3) <= std_bool(word_aligned_data_r(12 to 15) = SCP_3) after DLY;
492
493        end if;
494
495    end process;
496
497
498    process (USER_CLK)
499
500    begin
501
502        if (USER_CLK 'event and USER_CLK = '1') then
503
504            RX_SCP_Buffer <= rx_pe_control_r(0) and
505                             rx_pe_control_r(1) and
506                             rx_scp_d_r(0)      and
507                             rx_scp_d_r(1)      and
508                             rx_scp_d_r(2)      and
509                             rx_scp_d_r(3)      after DLY;
510
511        end if;
512
513    end process;
514
515
516    -- Decode RX_ECP
517
518    process (USER_CLK)
519
520    begin
521
522        if (USER_CLK 'event and USER_CLK = '1') then
523
524            rx_ecp_d_r(0) <= std_bool(word_aligned_data_r(0 to 3)   = ECP_0) after DLY;
525            rx_ecp_d_r(1) <= std_bool(word_aligned_data_r(4 to 7)   = ECP_1) after DLY;
526            rx_ecp_d_r(2) <= std_bool(word_aligned_data_r(8 to 11)  = ECP_2) after DLY;
527            rx_ecp_d_r(3) <= std_bool(word_aligned_data_r(12 to 15) = ECP_3) after DLY;
528
529        end if;
530
531    end process;
532
533
534    process (USER_CLK)
535
536    begin
537
538        if (USER_CLK 'event and USER_CLK = '1') then
539
540            RX_ECP_Buffer <= rx_pe_control_r(0) and
541                             rx_pe_control_r(1) and
542                             rx_ecp_d_r(0)      and
543                             rx_ecp_d_r(1)      and
544                             rx_ecp_d_r(2)      and
545                             rx_ecp_d_r(3)      after DLY;
546
547        end if;
548
549    end process;
550
551
552    -- Decode RX_SNF
553
554    process (USER_CLK)
555
556    begin
557
558        if (USER_CLK 'event and USER_CLK = '1') then
559
560            rx_snf_d_r(0) <= std_bool(word_aligned_data_r(0 to 3) = SNF_0) after DLY;
561            rx_snf_d_r(1) <= std_bool(word_aligned_data_r(4 to 7) = SNF_1) after DLY;
562
563        end if;
564
565    end process;
566
567
568    process (USER_CLK)
569
570    begin
571
572        if (USER_CLK 'event and USER_CLK = '1') then
573
574            RX_SNF_Buffer <= rx_pe_control_r(0) and
575                             rx_snf_d_r(0)      and
576                             rx_snf_d_r(1)      after DLY;
577
578        end if;
579
580    end process;
581
582
583    -- Extract the Flow Control Size code and register it for the RX_LL interface.
584
585    process (USER_CLK)
586
587    begin
588
589        if (USER_CLK 'event and USER_CLK = '1') then
590
591            RX_FC_NB_Buffer <= rx_pe_data_r(8 to 11) after DLY;
592
593        end if;
594
595    end process;
596
597
598    -- For an SP sequence to be valid, there must be 2 bytes of SP Data preceded
599    -- by a Comma and an SP Data byte in the MS byte and LS byte positions
600    -- respectively.  This flop stores the decode of the Comma and SP Data byte
601    -- combination from the previous cycle.  Data can be positive or negative.
602
603    process (USER_CLK)
604
605    begin
606
607        if (USER_CLK 'event and USER_CLK = '1') then
608
609            prev_beat_sp_d_r(0) <= std_bool(word_aligned_data_r(0 to 3)    = K_CHAR_0) after DLY;
610            prev_beat_sp_d_r(1) <= std_bool(word_aligned_data_r(4 to 7)    = K_CHAR_1) after DLY;
611            prev_beat_sp_d_r(2) <= std_bool((word_aligned_data_r(8 to 11)  = SP_DATA_0) or
612                                            (word_aligned_data_r(8 to 11)  = SP_NEG_DATA_0)) after DLY;
613            prev_beat_sp_d_r(3) <= std_bool((word_aligned_data_r(12 to 15) = SP_DATA_1) or
614                                            (word_aligned_data_r(12 to 15) = SP_NEG_DATA_1)) after DLY;
615
616        end if;
617
618    end process;
619
620
621    process (USER_CLK)
622
623    begin
624
625        if (USER_CLK 'event and USER_CLK = '1') then
626
627            prev_beat_sp_r <= std_bool((rx_pe_control_r  = "10") and
628                                       (prev_beat_sp_d_r = "1111")) after DLY;
629
630        end if;
631
632    end process;
633
634
635    -- This flow stores the decode of a Comma and SPA Data byte combination from the
636    -- previous cycle.  It is used along with decodes for SPA data in the current
637    -- cycle to determine whether an SPA sequence was received.
638
639    process (USER_CLK)
640
641    begin
642
643        if (USER_CLK 'event and USER_CLK = '1') then
644
645            prev_beat_spa_d_r(0) <= std_bool(word_aligned_data_r(0 to 3)   = K_CHAR_0) after DLY;
646            prev_beat_spa_d_r(1) <= std_bool(word_aligned_data_r(4 to 7)   = K_CHAR_1) after DLY;
647            prev_beat_spa_d_r(2) <= std_bool(word_aligned_data_r(8 to 11)  = SPA_DATA_0) after DLY;
648            prev_beat_spa_d_r(3) <= std_bool(word_aligned_data_r(12 to 15) = SPA_DATA_1) after DLY;
649
650        end if;
651
652    end process;
653
654
655    process (USER_CLK)
656
657    begin
658
659        if (USER_CLK 'event and USER_CLK = '1') then
660
661            prev_beat_spa_r <= std_bool((rx_pe_control_r   = "10") and
662                                        (prev_beat_spa_d_r = "1111")) after DLY;
663
664        end if;
665
666    end process;
667
668
669    -- Indicate the SP sequence was received.
670
671    process (USER_CLK)
672
673    begin
674
675        if (USER_CLK 'event and USER_CLK = '1') then
676
677            rx_sp_d_r(0) <= std_bool((word_aligned_data_r(0 to 3)   = SP_DATA_0) or
678                                     (word_aligned_data_r(0 to 3)   = SP_NEG_DATA_0)) after DLY;
679            rx_sp_d_r(1) <= std_bool((word_aligned_data_r(4 to 7)   = SP_DATA_1) or
680                                     (word_aligned_data_r(4 to 7)   = SP_NEG_DATA_1)) after DLY;
681            rx_sp_d_r(2) <= std_bool((word_aligned_data_r(8 to 11)  = SP_DATA_0) or
682                                     (word_aligned_data_r(8 to 11)  = SP_NEG_DATA_0)) after DLY;
683            rx_sp_d_r(3) <= std_bool((word_aligned_data_r(12 to 15) = SP_DATA_1) or
684                                     (word_aligned_data_r(12 to 15) = SP_NEG_DATA_1)) after DLY;
685
686        end if;
687
688    end process;
689
690
691    process (USER_CLK)
692
693    begin
694
695        if (USER_CLK 'event and USER_CLK = '1') then
696
697            RX_SP_Buffer <= prev_beat_sp_r and
698                            std_bool((rx_pe_control_r = "00") and
699                                     (rx_sp_d_r       = "1111")) after DLY;
700
701        end if;
702
703    end process;
704
705
706    -- Indicate the SPA sequence was received.
707
708    process (USER_CLK)
709
710    begin
711
712        if (USER_CLK 'event and USER_CLK = '1') then
713
714            rx_spa_d_r(0) <= std_bool(word_aligned_data_r(0 to 3)   = SPA_DATA_0) after DLY;
715            rx_spa_d_r(1) <= std_bool(word_aligned_data_r(4 to 7)   = SPA_DATA_1) after DLY;
716            rx_spa_d_r(2) <= std_bool(word_aligned_data_r(8 to 11)  = SPA_DATA_0) after DLY;
717            rx_spa_d_r(3) <= std_bool(word_aligned_data_r(12 to 15) = SPA_DATA_1) after DLY;
718
719        end if;
720
721    end process;
722
723
724    process (USER_CLK)
725
726    begin
727
728        if (USER_CLK 'event and USER_CLK = '1') then
729
730            RX_SPA_Buffer <= prev_beat_spa_r and
731                             std_bool((rx_pe_control_r = "00") and
732                                      (rx_spa_d_r      = "1111")) after DLY;
733
734        end if;
735
736    end process;
737
738
739    -- Indicate reversed data received.  We look only at the word-aligned LS byte
740    -- which, during an /SP/ or /SPA/ sequence, will always contain a data byte.
741
742    process (USER_CLK)
743
744    begin
745
746        if (USER_CLK 'event and USER_CLK = '1') then
747
748            rx_sp_neg_d_r(0)  <= std_bool(word_aligned_data_r(8 to 11)  = SP_NEG_DATA_0) after DLY;
749            rx_sp_neg_d_r(1)  <= std_bool(word_aligned_data_r(12 to 15) = SP_NEG_DATA_1) after DLY;
750            rx_spa_neg_d_r(0) <= std_bool(word_aligned_data_r(8 to 11)  = SPA_NEG_DATA_0) after DLY;
751            rx_spa_neg_d_r(1) <= std_bool(word_aligned_data_r(12 to 15) = SPA_NEG_DATA_1) after DLY;
752
753        end if;
754
755    end process;
756
757
758    process (USER_CLK)
759
760    begin
761
762        if (USER_CLK 'event and USER_CLK = '1') then
763
764            RX_NEG_Buffer <= not rx_pe_control_r(1) and
765                             std_bool((rx_sp_neg_d_r  = "11") or
766                                      (rx_spa_neg_d_r = "11")) after DLY;
767
768        end if;
769
770    end process;
771
772
773    -- GOT_A is decoded from the non_word-aligned input.
774
775    process (USER_CLK)
776
777    begin
778
779        if (USER_CLK 'event and USER_CLK = '1') then
780
781            got_a_d_r(0) <= std_bool(word_aligned_data_r(0 to 3)   = A_CHAR_0) after DLY;
782            got_a_d_r(1) <= std_bool(word_aligned_data_r(4 to 7)   = A_CHAR_1) after DLY;
783            got_a_d_r(2) <= std_bool(word_aligned_data_r(8 to 11)  = A_CHAR_0) after DLY;
784            got_a_d_r(3) <= std_bool(word_aligned_data_r(12 to 15) = A_CHAR_1) after DLY;
785
786        end if;
787
788    end process;
789
790
791    process (USER_CLK)
792
793    begin
794
795        if (USER_CLK 'event and USER_CLK = '1') then
796
797            GOT_A_Buffer(0) <= rx_pe_control_r(0) and std_bool(got_a_d_r(0 to 1) = "11") after DLY;
798            GOT_A_Buffer(1) <= rx_pe_control_r(1) and std_bool(got_a_d_r(2 to 3) = "11") after DLY;
799
800        end if;
801
802    end process;
803
804
805    -- Verification symbol decode --
806
807    -- This flow stores the decode of a Comma and SPA Data byte combination from the
808    -- previous cycle.  It is used along with decodes for SPA data in the current
809    -- cycle to determine whether an SPA sequence was received.
810
811    process (USER_CLK)
812
813    begin
814
815        if (USER_CLK 'event and USER_CLK = '1') then
816
817            prev_beat_v_d_r(0) <= std_bool(word_aligned_data_r(0 to 3)   = K_CHAR_0) after DLY;
818            prev_beat_v_d_r(1) <= std_bool(word_aligned_data_r(4 to 7)   = K_CHAR_1) after DLY;
819            prev_beat_v_d_r(2) <= std_bool(word_aligned_data_r(8 to 11)  = VER_DATA_0) after DLY;
820            prev_beat_v_d_r(3) <= std_bool(word_aligned_data_r(12 to 15) = VER_DATA_1) after DLY;
821
822        end if;
823
824    end process;
825
826
827    process (USER_CLK)
828
829    begin
830
831        if (USER_CLK 'event and USER_CLK = '1') then
832
833            prev_beat_v_r <= std_bool((rx_pe_control_r = "10") and
834                                      (prev_beat_v_d_r = "1111")) after DLY;
835
836        end if;
837
838    end process;
839
840
841    -- Indicate the SP sequence was received.
842
843    process (USER_CLK)
844
845    begin
846
847        if (USER_CLK 'event and USER_CLK = '1') then
848
849            rx_v_d_r(0) <= std_bool(word_aligned_data_r(0 to 3)   = VER_DATA_0) after DLY;
850            rx_v_d_r(1) <= std_bool(word_aligned_data_r(4 to 7)   = VER_DATA_1) after DLY;
851            rx_v_d_r(2) <= std_bool(word_aligned_data_r(8 to 11)  = VER_DATA_0) after DLY;
852            rx_v_d_r(3) <= std_bool(word_aligned_data_r(12 to 15) = VER_DATA_1) after DLY;
853
854        end if;
855
856    end process;
857
858
859    got_v_c <= prev_beat_v_r and
860               std_bool((rx_pe_control_r = "00") and
861                        (rx_v_d_r        = "1111"));
862
863    process (USER_CLK)
864
865    begin
866
867        if (USER_CLK 'event and USER_CLK = '1') then
868
869            GOT_V_Buffer <= got_v_c after DLY;
870
871        end if;
872
873    end process;
874
875
876    -- Remember that the first V sequence has been detected.
877
878    process (USER_CLK)
879
880    begin
881
882        if (USER_CLK 'event and USER_CLK = '1') then
883
884            if (RESET = '1') then
885
886                first_v_received_r <= '0' after DLY;
887
888            else
889
890                if (got_v_c = '1') then
891
892                    first_v_received_r <= '1' after DLY;
893
894                end if;
895
896            end if;
897
898        end if;
899
900    end process;
901
902end RTL;
Note: See TracBrowser for help on using the repository browser.