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

Subversion Repositories udp_ip_stack

[/] [udp_ip_stack/] [trunk/] [rtl/] [vhdl/] [arp_RX.vhd] - Blame information for rev 14

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

Line No. Rev Author Line
1 10 pjf
----------------------------------------------------------------------------------
2
-- Company: 
3
-- Engineer:            Peter Fall
4
-- 
5
-- Create Date:    12:00:04 05/31/2011 
6
-- Design Name: 
7
-- Module Name:    arp_rx - Behavioral 
8
-- Project Name: 
9
-- Target Devices: 
10
-- Tool versions: 
11
-- Description:
12
--              handle receipt of arp pkt
13
--              ignores other types of pkt
14
--
15
--              When it receives an ARP pkt that is either addressed to our IP or is a global request,
16
--              it outputs for a single clock cycle either recv_who_has or recv_I_have along
17
--              with associated mac or arp entry data.
18
--
19
--              Note that if recv who_has and we have it, then we also assert I_have so that we can cache the rev lookup
20
--              on the expectation that we will want to reply to this host.
21
--
22
-- Dependencies: 
23
--
24
-- Revision: 
25
-- Revision 0.01 - File Created - refactored from arp v0.02 module
26
-- Additional Comments: 
27
--
28
----------------------------------------------------------------------------------
29
library IEEE;
30
use IEEE.STD_LOGIC_1164.ALL;
31
use IEEE.NUMERIC_STD.ALL;
32
use work.arp_types.all;
33
 
34
entity arp_rx is
35
    Port (
36
                        -- MAC layer RX signals
37
                        data_in                                 : in  STD_LOGIC_VECTOR (7 downto 0);             -- ethernet frame (from dst mac addr through to last byte of frame)
38
                        data_in_valid           : in  STD_LOGIC;                                                                        -- indicates data_in valid on clock
39
                        data_in_last            : in  STD_LOGIC;                                                                        -- indicates last data in frame
40
                        -- ARP output signals
41
                        recv_who_has            : out std_logic;                                                                        -- pulse will be latched
42
                        arp_entry_for_who_has   : out arp_entry_t;                                              -- target for who_has msg (Iie, who to reply to)
43
                        recv_I_have                     : out std_logic;                                                                        -- pulse will be latched
44
                        arp_entry_for_I_have    : out arp_entry_t;                                                      -- arp target for I_have msg
45
                        -- control and status signals
46
                        req_count                       : out STD_LOGIC_VECTOR(7 downto 0);                      -- count of arp pkts received
47
                        -- system signals
48
                        our_ip_address  : in STD_LOGIC_VECTOR (31 downto 0);
49
                        rx_clk                          : in std_logic;
50
                        reset                           : in  STD_LOGIC
51
                        );
52
end arp_rx;
53
 
54
 
55
architecture Behavioral of arp_rx is
56
 
57
        type rx_state_t is (IDLE,PARSE,PROCESS_ARP,WAIT_END);
58
        type rx_event_t is (NO_EVENT,DATA);
59
        type count_mode_t is (RST,INCR,HOLD);
60
        type arp_oper_t is (NOP,REQUEST,REPLY);
61
 
62
        type tx_state_type is (IDLE,WAIT_MAC,SEND);
63
 
64
        -- state variables
65
        signal send_request_needed              : std_logic;
66
        signal tx_mac_chn_reqd  : std_logic;
67
 
68
        signal rx_state                         : rx_state_t;
69
        signal rx_count                         : unsigned (7 downto 0);
70
        signal arp_operation            : arp_oper_t;
71
        signal arp_req_count            : unsigned (7 downto 0);
72
        signal new_arp_entry            : arp_entry_t;
73
 
74
-- FIXME        - remove these debug state signals
75
        signal arp_err_data             : std_logic_vector (7 downto 0);
76
        signal set_err_data             : std_logic;
77
 
78
  attribute keep : string;
79
  attribute keep of arp_err_data             : signal is "true";
80
 
81
 
82
        -- rx control signals
83
        signal next_rx_state    : rx_state_t;
84
        signal set_rx_state             : std_logic;
85
        signal rx_event                         : rx_event_t;
