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

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

Line No. Rev Author Line
1 2 pjf
----------------------------------------------------------------------------------
2
-- Company: 
3
-- Engineer:            Peter Fall
4
-- 
5
-- Create Date:    12:00:04 05/31/2011 
6
-- Design Name: 
7
-- Module Name:    arp - Behavioral 
8
-- Project Name: 
9
-- Target Devices: 
10
-- Tool versions: 
11
-- Description:
12
--              handle simple IP lookup in cache
13
--              request cache fill through ARP protocol if required
14
--              cache is simple 1 deep
15
--              Handle ARP protocol
16
--              Respond to ARP requests and replies
17
--              Ignore pkts that are not ARP
18
--              Ignore pkts that are not addressed to us
19
--
20
-- Dependencies: 
21
--
22
-- Revision: 
23
-- Revision 0.01 - File Created
24 4 pjf
-- Revision 0.02 - Added req for mac tx and wait for grant
25
-- Revision 0.03 - Added data_out_first
26
 
27 2 pjf
-- Additional Comments: 
28
--
29
----------------------------------------------------------------------------------
30
library IEEE;
31
use IEEE.STD_LOGIC_1164.ALL;
32
use IEEE.NUMERIC_STD.ALL;
33
use work.arp_types.all;
34
 
35
entity arp is
36
    Port (
37
                        -- lookup request signals
38
                        arp_req_req                     : in arp_req_req_type;
39
                        arp_req_rslt            : out arp_req_rslt_type;
40
                        -- MAC layer RX signals
41
                        data_in_clk             : in  STD_LOGIC;
42
                        reset                           : in  STD_LOGIC;
43
                        data_in                                 : in  STD_LOGIC_VECTOR (7 downto 0);             -- ethernet frame (from dst mac addr through to last byte of frame)
44
                        data_in_valid           : in  STD_LOGIC;                                                                        -- indicates data_in valid on clock
45
                        data_in_last            : in  STD_LOGIC;                                                                        -- indicates last data in frame
46
                        -- MAC layer TX signals
47
                        mac_tx_req                      : out std_logic;                                                                        -- indicates that ip wants access to channel (stays up for as long as tx)
48
                        mac_tx_granted          : in std_logic;                                                                 -- indicates that access to channel has been granted            
49
                        data_out_clk            : in std_logic;
50
                        data_out_ready          : in std_logic;                                                                 -- indicates system ready to consume data
51
                        data_out_valid          : out std_logic;                                                                        -- indicates data out is valid
52 4 pjf
                        data_out_first          : out std_logic;                                                                        -- with data out valid indicates the first byte of a frame
53 2 pjf
                        data_out_last           : out std_logic;                                                                        -- with data out valid indicates the last byte of a frame
54
                        data_out                                : out std_logic_vector (7 downto 0);             -- ethernet frame (from dst mac addr through to last byte of frame)
55
                        -- system signals
56
                        our_mac_address         : in STD_LOGIC_VECTOR (47 downto 0);
57
                        our_ip_address  : in STD_LOGIC_VECTOR (31 downto 0);
58
                        req_count                       : out STD_LOGIC_VECTOR(7 downto 0)                       -- count of arp pkts received
59
                        );
60
end arp;
61
 
62
architecture Behavioral of arp is
63
 
64
        type req_state_type is (IDLE,LOOKUP,REQUEST,WAIT_REPLY);
65
        type rx_state_type is (IDLE,PARSE,PROCESS_ARP,WAIT_END);
66
        type rx_event_type is (NO_EVENT,DATA);
67
        type count_mode_type is (RST,INCR,HOLD);
68
        type arp_oper_type is (NOP,REQUEST,REPLY);
69
        type set_clr_type is (SET, CLR, HOLD);
70
 
71
        type tx_state_type is (IDLE,WAIT_MAC,SEND);
72
 
73
 
74
        type arp_entry_type is record
75
                ip                              : std_logic_vector (31 downto 0);
76
                mac                             : std_logic_vector (47 downto 0);
77
                is_valid                        : std_logic;
78
                reply_required  : std_logic;
79
        end record;
80
 
