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/] [arpsnd.vhd] - Blame information for rev 145

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
-------------------------------------------------------------------------------
2
-- arpsnd.vhd
3
--
4
-- Author(s):     Jussi Nieminen after Ashley Partis and Jorgen Peddersen
5
-- Created:       Feb 2001
6
-- Last Modified: Feb 2001
7
-- 
8
-- Sits transparently between the internet send and ethernet send layers.
9
-- All frame send requests from the internet layer are passed through after
10
-- the destination MAC is either looked up from the ARP table, or an ARP 
11
-- request is sent out and an ARP reply is receiver.  ARP replies are created
12
-- and then sent to the ethernet later after being requested by the ARP layer.  
13
-- After each frame is passed on to the ethernet layer and then sent, it informs
14
-- the layer above that the frame has been sent.
15
--
16
-- Licenced under LGPL.
17
-------------------------------------------------------------------------------
18
 
19
library ieee;
20
use ieee.std_logic_1164.all;
21
use ieee.std_logic_unsigned.all;
22
use work.udp_ip_pkg.all;
23
 
24
entity ARPSnd is
25
  port (
26
    clk                : in  std_logic;  -- clock
27
    rstn               : in  std_logic;  -- aysnchronous active low reset
28
    request_MAC_in     : in  std_logic;  -- IP layer want's to know a MAC addr
29
    targer_IP_in       : in  std_logic_vector (31 downto 0);  -- destination IP from the internet layer
30
    ARP_entry_valid_in : in  std_logic;  -- input from ARP indicating that it contains the requested IP
31
    gen_ARP_reply_in   : in  std_logic;  -- input from ARP requesting an ARP reply
32
    gen_ARP_IP_in      : in  std_logic_vector (31 downto 0);  -- input from ARP saying which IP to send a reply to
33
    lookup_MAC_in      : in  std_logic_vector (47 downto 0);  -- input from ARP giving a requested MAC
34
    lookup_IP_out      : out std_logic_vector (31 downto 0);  -- output to ARP requesting an IP to be looked up in the table
35
    sending_reply_out  : out std_logic;  -- output to ARP to tell it's sending the ARP reply
36
    target_MAC_out     : out std_logic_vector (47 downto 0);  -- destination MAC for the physical layer
37
    requested_MAC_out  : out std_logic_vector( 47 downto 0 );  -- requested MAC to UDP/IP
38
    req_MAC_valid_out  : out std_logic;
39
    gen_frame_out      : out std_logic;  -- tell the ethernet layer (PHY) to send a frame
40
    frame_type_out     : out std_logic_vector( frame_type_w_c-1 downto 0 );
41
    frame_size_out     : out std_logic_vector (10 downto 0);  -- tell the PHY what size the frame size is
42
    tx_ready_out           : out std_logic;  -- idle signal
43
    wr_data_valid_out  : out std_logic;
44
    wr_data_out        : out std_logic_vector (15 downto 0);
45
    wr_re_in           : in  std_logic
46
    );
47
end ARPSnd;
48
 
49
architecture ARPSnd_arch of ARPSnd is
50
 
51
-- FSM state definitions
52
  type STATETYPE is (stIdle, stGenARPReply, stGetReplyMAC, stStoreARPReply, stCheckARPEntry, stCheckARPEntry2,
53
                     stGenARPRequest, stStoreARPRequest, stWaitForValidEntry, stGiveMAC);
54
  signal presState : STATETYPE;
55
  signal nextState : STATETYPE;
56
 
57
-- signals to synchronously increment and reset the counter
58
  signal cnt    : std_logic_vector (4 downto 0);
59
  signal incCnt : std_logic;
60
  signal rstCnt : std_logic;
61
 
62
-- next write data value
63
  signal nextWrData : std_logic_vector (15 downto 0);
64
 
65
-- signals and buffers to latch input data
66
  signal latchTargetIP   : std_logic;
67
  signal latchInternetIP : std_logic;
68
  signal IP_r            : std_logic_vector (31 downto 0);
69
  signal latchTargetMAC  : std_logic;
70
  signal MAC_r           : std_logic_vector (47 downto 0);
71
 
72
-- 20 second ARP reply timeout counter at 50MHz
73
  signal ARP_timeout_cnt_r  : std_logic_vector (29 downto 0);
