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

Subversion Repositories udp_ip_stack

[/] [udp_ip_stack/] [trunk/] [contrib/] [from_tim/] [udp_ip_stack/] [tags/] [v2.0/] [rtl/] [vhdl/] [arp_REQ.vhd] - Blame information for rev 35

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 35 pjf
----------------------------------------------------------------------------------
2
-- Company: 
3
-- Engineer:            Peter Fall
4
-- 
5
-- Create Date:    12:00:04 05/31/2011 
6
-- Design Name: 
7
-- Module Name:    arp_REQ - Behavioral 
8
-- Project Name: 
9
-- Target Devices: 
10
-- Tool versions: 
11
-- Description:
12
--              handle requests for ARP resolution
13
--              responds from single entry cache or searches external arp store, or asks to send a request
14
--
15
-- Dependencies: 
16
--
17
-- Revision: 
18
-- Revision 0.01 - File Created from arp.vhd 0.2
19
-- Additional Comments: 
20
--
21
----------------------------------------------------------------------------------
22
library IEEE;
23
use IEEE.STD_LOGIC_1164.ALL;
24
use IEEE.NUMERIC_STD.ALL;
25
use work.arp_types.all;
26
 
27
entity arp_req is
28
         generic (
29
                        CLOCK_FREQ                       : integer := 125000000;                        -- freq of data_in_clk -- needed to timout cntr
30
                        ARP_TIMEOUT                      : integer := 60;                                               -- ARP response timeout (s)
31
                        ARP_MAX_PKT_TMO  : integer := 5                                         -- # wrong nwk pkts received before set error
32
                        );
33
    Port (
34
                        -- lookup request signals
35
                        arp_req_req                     : in arp_req_req_type;                          -- request for a translation from IP to MAC
36
                        arp_req_rslt            : out arp_req_rslt_type;                        -- the result
37
                        -- external arp store signals
38
                        arp_store_req           : out arp_store_rdrequest_t;            -- requesting a lookup or store
39
                        arp_store_result        : in arp_store_result_t;                        -- the result
40
                        -- network request signals
41
                        arp_nwk_req                     : out arp_nwk_request_t;                        -- requesting resolution via the network
42
                        arp_nwk_result          : in arp_nwk_result_t;                          -- the result
43
                        -- system signals
44
                        clear_cache                     : in std_logic;                                         -- clear the internal cache
45
                        clk                                     : in std_logic;
46
                        reset                           : in  STD_LOGIC
47
                        );
48
end arp_req;
49
 
50
architecture Behavioral of arp_req is
51
 
52
        type req_state_t is (IDLE,LOOKUP,WAIT_REPLY,PAUSE1,PAUSE2,PAUSE3);
53
        type set_cntr_t is (HOLD,CLR,INCR);
54
        type set_clr_type is (SET, CLR, HOLD);
55
 
56
        -- state variables
57
        signal req_state                                : req_state_t;
58
        signal req_ip_addr                      : std_logic_vector (31 downto 0);                -- IP address to lookup
59
        signal arp_entry_cache          : arp_entry_t;                                                                  -- single entry cache for fast response
60
        signal cache_valid                      : std_logic;                                                                    -- single entry cache is valid
61
        signal nwk_rx_cntr                      : unsigned(7 downto 0);                                          -- counts nwk rx pkts that dont satisfy
62
        signal freq_scaler                      : unsigned (31 downto 0);                                        -- scales data_in_clk downto 1Hz
63
        signal timer                                    : unsigned (7 downto 0);                                 -- counts seconds timeout
64
        signal timeout_reg                      : std_logic;
65
 
66
        -- busses
67
        signal next_req_state           : req_state_t;
68
        signal arp_entry_val                    : arp_entry_t;
69
 
70
        -- requester control signals
71
        signal set_req_state                    : std_logic;
72
        signal set_req_ip                               : std_logic;
73
        signal store_arp_cache          : std_logic;
74
        signal set_nwk_rx_cntr          : set_cntr_t;
75
        signal set_timer                                : set_cntr_t;                           -- timer reset, count, hold control
76
        signal timer_enable                     : std_logic;                            -- enable the timer counting
77
        signal set_timeout                      : set_clr_type;                 -- control the timeout register
78
        signal clear_cache_valid        : std_logic;
79
 
80
begin
81
        req_combinatorial : process (
82
                -- input signals
83
                arp_req_req, arp_store_result, arp_nwk_result, clear_cache,
84
                -- state variables
85
                req_state, req_ip_addr, arp_entry_cache, cache_valid, nwk_rx_cntr,
86
                freq_scaler, timer, timeout_reg,
87
                -- busses
88
                next_req_state, arp_entry_val,
89
                -- control signals
90
                set_req_state, set_req_ip, store_arp_cache, set_nwk_rx_cntr, clear_cache_valid,
91
                set_timer, timer_enable, set_timeout
92
                )