81
        -- state variables
82
        signal req_state                        : req_state_type;
83
        signal req_ip_addr              : std_logic_vector (31 downto 0);                -- IP address to lookup
84
        signal mac_addr_found   : STD_LOGIC_VECTOR (47 downto 0);                -- mac address found
85
        signal mac_addr_valid_reg: std_logic;
86
        signal send_request_needed              : std_logic;
87
        signal tx_mac_chn_reqd  : std_logic;
88
 
89
        signal rx_state                         : rx_state_type;
90
        signal rx_count                         : unsigned (7 downto 0);
91
        signal arp_operation            : arp_oper_type;
92
        signal arp_req_count            : unsigned (7 downto 0);
93
        signal arp_entry                        : arp_entry_type;                               -- arp entry store
94
        signal new_arp_entry            : arp_entry_type;
95
        signal tx_state                 : tx_state_type;
96
        signal tx_count                         : unsigned (7 downto 0);
97
 
98
-- FIXME        - remove these debug state signals
99
        signal arp_err_data             : std_logic_vector (7 downto 0);
100
        signal set_err_data             : std_logic;
101
 
102
  attribute keep : string;
103
  attribute keep of arp_err_data             : signal is "true";
104
 
105
        -- requester control signals
106
        signal next_req_state   : req_state_type;
107
        signal set_req_state            : std_logic;
108
        signal set_req_ip                       : std_logic;
109
        signal set_mac_addr             : std_logic;
110
        signal set_mac_addr_invalid : std_logic;
111
        signal set_send_req             : std_logic;
112
        signal clear_send_req   : std_logic;
113
 
114
 
115
        -- rx control signals
116
        signal next_rx_state    : rx_state_type;
117
        signal set_rx_state             : std_logic;
118
        signal rx_event                         : rx_event_type;
119
        signal rx_count_mode    : count_mode_type;
120
        signal set_arp_oper             : std_logic;
121
        signal arp_oper_set_val : arp_oper_type;
122
        signal dataval                  : std_logic_vector (7 downto 0);
123
        signal set_arp_entry_request            : std_logic;
124
 
125
        signal set_mac5                         : std_logic;
126
        signal set_mac4                         : std_logic;
127
        signal set_mac3                         : std_logic;
128
        signal set_mac2                         : std_logic;
129
        signal set_mac1                         : std_logic;
130
        signal set_mac0                         : std_logic;
131
 
132
        signal set_ip3                  : std_logic;
133
        signal set_ip2                  : std_logic;
134
        signal set_ip1                  : std_logic;
135
        signal set_ip0                  : std_logic;
136
 
137
        -- tx control signals
138
        signal next_tx_state    : tx_state_type;
139
        signal set_tx_state             : std_logic;
140
        signal tx_count_mode            : count_mode_type;
141
        signal clear_reply_req  : std_logic;
142
        signal set_chn_reqd             : set_clr_type;
143
        signal kill_data_out_valid      : std_logic;
144
 
145
 
146
        -- function to determine whether the rx pkt is an arp pkt and whether we want to process it
147
        -- Returns 1 if we should discard
148
        -- The following will make us ignore the frame (all values hexadecimal):
149
        -- PDU type /= 0806
150
        -- Protocol Type /= 0800
151
        -- Hardware Type /= 1
152
        -- Hardware Length /= 6
153
        -- Protocol Length /= 4
154
        -- Operation /= 1 or 2
155
        -- Target IP /= our IP (i.er. message is not meant for us)
156
        --
157
        function not_our_arp(data : STD_LOGIC_VECTOR; count : unsigned; our_ip : std_logic_vector) return std_logic is
158
        begin
159
                if
160
                        (count = 12 and data /= x"08") or                                               -- PDU type 0806 : ARP
161
                        (count = 13 and data /= x"06") or
162
                        (count = 14 and data /= x"00") or                                               -- HW type 1 : eth
163
                        (count = 15 and data /= x"01") or
164
                        (count = 16 and data /= x"08") or                                               -- Protocol 0800 : IP
165
                        (count = 17 and data /= x"00") or
166
                        (count = 18 and data /= x"06") or                                               -- HW Length 6
