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