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

Subversion Repositories udp_ip_stack

[/] [udp_ip_stack/] [trunk/] [rtl/] [vhdl/] [IPv4_RX.vhd] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 pjf
----------------------------------------------------------------------------------
2
-- Company: 
3
-- Engineer:            Peter Fall
4
-- 
5
-- Create Date:    16:20:42 06/01/2011 
6
-- Design Name: 
7
-- Module Name:    IPv4_RX - Behavioral 
8
-- Project Name: 
9
-- Target Devices: 
10
-- Tool versions: 
11
-- Description: 
12
--              handle simple IP RX
13
--              doesnt handle reassembly
14
--              checks and filters for IP protocol
15
--              checks and filters for IP addr
16
--              Handle IPv4 protocol
17
-- Dependencies: 
18
--
19
-- Revision: 
20
-- Revision 0.01 - File Created
21
-- Revision 0.02 - Improved error handling
22
-- Additional Comments: 
23
--
24
----------------------------------------------------------------------------------
25
library IEEE;
26
use IEEE.STD_LOGIC_1164.ALL;
27
use IEEE.NUMERIC_STD.ALL;
28
use work.axi.all;
29
use work.ipv4_types.all;
30
use work.arp_types.all;
31
 
32
entity IPv4_RX is
33
    Port (
34
                        -- IP Layer signals
35
                        ip_rx                                           : out ipv4_rx_type;
36
                        ip_rx_start                             : out std_logic;                                                                        -- indicates receipt of ip frame.
37
                        -- system signals
38
                        clk                                             : in  STD_LOGIC;                                                                        -- same clock used to clock mac data and ip data
39
                        reset                                   : in  STD_LOGIC;
40
                        our_ip_address          : in STD_LOGIC_VECTOR (31 downto 0);
41
                        rx_pkt_count                    : out STD_LOGIC_VECTOR(7 downto 0);                      -- number of IP pkts received for us
42
                        -- MAC layer RX signals
43
                        mac_data_in                     : in  STD_LOGIC_VECTOR (7 downto 0);             -- ethernet frame (from dst mac addr through to last byte of frame)
44
                        mac_data_in_valid       : in  STD_LOGIC;                                                                        -- indicates data_in valid on clock
45
                        mac_data_in_last                : in  STD_LOGIC                                                                 -- indicates last data in frame
46
                        );
47
end IPv4_RX;
48
 
49
architecture Behavioral of IPv4_RX is
50
 
51
        type rx_state_type is (IDLE, ETH_HDR, IP_HDR, USER_DATA, WAIT_END, ERR);
52
 
53
        type rx_event_type is (NO_EVENT,DATA);
54
        type count_mode_type is (RST, INCR, HOLD);
55
        type settable_count_mode_type is (RST, INCR, SET_VAL, HOLD);
56
        type set_clr_type is (SET, CLR, HOLD);
57
 
58
 
59
        -- state variables
60
        signal rx_state                         : rx_state_type;
61
        signal rx_count                         : unsigned (15 downto 0);
62
        signal src_ip                           : std_logic_vector (31 downto 0);        -- src IP captured from input
63
        signal protocol                 : std_logic_vector (7 downto 0);         -- src protocol captured from input
64
        signal data_len                 : std_logic_vector (15 downto 0);        -- src data length captured from input
65
        signal ip_rx_start_reg  : std_logic;                                                            -- indicates start of user data
66
        signal hdr_valid_reg            : std_logic;                                                            -- indicates that hdr data is valid
67
        signal frame_err_cnt            : unsigned (7 downto 0);                         -- number of frame errors
68
        signal error_code_reg   : std_logic_vector (3 downto 0);
69
        signal rx_pkt_counter   : unsigned (7 downto 0);                         -- number of rx frames received for us
70
 
71
        -- rx control signals
72
        signal next_rx_state    : rx_state_type;
73
        signal set_rx_state             : std_logic;
74
        signal rx_event                         : rx_event_type;
75
        signal rx_count_mode    : settable_count_mode_type;
76
        signal set_ip3                  : std_logic;
77
        signal set_ip2                  : std_logic;
78
        signal set_ip1                  : std_logic;
79
        signal set_ip0                  : std_logic;
80
        signal set_protocol             : std_logic;
81
        signal set_len_H                        : std_logic;
82
        signal set_len_L                        : std_logic;
83
        signal set_ip_rx_start  : set_clr_type;