167
                        (count = 19 and data /= x"04") or                                               -- protocol length 4
168
                        (count = 20 and data /= x"00") or                                               -- operation 1 or 2 (req or reply)
169
                        (count = 21 and data /= x"01" and data /= x"02") or
170
                        (count = 38 and data /= our_ip(31 downto 24)) or        -- target IP is ours
171
                        (count = 39 and data /= our_ip(23 downto 16)) or
172
                        (count = 40 and data /= our_ip(15 downto 8)) or
173
                        (count = 41 and data /= our_ip(7 downto 0))
174
                then
175
                        return '1';
176
                else
177
                        return '0';
178
                end if;
179
        end function not_our_arp;
180
 
181
begin
182
        req_combinatorial : process (
183
                -- input signals
184
                arp_req_req,
185
                -- state variables
186
                req_state, req_ip_addr, mac_addr_found, mac_addr_valid_reg, send_request_needed, arp_entry,
187
                -- control signals
188
                next_req_state, set_req_state, set_req_ip, set_mac_addr,set_mac_addr_invalid,set_send_req, clear_send_req)
189
        begin
190
                -- set output followers
191
                arp_req_rslt.got_err <= '0';     -- errors not returned in this version
192
                -- zero time response to lookup request if already in cache
193
                if arp_req_req.lookup_req = '1' and arp_req_req.ip = arp_entry.ip and arp_entry.is_valid = '1' then
194
                        arp_req_rslt.got_mac <= '1';
195
                        arp_req_rslt.mac <= arp_entry.mac;
196 6 pjf
                elsif arp_req_req.lookup_req = '1' then
197
                        arp_req_rslt.got_mac <= '0';             -- hold off got_mac while req is there as arp_entry will not be correct yet
198
                        arp_req_rslt.mac <= arp_entry.mac;
199 2 pjf
                else
200
                        arp_req_rslt.got_mac <= mac_addr_valid_reg;
201
                        arp_req_rslt.mac <= mac_addr_found;
202
                end if;
203
 
204
                -- set signal defaults
205
                next_req_state <= IDLE;
206
                set_req_state <= '0';
207
                set_req_ip <= '0';
208
                set_mac_addr <= '0';
209
                set_mac_addr_invalid <= '0';
210
                set_send_req <= '0';
211
                clear_send_req <= '0';
212
 
213
                -- REQ FSM
214
                case req_state is
215
                        when IDLE =>
216
                                if arp_req_req.lookup_req = '1' then
217
                                        -- check if we already have the info in cache
218
                                        if arp_req_req.ip = arp_entry.ip and arp_entry.is_valid = '1' then
219
                                                -- already have this IP
220
                                                set_mac_addr <= '1';
221
                                        else
222
                                                next_req_state <= LOOKUP;
223
                                                set_req_state <= '1';
224
                                                set_req_ip <= '1';
225
                                                set_mac_addr_invalid <= '1';
226
                                        end if;
227
                                end if;
228
 
229
                        when LOOKUP =>
230
                                if arp_entry.ip = req_ip_addr and arp_entry.is_valid = '1' then
231
                                        -- already have this IP
232
                                        next_req_state <= IDLE;
233
                                        set_req_state <= '1';
234
                                        set_mac_addr <= '1';
235
                                else
236
                                        -- need to request mac for this IP
237
                                        next_req_state <= REQUEST;
238
                                        set_req_state <= '1';
239
                                        set_send_req <= '1';
240
                                end if;
241
 
242
                        when REQUEST =>
243
                                        clear_send_req <= '1';
244
                                        next_req_state <= WAIT_REPLY;
245
                                        set_req_state <= '1';
246
 
247
                        when WAIT_REPLY =>
248
                                if arp_entry.is_valid = '1' then
249
                                        -- have reply, go back to LOOKUP state to see if it is the right one
250
                                        next_req_state <= LOOKUP;
251
                                        set_req_state <= '1';
252
                                end if;
253
                                -- TODO: add timeout here                               
254
 
255
                end case;
256
        end process;
257
 
258
        req_sequential : process (data_in_clk,reset)