74
  signal rstARPCnt          : std_logic;
75
  signal ARP_cnt_overflow_r : std_logic;
76
 
77
  signal wr_data_r     : std_logic_vector( 15 downto 0 );
78
  signal wr_data_valid : std_logic;
79
  signal start_tx      : std_logic;
80
  signal MAC_to_output : std_logic;
81
  signal req_MAC_valid_r : std_logic;
82
 
83
  constant ARP_frame_size_c : std_logic_vector( 10 downto 0 ) := "00000011100";
84
 
85
-------------------------------------------------------------------------------
86
begin
87
-------------------------------------------------------------------------------
88
 
89
  -- connect output to register
90
  wr_data_out <= wr_data_r;
91
  req_MAC_valid_out <= req_MAC_valid_r;
92
 
93
  process (rstn, clk)
94
  begin
95
    -- set up the asynchronous active low reset
96
    if rstn = '0' then
97
 
98
      presState         <= stIdle;
99
      cnt               <= (others => '0');
100
      wr_data_valid_out <= '0';
101
      wr_data_r         <= (others => '0');
102
 
103
      ARP_timeout_cnt_r  <= (others => '0');
104
      ARP_cnt_overflow_r <= '0';
105
      IP_r               <= (others => '0');
106
      MAC_r              <= (others => '0');
107
 
108
      gen_frame_out     <= '0';
109
      target_MAC_out    <= (others => '0');
110
      frame_size_out    <= (others => '0');
111
      frame_type_out    <= (others => '0');
112
      req_MAC_valid_r   <= '0';
113
      requested_MAC_out <= (others => '0');
114
 
115
    elsif clk'event and clk = '1' then
116
 
117
      presState <= nextState;
118
      -- set the write data bus to it's next value
119
      wr_data_r <= nextWrData;
120
 
121
      -- register valid signal
122
      if wr_data_valid = '1' then
123
        wr_data_valid_out <= '1';
124
      end if;
125
 
126
      -- start a tx
127
      if start_tx = '1' then
128
        if latchTargetMAC = '1' then
129
          target_MAC_out <= lookup_MAC_in;
130
        else
131
          target_MAC_out <= x"FFFFFFFFFFFF";
132
        end if;
133
        gen_frame_out    <= '1';        -- goes to 'new tx' and 'snd_req' (udp)
134
        frame_size_out   <= ARP_frame_size_c;
135
        frame_type_out   <= ARP_frame_type_c;
136
      end if;
137
 
138
      if wr_re_in = '1' then
139
        -- clear gen_frame_out when eth cntrl starts to read
140
        gen_frame_out     <= '0';
141
        -- also clear the valid signal
142
        wr_data_valid_out <= '0';
143
      end if;
144
 
145
 
146
      -- increment and reset the counter synchronously to avoid race conditions
147
      if incCnt = '1' then
148
        cnt <= cnt + 1;
149
      elsif rstCnt = '1' then
150
        cnt <= (others => '0');
151
      end if;
152
 
153
      -- set the ARP counter to 1
154
      if rstARPCnt = '1' then
155
        ARP_timeout_cnt_r  <= "00" & x"0000001";
156
        ARP_cnt_overflow_r <= '0';
157
        -- if the ARP counter isn't 0, keep incrementing it
158
      elsif ARP_timeout_cnt_r /= "00" & x"0000000" then
159
        ARP_timeout_cnt_r  <= ARP_timeout_cnt_r + 1;
160
        ARP_cnt_overflow_r <= '0';
161
        -- if the counter is 0, set the overflow signal
162
      else
163
        ARP_cnt_overflow_r <= '1';
164
      end if;
165
 
166
      -- latch the IP to send the ARP request to, send the ARP reply to or to lookup
167
      -- from either the ARP layer or internet send layer
168
      if latchTargetIP = '1' then
169
        IP_r <= gen_ARP_IP_in;
170
      elsif latchInternetIP = '1' then
171
        IP_r <= targer_IP_in;
172
      end if;
173
 
174
      -- latch the MAC from the ARP table that has been looked up
175
      if latchTargetMAC = '1' then
176
        MAC_r <= lookup_MAC_in;
177
      end if;
178
 
179
      if MAC_to_output = '1' then
