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/] [udp.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
-- Title      : UDP/IP header handling
3
-- Project    : 
4
-------------------------------------------------------------------------------
5
-- File       : udp.vhd
6
-- Author     : Jussi Nieminen  <niemin95@galapagosinkeiju.cs.tut.fi>
7
-- Company    : 
8
-- Last update: 2010/01/06
9
-- Platform   : 
10
-------------------------------------------------------------------------------
11
-- Description: Adds and removes UDP and IP headers to data
12
-------------------------------------------------------------------------------
13
-- Revisions  :
14
-- Date        Version  Author  Description
15
-- 2009/09/16  1.0      niemin95        Created
16
-------------------------------------------------------------------------------
17
 
18
library ieee;
19
use ieee.std_logic_1164.all;
20
use ieee.numeric_std.all;
21
use work.udp_ip_pkg.all;
22
 
23
 
24
entity udp is
25
 
26
  generic (
27
    data_width_g : integer := 16;
28
    tx_len_w_g   : integer := 11);
29
 
30
  port (
31
    clk                   : in  std_logic;
32
    rst_n                 : in  std_logic;
33
    -- from application to udp
34
    new_tx_in             : in  std_logic;
35
    tx_len_in             : in  std_logic_vector( tx_len_w_g-1 downto 0 );
36
    target_IP_in          : in  std_logic_vector( ip_addr_w_c-1 downto 0 );
37
    target_port_in        : in  std_logic_vector( port_w_c-1 downto 0 );
38
    source_port_in        : in  std_logic_vector( port_w_c-1 downto 0 );
39
    -- from udp to eth
40
    new_tx_out            : out std_logic;
41
    tx_MAC_addr_out       : out std_logic_vector( MAC_addr_w_c-1 downto 0 );
42
    tx_len_out            : out std_logic_vector( tx_len_w_g-1 downto 0 );
43
    tx_frame_type_out     : out std_logic_vector( frame_type_w_c-1 downto 0 );
44
    header_data_out       : out std_logic_vector( data_width_g-1 downto 0 );
45
    header_data_valid_out : out std_logic;
46
    ethernet_re_in        : in  std_logic;
47
    new_rx_in             : in  std_logic;
48
    rx_data_in            : in  std_logic_vector( data_width_g-1 downto 0 );
49
    rx_data_valid_in      : in  std_logic;
50
    rx_len_in             : in  std_logic_vector( tx_len_w_g-1 downto 0 );
51
    rx_frame_type_in      : in  std_logic_vector( frame_type_w_c-1 downto 0 );
52
    rx_re_out             : out std_logic;
53
    rx_erroneous_in       : in  std_logic;
54
    -- from udp to application
55
    rx_erroneous_out      : out std_logic;
56
    new_rx_out            : out std_logic;
57
    rx_len_out            : out std_logic_vector( tx_len_w_g-1 downto 0 );
58
    source_IP_out         : out std_logic_vector( ip_addr_w_c-1 downto 0 );
59
    source_port_out       : out std_logic_vector( port_w_c-1 downto 0 );
60
    dest_port_out         : out std_logic_vector( port_w_c-1 downto 0 );
61
    application_re_in     : in  std_logic;
62
    -- from udp to arpsnd
63
    request_MAC_out       : out std_logic;
64
    IP_to_arp_out         : out std_logic_vector( ip_addr_w_c-1 downto 0 );
65
    requested_MAC_in      : in  std_logic_vector( MAC_addr_w_c-1 downto 0 );
66
    req_MAC_valid_in      : in  std_logic;
67
    rx_arp_ready_in       : in  std_logic;
68
    snd_req_from_arp_in   : in  std_logic;
69
    tx_arp_ready_in       : in  std_logic;
70
    -- other control signals
71
    rx_error_out          : out std_logic;
72
    input_select_out      : out std_logic_vector( 1 downto 0 );
73
    output_select_out     : out std_logic_vector( 1 downto 0 )
74
    );
75
 
76
end udp;
77
 
78
 
79
architecture rtl of udp is
80
 
81
  type tx_state_type is (tx_idle, write_IP_headers, write_UDP_headers, relay_tx_data, tx_arp);
82
  type rx_state_type is (rx_idle, read_IP_headers, read_UDP_headers, relay_rx_data,
83
                         rx_arp, rx_discard, rx_error);
84
  type IP_header_state_type is (version_IHL_DS, IP_length, ID, flags_offset, TTL_protocol,
85
                                header_checksum, source_addr1, source_addr2,
86
                                dest_addr1, dest_addr2, discard);
87
  type UDP_header_state_type is (source_port, dest_port, UDP_length, UDP_checksum);
88
 
89
  signal rx_state_r     : rx_state_type;
90
  signal tx_state_r     : tx_state_type;
91
  signal tx_IP_state_r  : IP_header_state_type;
92
  signal tx_UDP_state_r : UDP_header_state_type;
93
  signal rx_IP_state_r  : IP_header_state_type;
94
  signal rx_UDP_state_r : UDP_header_state_type;
95
 
96
 
97
  signal rx_len_r        : integer range 0 to 2**tx_len_w_g-1;
98
  signal rx_re_r         : std_logic;
99
 
100
  signal discard_rx_r : std_logic;
101
 
102
  signal tx_len_r      : integer range 0 to 2**tx_len_w_g-1;
103
  signal target_port_r : std_logic_vector( port_w_c-1 downto 0 );
104
  signal source_port_r : std_logic_vector( port_w_c-1 downto 0 );
105
  signal target_addr_r : std_logic_vector( ip_addr_w_c-1 downto 0 );
106
 
107
  signal ip_checksum : std_logic_vector( ip_checksum_w_c-1 downto 0 );
108
 
109
  signal discard_xtra_bytes_r : std_logic;
110
  signal num_xtra_bytes_r : integer range 0 to 63;
111
 
112
  constant IP_header_words_c : integer := 5;  -- 32bit words
113
  constant UDP_header_length_c : integer := 8;  -- bytes
114
 
115
  -- precounted part of IP checksum, including field version_IHL_DS, ID,
116
  -- flags_offset and TTL_protocol
117
  constant pre_counted_part_of_checksum_c : std_logic_vector( ip_checksum_w_c-1 downto 0 )
118
    := "0100101000010001";
119
 
120
  signal tx_len_for_checksum : std_logic_vector( 15 downto 0 );
121
 
122
-------------------------------------------------------------------------------
123
begin  -- rtl
124
-------------------------------------------------------------------------------
125
 
126
  -- *********************************************************************************
127
  -- REMEMBER!! rx_data_in(15 downto 8) = LSByte and rx_data_in(7 downto 0) = MSByte!!
128
  -- Same goes for the tx_data_out too!
129
  -- *********************************************************************************
130
 
131
 
132
-------------------------------------------------------------------------------
133
  rx_re_out <= rx_re_r;
134
 
135
  rx_process : process (clk, rst_n)
136
 
137
    variable incoming_len_v : integer range 0 to 2**tx_len_w_g-1;
138
 
139
  begin  -- process rx_process
140
    if rst_n = '0' then                 -- asynchronous reset (active low)
141
 
142
      rx_state_r <= rx_idle;
143
      rx_IP_state_r <= version_IHL_DS;
144
      rx_UDP_state_r <= source_port;
145
 
146
      rx_re_r               <= '0';
147
      rx_erroneous_out      <= '0';
148
      new_rx_out            <= '0';
149
      rx_len_out            <= (others => '0');
150
      source_IP_out         <= (others => '0');
151
      source_port_out       <= (others => '0');
152
      dest_port_out         <= (others => '0');
153
      discard_rx_r          <= '0';
154
      discard_xtra_bytes_r  <= '0';
155
      num_xtra_bytes_r      <= 0;
156
 
157
      input_select_out <= (others => '0');
158
 
159
      rx_error_out <= '0';
160
 
161
    elsif clk'event and clk = '1' then  -- rising clock edge
162
 
163
      case rx_state_r is
164
        when rx_idle =>
165
 
166
          new_rx_out       <= '0';
167
          rx_len_out       <= (others => '0');
168
          source_IP_out    <= (others => '0');
169
          source_port_out  <= (others => '0');
170
          dest_port_out    <= (others => '0');
171
          rx_erroneous_out <= '0';
172
 
173
          discard_rx_r         <= '0';
174
          discard_xtra_bytes_r <= '0';
175
          num_xtra_bytes_r     <= 0;
176
 
177
          if new_rx_in = '1' then
178
 
179
            if rx_frame_type_in = ARP_frame_type_c then
180
              -- arp packet goes straight to arp
181
              rx_state_r <= rx_arp;
182
 
183
            elsif rx_frame_type_in = IP_frame_type_c then
184
              -- data transfer coming, start reading the headers
185
              rx_state_r <= read_IP_headers;
186
              rx_IP_state_r <= version_IHL_DS;
187
 
188
              rx_len_r <= to_integer( unsigned( rx_len_in ));
189
              rx_erroneous_out <= rx_erroneous_in;
190
 
191
            else
192
              -- whoaa, unknown protocol, discard
193
              rx_len_r <= to_integer( unsigned( rx_len_in ));
194
              rx_state_r <= rx_discard;
195
 
196
            end if;
197
          end if;
198
 
199
        when read_IP_headers =>
200
 
201
          if rx_data_valid_in = '1' and rx_re_r = '0' then
202
            rx_re_r <= '1';
203
          end if;
204
 
205
          if rx_data_valid_in = '1' and rx_re_r = '1' then
206
            rx_re_r <= '0';
207
 
208
            -------------------------------------------------------------------
209
            -- sub FSM handling the different fields of tx
210
            case rx_IP_state_r is
211
              when version_IHL_DS =>
212
 
213
                -- 0_____________4_______________8_________________________16
214
                -- |   version   | header length | Differentiated Services |
215
 
216
                -- only thing we are interested of is the header length
217
                -- if there's options-fields (over 5 32bit words in the header)
218
                -- we simply discard this transmission
219
                if to_integer( unsigned( rx_data_in(3 downto 0) )) /= IP_header_words_c then
220
                  discard_rx_r <= '1';
221
                end if;
222
 
223
                rx_IP_state_r <= IP_length;
224
 
225
              when IP_length =>
226
 
227
                -- total length of the packet, including header and the data.
228
                incoming_len_v := to_integer( unsigned( rx_data_in(7 downto 0 ) & rx_data_in( 15 downto 8 ) ));
229
 
230
                -- +1, because when reading two bytes at a time, we don't need
231
                -- to read any xtra if rx_len = incoming_len_v + 1
232
                if rx_len_r > incoming_len_v + 1 then
233
                  -- amount of data is less than ethernet minimum frame size (64 bytes)
234
                  -- we have to discard the extra bytes after data has been relayed.
235
                  discard_xtra_bytes_r <= '1';
236
 
237
                  -- getting rid of the last bit, because with odd lengths one
238
                  -- of the xtra bytes is already read out with the last databyte
239
                  num_xtra_bytes_r <= (( rx_len_r - incoming_len_v ) / 2 ) * 2;
240
 
241
                elsif rx_len_r /= incoming_len_v and rx_len_r /= incoming_len_v + 1 then
242
                  -- there's something wrong
243
                  rx_state_r <= rx_error;
244
                end if;
245
 
246
                rx_len_r <= incoming_len_v;
247
                rx_IP_state_r <= ID;
248
 
249
              when ID =>
250
                -- we don't care about this field
251
                rx_IP_state_r <= flags_offset;
252
              when flags_offset =>
253
                -- we don't care about the flags or the offset either
254
                rx_IP_state_r <= TTL_protocol;
255
 
256
              when TTL_protocol =>
257
 
258
                -- 0______________8______________16
259
                -- | Time To Live |   Protocol   |
260
 
261
                -- check that the protocol is UDP and TTL /= 0,
262
                -- otherwise discard this transmission
263
                if to_integer( unsigned( rx_data_in( 7 downto 0 ) )) = 0 or
264
                  rx_data_in( 15 downto 8 ) /= UDP_protocol_c
265
                then
266
                  discard_rx_r <= '1';
267
                end if;
268
                rx_IP_state_r <= header_checksum;
269
 
270
              when header_checksum =>
271
 
272
                -- checksum check not implemented yet, maybe some day...
273
                rx_IP_state_r <= source_addr1;
274
 
275
              when source_addr1 =>
276
 
277
                source_IP_out( 31 downto 24 ) <= rx_data_in( 7 downto 0 );
278
                source_IP_out( 23 downto 16 ) <= rx_data_in( 15 downto 8 );
279
                rx_IP_state_r <= source_addr2;
280
 
281
              when source_addr2 =>
282
 
283
                source_IP_out( 15 downto 8 ) <= rx_data_in( 7 downto 0 );
284
                source_IP_out( 7 downto 0 )  <= rx_data_in( 15 downto 8 );
285
                rx_IP_state_r <= dest_addr1;
286
 
287
              when dest_addr1 =>
288
 
289
                -- just check that the addr matches
290
                if rx_data_in( 7 downto 0 ) /= own_ip_c( 31 downto 24 ) or
291
                  rx_data_in( 15 downto 8 ) /= own_ip_c( 23 downto 16 )
292
                then
293
                  -- some multicast messages contain a certain IP, so we might
294
                  -- get packets with wrong address
295
                  discard_rx_r <= '1';
296
                end if;
297
                rx_IP_state_r <= dest_addr2;
298
 
299
              when dest_addr2 =>
300
 
301
                if (rx_data_in( 7 downto 0 ) /= own_ip_c( 15 downto 8 ) or
302
                  rx_data_in( 15 downto 8 ) /= own_ip_c( 7 downto 0 ))
303
                  or discard_rx_r = '1'
304
                then
305
                  -- if message is to be discarded, go and discard it, otherwise
306
                  -- start reading UDP headers
307
                  rx_IP_state_r <= discard;
308
                  -- there might also be extra bytes to discard, so add them to
309
                  -- the length and remove IP header length
310
                  rx_len_r <= rx_len_r + num_xtra_bytes_r - ( IP_header_words_c*4 );
311
 
312
                else
313
                  rx_state_r     <= read_UDP_headers;
314
                  rx_UDP_state_r <= source_port;
315
                  rx_IP_state_r  <= version_IHL_DS;
316
 
317
                  -- remove IP header length
318
                  rx_len_r <= rx_len_r - ( IP_header_words_c * 4 );
319
                end if;
320
 
321
 
322
 
323
 
324
              when discard =>
325
 
326
                -- just pretend to be reading
327
                if rx_len_r <= 2 then
328
                  -- all done
329
                  rx_len_r <= 0;
330
                  rx_IP_state_r <= version_IHL_DS;
331
                  rx_state_r <= rx_idle;
332
                else
333
                  rx_len_r <= rx_len_r - 2;
334
                end if;
335
 
336
              when others => null;
337
            end case;
338
            -- /rx_IP_state_r
339
            -------------------------------------------------------------------            
340
          end if;
341
 
342
 
343
 
344
        when read_UDP_headers =>
345
 
346
          if rx_data_valid_in = '1' and rx_re_r = '0' then
347
            rx_re_r <= '1';
348
          end if;
349
 
350
          if rx_data_valid_in = '1' and rx_re_r = '1' then
351
            rx_re_r <= '0';
352
 
353
            -- FSM to read the UDP header
354
            -------------------------------------------------------------------
355
            case rx_UDP_state_r is
356
              when source_port =>
357
 
358
                source_port_out( 15 downto 8 ) <= rx_data_in( 7 downto 0 );
359
                source_port_out( 7 downto 0 )  <= rx_data_in( 15 downto 8 );
360
                rx_UDP_state_r <= dest_port;
361
 
362
              when dest_port =>
363
 
364
                dest_port_out( 15 downto 8 ) <= rx_data_in( 7 downto 0 );
365
                dest_port_out( 7 downto 0 )  <= rx_data_in( 15 downto 8 );
366
                rx_UDP_state_r <= UDP_length;
367
 
368
              when UDP_length =>
369
 
370
                -- check that the length field is correct
371
                if rx_len_r /=
372
                  to_integer( unsigned( rx_data_in(7 downto 0 ) & rx_data_in( 15 downto 8 ) ))
373
                then
374
                  rx_state_r <= rx_error;
375
                end if;
376
                rx_UDP_state_r <= UDP_checksum;
377
 
378
              when UDP_checksum =>
379
 
380
                -- umm, it's propably correct...
381
                -- give rx_data to application
382
                input_select_out <= "10";
383
                rx_state_r <= relay_rx_data;
384
                -- notify application about new tx
385
                new_rx_out <= '1';
386
                rx_len_out <= std_logic_vector( to_unsigned( rx_len_r -
387
                                                             UDP_header_length_c,
388
                                                             tx_len_w_g ));
389
 
390
 
391
                rx_UDP_state_r <= source_port;
392
                rx_len_r <= rx_len_r - UDP_header_length_c;
393
 
394
              when others => null;
395
            end case;
396
            -- /rx_UDP_state_r
397
            -------------------------------------------------------------------
398
          end if;
399
 
400
 
401
        when relay_rx_data =>
402
 
403
          -- monitor application_re
404
          if application_re_in = '1' and rx_data_valid_in = '1' then
405
 
406
            new_rx_out <= '0';
407
 
408
            if rx_len_r <= 2 then
409
              -- all received
410
              input_select_out <= "00";
411
 
412
              -- if there is extra bytes
413
              if discard_xtra_bytes_r = '1' then
414
 
415
                rx_state_r           <= rx_discard;
416
                rx_len_r             <= num_xtra_bytes_r;
417
                discard_xtra_bytes_r <= '0';
418
                num_xtra_bytes_r     <= 0;
419
 
420
              else
421
                rx_state_r <= rx_idle;
422
                rx_len_r   <= 0;
423
              end if;
424
 
425
            else
426
              rx_len_r <= rx_len_r - 2;
427
            end if;
428
          end if;
429
 
430
 
431
        when rx_arp =>
432
 
433
          -- give turn to arp until it says it's ready
434
          input_select_out <= "01";
435
          if rx_arp_ready_in = '1' then
436
            input_select_out <= "00";
437
            rx_state_r <= rx_idle;
438
          end if;
439
 
440
 
441
        when rx_discard =>
442
          -- we come here, if the frame type of ethernet frame is something
443
          -- else than ARP or IP or if there is extra bytes in the frame (less
444
          -- data than minimum ethernet frame size)
445
 
446
          if rx_data_valid_in = '1' and rx_re_r = '0' then
447
            rx_re_r <= '1';
448
          end if;
449
 
450
          if rx_data_valid_in = '1' and rx_re_r = '1' then
451
            rx_re_r <= '0';
452
 
453
            -- just pretend to be reading
454
            if rx_len_r <= 2 then
455
              -- all done
456
              rx_len_r <= 0;
457
              rx_state_r <= rx_idle;
458
            else
459
              rx_len_r <= rx_len_r - 2;
460
            end if;
461
          end if;
462
 
463
        when rx_error =>
464
 
465
          -- shit just hit the fan
466
          rx_error_out <= '1';
467
 
468
        when others => null;
469
      end case;
470
 
471
    end if;
472
  end process rx_process;
473
-------------------------------------------------------------------------------
474
 
475
  tx_len_for_checksum <= std_logic_vector( to_unsigned( tx_len_r, 16 ));
476
 
477
  -- IP checksum computation
478
  checksum_adder: entity work.ip_checksum
479
    generic map (
480
        pre_counted_part_g => pre_counted_part_of_checksum_c
481
        )
482
    port map (
483
        total_length_field_in => tx_len_for_checksum,
484
        source_addr_field_in  => own_ip_c,
485
        dest_addr_field_in    => target_addr_r,
486
        header_checksum_out   => ip_checksum
487
        );
488
 
489
-------------------------------------------------------------------------------
490
 
491
 
492
  tx_process: process (clk, rst_n)
493
 
494
    variable tx_len_v : integer range 0 to 2**tx_len_w_g-1;
495
    variable tx_len_slv_v : std_logic_vector( 15 downto 0 );
496
 
497
  begin  -- process tx_process
498
    if rst_n = '0' then                 -- asynchronous reset (active low)
499
 
500
      tx_state_r <= tx_idle;
501
      tx_IP_state_r <= version_IHL_DS;
502
      tx_UDP_state_r <= source_port;
503
 
504
      output_select_out <= (others => '0');
505
      tx_len_r <= 0;
506
      target_addr_r <= (others => '0');
507
      target_port_r <= (others => '0');
508
      source_port_r <= (others => '0');
509
 
510
      request_MAC_out       <= '0';
511
      IP_to_arp_out         <= (others => '0');
512
      new_tx_out            <= '0';
513
      tx_MAC_addr_out       <= (others => '0');
514
      tx_len_out            <= (others => '0');
515
      tx_frame_type_out     <= (others => '0');
516
      header_data_out       <= (others => '0');
517
      header_data_valid_out <= '0';
518
 
519
 
520
    elsif clk'event and clk = '1' then  -- rising clock edge
521
 
522
      case tx_state_r is
523
        when tx_idle =>
524
 
525
          -- if arp want's to send, give it the output
526
          if snd_req_from_arp_in = '1' then
527
            tx_state_r <= tx_arp;
528
 
529
          elsif new_tx_in = '1' then
530
 
531
            if req_MAC_valid_in = '1' then
532
              -- MAC found from the ARP table, start sending
533
              tx_state_r <= write_IP_headers;
534
              -- write first word here already (version_IHL_DS)
535
              -- first the version, IPv4
536
              header_data_out( 7 downto 4 ) <= "0100";
537
              -- then header length in words
538
              header_data_out( 3 downto 0 ) <= std_logic_vector( to_unsigned( IP_header_words_c, 4 ));
539
              -- then Differentiated Services (just zeros)
540
              header_data_out( 15 downto 8 ) <= (others => '0');
541
 
542
              header_data_valid_out <= '1';
543
 
544
              tx_len_v   := to_integer( unsigned( tx_len_in )) +
545
                            IP_header_words_c*4 + UDP_header_length_c;
546
              tx_len_r   <= tx_len_v;
547
              tx_len_out <= std_logic_vector( to_unsigned( tx_len_v, tx_len_w_g ));
548
              new_tx_out <= '1';
549
              tx_frame_type_out <= IP_frame_type_c;
550
 
551
              source_port_r    <= source_port_in;
552
              target_port_r    <= target_port_in;
553
              target_addr_r    <= target_IP_in;
554
              tx_MAC_addr_out  <= requested_MAC_in;
555
 
556
              request_MAC_out <= '0';
557
 
558
            else
559
              -- We must get the MAC address before we can start sending
560
              request_MAC_out <= '1';
561
              IP_to_arp_out   <= target_IP_in;
562
            end if;
563
          end if;
564
 
565
 
566
        when write_IP_headers =>
567
 
568
          if ethernet_re_in = '1' then
569
            -- the data of the next state is written during the previous one
570
            case tx_IP_state_r is
571
              when version_IHL_DS =>
572
 
573
                new_tx_out <= '0';
574
                tx_IP_state_r <= IP_length;
575
 
576
                -- remember, data goes in as 2 bytes, not as single 16-bit word
577
                tx_len_slv_v := std_logic_vector( to_unsigned( tx_len_r, 16 ));
578
                header_data_out <= tx_len_slv_v( 7 downto 0 ) & tx_len_slv_v( 15 downto 8 );
579
 
580
              when IP_length =>
581
                tx_IP_state_r <= ID;
582
                header_data_out <= (others => '0');
583
 
584
              when ID =>
585
                tx_IP_state_r <= flags_offset;
586
                header_data_out <= (others => '0');
587
 
588
              when flags_offset =>
589
 
590
                tx_IP_state_r <= TTL_protocol;
591
                -- this block is made for direct communication, not router
592
                -- networks, so 1 to TTL field should do. Still, just in case,
593
                -- we'll put there a 5.
594
                header_data_out( 7 downto 0 )  <= "00000101";
595
                -- protocol is UDP
596
                header_data_out( 15 downto 8 ) <= UDP_protocol_c;
597
 
598
              when TTL_protocol =>
599
                tx_IP_state_r <= header_checksum;
600
                header_data_out <= ip_checksum( 7 downto 0 ) & ip_checksum( 15 downto 8 );
601
 
602
              when header_checksum =>
603
                tx_IP_state_r <= source_addr1;
604
                header_data_out <= own_ip_c( 23 downto 16 ) & own_ip_c( 31 downto 24 );
605
 
606
              when source_addr1 =>
607
                tx_IP_state_r <= source_addr2;
608
                header_data_out <= own_ip_c( 7 downto 0 ) & own_ip_c( 15 downto 8 );
609
 
610
              when source_addr2 =>
611
                tx_IP_state_r <= dest_addr1;
612
                header_data_out <= target_addr_r( 23 downto 16 ) & target_addr_r( 31 downto 24 );
613
 
614
              when dest_addr1 =>
615
                tx_IP_state_r <= dest_addr2;
616
                header_data_out <= target_addr_r( 7 downto 0 ) & target_addr_r( 15 downto 8 );
617
 
618
              when dest_addr2 =>
619
                -- all written, move on to write the UDP addr
620
                tx_state_r <= write_UDP_headers;
621
                tx_IP_state_r <= version_IHL_DS;
622
                -- first UDP data
623
                header_data_out <= source_port_r( 7 downto 0 ) & source_port_r( 15 downto 8 );
624
 
625
              when others => null;
626
            end case;
627
          end if;
628
 
629
 
630
        when write_UDP_headers =>
631
 
632
          if ethernet_re_in = '1' then
633
 
634
            case tx_UDP_state_r is
635
              when source_port =>
636
 
637
                tx_UDP_state_r <= dest_port;
638
                header_data_out <= target_port_r( 7 downto 0 ) & target_port_r( 15 downto 8 );
639
 
640
              when dest_port =>
641
 
642
                tx_UDP_state_r <= UDP_length;
643
                tx_len_slv_v := std_logic_vector( to_unsigned( tx_len_r -
644
                                                               IP_header_words_c*4, 16 ));
645
                header_data_out <= tx_len_slv_v( 7 downto 0 ) & tx_len_slv_v( 15 downto 8 );
646
 
647
              when UDP_length =>
648
                tx_UDP_state_r <= UDP_checksum;
649
                -- not used
650
                header_data_out <= (others => '0');
651
 
652
              when UDP_checksum =>
653
 
654
                -- all done, start relaying the data
655
                header_data_valid_out <= '0';
656
                header_data_out       <= (others => '0');
657
                tx_UDP_state_r        <= source_port;
658
                tx_state_r            <= relay_tx_data;
659
                output_select_out     <= "10";
660
                -- remove headers from length
661
                tx_len_r <= tx_len_r - IP_header_words_c*4 - UDP_header_length_c;
662
 
663
              when others => null;
664
            end case;
665
          end if;
666
 
667
 
668
        when relay_tx_data =>
669
 
670
          -- count the amount of sent data and go back to idle after all is sent
671
          if ethernet_re_in = '1' then
672
 
673
            if tx_len_r <= 2 then
674
              -- all sent
675
              tx_len_r          <= 0;
676
              tx_state_r        <= tx_idle;
677
              output_select_out <= "00";
678
 
679
            else
680
              tx_len_r <= tx_len_r - 2;
681
            end if;
682
          end if;
683
 
684
 
685
        when tx_arp =>
686
 
687
          -- give output to arp
688
          output_select_out <= "01";
689
 
690
          -- wait until it's idle again
691
          if tx_arp_ready_in = '1' then
692
            output_select_out <= "00";
693
            tx_state_r <= tx_idle;
694
          end if;
695
 
696
        when others => null;
697
      end case;
698
 
699
    end if;
700
  end process tx_process;
701
 
702
 
703
 
704
end rtl;

powered by: WebSVN 2.1.0

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