259
        begin
260
                if rising_edge(data_in_clk) then
261
                        if reset = '1' then
262
                                -- reset state variables
263
                                req_state <= IDLE;
264
                                req_ip_addr <= (others => '0');
265
                                mac_addr_found <= (others => '0');
266
                                mac_addr_valid_reg <= '0';
267
                                send_request_needed <= '0';
268
                        else
269
                                -- Next req_state processing
270
                                if set_req_state = '1' then
271
                                        req_state <= next_req_state;
272
                                else
273
                                        req_state <= req_state;
274
                                end if;
275
 
276
                                -- Latch the requested IP address
277
                                if set_req_ip = '1' then
278
                                        req_ip_addr <= arp_req_req.ip;
279
                                else
280
                                        req_ip_addr <= req_ip_addr;
281
                                end if;
282
 
283
                                -- send request to TX&RX FSMs to send an ARP request
284
                                if set_send_req = '1' then
285
                                        send_request_needed <= '1';
286
                                elsif clear_send_req = '1' then
287
                                        send_request_needed <= '0';
288
                                else
289
                                        send_request_needed <= send_request_needed;
290
                                end if;
291
 
292
                                -- Set the found mac address
293
                                if set_mac_addr = '1' then
294
                                        mac_addr_found <= arp_entry.mac;
295
                                        mac_addr_valid_reg <= '1';
296
                                elsif set_mac_addr_invalid = '1' then
297
                                        mac_addr_found <= (others => '0');
298
                                        mac_addr_valid_reg <= '0';
299
                                else
300
                                        mac_addr_found <= mac_addr_found;
301
                                        mac_addr_valid_reg <= mac_addr_valid_reg;
302
                                end if;
303
 
304
                        end if;
305
                end if;
306
        end process;
307
 
308
 
309
        rx_combinatorial : process (
310
                -- input signals
311
                data_in, data_in_valid, data_in_last, our_ip_address,
312
                -- state variables
313
                rx_state, rx_count, arp_operation, arp_req_count, arp_err_data,
314
                -- control signals
315
                next_rx_state, set_rx_state, rx_event, rx_count_mode, set_arp_oper, arp_oper_set_val,
316
                dataval,set_mac5,set_mac4,set_mac3,set_mac2,set_mac1,set_mac0,set_ip3,set_ip2,set_ip1,set_ip0, set_err_data,
317
                set_arp_entry_request)
318
        begin
319
                -- set output followers
320
                req_count <= STD_LOGIC_VECTOR(arp_req_count);
321
 
322
                -- set signal defaults
323
                next_rx_state <= IDLE;
324
                set_rx_state <= '0';
325
                rx_event <= NO_EVENT;
326
                rx_count_mode <= HOLD;
327
                set_arp_oper <= '0';
328
                arp_oper_set_val <= NOP;
329
                dataval <= (others => '0');
330
                set_mac5 <= '0';
331
                set_mac4 <= '0';
332
                set_mac3 <= '0';
333
                set_mac2 <= '0';
334
                set_mac1 <= '0';
335
                set_mac0 <= '0';
336
                set_ip3 <= '0';
337
                set_ip2 <= '0';
338
                set_ip1 <= '0';
339
                set_ip0 <= '0';
340
                set_arp_entry_request <= '0';
341
                set_err_data <= '0';
342
 
343
                -- determine event (if any)
344
                if data_in_valid = '1' then
345
                        rx_event <= DATA;
346
                end if;
347
 
348
                -- RX FSM
349
                case rx_state is
350
                        when IDLE =>
351
                                rx_count_mode <= RST;
352
                                case rx_event is
353
                                        when NO_EVENT => -- (nothing to do)
354
                                        when DATA =>
355
                                                next_rx_state <= PARSE;
356
                                                set_rx_state <= '1';
357
                                                rx_count_mode <= INCR;
358
                                end case;
359
 
360
                        when PARSE =>
361
                                case rx_event is
362
                                        when NO_EVENT => -- (nothing to do)
363
                                        when DATA =>
364
                                                rx_count_mode <= INCR;
365
                                                -- handle early frame termination
