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 19

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

Line No. Rev Author Line
1 18 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 2 pjf
 
28 18 pjf
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 2 pjf
-- IP datagram header format
82
--
83 18 pjf
--      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 2 pjf
 
98
 
99 18 pjf
begin
100 2 pjf
 
101 18 pjf
  -----------------------------------------------------------------------
102
  -- combinatorial process to implement FSM and determine control signals
103
  -----------------------------------------------------------------------
104 2 pjf
 
105 18 pjf
  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 2 pjf
 
124 18 pjf
    -- 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 2 pjf
 
135 18 pjf
    -- 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.