93
        begin
94
                -- set output followers
95
                arp_req_rslt.got_mac <= '0';     -- set initial value of request result outputs
96
                arp_req_rslt.got_err <= '0';
97
                arp_req_rslt.mac <= (others => '0');
98
                arp_store_req.req <= '0';
99
                arp_store_req.ip <= (others => '0');
100
                arp_nwk_req.req <= '0';
101
                arp_nwk_req.ip <= (others => '0');
102
 
103
                -- zero time response to lookup request if already in cache
104
                if arp_req_req.lookup_req = '1' and arp_req_req.ip = arp_entry_cache.ip and cache_valid = '1' then
105
                        arp_req_rslt.got_mac <= '1';
106
                        arp_req_rslt.mac <= arp_entry_cache.mac;
107
                elsif arp_req_req.lookup_req = '1' then
108
                        -- hold off got_mac while req is there as arp_entry will not be correct yet
109
                        arp_req_rslt.got_mac <= '0';
110
                        arp_req_rslt.mac <= arp_entry_cache.mac;
111
                else
112
                        arp_req_rslt.got_mac <= cache_valid;
113
                        arp_req_rslt.mac <= arp_entry_cache.mac;
114
                end if;
115
 
116
                if arp_req_req.lookup_req = '1' then
117
                        -- ensure any existing error report is killed at the start of a request
118
                        arp_req_rslt.got_err <= '0';
119
                else
120
                        arp_req_rslt.got_err <= timeout_reg;
121
                end if;
122
 
123
                -- set signal defaults
124
                next_req_state <= IDLE;
125
                set_req_state <= '0';
126
                set_req_ip <= '0';
127
                store_arp_cache <= '0';
128
                arp_entry_val.ip <= (others => '0');
129
                arp_entry_val.mac <= (others => '0');
130
                set_nwk_rx_cntr <= HOLD;
131
                set_timer <= INCR;                      -- default is timer running, unless we hold or reset it
132
                set_timeout <= HOLD;
133
                timer_enable <= '0';
134
                clear_cache_valid <= clear_cache;
135
 
136
                -- combinatorial logic
137
                if freq_scaler = x"00000000" then
138
                                timer_enable <= '1';
139
                end if;
140
 
141
                -- REQ FSM
142
                case req_state is
143
                        when IDLE =>
144
                                set_timer <= CLR;
145
                                if arp_req_req.lookup_req = '1' then
146
                                        -- check if we already have the info in cache
147
                                        if arp_req_req.ip = arp_entry_cache.ip and cache_valid = '1' then
148
                                                -- already have this IP - feed output back
149
                                                arp_req_rslt.got_mac <= '1';
150
                                                arp_req_rslt.mac <= arp_entry_cache.mac;
151
                                        else
152
                                                clear_cache_valid <= '1';               -- remove cache entry
153
                                                set_timeout <= CLR;
154
                                                next_req_state <= LOOKUP;
155
                                                set_req_state <= '1';
156
                                                set_req_ip <= '1';
157
                                        end if;
158
                                end if;
159
 
160
                        when LOOKUP =>
161
                                -- put request on the store
162
                                arp_store_req.ip <= req_ip_addr;
163
                                arp_store_req.req <= '1';
164
                                case arp_store_result.status is
165
                                        when FOUND =>
166
                                                -- update the cache
167
                                                arp_entry_val <= arp_store_result.entry;
168
                                                store_arp_cache <= '1';
169
                                                -- and feed output back
170
                                                arp_req_rslt.got_mac <= '1';
171
                                                arp_req_rslt.mac <= arp_store_result.entry.mac;
172
                                                next_req_state <= IDLE;
173
                                                set_req_state <= '1';
174
 
175
                                        when NOT_FOUND =>
176
                                                -- need to request from the network
177
                                                set_timer <= CLR;
178
                                                set_nwk_rx_cntr <= CLR;
179
                                                arp_nwk_req.req <= '1';
180
                                                arp_nwk_req.ip <= req_ip_addr;
181
                                                next_req_state <= WAIT_REPLY;
182
                                                set_req_state <= '1';
183
 
184
                                        when OTHERS =>
185
                                                -- just keep waiting - no timeout (assumes lookup with either succeed or fail)
186
                                end case;
187
 
188
                        when WAIT_REPLY =>
189
                                case arp_nwk_result.status is
190
                                        when RECEIVED =>
191
                                                -- store into cache
192
                                                arp_entry_val <= arp_nwk_result.entry;
