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

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.hwp.interface/] [udp_ip/] [1.0/] [vhd/] [arp3.vhd] - Blame information for rev 185

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

Line No. Rev Author Line
1 145 lanttu
-------------------------------------------------------------------------------
2
-- arp3.vhd
3
--
4
-- Author(s):     Jussi Nieminen after Ashley Partis and Jorgen Peddersen
5
-- Created:       Feb 2001
6
-- Last Modified: 2009-09-03
7
-- 
8
-- Manages an ARP table for the network stack project.  This protocol listens
9
-- to incoming data and when an ARP request or reply arrives, the data of the
10
-- source is added to the ARP table.  The ARP table contains two entries.
11
-- When a request arrives a signal is also asserted telling the arp sender to
12
-- send an ARP reply when possible.  The incoming data from the ethernet layer
13
-- is a byte stream.
14
-- Licenced under LGPL.
15
-------------------------------------------------------------------------------
16
 
17
library IEEE;
18
use IEEE.std_logic_1164.all;
19
use IEEE.numeric_std.all;
20
use work.udp_ip_pkg.all;
21
 
22
entity ARP is
23
  port (
24
    clk               : in  std_logic;  -- clock signal
25
    rstn              : in  std_logic;  -- asynchronous active low reset
26
    new_frame_in      : in  std_logic;  -- from ethernet layer indicates data arrival
27
    new_word_valid_in : in  std_logic;  -- indicates a new word in the stream
28
    frame_re_out      : out std_logic;
29
    frame_data_in     : in  std_logic_vector (15 downto 0);  -- the stream data
30
    frame_valid_in    : in  std_logic;  -- indicates validity
31
    frame_len_in      : in  std_logic_vector( tx_len_w_c-1 downto 0 );
32
    sending_reply_in  : in  std_logic;  -- ARP sender asserts this when the reply is been transmitted
33
    req_IP_in         : in  std_logic_vector (31 downto 0);  -- ARP sender can request MACs for this address
34
    gen_ARP_rep_out   : out std_logic;  -- tell ARP sender to generate a reply
35
    gen_ARP_IP_out    : out std_logic_vector (31 downto 0);  -- destination IP for generated reply
36
    lookup_MAC_out    : out std_logic_vector (47 downto 0);  -- if valid, MAC for requested IP
37
    valid_entry_out   : out std_logic;   -- indicates if req_IP_in is in table
38
    done_out          : out std_logic
39
    );
40
end ARP;
41
 
42
architecture ARP_arch of ARP is
43
 
44
-- State signals and types
45
  type STATETYPE is (stIdle, stHandleARP, stOperate, stCheckValid);
46
  signal presState : STATETYPE;
47
  signal nextState : STATETYPE;
48
 
49
  -- range of 0 to 25 should be enough, but just to be sure..
50
  signal cnt    : integer range 0 to 2**tx_len_w_c-1;
51
  signal incCnt : std_logic;              -- signal to increment cnt
52
  signal rstCnt : std_logic;              -- signal to clear cnt
53
 
54
  signal latchFrameData   : std_logic;  -- signal to latch stream data
55
  signal frameData_r      : std_logic_vector (15 downto 0);  -- register for latched data
56
  signal shiftSourceIPIn  : std_logic;  -- signal to shift in source IP
57
  signal source_IP_r      : std_logic_vector (31 downto 0);  -- stores source IP
58
  signal shiftSourceMACIn : std_logic;  -- signal to shift in source MAC
59
  signal source_MAC_r     : std_logic_vector (47 downto 0);  -- stores source MAC
60
 
61
  signal ARP_operation_r    : std_logic;  -- '0' for reply, '1' for request
62
  signal determineOperation : std_logic;  -- signal to latch ARP_operation_r from stream
63
 
64
  signal updateARPTable      : std_logic;  -- this signal updates the ARP table
65
  signal ARP_entry_IP_r      : std_logic_vector (31 downto 0);  -- most recent ARP entry IP
66
  signal ARP_entry_MAC_r     : std_logic_vector (47 downto 0);  -- most recent ARP entry MAC
67
  signal ARP_entry_IP_old_r  : std_logic_vector (31 downto 0);  -- 2nd ARP entry IP
68
  signal ARP_entry_MAC_old_r : std_logic_vector (47 downto 0);  -- 2nd ARP entry MAC
69
 
70
  signal doGenARPRep : std_logic;       -- asserted when an ARP reply must be generated
71
 
72
  signal frame_len_r : integer range 0 to 2**tx_len_w_c-1;
73
  signal frame_invalid_r : std_logic;
74
  signal frame_invalid : std_logic;
75
  signal clear_invalid : std_logic;
76
 
77
-------------------------------------------------------------------------------
78
begin
79
-------------------------------------------------------------------------------
80
 