84
        signal set_hdr_valid    : set_clr_type;
85
        signal set_frame_err_cnt: count_mode_type;
86
        signal dataval                  : std_logic_vector (7 downto 0);
87
        signal rx_count_val             : unsigned (15 downto 0);
88
        signal set_error_code   : std_logic;
89
        signal error_code_val   : std_logic_vector (3 downto 0);
90
        signal set_pkt_cnt              : count_mode_type;
91
        signal set_data_last            : std_logic;
92
 
93
 
94
-- IP datagram header format
95
--
96
--      0          4          8                      16      19             24                    31
97
--      --------------------------------------------------------------------------------------------
98
--      | Version  | *Header  |    Service Type      |        Total Length including header        |
99
--      |   (4)    |  Length  |     (ignored)        |                 (in bytes)                  |
100
--      --------------------------------------------------------------------------------------------
101
--      |           Identification                   | Flags |       Fragment Offset               |
102
--      |                                            |       |      (in 32 bit words)              |
103
--      --------------------------------------------------------------------------------------------
104
--      |    Time To Live     |       Protocol       |             Header Checksum                 |
105
--      |     (ignored)       |                      |                                             |
106
--      --------------------------------------------------------------------------------------------
107
--      |                                   Source IP Address                                      |
108
--      |                                                                                          |
109
--      --------------------------------------------------------------------------------------------
110
--      |                                 Destination IP Address                                   |
111
--      |                                                                                          |
112
--      --------------------------------------------------------------------------------------------
113
--      |                          Options (if any - ignored)               |       Padding        |
114
--      |                                                                   |      (if needed)     |
115
--      --------------------------------------------------------------------------------------------
116
--      |                                          Data                                            |
117
--      |                                                                                          |
118
--      --------------------------------------------------------------------------------------------
119
--      |                                          ....                                            |
120
--      |                                                                                          |
121
--      --------------------------------------------------------------------------------------------
122
--
123
-- * - in 32 bit words 
124
 
125
begin
126
 
127
        -----------------------------------------------------------------------
128
        -- combinatorial process to implement FSM and determine control signals
129
        -----------------------------------------------------------------------
130
 
131
        rx_combinatorial : process (
132
                -- input signals
133
                mac_data_in, mac_data_in_valid, mac_data_in_last, our_ip_address,
134
                -- state variables
135
                rx_state, rx_count, src_ip, protocol, data_len, ip_rx_start_reg, hdr_valid_reg, frame_err_cnt, error_code_reg, rx_pkt_counter,
136
                -- control signals
137
                next_rx_state, set_rx_state, rx_event, rx_count_mode,
138
                set_ip3, set_ip2, set_ip1, set_ip0, set_protocol, set_len_H, set_len_L,
139
                set_ip_rx_start, set_hdr_valid, set_frame_err_cnt, dataval, rx_count_val,
140
                set_error_code, error_code_val, set_pkt_cnt, set_data_last
141
                )
142
        begin
143
                -- set output followers
144
                ip_rx_start <= ip_rx_start_reg;
145
                ip_rx.hdr.is_valid <= hdr_valid_reg;
146
                ip_rx.hdr.protocol <= protocol;
147
                ip_rx.hdr.data_length <= data_len;
148
                ip_rx.hdr.src_ip_addr <= src_ip;
149
                ip_rx.hdr.num_frame_errors <= std_logic_vector(frame_err_cnt);
150
                ip_rx.hdr.last_error_code <= error_code_reg;
151
                rx_pkt_count <= STD_LOGIC_VECTOR(rx_pkt_counter);
152
 
153
                -- transfer data upstream if in user data phase
154
                if rx_state = USER_DATA then
155
                        ip_rx.data.data_in <= mac_data_in;
156
                        ip_rx.data.data_in_valid <= mac_data_in_valid;
157
                        ip_rx.data.data_in_last <= set_data_last;
158
                else
159
                        ip_rx.data.data_in <= (others => '0');
160
                        ip_rx.data.data_in_valid <= '0';
161
                        ip_rx.data.data_in_last <= '0';
162
                end if;
163
 
164
                -- set signal defaults
165
                next_rx_state <= IDLE;
166
                set_rx_state <= '0';
167
                rx_event <= NO_EVENT;
168
                rx_count_mode <= HOLD;
169
                set_ip3 <= '0';
170
                set_ip2 <= '0';
171
                set_ip1 <= '0';
172
                set_ip0 <= '0';