366
                                                if data_in_last = '1' then
367
                                                        next_rx_state <= IDLE;
368
                                                        set_rx_state <= '1';
369
                                                else
370
                                                        -- check for end of frame. Also, detect and discard if not our frame
371
                                                        if rx_count = 42 then
372
                                                                next_rx_state <= PROCESS_ARP;
373
                                                                set_rx_state <= '1';
374
                                                        elsif not_our_arp(data_in,rx_count,our_ip_address) = '1' then
375
                                                                dataval <= data_in;
376
                                                                set_err_data <= '1';
377
                                                                next_rx_state <= WAIT_END;
378
                                                                set_rx_state <= '1';
379
                                                        elsif rx_count = 21 then
380
                                                                -- capture ARP operation
381
                                                                case data_in is
382
                                                                        when x"01" =>
383
                                                                                arp_oper_set_val <= REQUEST;
384
                                                                                set_arp_oper <= '1';
385
                                                                        when x"02" =>
386
                                                                                arp_oper_set_val <= REPLY;
387
                                                                                set_arp_oper <= '1';
388
                                                                        when others =>  -- ignore other values
389
                                                                end case;
390
                                                        -- capture source mac addr
391
                                                        elsif rx_count = 22 then
392
                                                                set_mac5 <= '1';
393
                                                                dataval <= data_in;
394
                                                        elsif rx_count = 23 then
395
                                                                set_mac4 <= '1';
396
                                                                dataval <= data_in;
397
                                                        elsif rx_count = 24 then
398
                                                                set_mac3 <= '1';
399
                                                                dataval <= data_in;
400
                                                        elsif rx_count = 25 then
401
                                                                set_mac2 <= '1';
402
                                                                dataval <= data_in;
403
                                                        elsif rx_count = 26 then
404
                                                                set_mac1 <= '1';
405
                                                                dataval <= data_in;
406
                                                        elsif rx_count = 27 then
407
                                                                set_mac0 <= '1';
408
                                                                dataval <= data_in;
409
                                                        -- capture source ip addr
410
                                                        elsif rx_count = 28 then
411
                                                                set_ip3 <= '1';
412
                                                                dataval <= data_in;
413
                                                        elsif rx_count = 29 then
414
                                                                set_ip2 <= '1';
415
                                                                dataval <= data_in;
416
                                                        elsif rx_count = 30 then
417
                                                                set_ip1 <= '1';
418
                                                                dataval <= data_in;
419
                                                        elsif rx_count = 31 then
420
                                                                set_ip0 <= '1';
421
                                                                dataval <= data_in;
422
                                                        end if;
423
                                                end if;
424
                                end case;
425
 
426
                        when PROCESS_ARP =>
427
                                next_rx_state <= WAIT_END;
428
                                set_rx_state <= '1';
429
                                case arp_operation is
430
                                        when NOP => -- (nothing to do)
431
                                        when REQUEST =>
432
                                                        set_arp_entry_request <= '1';
433
                                                        arp_oper_set_val <= NOP;
434
                                                        set_arp_oper <= '1';
435
                                        when REPLY =>
436
                                                        set_arp_entry_request <= '1';
437
                                                        arp_oper_set_val <= NOP;
438
                                                        set_arp_oper <= '1';
439
                                end case;
440
 
441
                        when WAIT_END =>
442
                                case rx_event is
443
                                        when NO_EVENT => -- (nothing to do)
444
                                        when DATA =>
445
                                                if data_in_last = '1' then
446
                                                        next_rx_state <= IDLE;
447
                                                        set_rx_state <= '1';
448
                                                end if;
449
                                end case;
450
 
451
                end case;
452
 
453
        end process;
454
 
455
        rx_sequential : process (data_in_clk)
456
        begin
457
                if rising_edge(data_in_clk) then
458
                        if reset = '1' then
459
                                -- reset state variables
460
                                rx_state <= IDLE;
461
                                rx_count <= x"00";
462
                                arp_operation <= NOP;
463
                                arp_req_count <= x"00";
464
                                -- reset arp entry store
465
                                arp_entry.ip <= x"00000000";