180
        -- put out the MAC when we have it
181
        requested_MAC_out <= MAC_r;
182
        req_MAC_valid_r <= '1';
183
 
184
      elsif request_MAC_in = '0' then
185
        -- clear the valid signal when IP layer stops requesting
186
        req_MAC_valid_r <= '0';
187
      end if;
188
 
189
    end if;
190
  end process;
191
 
192
 
193
 
194
-- ARP header format
195
--
196
--      0                     8                     16                                             31
197
--      --------------------------------------------------------------------------------------------
198
--      |                Hardware Type               |               Protocol Type                 |
199
--      |                                            |                                             |
200
--      --------------------------------------------------------------------------------------------
201
--      |   Hardware Address  |   Protocol Address   |                 Operation                   |
202
--      |       Length        |       Length         |                                             |
203
--      --------------------------------------------------------------------------------------------
204
--      |                          Sender Hardware Address (MAC) (bytes 0 - 3)                     |
205
--      |                                                                                          |
206
--      --------------------------------------------------------------------------------------------
207
--      |           Sender MAC (bytes 4 - 5)         |        Sender IP Address (bytes 0 - 1)      |
208
--      |                                            |                                             |
209
--      --------------------------------------------------------------------------------------------
210
--      |            Sender IP (bytes 2 - 3)         |    Target Hardware Address (bytes 0 - 1)    |
211
--      |                                            |                                             |
212
--      --------------------------------------------------------------------------------------------
213
--      |                                  Target MAC (bytes 2 - 5)                                |
214
--      |                                                                                          |
215
--      --------------------------------------------------------------------------------------------
216
--      |                               Target IP Address (bytes 0 - 3)                            |
217
--      |                                                                                          |
218
--      --------------------------------------------------------------------------------------------
219
--
220
 
221
  -- main FSM process
222
  process (presState, gen_ARP_reply_in, cnt, IP_r, MAC_r, wr_data_r, req_MAC_valid_r,
223
           ARP_entry_valid_in, ARP_cnt_overflow_r, request_MAC_in, wr_re_in)
224
  begin
225
    -- remember the value of the RAM write data bus by default
226
    nextWrData        <= wr_data_r;
227
    -- lookup the latched IP by default
228
    lookup_IP_out     <= IP_r;
229
    rstCnt            <= '0';
230
    incCnt            <= '0';
231
    sending_reply_out <= '0';
232
    tx_ready_out      <= '0';
233
    latchInternetIP   <= '0';
234
    latchTargetIP     <= '0';
235
    latchTargetMAC    <= '0';
236
    rstARPCnt         <= '0';
237
    wr_data_valid     <= '0';
238
    MAC_to_output     <= '0';
239
 
240
    start_tx <= '0';
241
 
242
    case presState is
243
      when stIdle =>
244
        -- wait for a frame to arrive
245
        -- if req_MAC_valid_r = '1', we have just arrived from state stGiveMAC
246
        -- and we don't want to get again to stCheckARPEntry.
247
        if (req_MAC_valid_r = '1' or request_MAC_in = '0')
248
          and gen_ARP_reply_in = '0'
249
        then
250
          nextState    <= stIdle;
251
          tx_ready_out <= '1';
252
          rstCnt       <= '1';
253
 
254
          -- create an ARP reply when asked, giving ARP message priority
255
        elsif gen_ARP_reply_in = '1' then
256
          nextState     <= stGetReplyMAC;
257
          -- latch the target IP from the ARP layer
258
          latchTargetIP <= '1';
259
 
260
        -- IP layer wants to have a MAC address
261
        else
262
          nextState       <= stCheckARPEntry;
263
          -- latch input from the IP layer
264
          latchInternetIP <= '1';
265
        end if;
266
 
267
        -- create the ARP reply, getting the target MAC from the ARP table
268
      when stGetReplyMAC =>
269
        nextState         <= stGenARPReply;
270
        lookup_IP_out     <= IP_r;
271
        latchTargetMAC    <= '1';
272
        -- tell the ARP table that we're sending the reply
273
        sending_reply_out <= '1';
274
        start_tx          <= '1';
275
 
276
        -- generate each byte of the ARP reply according to count
277
      when stGenARPReply =>
278
 
