1-------------------------------------------------------------------------------
2-- Title      : 802.3x 1000base-X compatible synchronization detect unit
3-- Project    : WhiteRabbit Switch
4-------------------------------------------------------------------------------
5-- File       : ep_sync_detect.vhd
6-- Author     : Tomasz Wlostowski
7-- Company    : CERN BE-Co-HT
8-- Created    : 2010-05-28
9-- Last update: 2012-01-18
10-- Platform   : FPGA-generics
11-- Standard   : VHDL
12-------------------------------------------------------------------------------
13-- Description: Module implements a link synchronization detect state machine
14-- compatible with 802.3x spec.
15-------------------------------------------------------------------------------
16--
17-- Copyright (c) 2010 CERN
18--
19-- This source file is free software; you can redistribute it
20-- and/or modify it under the terms of the GNU Lesser General
21-- Public License as published by the Free Software Foundation;
22-- either version 2.1 of the License, or (at your option) any
23-- later version.
24--
25-- This source is distributed in the hope that it will be
26-- useful, but WITHOUT ANY WARRANTY; without even the implied
27-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
28-- PURPOSE.  See the GNU Lesser General Public License for more
29-- details.
30--
31-- You should have received a copy of the GNU Lesser General
32-- Public License along with this source; if not, download it
33-- from http://www.gnu.org/licenses/lgpl-2.1.html
34--
35-------------------------------------------------------------------------------
36-- Revisions  :
37-- Date        Version  Author          Description
38-- 2010-05-28  1.0      twlostow        Created
39-------------------------------------------------------------------------------
40
41
42
43library ieee;
44use ieee.std_logic_1164.all;
45use ieee.numeric_std.all;
46
47library work;
48use work.endpoint_private_pkg.all;
49
50entity ep_sync_detect_16bit is
51
52  port (
53-- reset, synchronous to rbclk_i, active LOW
54    rst_n_i  : in  std_logic;
55-- recovered byte clock
56    rbclk_i  : in  std_logic;
57-- enable, active HI
58    en_i     : in  std_logic;
59-- decoded data input, active HI
60    data_i   : in  std_logic_vector(15 downto 0);
61-- decoded K signal, active HI
62    k_i      : in  std_logic_vector(1 downto 0);
63-- 8b10b coding error indication, active HI
64    err_i    : in  std_logic;
65-- sync detect output, active HI
66    synced_o : out std_logic;
67
68    cal_i : in std_logic
69    );
70
71end ep_sync_detect_16bit;
72
73architecture behavioral of ep_sync_detect_16bit is
74
75  type t_sync_fsm_state is (LOSS_OF_SYNC, CD_ACQ_1, CD_ACQ_2, CD_ACQ_3, SYNC_ACQUIRED_1, SYNC_ACQUIRED_2, SYNC_ACQUIRED_3, SYNC_ACQUIRED_4, SYNC_ACQUIRED_2A, SYNC_ACQUIRED_3A, SYNC_ACQUIRED_4A);
76
77
78  function f_pick(sel : std_logic;
79                  w1  : t_sync_fsm_state;
80                  w0  : t_sync_fsm_state) return t_sync_fsm_state is
81
82  begin
83    if(sel = '1') then
84      return w1;
85    else
86      return w0;
87    end if;
88  end f_pick;
89
90
91
92  signal state    : t_sync_fsm_state;
93  signal good_cgs : unsigned(2 downto 0);
94
95  signal valid_idle   : std_logic;
96  signal invalid_code : std_logic;
97  signal valid_data   : std_logic;
98
99begin  -- behavioral
100
101  valid_idle   <= '1' when (k_i = "10" and data_i(15 downto 8) = c_k28_5 and err_i = '0')   else '0';
102  valid_data   <= '1' when (k_i = "00" and err_i = '0')                                     else '0';
103  invalid_code <= '1' when (err_i = '1' or (k_i(0) = '1' and data_i(7 downto 0) = c_k28_5)) else '0';
104
105
106  sync_fsm : process (rbclk_i, rst_n_i)
107  begin  -- process sync_fsm
108    if rising_edge(rbclk_i) then
109      if(rst_n_i = '0') then
110        state    <= LOSS_OF_SYNC;
111        synced_o <= '0';
112        good_cgs <= (others => '0');
113      else
114        if(en_i = '0') then
115          state    <= LOSS_OF_SYNC;
116          synced_o <= '0';
117          good_cgs <= (others => '0');
118        else
119
120          -- prevents from
121          if(cal_i = '0') then
122
123            case state is
124              when LOSS_OF_SYNC =>
125                synced_o <= '0';
126                state    <= f_pick(valid_idle, CD_ACQ_1, LOSS_OF_SYNC);
127              when CD_ACQ_1 =>
128                state <= f_pick(valid_idle or valid_data, CD_ACQ_2, LOSS_OF_SYNC);
129              when CD_ACQ_2 =>
130                state <= f_pick(valid_idle, CD_ACQ_3, LOSS_OF_SYNC);
131              when CD_ACQ_3 =>
132                state <= f_pick(valid_idle or valid_data, SYNC_ACQUIRED_1, LOSS_OF_SYNC);
133
134              when SYNC_ACQUIRED_1 =>
135                synced_o <= '1';
136                state    <= f_pick(invalid_code, SYNC_ACQUIRED_2, SYNC_ACQUIRED_1);
137
138              when SYNC_ACQUIRED_2 =>
139                good_cgs <= (others => '0');
140                state    <= f_pick(invalid_code, SYNC_ACQUIRED_3, SYNC_ACQUIRED_2A);
141
142              when SYNC_ACQUIRED_2A =>
143                good_cgs <= good_cgs + 1;
144
145                if(good_cgs = "011" and invalid_code = '0') then
146                  state <= SYNC_ACQUIRED_1;
147                end if;
148
149                if(invalid_code = '1') then
150                  state <= SYNC_ACQUIRED_3;
151                end if;
152
153              when SYNC_ACQUIRED_3 =>
154                good_cgs <= (others => '0');
155                state    <= f_pick(invalid_code, SYNC_ACQUIRED_4, SYNC_ACQUIRED_3A);
156
157
158              when SYNC_ACQUIRED_3A =>
159                good_cgs <= good_cgs + 1;
160
161                if(good_cgs = "011" and invalid_code = '0') then
162                  state <= SYNC_ACQUIRED_2;
163                end if;
164
165                if(invalid_code = '1') then
166                  state <= SYNC_ACQUIRED_4;
167                end if;
168
169              when SYNC_ACQUIRED_4 =>
170                good_cgs <= (others => '0');
171                state    <= f_pick(invalid_code, LOSS_OF_SYNC, SYNC_ACQUIRED_4A);
172
173              when SYNC_ACQUIRED_4A =>
174                good_cgs <= good_cgs + 1;
175
176                if(good_cgs = "011" and invalid_code = '0') then
177                  state <= SYNC_ACQUIRED_3;
178                end if;
179
180                if (invalid_code = '1') then
181                  state <= LOSS_OF_SYNC;
182                end if;
183            end case;
184          end if;
185        end if;
186      end if;
187    end if;
188  end process;
189
190
191
192
193end behavioral;
194