86
        signal rx_count_mode    : count_mode_t;
87
        signal set_arp_oper             : std_logic;
88
        signal arp_oper_set_val : arp_oper_t;
89
        signal dataval                  : std_logic_vector (7 downto 0);
90
        signal count_arp_rcvd   : std_logic;
91
 
92
        signal set_mac5                         : std_logic;
93
        signal set_mac4                         : std_logic;
94
        signal set_mac3                         : std_logic;
95
        signal set_mac2                         : std_logic;
96
        signal set_mac1                         : std_logic;
97
        signal set_mac0                         : std_logic;
98
 
99
        signal set_ip3                  : std_logic;
100
        signal set_ip2                  : std_logic;
101
        signal set_ip1                  : std_logic;
102
        signal set_ip0                  : std_logic;
103
 
104
 
105
 
106
        -- function to determine whether the rx pkt is an arp pkt and whether we want to process it
107
        -- Returns 1 if we should discard
108
        -- The following will make us ignore the frame (all values hexadecimal):
109
        -- PDU type /= 0806
110
        -- Protocol Type /= 0800
111
        -- Hardware Type /= 1
112
        -- Hardware Length /= 6
113
        -- Protocol Length /= 4
114
        -- Operation /= 1 or 2
115
        -- Target IP /= our IP (i.er. message is not meant for us)
116
        --
117
        function not_our_arp(data : STD_LOGIC_VECTOR; count : unsigned; our_ip : std_logic_vector) return std_logic is
118
        begin
119
                if
120
                        (count = 12 and data /= x"08") or                                               -- PDU type 0806 : ARP
121
                        (count = 13 and data /= x"06") or
122
                        (count = 14 and data /= x"00") or                                               -- HW type 1 : eth
123
                        (count = 15 and data /= x"01") or
124
                        (count = 16 and data /= x"08") or                                               -- Protocol 0800 : IP
125
                        (count = 17 and data /= x"00") or
126
                        (count = 18 and data /= x"06") or                                               -- HW Length 6
127
                        (count = 19 and data /= x"04") or                                               -- protocol length 4
128
                        (count = 20 and data /= x"00") or                                               -- operation 1 or 2 (req or reply)
129
                        (count = 21 and data /= x"01" and data /= x"02") or
130
                        (count = 38 and data /= our_ip(31 downto 24)) or        -- target IP is ours
131
                        (count = 39 and data /= our_ip(23 downto 16)) or
132
                        (count = 40 and data /= our_ip(15 downto 8)) or
133
                        (count = 41 and data /= our_ip(7 downto 0))
134
                then
135
                        return '1';
136
                else
137
                        return '0';
138
                end if;
139
        end function not_our_arp;
140
 
141
begin
142
 
143
        rx_combinatorial : process (
144
                -- input signals
145
                data_in, data_in_valid, data_in_last, our_ip_address,
146
                -- state variables
147
                rx_state, rx_count, arp_operation, arp_req_count, arp_err_data, new_arp_entry,
148
                -- control signals
149
                next_rx_state, set_rx_state, rx_event, rx_count_mode, set_arp_oper, arp_oper_set_val,
150
                dataval,set_mac5,set_mac4,set_mac3,set_mac2,set_mac1,set_mac0,set_ip3,set_ip2,set_ip1,set_ip0, set_err_data,
151
                count_arp_rcvd
152
                )
153
        begin
154
                -- set output followers
155
                req_count <= STD_LOGIC_VECTOR(arp_req_count);
156
 
157
                -- set defaults for combinatorial outputs
158
                recv_who_has <= '0';
159
                arp_entry_for_who_has.ip <= (others => '0');
160
                arp_entry_for_who_has.mac <= (others => '0');
161
                recv_I_have <= '0';
162
                arp_entry_for_I_have.ip <= (others => '0');
163
                arp_entry_for_I_have.mac <= (others => '0');
164
 
165
                -- set signal defaults
166
                next_rx_state <= IDLE;
167
                set_rx_state <= '0';
168
                rx_event <= NO_EVENT;
169
                rx_count_mode <= HOLD;
170
                set_arp_oper <= '0';
171
                arp_oper_set_val <= NOP;