81
  process (clk, rstn)
82
  begin
83
    if rstn = '0' then                  -- reset state and ARP entries
84
 
85
      presState           <= stIdle;
86
      ARP_entry_IP_r      <= (others => '0');
87
      ARP_entry_MAC_r     <= (others => '0');
88
      ARP_entry_IP_old_r  <= (others => '0');
89
      ARP_entry_MAC_old_r <= (others => '0');
90
      frame_re_out <= '0';
91
      cnt <= 0;
92
      ARP_operation_r <= '0';
93
      frameData_r <= (others => '0');
94
      source_IP_r <= (others => '0');
95
      source_MAC_r <= (others => '0');
96
      frame_invalid_r <= '0';
97
      gen_ARP_rep_out <= '0';
98
      gen_ARP_IP_out <= (others => '0');
99
 
100
    elsif clk'event and clk = '1' then
101
      presState <= nextState;           -- go to next state
102
      frame_re_out <= '0';
103
 
104
      if incCnt = '1' then              -- handle counter
105
        cnt <= cnt + 1;
106
      elsif rstCnt = '1' then
107
        cnt <= 0;
108
      end if;
109
 
110
      if latchFrameData = '1' then      -- latch stream data
111
        frameData_r <= frame_data_in;
112
        frame_re_out <= '1';
113
      end if;
114
 
115
      if determineOperation = '1' then  -- determine ARP Operation value
116
        ARP_operation_r <= frameData_r(8);
117
      end if;
118
 
119
      if shiftSourceIPIn = '1' then     -- shift in IP
120
        source_IP_r <= source_IP_r (15 downto 0) &
121
                       frameData_r( 7 downto 0 ) & frameData_r( 15 downto 8 );
122
      end if;
123
 
124
      if shiftSourceMACIn = '1' then    -- shift in MAC
125
        source_MAC_r <= source_MAC_r (31 downto 0) &
126
                        frameData_r( 7 downto 0 ) & frameData_r( 15 downto 8 );
127
      end if;
128
 
129
      if updateARPTable = '1' then      -- update ARP table
130
        if ARP_entry_IP_r = source_IP_r then  -- We already have this ARP, so update
131
          ARP_entry_MAC_r     <= source_MAC_r;
132
        else                            -- Lose one old ARP entry and add new one.
133
          ARP_entry_IP_old_r  <= ARP_entry_IP_r;
134
          ARP_entry_MAC_old_r <= ARP_entry_MAC_r;
135
          ARP_entry_IP_r      <= source_IP_r;
136
          ARP_entry_MAC_r     <= source_MAC_r;
137
        end if;
138
      end if;
139
 
140
      if frame_invalid = '1' then
141
        frame_invalid_r <= '1';
142
      elsif clear_invalid = '1' then
143
        frame_invalid_r <= '0';
144
      end if;
145
 
146
      if new_frame_in = '1' then
147
        frame_len_r <= to_integer( unsigned( frame_len_in ));
148
      end if;
149
 
150
      -- gen_ARP_rep_out is asserted by doGenARPRep and will stay high until cleared 
151
      -- by sending_reply_in
152
      if doGenARPRep = '1' then
153
        gen_ARP_rep_out <= '1';         -- when a request is needed assert gen_ARP_rep_out
154
        gen_ARP_IP_out  <= source_IP_r;  -- and latch the outgoing address
155
      elsif sending_reply_in = '1' then
156
        gen_ARP_rep_out <= '0';         -- when the request is been generated, stop requesting
157
      end if;
158
    end if;
159
  end process;
160
 
161
  process (presState, ARP_operation_r, cnt, new_frame_in, frame_invalid_r,
162
           new_word_valid_in, frameData_r, frame_valid_in, frame_len_r)
163
  begin
164
    -- defaulting of signals
165
    rstCnt             <= '0';
166
    incCnt             <= '0';
167
    shiftSourceIPIn    <= '0';
168
    determineOperation <= '0';
169
    updateARPTable     <= '0';
170
    shiftSourceIPIn    <= '0';
171
    shiftSourceMACIn   <= '0';
172
    latchFrameData     <= '0';
173
    doGenARPRep        <= '0';
174
    frame_invalid      <= '0';
175
    clear_invalid      <= '0';
176
    done_out           <= '0';
177
 
178
    case presState is
179
      when stIdle =>
180
        -- wait for an ARP frame to arrive (udp_ip makes sure that it really is
181
        -- an ARP frame)
182
        if new_frame_in = '1' then
183
          nextState <= stHandleARP;
184
          rstCnt    <= '1';
185
        else
186
          -- if there is data still coming to ARP, just pretend to be reading it
187
          if new_word_valid_in = '1' then