466
                                arp_entry.mac <= x"000000000000";
467
                                arp_entry.is_valid <= '0';
468
                                arp_entry.reply_required <= '0';
469
                                arp_err_data <= (others => '0');
470
                        else
471
                                -- Next rx_state processing
472
                                if set_rx_state = '1' then
473
                                        rx_state <= next_rx_state;
474
                                else
475
                                        rx_state <= rx_state;
476
                                end if;
477
 
478
                                -- rx_count processing
479
                                case rx_count_mode is
480
                                        when RST =>
481
                                                rx_count <= x"00";
482
                                        when INCR =>
483
                                                rx_count <= rx_count + 1;
484
                                        when HOLD =>
485
                                                rx_count <= rx_count;
486
                                end case;
487
 
488
                                -- err data
489
                                if set_err_data = '1' then
490
                                        arp_err_data <= data_in;
491
                                else
492
                                        arp_err_data <= arp_err_data;
493
                                end if;
494
 
495
                                -- arp operation processing
496
                                if set_arp_oper = '1' then
497
                                        arp_operation <= arp_oper_set_val;
498
                                else
499
                                        arp_operation <= arp_operation;
500
                                end if;
501
 
502
                                -- source mac capture
503
                                if (set_mac5 = '1') then new_arp_entry.mac(47 downto 40) <= dataval; end if;
504
                                if (set_mac4 = '1') then new_arp_entry.mac(39 downto 32) <= dataval; end if;
505
                                if (set_mac3 = '1') then new_arp_entry.mac(31 downto 24) <= dataval; end if;
506
                                if (set_mac2 = '1') then new_arp_entry.mac(23 downto 16) <= dataval; end if;
507
                                if (set_mac1 = '1') then new_arp_entry.mac(15 downto 8) <= dataval; end if;
508
                                if (set_mac0 = '1') then new_arp_entry.mac(7 downto 0) <= dataval; end if;
509
 
510
                                -- source ip capture
511
                                if (set_ip3 = '1') then new_arp_entry.ip(31 downto 24) <= dataval; end if;
512
                                if (set_ip2 = '1') then new_arp_entry.ip(23 downto 16) <= dataval; end if;
513
                                if (set_ip1 = '1') then new_arp_entry.ip(15 downto 8) <= dataval; end if;
514
                                if (set_ip0 = '1') then new_arp_entry.ip(7 downto 0) <= dataval; end if;
515
 
516
                                -- set arp entry request
517
                                if set_arp_entry_request = '1' then
518
                                        -- copy info from new entry to arp_entry and set reply required
519
                                        arp_entry.mac <= new_arp_entry.mac;
520
                                        arp_entry.ip <= new_arp_entry.ip;
521
                                        arp_entry.is_valid <= '1';
522
                                        if arp_operation = REQUEST then
523
                                                arp_entry.reply_required <= '1';
524
                                        else
525
                                                arp_entry.reply_required <= '0';
526
                                        end if;
527
                                        -- count another ARP pkt received
528
                                        arp_req_count <= arp_req_count + 1;
529
                                elsif clear_reply_req = '1' then
530
                                        -- note: clear_reply_req is set by tx logic, but handled in the clk domain of the rx
531
                                        -- maintain arp entry state, but reset the reply required flag
532
                                        arp_entry.mac <= arp_entry.mac;
533
                                        arp_entry.ip <= arp_entry.ip;
534
                                        arp_entry.is_valid <= arp_entry.is_valid;
535
                                        arp_entry.reply_required <= '0';
536
                                        arp_req_count <= arp_req_count;
537
                                elsif send_request_needed = '1' then
538
                                        -- set up the arp entry to take the request to be transmitted out by the TX FSM
539
                                        arp_entry.ip <= req_ip_addr;
540
                                        arp_entry.mac <= (others => '0');
541
                                        arp_entry.is_valid <= '0';
542
                                        arp_entry.reply_required <= '0';
543
                                else
544
                                        arp_entry <= arp_entry;
545
                                        arp_req_count <= arp_req_count;
546
                                end if;
547
 
548
                        end if;
549
                end if;
550
        end process;
551
 