173
                set_protocol <= '0';
174
                set_len_H <= '0';
175
                set_len_L <= '0';
176
                set_ip_rx_start <= HOLD;
177
                set_hdr_valid <= HOLD;
178
                set_frame_err_cnt <= HOLD;
179
                rx_count_val <= x"0000";
180
                set_error_code  <= '0';
181
                error_code_val  <= RX_EC_NONE;
182
                set_pkt_cnt <= HOLD;
183
                dataval <= (others => '0');
184
                set_data_last <= '0';
185
 
186
                -- determine event (if any)
187
                if mac_data_in_valid = '1' then
188
                        rx_event <= DATA;
189
                        dataval <= mac_data_in;
190
                end if;
191
 
192
                -- RX FSM
193
                case rx_state is
194
                        when IDLE =>
195
                                rx_count_mode <= RST;
196
                                case rx_event is
197
                                        when NO_EVENT => -- (nothing to do)
198
                                        when DATA =>
199
                                                rx_count_mode <= INCR;
200
                                                set_hdr_valid <= CLR;
201
                                                next_rx_state <= ETH_HDR;
202
                                                set_rx_state <= '1';
203
                                end case;
204
 
205
                        when ETH_HDR =>
206
                                case rx_event is
207
                                        when NO_EVENT => -- (nothing to do)
208
                                        when DATA =>
209
                                                if rx_count = x"000d" then
210
                                                        rx_count_mode <= RST;
211
                                                        next_rx_state <= IP_HDR;
212
                                                        set_rx_state <= '1';
213
                                                else
214
                                                        rx_count_mode <= INCR;
215
                                                end if;
216
                                                -- handle early frame termination
217
                                                if mac_data_in_last = '1' then
218
                                                        error_code_val <= RX_EC_ET_ETH;
219
                                                        set_error_code <= '1';
220
                                                        set_frame_err_cnt <= INCR;
221
                                                        set_ip_rx_start <= CLR;
222
                                                        set_data_last <= '1';
223
                                                        next_rx_state <= IDLE;
224
                                                        set_rx_state <= '1';
225
                                                else
226
                                                        case rx_count is
227
                                                                when x"000c" =>
228
                                                                        if mac_data_in /= x"08" then                                    -- ignore pkts that are not type=IP
229
                                                                                next_rx_state <= WAIT_END;
230
                                                                                set_rx_state <= '1';
231
                                                                        end if;
232
 
233
                                                                when x"000d" =>
234
                                                                        if mac_data_in /= x"00" then                                    -- ignore pkts that are not type=IP
235
                                                                                next_rx_state <= WAIT_END;
236
                                                                                set_rx_state <= '1';
237
                                                                        end if;
238
 
239
                                                                when others => -- ignore other bytes in eth header
240
                                                        end case;
241
                                                end if;
242
                                end case;
243
 
244
                        when IP_HDR =>
245
                                case rx_event is
246
                                        when NO_EVENT => -- (nothing to do)
247
                                        when DATA =>
248
                                                if rx_count = x"0013" then
249
                                                        rx_count_val <= x"0001";                                                                        -- start counter at 1
250
                                                        rx_count_mode <= SET_VAL;
251
                                                else
252
                                                        rx_count_mode <= INCR;
253
                                                end if;
254
                                                -- handle early frame termination
255
                                                if mac_data_in_last = '1' then
256
                                                        error_code_val <= RX_EC_ET_IP;
257
                                                        set_error_code <= '1';
258
                                                        set_frame_err_cnt <= INCR;
259
                                                        set_ip_rx_start <= CLR;
260
                                                        set_data_last <= '1';
261
                                                        next_rx_state <= IDLE;
262
                                                        set_rx_state <= '1';
263
                                                else
264
                                                        case rx_count is
265
                                                                when x"0000" =>
266
                                                                        if mac_data_in /= x"45" then                                    -- ignore pkts that are not v4 with 5 header words
267
                                                                                next_rx_state <= WAIT_END;
268
                                                                                set_rx_state <= '1';
269
                                                                        end if;
270
 
271
                                                                when x"0002" => set_len_H <= '1';
272
                                                                when x"0003" => set_len_L <= '1';
273
 
274
                                                                when x"0006" =>
275
                                                                        if (mac_data_in(7) = '1') or (mac_data_in (4 downto 0) /= "00000") then
276
                                                                                -- ignore pkts that require reassembly (MF=1 or frag offst /= 0)