172
                dataval <= (others => '0');
173
                set_mac5 <= '0';
174
                set_mac4 <= '0';
175
                set_mac3 <= '0';
176
                set_mac2 <= '0';
177
                set_mac1 <= '0';
178
                set_mac0 <= '0';
179
                set_ip3 <= '0';
180
                set_ip2 <= '0';
181
                set_ip1 <= '0';
182
                set_ip0 <= '0';
183
                count_arp_rcvd <= '0';
184
                set_err_data <= '0';
185
 
186
                -- determine event (if any)
187
                if data_in_valid = '1' then
188
                        rx_event <= DATA;
189
                end if;
190
 
191
                -- RX FSM
192
                case rx_state is
193
                        when IDLE =>
194
                                rx_count_mode <= RST;
195
                                case rx_event is
196
                                        when NO_EVENT => -- (nothing to do)
197
                                        when DATA =>
198
                                                next_rx_state <= PARSE;
199
                                                set_rx_state <= '1';
200
                                                rx_count_mode <= INCR;
201
                                end case;
202
 
203
                        when PARSE =>
204
                                case rx_event is
205
                                        when NO_EVENT => -- (nothing to do)
206
                                        when DATA =>
207
                                                rx_count_mode <= INCR;
208
                                                -- handle early frame termination
209
                                                if data_in_last = '1' then
210
                                                        next_rx_state <= IDLE;
211
                                                        set_rx_state <= '1';
212
                                                else
213
                                                        -- check for end of frame. Also, detect and discard if not our frame
214
                                                        if rx_count = 42 then
215
                                                                next_rx_state <= PROCESS_ARP;
216
                                                                set_rx_state <= '1';
217
                                                        elsif not_our_arp(data_in,rx_count,our_ip_address) = '1' then
218
                                                                dataval <= data_in;
219
                                                                set_err_data <= '1';
220
                                                                next_rx_state <= WAIT_END;
221
                                                                set_rx_state <= '1';
222
                                                        elsif rx_count = 21 then
223
                                                                -- capture ARP operation
224
                                                                case data_in is
225
                                                                        when x"01" =>
226
                                                                                arp_oper_set_val <= REQUEST;
227
                                                                                set_arp_oper <= '1';
228
                                                                        when x"02" =>
229
                                                                                arp_oper_set_val <= REPLY;
230
                                                                                set_arp_oper <= '1';
231
                                                                        when others =>  -- ignore other values
232
                                                                end case;
233
                                                        -- capture source mac addr
234
                                                        elsif rx_count = 22 then
235
                                                                set_mac5 <= '1';
236
                                                                dataval <= data_in;
237
                                                        elsif rx_count = 23 then
238
                                                                set_mac4 <= '1';
239
                                                                dataval <= data_in;
240
                                                        elsif rx_count = 24 then
241
                                                                set_mac3 <= '1';
242
                                                                dataval <= data_in;
243
                                                        elsif rx_count = 25 then
244
                                                                set_mac2 <= '1';
245
                                                                dataval <= data_in;
246
                                                        elsif rx_count = 26 then
247
                                                                set_mac1 <= '1';
248
                                                                dataval <= data_in;
249
                                                        elsif rx_count = 27 then
250
                                                                set_mac0 <= '1';
251
                                                                dataval <= data_in;
252
                                                        -- capture source ip addr
253
                                                        elsif rx_count = 28 then
254
                                                                set_ip3 <= '1';
255
                                                                dataval <= data_in;
256
                                                        elsif rx_count = 29 then
257
                                                                set_ip2 <= '1';
258
                                                                dataval <= data_in;
259
                                                        elsif rx_count = 30 then
260
                                                                set_ip1 <= '1';
261
                                                                dataval <= data_in;
262
                                                        elsif rx_count = 31 then
263
                                                                set_ip0 <= '1';
264
                                                                dataval <= data_in;
265
                                                        end if;
266
                                                end if;
267
                                end case;
268
 
269
                        when PROCESS_ARP =>
270
                                next_rx_state <= WAIT_END;
271
                                set_rx_state <= '1';
272
                                arp_oper_set_val <= NOP;
273
                                set_arp_oper <= '1';