552
        tx_combinatorial : process (
553
                -- input signals
554
                data_out_ready, send_request_needed, mac_tx_granted, our_mac_address, our_ip_address,
555
                -- state variables
556
                tx_state, tx_count, tx_mac_chn_reqd, arp_entry,
557
                -- control signals
558
                next_rx_state, set_rx_state, tx_count_mode, kill_data_out_valid,
559
                set_chn_reqd, clear_reply_req)
560
        begin
561
                -- set output followers
562 4 pjf
                mac_tx_req <= tx_mac_chn_reqd;
563 2 pjf
 
564 4 pjf
                -- set initial values for combinatorial outputs
565
                data_out_first <= '0';
566
 
567 2 pjf
                case tx_state is
568
                        when SEND   =>
569
                                if data_out_ready = '1' and kill_data_out_valid = '0' then
570
                                        data_out_valid <= '1';
571
                                else
572
                                        data_out_valid <= '0';
573
                                end if;
574
                        when OTHERS =>  data_out_valid <= '0';
575
                end case;
576
 
577
                -- set signal defaults
578
                next_tx_state <= IDLE;
579
                set_tx_state <= '0';
580
                tx_count_mode <= HOLD;
581
                data_out <= x"00";
582
                data_out_last <= '0';
583
                clear_reply_req <= '0';
584
                set_chn_reqd <= HOLD;
585
                kill_data_out_valid <= '0';
586
 
587
                -- TX FSM
588
                case tx_state is
589
                        when IDLE =>
590
                                tx_count_mode <= RST;
591
                                if arp_entry.reply_required = '1' then
592
                                        set_chn_reqd <= SET;
593
                                        next_tx_state <= WAIT_MAC;
594
                                        set_tx_state <= '1';
595
                                elsif send_request_needed = '1' then
596
                                        set_chn_reqd <= SET;
597
                                        next_tx_state <= WAIT_MAC;
598
                                        set_tx_state <= '1';
599
                                else
600
                                        set_chn_reqd <= CLR;
601
                                end if;
602
 
603
                        when WAIT_MAC =>
604
                                tx_count_mode <= RST;
605
                                if mac_tx_granted = '1' then
606
                                        next_tx_state <= SEND;
607
                                        set_tx_state <= '1';
608
                                end if;
609
                                -- TODO - should handle timeout here
610
 
611
                        when SEND =>
612
                                if data_out_ready = '1' then
613
                                                tx_count_mode <= INCR;
614
                                end if;
615
                                case tx_count is
616 4 pjf
                                        when x"00"  =>
617
                                                data_out_first <= data_out_ready;
618
                                                data_out <= x"ff";                                                              -- dst = broadcast
619
 
620 2 pjf
                                        when x"01"  => data_out <= x"ff";
621
                                        when x"02"  => data_out <= x"ff";
622
                                        when x"03"  => data_out <= x"ff";
623
                                        when x"04"  => data_out <= x"ff";
624
                                        when x"05"  => data_out <= x"ff";
625
                                        when x"06"  => data_out <= our_mac_address (47 downto 40);      -- src = our mac
626
                                        when x"07"  => data_out <= our_mac_address (39 downto 32);
627
                                        when x"08"  => data_out <= our_mac_address (31 downto 24);
628
                                        when x"09"  => data_out <= our_mac_address (23 downto 16);
629
                                        when x"0a"  => data_out <= our_mac_address (15 downto 8);
630
                                        when x"0b"  => data_out <= our_mac_address (7 downto 0);
631
                                        when x"0c"  => data_out <= x"08";                                                                       -- pkt type = 0806 : ARP
632
                                        when x"0d"  => data_out <= x"06";
633
                                        when x"0e"  => data_out <= x"00";                                                                       -- HW type = 0001 : eth
634
                                        when x"0f"  => data_out <= x"01";
635
                                        when x"10"  => data_out <= x"08";                                                                       -- protocol = 0800 : ip
636
                                        when x"11"  => data_out <= x"00";
637
                                        when x"12"  => data_out <= x"06";                                                                       -- HW size = 06
638
                                        when x"13"  => data_out <= x"04";                                                                       -- prot size = 04