277
                                                                                next_rx_state <= WAIT_END;
278
                                                                                set_rx_state <= '1';
279
                                                                        end if;
280
 
281
                                                                when x"0007" =>
282
                                                                        if mac_data_in /= x"00" then                                    -- ignore pkts that require reassembly (frag offst /= 0)
283
                                                                                next_rx_state <= WAIT_END;
284
                                                                                set_rx_state <= '1';
285
                                                                        end if;
286
 
287
                                                                when x"0009" => set_protocol <= '1';
288
 
289
                                                                when x"000c" => set_ip3 <= '1';
290
                                                                when x"000d" => set_ip2 <= '1';
291
                                                                when x"000e" => set_ip1 <= '1';
292
                                                                when x"000f" => set_ip0 <= '1'; set_hdr_valid <= SET;   -- header values are now valid, although the pkt may not be for us
293
 
294
                                                                when x"0010" =>
295
                                                                        if mac_data_in /= our_ip_address(31 downto 24) then             -- ignore pkts that are not addressed to us
296
                                                                                next_rx_state <= WAIT_END;
297
                                                                                set_rx_state <= '1';
298
                                                                        end if;
299
 
300
                                                                when x"0011" =>
301
                                                                        if mac_data_in /= our_ip_address(23 downto 16) then             -- ignore pkts that are not addressed to us
302
                                                                                next_rx_state <= WAIT_END;
303
                                                                                set_rx_state <= '1';
304
                                                                        end if;
305
 
306
                                                                when x"0012" =>
307
                                                                        if mac_data_in /= our_ip_address(15 downto 8) then              -- ignore pkts that are not addressed to us
308
                                                                                next_rx_state <= WAIT_END;
309
                                                                                set_rx_state <= '1';
310
                                                                        end if;
311
 
312
                                                                when x"0013" =>
313
                                                                        if mac_data_in /= our_ip_address(7 downto 0) then                        -- ignore pkts that are not addressed to us
314
                                                                                next_rx_state <= WAIT_END;
315
                                                                                set_rx_state <= '1';
316
                                                                        else
317
                                                                                next_rx_state <= USER_DATA;
318
                                                                                set_pkt_cnt <= INCR;                                                                                            -- count another pkt
319
                                                                                set_rx_state <= '1';
320
                                                                                set_ip_rx_start <= SET;
321
                                                                        end if;
322
 
323
                                                                when others => -- ignore other bytes in ip header                                                                               
324
                                                        end case;
325
                                                end if;
326
                                end case;
327
 
328
                        when USER_DATA =>
329
                                case rx_event is
330
                                        when NO_EVENT => -- (nothing to do)
331
                                        when DATA =>
332
                                                -- note: data gets transfered upstream as part of "output followers" processing
333
                                                if rx_count = unsigned(data_len) then
334
                                                        set_ip_rx_start <= CLR;
335
                                                        rx_count_mode <= RST;
336
                                                        set_data_last <= '1';
337
                                                        if mac_data_in_last = '1' then
338
                                                                next_rx_state <= IDLE;
339
                                                                set_ip_rx_start <= CLR;
340
                                                        else
341
                                                                next_rx_state <= WAIT_END;
342
                                                        end if;
343
                                                        set_rx_state <= '1';
344
                                                else
345
                                                        rx_count_mode <= INCR;
346
                                                        -- check for early frame termination
347
                                                        if mac_data_in_last = '1' then
348
                                                                error_code_val <= RX_EC_ET_USER;
349
                                                                set_error_code <= '1';
350
                                                                set_frame_err_cnt <= INCR;
351
                                                                set_ip_rx_start <= CLR;
352
                                                                next_rx_state <= IDLE;
353
                                                                set_rx_state <= '1';
354
                                                        end if;
355
                                                end if;
356
                                end case;
357
 
358
                        when ERR =>
359
                                set_frame_err_cnt <= INCR;
360
                                set_ip_rx_start <= CLR;
361
                                if mac_data_in_last = '0' then
362
                                        set_data_last <= '1';
363
                                        next_rx_state <= WAIT_END;
364
                                        set_rx_state <= '1';
365
                                else
366
                                        next_rx_state <= IDLE;
367
                                        set_rx_state <= '1';
368
                                end if;
369
 
370
 
371
                        when WAIT_END =>
372
                                case rx_event is
373
                                        when NO_EVENT => -- (nothing to do)