188
            latchFrameData <= '1';
189
          end if;
190
 
191
          nextState <= stIdle;
192
        end if;
193
 
194
      when stHandleARP =>
195
        -- receive a byte from the stream
196
        if new_word_valid_in = '0' then
197
          nextState      <= stHandleARP;
198
        else
199
          nextState      <= stOperate;
200
          latchFrameData <= '1';
201
        end if;
202
 
203
      when stOperate =>
204
        -- increment counter
205
        incCnt <= '1';
206
        -- choose state based on values in the header
207
        -- The following will make us ignore the frame (all values hexadecimal):
208
        -- Hardware Type /= 1
209
        -- Protocol Type /= 800
210
        -- Hardware Length /= 6
211
        -- Protocol Length /= 4
212
        -- Operation /= 1 or 2
213
        -- Target IP /= our IP (i.e. message is not meant for us)
214
        if (cnt = 0 and frameData_r /= x"0100") or
215
          (cnt = 1 and frameData_r /= x"0008") or  -- MSByte = 0 to 7, LSByte = 8 to 15
216
          (cnt = 2 and frameData_r /= x"0406") or
217
          (cnt = 3 and frameData_r /= x"0100" and frameData_r /= x"0200") or
218
          (cnt = 12 and frameData_r /= own_ip_c( 23 downto 16 ) & own_ip_c( 31 downto 24 )) or
219
          (cnt = 13 and frameData_r /= own_ip_c( 7 downto 0 ) & own_ip_c( 15 downto 8 )) then
220
 
221
          --if ((cnt = "00000" or cnt = "00011" or cnt = "00110") and frameData_r /= 0 )or
222
          --  (cnt = "00001" and frameData_r /= 1) or
223
          --  (cnt = "00010" and frameData_r /= 8) or
224
          --  (cnt = "00100" and frameData_r /= 6) or
225
          --  (cnt = "00101" and frameData_r /= 4) or
226
          --  (cnt = "00111" and frameData_r /= 1 and frameData_r /= 2 )or
227
          --  (cnt = "11000" and frameData_r /= DEVICE_IP (31 downto 24)) or
228
          --  (cnt = "11001" and frameData_r /= DEVICE_IP (23 downto 16)) or
229
          --  (cnt = "11010" and frameData_r /= DEVICE_IP (15 downto 8)) or
230
          --  (cnt = "11011" and frameData_r /= DEVICE_IP (7 downto 0)) then
231
 
232
          frame_invalid <= '1';
233
        end if;
234
 
235
        -- frame len is in bytes, so divide by two
236
        if cnt = frame_len_r/2-1 then
237
          nextState <= stCheckValid;  -- exit when data is totally received
238
        else
239
          nextState <= stHandleARP;   -- otherwise loop until complete
240
        end if;
241
 
242
 
243
        -- latch and shift in signals from stream when needed
244
        if cnt = 3 then
245
          determineOperation <= '1';
246
        end if;
247
        if cnt = 4 or cnt = 5 or cnt = 6 then
248
          shiftSourceMACIn   <= '1';
249
        end if;
250
        if cnt = 7 or cnt = 8 then
251
          shiftSourceIPIn    <= '1';
252
        end if;
253
 
254
      when stCheckValid =>
255
        clear_invalid <= '1';
256
 
257
        done_out  <= '1';
258
        nextState <= stIdle;
259
 
260
        if frame_valid_in = '1' and frame_invalid_r = '0' then
261
          -- frame didn't fail CRC and it's not invalid in any other way either
262
          -- generate a reply if required and wait for more messages
263
          if ARP_operation_r = '1' then
264
            doGenARPRep  <= '1';
265
          end if;
266
          updateARPTable <= '1';        -- update the ARP table with the new data
267
        end if;
268
 
269
      when others => null;
270
 
271
    end case;
272
  end process;
273
 
274
  -- handle requests for entries in the ARP table.
275
  process (req_IP_in, ARP_entry_IP_r, ARP_entry_MAC_r, ARP_entry_IP_old_r, ARP_entry_MAC_old_r)
276
  begin
277
    if req_IP_in = ARP_entry_IP_r then  -- check most recent entry
278
      valid_entry_out <= '1';
279
      lookup_MAC_out  <= ARP_entry_MAC_r;
280
    elsif req_IP_in = ARP_entry_IP_old_r then  -- check 2nd entry
281
      valid_entry_out <= '1';
282
      lookup_MAC_out  <= ARP_entry_MAC_old_r;
283
    else                                -- if neither entry matches, valid = 0
284
      valid_entry_out <= '0';
285
      lookup_MAC_out  <= (others => '1');
286
    end if;
287
  end process;
288
end ARP_arch;

powered by: WebSVN 2.1.0

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