639
 
640
                                        when x"14"  =>  data_out <= x"00";                                                                      -- opcode =             
641
                                        when x"15"  =>
642
                                                if arp_entry.is_valid = '1' then
643
                                                        data_out <= x"02";                                                                                                                                                      -- 02 : REPLY if arp_entry valid
644
                                                else
645
                                                        data_out <= x"01";                                                                                                                                                      -- 01 : REQ if arp_entry invalid
646
                                                end if;
647
 
648
                                        when x"16" => data_out <= our_mac_address (47 downto 40);       -- sender mac
649
                                        when x"17" => data_out <= our_mac_address (39 downto 32);
650
                                        when x"18" => data_out <= our_mac_address (31 downto 24);
651
                                        when x"19" => data_out <= our_mac_address (23 downto 16);
652
                                        when x"1a" => data_out <= our_mac_address (15 downto 8);
653
                                        when x"1b" => data_out <= our_mac_address (7 downto 0);
654
                                        when x"1c" => data_out <= our_ip_address (31 downto 24);        -- sender ip
655
                                        when x"1d" => data_out <= our_ip_address (23 downto 16);
656
                                        when x"1e" => data_out <= our_ip_address (15 downto 8);
657
                                        when x"1f" => data_out <= our_ip_address (7 downto 0);
658
                                        when x"20" => data_out <= arp_entry.mac (47 downto 40);         -- target mac
659
                                        when x"21" => data_out <= arp_entry.mac (39 downto 32);
660
                                        when x"22" => data_out <= arp_entry.mac (31 downto 24);
661
                                        when x"23" => data_out <= arp_entry.mac (23 downto 16);
662
                                        when x"24" => data_out <= arp_entry.mac (15 downto 8);
663
                                        when x"25" => data_out <= arp_entry.mac (7 downto 0);
664
                                        when x"26" => data_out <= arp_entry.ip  (31 downto 24);         -- target ip
665
                                        when x"27" => data_out <= arp_entry.ip   (23 downto 16);
666
                                        when x"28" => data_out <= arp_entry.ip   (15 downto 8);
667
 
668
                                        when x"29" =>
669
                                                data_out <= arp_entry.ip(7 downto 0);
670
                                                data_out_last <= '1';
671
 
672
                                        when x"2a" =>
673
                                                clear_reply_req <= '1';                 -- reset the reply request (done in the rx clk process domain)
674
                                                kill_data_out_valid <= '1';     -- data is no longer valid
675
                                                next_tx_state <= IDLE;
676
                                                set_tx_state <= '1';
677
 
678
                                        when others =>
679
                                                next_tx_state <= IDLE;
680
                                                set_tx_state <= '1';
681
                                end case;
682
                end case;
683
        end process;
684
 
685
        tx_sequential : process (data_out_clk,reset)
686
        begin
687
                if rising_edge(data_out_clk) then
688
                        if reset = '1' then
689
                                -- reset state variables
690
                                tx_state <= IDLE;
691
                                tx_mac_chn_reqd <= '0';
692
                        else
693
                                -- Next rx_state processing
694
                                if set_tx_state = '1' then
695
                                        tx_state <= next_tx_state;
696
                                else
697
                                        tx_state <= tx_state;
698
                                end if;
699
 
700
                                -- tx_count processing
701
                                case tx_count_mode is
702
                                        when RST =>
703
                                                tx_count <= x"00";
704
                                        when INCR =>
705
                                                tx_count <= tx_count + 1;
706
                                        when HOLD =>
707
                                                tx_count <= tx_count;
708
                                end case;
709
 
710
                                -- control access request to mac tx chn
711
                                case set_chn_reqd is
712
                                        when SET => tx_mac_chn_reqd <= '1';
713
                                        when CLR => tx_mac_chn_reqd <= '0';
714
                                        when HOLD => tx_mac_chn_reqd <= tx_mac_chn_reqd;
715
                                end case;
716
 
717
                        end if;
718
                end if;
719
        end process;
720
 
721
 
722
end Behavioral;
723
 

powered by: WebSVN 2.1.0

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