374
                                        when DATA =>
375
                                                if mac_data_in_last = '1' then
376
                                                        set_data_last <= '1';
377
                                                        next_rx_state <= IDLE;
378
                                                        set_rx_state <= '1';
379
                                                        set_ip_rx_start <= CLR;
380
                                                end if;
381
                                end case;
382
 
383
                end case;
384
 
385
        end process;
386
 
387
 
388
        -----------------------------------------------------------------------------
389
        -- sequential process to action control signals and change states and outputs
390
        -----------------------------------------------------------------------------
391
 
392
        rx_sequential : process (clk,reset)
393
        begin
394
                if rising_edge(clk) then
395
                        if reset = '1' then
396
                                -- reset state variables
397
                                rx_state <= IDLE;
398
                                rx_count <= x"0000";
399
                                src_ip <= (others => '0');
400
                                protocol <= (others => '0');
401
                                data_len <= (others => '0');
402
                                ip_rx_start_reg <= '0';
403
                                hdr_valid_reg <= '0';
404
                                frame_err_cnt <= (others => '0');
405
                                error_code_reg <= RX_EC_NONE;
406
                                rx_pkt_counter <= x"00";
407
 
408
                        else
409
                                -- Next rx_state processing
410
                                if set_rx_state = '1' then
411
                                        rx_state <= next_rx_state;
412
                                else
413
                                        rx_state <= rx_state;
414
                                end if;
415
 
416
                                -- rx_count processing
417
                                case rx_count_mode is
418
                                        when RST =>             rx_count <= x"0000";
419
                                        when INCR =>            rx_count <= rx_count + 1;
420
                                        when SET_VAL =>         rx_count <= rx_count_val;
421
                                        when HOLD =>            rx_count <= rx_count;
422
                                end case;
423
 
424
                                -- frame error count processing
425
                                case set_frame_err_cnt is
426
                                        when RST =>  frame_err_cnt <= x"00";
427
                                        when INCR => frame_err_cnt <= frame_err_cnt + 1;
428
                                        when HOLD => frame_err_cnt <= frame_err_cnt;
429
                                end case;
430
 
431
                                -- ip pkt processing
432
                                case set_pkt_cnt is
433
                                        when RST =>  rx_pkt_counter <= x"00";
434
                                        when INCR => rx_pkt_counter <= rx_pkt_counter + 1;
435
                                        when HOLD => rx_pkt_counter <= rx_pkt_counter;
436
                                end case;
437
 
438
                                -- source ip capture
439
                                if (set_ip3 = '1') then src_ip(31 downto 24) <= dataval; end if;
440
                                if (set_ip2 = '1') then src_ip(23 downto 16) <= dataval; end if;
441
                                if (set_ip1 = '1') then src_ip(15 downto 8) <= dataval; end if;
442
                                if (set_ip0 = '1') then src_ip(7 downto 0) <= dataval; end if;
443
 
444
                                if (set_protocol = '1') then
445
                                        protocol <= dataval;
446
                                else
447
                                        protocol <= protocol;
448
                                end if;
449
 
450
                                if (set_len_H = '1') then
451
                                        data_len (15 downto 8) <= dataval;
452
                                        data_len (7 downto 0) <= x"00";
453
                                elsif (set_len_L = '1') then
454
                                        -- compute data length, taking into account that we need to subtract the header length
455
                                        data_len <= std_logic_vector(unsigned(data_len(15 downto 8) & dataval) - 20);
456
                                else
457
                                        data_len <= data_len;
458
                                end if;
459
 
460
                                case set_ip_rx_start is
461
                                        when SET => ip_rx_start_reg <= '1';
462
                                        when CLR => ip_rx_start_reg <= '0';
463
                                        when HOLD => ip_rx_start_reg <= ip_rx_start_reg;
464
                                end case;
465
 
466
                                case set_hdr_valid is
467
                                        when SET => hdr_valid_reg <= '1';
468
                                        when CLR => hdr_valid_reg <= '0';
469
                                        when HOLD => hdr_valid_reg <= hdr_valid_reg;
470
                                end case;
471
 
472
                                -- set error code
473
                                if set_error_code       = '1' then
474
                                        error_code_reg <= error_code_val;
475
                                else
476
                                        error_code_reg <= error_code_reg;
477
                                end if;
478
                        end if;
479
                end if;
480
        end process;
481
 
482
end Behavioral;
483
 

powered by: WebSVN 2.1.0

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