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_REQ.vhd] - Blame information for rev 18

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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