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 |
|