Rev Author Line No. Line
3641 kaklik 1 ---------------------------------------------
2 -- internal bitslip in iserdes works only with 8 bits. It may happen that when we make a 16-bit word from them,
3 -- internal bitslip is correct, but we need to swap the whole bytes. -> o_bitslip_swap_bytes
4 --
5 -- NOTE: swapping bytes is wrong, because that means we're grabbing when frame is "00FF". That suggests, that
6 -- we're using LSbyte from previous sample and MSbyte from current sample. It is correct to drop the byte, to have the frame signal "FF00"
7 --
8 -- However, the bytes are not swapped, i.e. LSbyte is still LSbyte. They just do not come from the same sample.
9  
10 library ieee;
11 use ieee.std_logic_1164.all;
12  
13 library UNISIM;
14 use UNISIM.vcomponents.all;
15  
16 --library utilities;
17  
18 entity bitslip_compensation is
19 port (
20  
21 clk : in std_logic;
22 rst : in std_logic;
23  
24 i_data : in std_logic_vector( 15 downto 0 );
25 i_valid : in std_logic;
26  
27 o_bitslip : out std_logic;
28 o_bitslip_done : out std_logic;
29 o_bitslip_drop_byte : out std_logic;
30 o_bitslip_failed : out std_logic
31  
32 );
33  
34 end bitslip_compensation;
35  
36 architecture behavioral of bitslip_compensation is
37  
38 component swap_endianness
39 port (
40 i_data : in std_logic_vector;
41 o_data : out std_logic_vector
42 );
43 end component;
44  
45 constant C_BITSLIP_FRAME_TRAINING_PATTERN : std_logic_vector( 15 downto 0 ) := X"FF00";
46  
47 -- wait a while before bitslipping again
48 subtype t_counter_busy is natural range 0 to 5; -- in theory 2 is enough
49 signal s_counter_busy : t_counter_busy := 0;
50  
51 -- count the number of bitslip attempts
52 subtype t_counter_attempts is natural range 0 to 9;
53 signal s_counter_attempts : t_counter_attempts := 0;
54  
55 signal s_i_data_bytes_swapped : std_logic_vector( 15 downto 0 );
56  
57 signal s_bitslip_done : std_logic;
58 signal s_bitslip_failed : std_logic;
59  
60  
61 begin
62  
63 swap_endianness_inst : swap_endianness
64 port map( i_data => i_data, o_data => s_i_data_bytes_swapped );
65  
66 o_bitslip_done <= s_bitslip_done;
67 o_bitslip_failed <= s_bitslip_failed;
68  
69 main_process : process( clk )
70  
71 begin
72 if( rising_edge(clk) ) then
73  
74 o_bitslip <= '0';
75 o_bitslip_drop_byte <= '0';
76  
77 if( rst = '1' ) then
78 -- reset
79 s_counter_busy <= t_counter_busy'high;
80 s_counter_attempts <= 0;
81 s_bitslip_done <= '0';
82 s_bitslip_failed <= '0';
83  
84 elsif( s_bitslip_done = '1' or s_bitslip_failed = '1' ) then
85 -- do nothing, the bitslip has already been determined.
86  
87 elsif( i_valid = '1' and s_counter_busy > 0 ) then
88 -- we are busy now, do not do anything
89 s_counter_busy <= s_counter_busy - 1;
90  
91 elsif( i_valid = '1' and s_counter_busy = 0 and i_data = C_BITSLIP_FRAME_TRAINING_PATTERN ) then
92 -- we are not busy and the incoming pattern matches the training pattern.
93 s_bitslip_done <= '1';
94  
95 elsif( i_valid = '1' and s_counter_busy = 0 and s_i_data_bytes_swapped = C_BITSLIP_FRAME_TRAINING_PATTERN ) then
96 -- we are not busy and the incoming pattern matches the training pattern if we swap its bytes:
97 -- drop the byte and start over.
98 o_bitslip_drop_byte <= '1';
99 s_counter_busy <= t_counter_busy'high;
100  
101 elsif( i_valid = '1' and s_counter_busy = 0 and s_counter_attempts < t_counter_attempts'high ) then
102 -- we are not busy, we may bitslip again and the incoming pattern does not match.
103 s_counter_attempts <= s_counter_attempts + 1;
104 s_counter_busy <= t_counter_busy'high;
105 o_bitslip <= '1';
106  
107 elsif( i_valid = '1' and s_counter_busy = 0 and s_counter_attempts = t_counter_attempts'high ) then
108 -- we are not busy, but we do not have another attempt and the pattern still does not match.
109 s_bitslip_failed <= '1';
110  
111 end if;
112 end if;
113 end process;
114  
115 end architecture;
116