OpenCores
URL https://opencores.org/ocsvn/udp_ipv4_for_10g_ethernet/udp_ipv4_for_10g_ethernet/trunk

Subversion Repositories udp_ipv4_for_10g_ethernet

[/] [udp_ipv4_for_10g_ethernet/] [trunk/] [src/] [hdl/] [frame_receiver.vhd] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 DFC
-------------------------------------------------------------------------------
2
--
3
-- (C) Copyright 2013 DFC Design, s.r.o., Brno, Czech Republic
4
-- Author: Marek Kvas (m.kvas@dfcdesign.cz)
5
--
6
-------------------------------------------------------------------------------
7
-- This file is part of UDP/IPv4 for 10 G Ethernet core.
8
-- 
9
-- UDP/IPv4 for 10 G Ethernet core is free software: you can 
10
-- redistribute it and/or modify it under the terms of 
11
-- the GNU Lesser General Public License as published by the Free 
12
-- Software Foundation, either version 3 of the License, or
13
-- (at your option) any later version.
14
-- 
15
-- UDP/IPv4 for 10 G Ethernet core is distributed in the hope that 
16
-- it will be useful, but WITHOUT ANY WARRANTY; without even 
17
-- the implied warranty of MERCHANTABILITY or FITNESS FOR A 
18
-- PARTICULAR PURPOSE.  See the GNU Lesser General Public License 
19
-- for more details.
20
-- 
21
-- You should have received a copy of the GNU Lesser General Public 
22
-- License along with UDP/IPv4 for 10 G Ethernet core.  If not, 
23
-- see <http://www.gnu.org/licenses/>.
24
-------------------------------------------------------------------------------
25
--
26
-- First block of the receiver chain. It has XGMII as an input.
27
-- Output is raw 64 bit data guaranteed to be aligned on the frame start and 
28
-- stripped of preamble and CRC, valid signal covering frame data,
29
-- and byte enable signal that shall be used in case data amount is not
30
-- 8 byte aligned. Another signal indicates either CRC error or line
31
-- signalized error, in which case frame should be discarded.
32
--
33
-- Byte enable signal is guaranteed to be all ones for whole frame except
34
-- for the last word, in case packet length is not 8 byte integer divisible.
35
--
36
-- This can work under assumption that minimum IPG in incoming stream is
37
-- 4 bytes. This means when T is on L0-L4, S cannot be on L5-L7 of the same
38
-- cycle and when T is on L5-L7 S cannot be on L0-L3 of the next cycle. Under
39
-- this condition DV is always at leased one cycle deasserted between
40
-- frames.
41
--
42
-- RST must be asserted for 16 cycles to fully empty pipeline
43
--
44
-------------------------------------------------------------------------------
45
 
46
library ieee;
47
use ieee.std_logic_1164.all;
48
use ieee.numeric_std.all;
49
 
50
Library UNISIM;
51
use UNISIM.vcomponents.all;
52
 
53
library work;
54
use work.srl_pkg.all;
55
 
56
 
57
entity frame_receiver is
58
   port (
59
      RST               : in std_logic; -- Sync to XGMII_RX_CLK
60
 
61
      -- XGMII RX input interface
62
      XGMII_RXCLK       : in  std_logic;
63
      XGMII_RXD         : in  std_logic_vector(63 downto 0);
64
      XGMII_RXC         : in  std_logic_vector( 7 downto 0);
65
 
66
      -- Output interface
67
      RX_DATA           : out std_logic_vector(63 downto 0);
68
      RX_DV             : out std_logic;
69
      RX_BE             : out std_logic_vector(7 downto 0);
70
      RX_ERR            : out std_logic;
71
      RX_ERR_VALID      : out std_logic
72
 
73
        );
74
end entity;
75
 
76
architecture synthesis of frame_receiver is
77
 
78
   -- Local constants
79
   constant LC_START_CHAR  : std_logic_vector(7 downto 0) := x"FB";
80
   constant LC_TERM_CHAR   : std_logic_vector(7 downto 0) := x"FD";
81
   constant LC_ERR_CHAR    : std_logic_vector(7 downto 0) := x"FE";
82
 
83
   -- Aligning block