279
        wr_data_valid <= '1';
280
        nextState     <= stStoreARPReply;
281
 
282
        case cnt is
283
 
284
          -- Hardware type
285
          when "00000" =>
286
            nextWrData <= x"0100";       -- remember, it's x"LSByte MSByte"
287
 
288
          -- Protocol type
289
          when "00001" =>
290
            nextWrData <= x"0008";
291
 
292
            -- Hardware and protocol Address lengths in bytes (x"PAL HAL")
293
          when "00010" =>
294
            nextWrData <= x"0406";
295
 
296
            -- Operation
297
          when "00011" =>
298
            nextWrData <= x"0200";
299
 
300
            -- Sender Hardware Address bytes 1 and 0
301
          when "00100" =>
302
            nextWrData <= MAC_addr_c( 39 downto 32 ) & MAC_addr_c (47 downto 40);
303
 
304
            -- Sender Hardware Address bytes 3 and 2
305
          when "00101" =>
306
            nextWrData <= MAC_addr_c( 23 downto 16 ) & MAC_addr_c (31 downto 24);
307
 
308
            -- Sender Hardware Address bytes 5 and 4
309
          when "00110" =>
310
            nextWrData <= MAC_addr_c( 7 downto 0 ) & MAC_addr_c (15 downto 8);
311
 
312
            -- Sender IP Address bytes 1 and 0
313
          when "00111" =>
314
            nextWrData <= own_IP_c( 23 downto 16 ) & own_IP_c (31 downto 24);
315
 
316
            -- Sender IP Address bytes 3 and 2
317
          when "01000" =>
318
            nextWrData <= own_IP_c( 7 downto 0 ) & own_IP_c (15 downto 8);
319
 
320
            -- Target Hardware Address bytes 1 and 0
321
          when "01001" =>
322
            nextWrData <= MAC_r( 39 downto 32 ) & MAC_r( 47 downto 40 );
323
 
324
            -- Target Hardware Address bytes 3 and 2
325
          when "01010" =>
326
            nextWrData <= MAC_r( 23 downto 16 ) & MAC_r( 31 downto 24 );
327
 
328
            -- Target Hardware Address bytes 5 and 4
329
          when "01011" =>
330
            nextWrData <= MAC_r( 7 downto 0 ) & MAC_r( 15 downto 8 );
331
 
332
            -- Target IP Address bytes 1 and 0
333
          when "01100" =>
334
            nextWrData <= IP_r( 23 downto 16 ) & IP_r (31 downto 24);
335
 
336
            -- Target IP Address bytes 3 and 2
337
          when "01101" =>
338
            nextWrData <= IP_r( 7 downto 0 ) & IP_r (15 downto 8);
339
 
340
          when others => null;
341
        end case;
342
 
343
        -- store the ARP reply for the Ethernet sender
344
      when stStoreARPReply =>
345
 
346
        if wr_re_in = '1' then
347
          if cnt = "01101" then
348
            nextState <= stIdle;
349
          else
350
            nextState <= stGenARPReply;
351
            incCnt    <= '1';
352
          end if;
353
 
354
        else
355
          nextState <= stStoreARPReply;
356
        end if;
357
 
358
 
359
        -----------------------------------------------------------------------------------
360
        -- handle frames passed on to us from the Internet layer
361
        -- check to the see if the desired IP is in the ARP table
362
      when stCheckARPEntry =>
363
        nextState     <= stCheckARPEntry2;
364
        lookup_IP_out <= IP_r;
365
 
366
        -- check to see if the ARP entry is valid
367
      when stCheckARPEntry2 =>
368
        lookup_IP_out    <= IP_r;
369
        -- if it's not a valid ARP entry, then generate an ARP request to find the
370
        -- desired MAC address
371
        if ARP_entry_valid_in = '0' then
372
          nextState      <= stGenArpRequest;
373
          start_tx       <= '1';
374
          -- otherwise pass the MAC to the UDP/IP block
375
        else
376
          nextState      <= stGiveMAC;
377
          latchTargetMAC <= '1';
378
        end if;
379
 
380
        -- create each byte of the ARP request according to cnt
381
      when stGenARPRequest =>
382
 
383
        wr_data_valid <= '1';
384
        nextState <= stStoreARPRequest;
385
        case cnt is