274
                                case arp_operation is
275
                                        when NOP => -- (nothing to do)
276
                                        when REQUEST =>
277
                                                        count_arp_rcvd <= '1';
278
                                                        recv_who_has <= '1';
279
                                                        arp_entry_for_who_has <= new_arp_entry;
280
                                                        -- setting I_Have as well allows us to cache the remote node's entry immediately
281
                                                        recv_I_have <= '1';
282
                                                        arp_entry_for_I_have    <= new_arp_entry;
283
                                        when REPLY =>
284
                                                        count_arp_rcvd <= '1';
285
                                                        recv_I_have <= '1';
286
                                                        arp_entry_for_I_have    <= new_arp_entry;
287
                                end case;
288
 
289
                        when WAIT_END =>
290
                                case rx_event is
291
                                        when NO_EVENT => -- (nothing to do)
292
                                        when DATA =>
293
                                                if data_in_last = '1' then
294
                                                        next_rx_state <= IDLE;
295
                                                        set_rx_state <= '1';
296
                                                end if;
297
                                end case;
298
 
299
                end case;
300
 
301
        end process;
302
 
303
        rx_sequential : process (rx_clk)
304
        begin
305
                if rising_edge(rx_clk) then
306
                        if reset = '1' then
307
                                -- reset state variables
308
                                rx_state <= IDLE;
309
                                rx_count <= x"00";
310
                                arp_operation <= NOP;
311
                                arp_req_count <= x"00";
312
                                arp_err_data <= (others => '0');
313
                        else
314
                                -- Next rx_state processing
315
                                if set_rx_state = '1' then
316
                                        rx_state <= next_rx_state;
317
                                else
318
                                        rx_state <= rx_state;
319
                                end if;
320
 
321
                                -- rx_count processing
322
                                case rx_count_mode is
323
                                        when RST =>
324
                                                rx_count <= x"00";
325
                                        when INCR =>
326
                                                rx_count <= rx_count + 1;
327
                                        when HOLD =>
328
                                                rx_count <= rx_count;
329
                                end case;
330
 
331
                                -- err data
332
                                if set_err_data = '1' then
333
                                        arp_err_data <= data_in;
334
                                else
335
                                        arp_err_data <= arp_err_data;
336
                                end if;
337
 
338
                                -- arp operation processing
339
                                if set_arp_oper = '1' then
340
                                        arp_operation <= arp_oper_set_val;
341
                                else
342
                                        arp_operation <= arp_operation;
343
                                end if;
344
 
345
                                -- source mac capture
346
                                if (set_mac5 = '1') then new_arp_entry.mac(47 downto 40) <= dataval; end if;
347
                                if (set_mac4 = '1') then new_arp_entry.mac(39 downto 32) <= dataval; end if;
348
                                if (set_mac3 = '1') then new_arp_entry.mac(31 downto 24) <= dataval; end if;
349
                                if (set_mac2 = '1') then new_arp_entry.mac(23 downto 16) <= dataval; end if;
350
                                if (set_mac1 = '1') then new_arp_entry.mac(15 downto 8) <= dataval; end if;
351
                                if (set_mac0 = '1') then new_arp_entry.mac(7 downto 0) <= dataval; end if;
352
 
353
                                -- source ip capture
354
                                if (set_ip3 = '1') then new_arp_entry.ip(31 downto 24) <= dataval; end if;
355
                                if (set_ip2 = '1') then new_arp_entry.ip(23 downto 16) <= dataval; end if;
356
                                if (set_ip1 = '1') then new_arp_entry.ip(15 downto 8) <= dataval; end if;
357
                                if (set_ip0 = '1') then new_arp_entry.ip(7 downto 0) <= dataval; end if;
358
 
359
                                -- set arp entry request
360
                                if count_arp_rcvd = '1' then
361
                                        -- count another ARP pkt received
362
                                        arp_req_count <= arp_req_count + 1;
363
                                else
364
                                        arp_req_count <= arp_req_count;
365
                                end if;
366
 
367
                        end if;
368
                end if;
369
        end process;
370
 
371
end Behavioral;
372
 

powered by: WebSVN 2.1.0

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