84
   signal align_buf_data  : std_logic_vector(XGMII_RXD'length-1 downto 0);
85
   signal align_res_data  : std_logic_vector(XGMII_RXD'length-1 downto 0);
86
   signal align_res_data_d: std_logic_vector(XGMII_RXD'length-1 downto 0);
87
   signal align_buf_ctrl  : std_logic_vector(XGMII_RXC'length-1 downto 0);
88
   signal align_res_ctrl  : std_logic_vector(XGMII_RXC'length-1 downto 0);
89
   type align_mode_type  is (S_L0, S_L4);
90
   signal align_mode     : align_mode_type;
91
 
92
   signal crc_data_d    : std_logic_vector(XGMII_RXD'length-1 downto 0);
93
   signal crc_data_dd   : std_logic_vector(XGMII_RXD'length-1 downto 0);
94
   signal data_mask_d   : std_logic_vector(7 downto 0);
95
   signal data_mask_dd  : std_logic_vector(7 downto 0);
96
   signal crc_mask_dd   : std_logic_vector(2 downto 0);
97
   signal crc_dv_d      : std_logic;
98
   signal crc_dv_dd     : std_logic;
99
   signal crc_eop       : std_logic;
100
   signal crc_eop_d     : std_logic;
101
   signal crc_eop_dd    : std_logic;
102
   signal data_valid    : std_logic;
103
   signal data_valid_d  : std_logic;
104
   signal sop_found     : std_logic;
105
   signal sop_found_d   : std_logic;
106
 
107
   signal extracted_crc          : std_logic_vector(31 downto 0);
108
   signal extracted_crc_eq       : std_logic_vector(31 downto 0);
109
   signal extracted_crc_n        : std_logic_vector(31 downto 0);
110
 
111
   signal data_err_valid         : std_logic;
112
   signal data_err_valid_d       : std_logic;
113
   signal data_err_valid_dd      : std_logic;
114
   signal data_err_valid_reg     : std_logic;
115
   signal data_err_valid_d_reg   : std_logic;
116
   signal data_err_valid_dd_reg  : std_logic;
117
 
118
   signal data_err               : std_logic;
119
   signal data_err_d             : std_logic;
120
   signal data_err_dd            : std_logic;
121
 
122
   -- Internal versions of output signals
123
   signal rx_data_i           : std_logic_vector(63 downto 0);
124
   signal rx_dv_i             : std_logic;
125
   signal rx_err_i            : std_logic;
126
   signal rx_err_valid_i      : std_logic;
127
   signal rx_be_i             : std_logic_vector(7 downto 0);
128
 
129
   signal data_err_eq_m1      : std_logic;
130
 
131
   -- crc connection
132
   signal crc32_result        : std_logic_vector(31 downto 0);
133
   signal crc32_result_n      : std_logic_vector(31 downto 0);
134
   signal crc_vld             : std_logic;
135
 
136
 
137
-- Returns true if there is a terminate command character in data
138
   function check_terminate_func(rxc : std_logic_vector; rxd : std_logic_vector)
139
                                             return boolean is
140
      variable res : boolean := false;
141
   begin
142
      if (rxd(7  downto  0) = LC_TERM_CHAR and rxc(0) = '1') or
143
         (rxd(15 downto  8) = LC_TERM_CHAR and rxc(1) = '1') or
144
         (rxd(23 downto 16) = LC_TERM_CHAR and rxc(2) = '1') or
145
         (rxd(31 downto 24) = LC_TERM_CHAR and rxc(3) = '1') or
146
         (rxd(39 downto 32) = LC_TERM_CHAR and rxc(4) = '1') or
147
         (rxd(47 downto 40) = LC_TERM_CHAR and rxc(5) = '1') or
148
         (rxd(55 downto 48) = LC_TERM_CHAR and rxc(6) = '1') or
149
         (rxd(63 downto 56) = LC_TERM_CHAR and rxc(7) = '1') then
150
         res := true;
151
      end if;
152
 
153
      return res;
154
   end function;
155
 
156
-- Returns true if there is a error command character in data
157
   function check_err_func(rxc : std_logic_vector; rxd : std_logic_vector)
158
                                             return boolean is
159
      variable res : boolean := false;
160
   begin
161
      if (rxd(7  downto  0) = LC_ERR_CHAR and rxc(0) = '1') or
162
         (rxd(15 downto  8) = LC_ERR_CHAR and rxc(1) = '1') or
163
         (rxd(23 downto 16) = LC_ERR_CHAR and rxc(2) = '1') or
164
         (rxd(31 downto 24) = LC_ERR_CHAR and rxc(3) = '1') or
165
         (rxd(39 downto 32) = LC_ERR_CHAR and rxc(4) = '1') or
166
         (rxd(47 downto 40) = LC_ERR_CHAR and rxc(5) = '1') or
167
         (rxd(55 downto 48) = LC_ERR_CHAR and rxc(6) = '1') or
168
         (rxd(63 downto 56) = LC_ERR_CHAR and rxc(7) = '1') then
169
         res := true;
170
      end if;
171
 
172
      return res;
173
   end function;
174
 
175
   -- transform byte enables to crc mask
176
   function be_to_crc_mask_func(be : std_logic_vector) return std_logic_vector is
177
      variable res : std_logic_vector(2 downto 0);
178
   begin
179
      case be(7 downto 0) is
180
         when "00000000" => res := "000";
181
         when "00000001" => res := "111";
182
         when "00000011" => res := "110";
183
         when "00000111" => res := "101";
184
         when "00001111" => res := "100";
185
         when "00011111" => res := "011";
186
         when "00111111" => res := "010";
187
         when "01111111" => res := "001";
188
         when others => res := "000";
189
      end case;
190
      return res;
191
   end function;
192
 
193
   function swap_bytes32_cut(i : std_logic_vector; idx : integer)
194
                                                return std_logic_vector is
195
      variable res : std_logic_vector(31 downto 0);
196
   begin
197
      res(7  downto 0 ) := i(31 + idx*8 downto 24+ idx*8 );
198
      res(15 downto 8 ) := i(23 + idx*8 downto 16+ idx*8 );
199
      res(23 downto 16) := i(15 + idx*8 downto 8 + idx*8 );
200
      res(31 downto 24) := i(7  + idx*8 downto 0 + idx*8 );
201
      return res;
202
   end function;
203
 
204
 
205
begin
206
 
207
--------------------------------------------------------------------------------
208
-- Allign data if start is on Lane 4
209
--------------------------------------------------------------------------------
210
 
211
   align_proc : process (XGMII_RXCLK)
212
      variable tmp      : std_logic_vector(2*align_res_data'length - 1 downto 0);
213
   begin
214
      if rising_edge(XGMII_RXCLK) then
215
         tmp := align_res_data & align_res_data_d;
216
         rx_err_valid_i <= '0';
217
         rx_err_i <= '0';
218
         crc_eop <= '0';
219
         sop_found <= '0';
220
 
221
         -- First stage - directly connected to input
222
         if XGMII_RXC(0) = '1' and
223
            XGMII_RXD((0+1)*8-1 downto 0*8) = LC_START_CHAR then
224
            align_mode <= S_L0;
225
            sop_found <= '1';
226
            data_err <= '0';
227
         elsif XGMII_RXC(0) = '1' and
228
               XGMII_RXD((4+1)*8-1 downto 4*8) = LC_START_CHAR then
229
            align_mode <= S_L4;
230
            sop_found <= '1';
231
            data_err <= '0';
232
         end if;
233
         align_buf_data <= XGMII_RXD;
234
         align_buf_ctrl <= XGMII_RXC;
235
 
236
         -- Second stage - registers after multiplexer that takes data
237
         -- either from buffer or from input
238
         case align_mode is
239
            when S_L0 =>
240
               align_res_data <= align_buf_data;
241
               align_res_ctrl <= align_buf_ctrl;
242
            when S_L4 =>
243
               align_res_data <= XGMII_RXD(31 downto 0) &
244
                                 align_buf_data(63 downto 32);
245
               align_res_ctrl <= XGMII_RXC(3 downto 0) &
246
                                 align_buf_ctrl(7 downto 4);
247
         end case;
248
         sop_found_d <= sop_found;
249
 
250
         -- Derive correct BE and crc mask, align data for crc to this info
251
         -- derive error signal (remote error or invalid control combination
252
         -- 3 cycles
253
         align_res_data_d <= align_res_data;
254
         crc_data_d <= align_res_data_d;
255
         crc_data_dd <= crc_data_d;
256
         crc_eop_d <= crc_eop;
257
         crc_eop_dd <= crc_eop_d;
258
         data_mask_dd <= data_mask_d;
259
         crc_mask_dd <= be_to_crc_mask_func(data_mask_dd);
260
 
261
         data_valid <= data_valid or sop_found_d;
262
         data_valid_d <= data_valid;
263
         crc_dv_d <= data_valid_d;
264
         crc_dv_dd <= crc_dv_d;
265
 
266
         if data_valid = '1' then
267
            data_mask_d <= (others => '1');
268
         end if;
269
 
270
 
271
         if data_valid = '1' and
272
            check_terminate_func (align_res_ctrl, align_res_data) then
273
            case align_res_ctrl is
274
               when "10000000" =>
275
                  data_mask_d <= "00000111";
276
                  data_valid_d  <= '1';
277
                  data_valid <= '0';
278
                  crc_eop     <= '1';
279
                  extracted_crc <= swap_bytes32_cut(tmp,11);
280
               when "11000000" =>
281
                  data_mask_d <= "00000011";
282
                  data_valid_d <= '1';
283
                  data_valid <= '0';
284
                  crc_eop     <= '1';
285
                  extracted_crc <= swap_bytes32_cut(tmp,10);
286
               when "11100000" =>
287
                  data_mask_d <= "00000001";
288
                  data_valid_d <= '1';
289
                  data_valid <= '0';
290
                  crc_eop     <= '1';
291
                  extracted_crc <= swap_bytes32_cut(tmp,9);
292
               when "11110000" =>
293
                  data_mask_d <= "00000000";
294
                  data_valid_d <= '0';
295
                  data_valid <= '0';
296
                  crc_eop_d   <= '1';
297
                  extracted_crc <= swap_bytes32_cut(tmp,8);
298
               when "11111000" =>
299
                  data_mask_d <= "00000000";
300
                  data_valid_d <= '0';
301
                  data_valid <= '0';
302
                  data_mask_dd <= "01111111";
303
                  crc_eop_d   <= '1';
304
                  extracted_crc <= swap_bytes32_cut(tmp,7);
305
               when "11111100" =>
306
                  data_mask_d <= "00000000";
307
                  data_valid_d <= '0';
308
                  data_valid <= '0';
309
                  data_mask_dd <= "00111111";
310
                  crc_eop_d   <= '1';
311
                  extracted_crc <= swap_bytes32_cut(tmp,6);
312
               when "11111110" =>
313
                  data_mask_d <= "00000000";
314
                  data_valid_d <= '0';
315
                  data_valid <= '0';
316
                  data_mask_dd <= "00011111";
317
                  crc_eop_d   <= '1';
318
                  extracted_crc <= swap_bytes32_cut(tmp,5);
319
               when "11111111" =>
320
                  data_mask_d <= "00000000";
321
                  data_valid_d <= '0';
322
                  data_valid <= '0';
323
                  data_mask_dd <= "00001111";
324
                  crc_eop_d   <= '1';
325
                  extracted_crc <= swap_bytes32_cut(tmp,4);
326
               when others =>
327
                  data_err <= '1';
328
                  data_valid_d <= '0';
329
                  data_valid <= '0';
330
            end case;
331
         end if;
332
 
333
         if check_err_func(align_res_ctrl, align_res_data) then
334
            data_err <= '1';
335
         end if;
336
 
337
         -- Check CRC validity
338
         -- takes 1 cycle, but crc itself has 4 cycles
339
         -- 5 cycles
340
         if crc_vld = '1' then
341
            if extracted_crc /= crc32_result then
342
               -- CRC error
343
               rx_err_i <= '1';
344
            else
345
               rx_err_i <= data_err_eq_m1;
346
            end if;
347
            rx_err_valid_i <= '1';
348
         end if;
349
 
350
         -- Reset only input to pipeline reset should be held asserted long
351
         -- enough to reset pipeline
352
         if RST = '1' then
353
            align_mode <= S_L0;
354
            align_buf_data <= (others => '0');
355
            align_buf_ctrl <= (others => '0');
356
            align_res_data <= (others => '0');
357
            align_res_ctrl <= (others => '0');
358
            data_valid <= '0';
359
            sop_found <= '0';
360
 
361
         end if;
362
      end if;
363
   end process;
364
 
365
   -- Equalized signals
366
   rx_data_eq_inst : ssrl_bus
367
   generic map (rx_data'length, 4) port map (XGMII_RXCLK, crc_data_dd,rx_data_i);
368
   rx_be_eq_inst : ssrl_bus
369
   generic map (rx_be'length, 5) port map (XGMII_RXCLK, data_mask_dd, rx_be_i);
370
   rx_dv_eq_inst : ssrl
371
   generic map (4) port map (XGMII_RXCLK, crc_dv_dd, rx_dv_i);
372
   data_err_eq_inst : ssrl
373
   generic map (4) port map (XGMII_RXCLK, data_err, data_err_eq_m1);
374
 
375
 
376
 
377
 
378
 
379
--------------------------------------------------------------------------------
380
-- Process data
381
--------------------------------------------------------------------------------
382
 
383
 
384
 
385
 
386
   crc32_gen_inst: entity work.crc32_gen
387
   generic map (
388
      DATA_WIDTH => 64
389
   )
390
   port map(
391
      DI    => crc_data_dd,
392
      DI_DV => crc_dv_dd,
393
      EOP   => crc_eop_dd,
394
      MASK  => crc_mask_dd,
395
      CLK   => XGMII_RXCLK,
396
      RESET => RST,
397
      CRC   => crc32_result,
398
      DO_DV => crc_vld
399
   );
400
 
401
 
402
   crc32_result_n <= not crc32_result;
403
 
404
   -- Outputs assignment
405
 
406
   RX_DATA        <= rx_data_i;
407
   RX_DV          <= rx_dv_i;
408
   RX_BE          <= rx_be_i;
409
   RX_ERR         <= rx_err_i;
410
   RX_ERR_VALID   <= rx_err_valid_i;
411
 
412
end architecture;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.