386
 
387
 
388
          -- Hardware type
389
          when "00000" =>
390
            nextWrData <= x"0100";       -- remember, it's x"LSByte MSByte"
391
 
392
            -- Protocol type
393
          when "00001" =>
394
            nextWrData <= x"0008";
395
 
396
            -- Hardware and protocol Address lengths in bytes (x"PAL HAL")
397
          when "00010" =>
398
            nextWrData <= x"0406";
399
 
400
            -- Operation
401
          when "00011" =>
402
            nextWrData <= x"0100";
403
 
404
            -- Sender Hardware Address bytes 1 and 0
405
          when "00100" =>
406
            nextWrData <= MAC_addr_c( 39 downto 32 ) & MAC_addr_c (47 downto 40);
407
 
408
            -- Sender Hardware Address bytes 3 and 2
409
          when "00101" =>
410
            nextWrData <= MAC_addr_c( 23 downto 16 ) & MAC_addr_c (31 downto 24);
411
 
412
            -- Sender Hardware Address bytes 5 and 4
413
          when "00110" =>
414
            nextWrData <= MAC_addr_c( 7 downto 0 ) & MAC_addr_c (15 downto 8);
415
 
416
            -- Sender IP Address bytes 1 and 0
417
          when "00111" =>
418
            nextWrData <= own_IP_c( 23 downto 16 ) & own_IP_c (31 downto 24);
419
 
420
            -- Sender IP Address bytes 3 and 2
421
          when "01000" =>
422
            nextWrData <= own_IP_c( 7 downto 0 ) & own_IP_c (15 downto 8);
423
 
424
            -- Target Hardware Address bytes 1 and 0
425
          when "01001"            =>
426
            nextWrData <= (others => '0');
427
 
428
            -- Target Hardware Address bytes 3 and 2
429
          when "01010"            =>
430
            nextWrData <= (others => '0');
431
 
432
            -- Target Hardware Address bytes 5 and 4
433
          when "01011"            =>
434
            nextWrData <= (others => '0');
435
 
436
            -- Target IP Address bytes 1 and 0
437
          when "01100" =>
438
            nextWrData <= IP_r( 23 downto 16 ) & IP_r (31 downto 24);
439
 
440
            -- Target IP Address bytes 3 and 2
441
          when "01101" =>
442
            nextWrData <= IP_r( 7 downto 0 ) & IP_r (15 downto 8);
443
 
444
          when others => null;
445
        end case;
446
 
447
        -- store the ARP reply for the Ethernet sender
448
      when stStoreARPRequest =>
449
 
450
        if wr_re_in = '1' then
451
          if cnt = "01101" then
452
            nextState <= stWaitForValidEntry;
453
            rstARPCnt <= '1';
454
          else
455
            nextState <= stGenARPRequest;
456
            incCnt    <= '1';
457
          end if;
458
 
459
        else
460
          nextState <= stStoreARPRequest;
461
        end if;
462
 
463
 
464
        -- wait for the ARP entry to become valid
465
      when stWaitForValidEntry =>
466
        -- if the ARP entry becomes valid then we fire off the reply
467
        if ARP_entry_valid_in = '1' then
468
          tx_ready_out   <= '1';
469
          nextState      <= stGiveMAC;
470
          latchTargetMAC <= '1';
471
 
472
          -- otherwise give a certain amount of time for the ARP reply to come
473
          -- back in (21.5 secs on a 50MHz clock)
474
        else
475
          -- if the reply doesn't come back, then inform the above layer that the
476
          -- frame was sent.  Assume the higher level protocol can account for this
477
          -- problem, or possibly an error signal could be created once a higher level
478
          -- protocol has been written that can accomodate this
479
          if ARP_cnt_overflow_r = '1' then
480
            nextState         <= stIdle;
481
          else
482
            nextState         <= stWaitForValidEntry;
483
          end if;
484
        end if;
485
        lookup_IP_out         <= IP_r;
486
 
487
 
488
      when stGiveMAC =>
489
 
490
        MAC_to_output <= '1';
491
        nextState     <= stIdle;
492
 
493
      when others => nextState <= stIdle;
494
    end case;
495
  end process;
496
 
497
end ARPSnd_arch;

powered by: WebSVN 2.1.0

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