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

Subversion Repositories udp_ip_stack

[/] [udp_ip_stack/] [trunk/] [rtl/] [vhdl/] [UDP_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:    5 June 2011 
6
-- Design Name: 
7
-- Module Name:    UDP_RX - Behavioral 
8
-- Project Name: 
9
-- Target Devices: 
10
-- Tool versions: 
11
-- Description: 
12
--              handle simple UDP RX
13
--              doesnt check the checsum
14
-- Dependencies: 
15
--
16
-- Revision: 
17
-- Revision 0.01 - File Created
18
-- Revision 0.02 - Improved error handling
19
-- Additional Comments: 
20
--
21
----------------------------------------------------------------------------------
22
library IEEE;
23
use IEEE.STD_LOGIC_1164.ALL;
24
use IEEE.NUMERIC_STD.ALL;
25
use work.axi.all;
26
use work.ipv4_types.all;
27
 
28
entity UDP_RX is
29
    Port (
30
                        -- UDP Layer signals
31
                        udp_rx_start                    : out std_logic;                                                        -- indicates receipt of udp header
32
                        udp_rxo                                 : out udp_rx_type;
33
                        -- system signals
34
                        clk                                             : in  STD_LOGIC;
35
                        reset                                   : in  STD_LOGIC;
36
                        -- IP layer RX signals
37
                        ip_rx_start                             : in std_logic;                                                 -- indicates receipt of ip header
38
                        ip_rx                                           : in ipv4_rx_type
39
                        );
40
end UDP_RX;
41
 
42
architecture Behavioral of UDP_RX is
43
 
44
        type rx_state_type is (IDLE, UDP_HDR, USER_DATA, WAIT_END, ERR);
45
 
46
        type rx_event_type is (NO_EVENT,DATA);
47
        type count_mode_type is (RST, INCR, HOLD);
48
        type settable_count_mode_type is (RST, INCR, SET_VAL, HOLD);
49
        type set_clr_type is (SET, CLR, HOLD);
50
 
51
 
52
        -- state variables
53
        signal rx_state                         : rx_state_type;
54
        signal rx_count                         : unsigned (15 downto 0);
55
        signal src_port                 : std_logic_vector (15 downto 0);        -- src port captured from input
56
        signal dst_port                 : std_logic_vector (15 downto 0);        -- dst port captured from input
57
        signal data_len                 : std_logic_vector (15 downto 0);        -- user data length captured from input
58
        signal udp_rx_start_reg : std_logic;                                                            -- indicates start of user data
59
        signal hdr_valid_reg            : std_logic;                                                            -- indicates that hdr data is valid
60
        signal src_ip_addr              : std_logic_vector (31 downto 0);        -- captured from IP hdr
61
 
62
        -- rx control signals
63
        signal next_rx_state    : rx_state_type;
64
        signal set_rx_state             : std_logic;
65
        signal rx_event                         : rx_event_type;
66
        signal rx_count_mode    : settable_count_mode_type;
67
        signal rx_count_val             : unsigned (15 downto 0);
68
        signal set_sph                  : std_logic;
69
        signal set_spl                  : std_logic;
70
        signal set_dph                  : std_logic;
71
        signal set_dpl                  : std_logic;
72
        signal set_len_H                        : std_logic;
73
        signal set_len_L                        : std_logic;
74
        signal set_udp_rx_start : set_clr_type;
75
        signal set_hdr_valid    : set_clr_type;
76
        signal dataval                  : std_logic_vector (7 downto 0);
77
        signal set_pkt_cnt              : count_mode_type;
78
        signal set_src_ip                       : std_logic;
79
        signal set_data_last            : std_logic;
80
 
81
-- IP datagram header format
82
--
83
--      0          4          8                      16      19             24                    31
84
--      --------------------------------------------------------------------------------------------
85
--      |              source port number            |              dest port number               |
86
--      |                                            |                                             |
87
--      --------------------------------------------------------------------------------------------
88
--      |                length (bytes)              |                checksum                     |
89
--      |          (header and data combined)        |                                             |
90
--      --------------------------------------------------------------------------------------------
91
--      |                                          Data                                            |
92
--      |                                                                                          |
93
--      --------------------------------------------------------------------------------------------
94
--      |                                          ....                                            |
95
--      |                                                                                          |
96
--      --------------------------------------------------------------------------------------------
97
 
98
 
99
begin
100
 
101
        -----------------------------------------------------------------------
102
        -- combinatorial process to implement FSM and determine control signals
103
        -----------------------------------------------------------------------
104
 
105
        rx_combinatorial : process (
106
                -- input signals
107
                ip_rx, ip_rx_start,
108
                -- state variables
109
                rx_state, rx_count, src_port, dst_port, data_len, udp_rx_start_reg, hdr_valid_reg, src_ip_addr,
110
                -- control signals
111
                next_rx_state, set_rx_state, rx_event, rx_count_mode, rx_count_val,
112
                set_sph, set_spl, set_dph, set_dpl, set_len_H, set_len_L, set_data_last,
113
                set_udp_rx_start, set_hdr_valid, dataval, set_pkt_cnt, set_src_ip
114
                )
115
        begin
116
                -- set output followers
117
                udp_rx_start <= udp_rx_start_reg;
118
                udp_rxo.hdr.is_valid <= hdr_valid_reg;
119
                udp_rxo.hdr.data_length <= data_len;
120
                udp_rxo.hdr.src_port <= src_port;
121
                udp_rxo.hdr.dst_port <= dst_port;
122
                udp_rxo.hdr.src_ip_addr <= src_ip_addr;
123
 
124
                -- transfer data upstream if in user data phase
125
                if rx_state = USER_DATA then
126
                        udp_rxo.data.data_in <= ip_rx.data.data_in;
127
                        udp_rxo.data.data_in_valid <= ip_rx.data.data_in_valid;
128
                        udp_rxo.data.data_in_last <= set_data_last;
129
                else
130
                        udp_rxo.data.data_in <= (others => '0');
131
                        udp_rxo.data.data_in_valid <= '0';
132
                        udp_rxo.data.data_in_last <= '0';
133
                end if;
134
 
135
                -- set signal defaults
136
                next_rx_state <= IDLE;
137
                set_rx_state <= '0';
138
                rx_event <= NO_EVENT;
139
                rx_count_mode <= HOLD;
140
                set_sph <= '0';
141
                set_spl <= '0';
142
                set_dph <= '0';
143
                set_dpl <= '0';
144
                set_len_H <= '0';
145
                set_len_L <= '0';
146
                set_udp_rx_start <= HOLD;
147
                set_hdr_valid <= HOLD;
148
                dataval <= (others => '0');
149
                set_src_ip <= '0';
150
                rx_count_val <= (others => '0');
151
                set_data_last <= '0';
152
 
153
                -- determine event (if any)
154
                if ip_rx.data.data_in_valid = '1' then
155
                        rx_event <= DATA;
156
                        dataval <= ip_rx.data.data_in;
157
                end if;
158
 
159
                -- RX FSM
160
                case rx_state is
161
                        when IDLE =>
162
                                rx_count_mode <= RST;
163
                                case rx_event is
164
                                        when NO_EVENT => -- (nothing to do)
165
                                        when DATA =>
166
                                                if ip_rx.hdr.protocol = x"11" then
167
                                                        -- UDP protocol
168
                                                        rx_count_mode <= INCR;
169
                                                        set_hdr_valid <= CLR;
170
                                                        set_src_ip <= '1';
171
                                                        set_sph <= '1';
172
                                                        next_rx_state <= UDP_HDR;
173
                                                        set_rx_state <= '1';
174
                                                else
175
                                                        -- non-UDP protocol - ignore this pkt
176
                                                        set_hdr_valid <= CLR;
177
                                                        next_rx_state <= WAIT_END;
178
                                                        set_rx_state <= '1';
179
                                                end if;
180
                                end case;
181
 
182
                        when UDP_HDR =>
183
                                case rx_event is
184
                                        when NO_EVENT => -- (nothing to do)
185
                                        when DATA =>
186
                                                if rx_count = x"0007" then
187
                                                        rx_count_mode <= SET_VAL;
188
                                                        rx_count_val <= x"0001";
189
                                                        next_rx_state <= USER_DATA;
190
                                                        set_rx_state <= '1';
191
                                                else
192
                                                        rx_count_mode <= INCR;
193
                                                end if;
194
                                                -- handle early frame termination
195
                                                if ip_rx.data.data_in_last = '1' then
196
                                                        next_rx_state <= ERR;
197
                                                        set_rx_state <= '1';
198
                                                else
199
                                                        case rx_count is
200
                                                                when x"0000" => set_sph <= '1';
201
                                                                when x"0001" => set_spl <= '1';
202
                                                                when x"0002" => set_dph <= '1';
203
                                                                when x"0003" => set_dpl <= '1';
204
 
205
                                                                when x"0004" => set_len_H <= '1';
206
                                                                when x"0005" => set_len_L <= '1'; set_hdr_valid <= SET; -- header values are now valid, although the pkt may not be for us
207
 
208
                                                                when x"0006" => -- ignore checksum values
209
                                                                when x"0007" => set_udp_rx_start <= SET;                -- indicate frame received
210
 
211
 
212
                                                                when others => -- ignore other bytes in udp header                                                                              
213
                                                        end case;
214
                                                end if;
215
                                end case;
216
 
217
                        when USER_DATA =>
218
                                case rx_event is
219
                                        when NO_EVENT => -- (nothing to do)
220
                                        when DATA =>
221
                                                -- note: data gets transfered upstream as part of "output followers" processing
222
                                                if rx_count = unsigned(data_len) then
223
                                                        set_udp_rx_start <= CLR;
224
                                                        rx_count_mode <= RST;
225
                                                        set_data_last <= '1';
226
                                                        if ip_rx.data.data_in_last = '1' then
227
                                                                next_rx_state <= IDLE;
228
                                                                set_udp_rx_start <= CLR;
229
                                                        else
230
                                                                next_rx_state <= WAIT_END;
231
                                                        end if;
232
                                                        set_rx_state <= '1';
233
                                                else
234
                                                        rx_count_mode <= INCR;
235
                                                        -- check for early frame termination
236
                                                        -- TODO need to mark frame as errored
237
                                                        if ip_rx.data.data_in_last = '1' then
238
                                                                next_rx_state <= IDLE;
239
                                                                set_rx_state <= '1';
240
                                                                set_data_last <= '1';
241
                                                        end if;
242
                                                end if;
243
                                end case;
244
 
245
                        when ERR =>
246
                                if ip_rx.data.data_in_last = '0' then
247
                                        next_rx_state <= WAIT_END;
248
                                        set_rx_state <= '1';
249
                                else
250
                                        next_rx_state <= IDLE;
251
                                        set_rx_state <= '1';
252
                                end if;
253
 
254
 
255
                        when WAIT_END =>
256
                                case rx_event is
257
                                        when NO_EVENT => -- (nothing to do)
258
                                        when DATA =>
259
                                                if ip_rx.data.data_in_last = '1' then
260
                                                        next_rx_state <= IDLE;
261
                                                        set_rx_state <= '1';
262
                                                end if;
263
                                end case;
264
 
265
                end case;
266
 
267
        end process;
268
 
269
 
270
        -----------------------------------------------------------------------------
271
        -- sequential process to action control signals and change states and outputs
272
        -----------------------------------------------------------------------------
273
 
274
        rx_sequential : process (clk,reset)
275
        begin
276
                if rising_edge(clk) then
277
                        if reset = '1' then
278
                                -- reset state variables
279
                                rx_state <= IDLE;
280
                                rx_count <= x"0000";
281
                                src_port <= (others => '0');
282
                                dst_port <= (others => '0');
283
                                data_len <= (others => '0');
284
                                udp_rx_start_reg <= '0';
285
                                hdr_valid_reg <= '0';
286
                                src_ip_addr <= (others => '0');
287
                        else
288
                                -- Next rx_state processing
289
                                if set_rx_state = '1' then
290
                                        rx_state <= next_rx_state;
291
                                else
292
                                        rx_state <= rx_state;
293
                                end if;
294
 
295
                                -- rx_count processing
296
                                case rx_count_mode is
297
                                        when RST =>             rx_count <= x"0000";
298
                                        when INCR =>            rx_count <= rx_count + 1;
299
                                        when SET_VAL => rx_count <= rx_count_val;
300
                                        when HOLD =>            rx_count <= rx_count;
301
                                end case;
302
 
303
                                -- port number capture
304
                                if (set_sph = '1') then src_port(15 downto 8) <= dataval; end if;
305
                                if (set_spl = '1') then src_port(7 downto 0) <= dataval; end if;
306
                                if (set_dph = '1') then dst_port(15 downto 8) <= dataval; end if;
307
                                if (set_dpl = '1') then dst_port(7 downto 0) <= dataval; end if;
308
 
309
                                if (set_len_H = '1') then
310
                                        data_len (15 downto 8) <= dataval;
311
                                        data_len (7 downto 0) <= x"00";
312
                                elsif (set_len_L = '1') then
313
                                        -- compute data length, taking into account that we need to subtract the header length
314
                                        data_len <= std_logic_vector(unsigned(data_len(15 downto 8) & dataval) - 8);
315
                                else
316
                                        data_len <= data_len;
317
                                end if;
318
 
319
                                case set_udp_rx_start is
320
                                        when SET => udp_rx_start_reg <= '1';
321
                                        when CLR => udp_rx_start_reg <= '0';
322
                                        when HOLD => udp_rx_start_reg <= udp_rx_start_reg;
323
                                end case;
324
 
325
                                -- capture src IP address
326
                                if set_src_ip = '1' then
327
                                        src_ip_addr <= ip_rx.hdr.src_ip_addr;
328
                                else
329
                                        src_ip_addr <= src_ip_addr;
330
                                end if;
331
 
332
                                case set_hdr_valid is
333
                                        when SET => hdr_valid_reg <= '1';
334
                                        when CLR => hdr_valid_reg <= '0';
335
                                        when HOLD => hdr_valid_reg <= hdr_valid_reg;
336
                                end case;
337
 
338
                        end if;
339
                end if;
340
        end process;
341
 
342
end Behavioral;
343
 

powered by: WebSVN 2.1.0

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