193
                                                store_arp_cache <= '1';
194
                                                -- and feed output back
195
                                                if arp_nwk_result.entry.ip = req_ip_addr then
196
                                                        arp_req_rslt.got_mac <= '1';
197
                                                        arp_req_rslt.mac <= arp_nwk_result.entry.mac;
198
                                                        next_req_state <= IDLE;
199
                                                        set_req_state <= '1';
200
                                                else
201
                                                        if nwk_rx_cntr > ARP_MAX_PKT_TMO then
202
                                                                set_timeout <= SET;
203
                                                                next_req_state <= IDLE;
204
                                                                set_req_state <= '1';
205
                                                        else
206
                                                                set_nwk_rx_cntr <= INCR;
207
                                                        end if;
208
                                                end if;
209
 
210
                                        when ERROR =>
211
                                                set_timeout <= SET;
212
 
213
                                        when OTHERS =>
214
                                                if timer >= ARP_TIMEOUT then
215
                                                        set_timeout <= SET;
216
                                                        next_req_state <= PAUSE1;
217
                                                        set_req_state <= '1';
218
                                                end if;
219
                                end case;
220
 
221
                        when PAUSE1 =>
222
                                        next_req_state <= PAUSE2;
223
                                        set_req_state <= '1';
224
 
225
                        when PAUSE2 =>
226
                                        next_req_state <= PAUSE3;
227
                                        set_req_state <= '1';
228
 
229
                        when PAUSE3 =>
230
                                        next_req_state <= IDLE;
231
                                        set_req_state <= '1';
232
 
233
                end case;
234
        end process;
235
 
236
        req_sequential : process (clk)
237
        begin
238
                if rising_edge(clk) then
239
                        if reset = '1' then
240
                                -- reset state variables
241
                                req_state <= IDLE;
242
                                req_ip_addr <= (others => '0');
243
                                arp_entry_cache.ip <= (others => '0');
244
                                arp_entry_cache.mac <= (others => '0');
245
                                cache_valid <= '0';
246
                                nwk_rx_cntr <= (others => '0');
247
                                freq_scaler <= to_unsigned(CLOCK_FREQ,32);
248
                                timer <= (others => '0');
249
                                timeout_reg <= '0';
250
                        else
251
                                -- Next req_state processing
252
                                if set_req_state = '1' then
253
                                        req_state <= next_req_state;
254
                                else
255
                                        req_state <= req_state;
256
                                end if;
257
 
258
                                -- Latch the requested IP address
259
                                if set_req_ip = '1' then
260
                                        req_ip_addr <= arp_req_req.ip;
261
                                else
262
                                        req_ip_addr <= req_ip_addr;
263
                                end if;
264
 
265
                                -- network received counter
266
                                case set_nwk_rx_cntr is
267
                                        when CLR  => nwk_rx_cntr <= (others => '0');
268
                                        when INCR => nwk_rx_cntr <= nwk_rx_cntr + 1;
269
                                        when HOLD => nwk_rx_cntr <= nwk_rx_cntr;
270
                                end case;
271
 
272
                                -- set the arp_entry_cache
273
                                if clear_cache_valid = '1' then
274
                                        arp_entry_cache <= arp_entry_cache;
275
                                        cache_valid <= '0';
276
                                elsif store_arp_cache = '1' then
277
                                        arp_entry_cache <= arp_entry_val;
278
                                        cache_valid <= '1';
279
                                else
280
                                        arp_entry_cache <= arp_entry_cache;
281
                                        cache_valid <= cache_valid;
282
                                end if;
283
 
284
                                -- freq scaling and 1-sec timer
285
                                if freq_scaler = x"00000000" then
286
                                        freq_scaler <= to_unsigned(CLOCK_FREQ,32);
287
                                else
288
                                        freq_scaler <= freq_scaler - 1;
289
                                end if;
290
 
291
                                -- timer processing
292
                                case set_timer is
293
                                        when CLR =>
294
                                                timer <= x"00";
295
                                        when INCR =>
296
                                                if timer_enable = '1' then
297
                                                        timer <= timer + 1;
298
                                                else
299
                                                        timer <= timer;
300
                                                end if;
301
                                        when HOLD =>
302
                                                timer <= timer;
303
                                end case;
304
 
305
                                -- timeout latching
306
                                case set_timeout is
307
                                        when CLR  => timeout_reg <= '0';
308
                                        when SET  => timeout_reg <= '1';
309
                                        when HOLD => timeout_reg <= timeout_reg;
310
                                end case;
311
 
312
                        end if;
313
                end if;
314
        end process;
315
 
316
end Behavioral;

powered by: WebSVN 2.1.0

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