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

Subversion Repositories ether_arp_1g

[/] [ether_arp_1g/] [trunk/] [rtl/] [arp_responder.vhdl] - Blame information for rev 3

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

Line No. Rev Author Line
1 2 jrwagz
----------------------------------------------------------------------------------
2 3 jrwagz
-- Company: Carnegie Mellon University, Pittsburgh PA 
3 2 jrwagz
-- Engineer: Justin Wagner
4
-- 
5
-- Create Date:    7/Oct/2011
6
-- Design Name: 
7
-- Module Name:    arp_responder - rtl 
8
-- Project Name: 
9
-- Target Devices:  n/a
10
-- Tool versions: 
11
--
12
-- Dependencies: arp_package.vhdl (Definitions of various constants)
13
--
14
----------------------------------------------------------------------------------
15
library IEEE;
16
use IEEE.STD_LOGIC_1164.ALL;
17
use IEEE.STD_LOGIC_ARITH.ALL;
18
use IEEE.STD_LOGIC_UNSIGNED.ALL;
19
use work.arp_package.all;
20
 
21
entity arp_responder is
22
Port (  ARESET        : in   STD_LOGIC;
23
        MY_MAC        : in   std_logic_vector(47 downto 0); --my MAC address
24
        MY_IPV4       : in   std_logic_vector(31 downto 0); --my IPV4 address
25
        CLK_RX        : in   STD_LOGIC;
26
        DATA_VALID_RX : in   STD_LOGIC;
27
        DATA_RX       : in   std_logic_vector(7 downto 0);
28
        CLK_TX        : in   STD_LOGIC;
29
        DATA_ACK_TX   : in   STD_LOGIC;
30
        DATA_VALID_TX : out  STD_LOGIC;
31
        DATA_TX       : out  std_logic_vector(7 downto 0)
32
      );
33
end arp_responder;
34
----------------------------------------------------------------------------------
35
architecture rtl of arp_responder is
36
    -- Edge Detector used to find positive edge of DATA_VALID_RX
37
    component edge_detector
38
        port(
39
                din   :  in  std_logic;
40
                clk   :  in  std_logic;
41
                rst_n :  in  std_logic;
42
                dout  :  out std_logic
43
            );
44
    end component edge_detector;
45
 
46
    --the following declares the various states for the machine
47
    type state_type is (IDLE,
48
                        CHECK_DA, CHECK_SA, CHECK_E_TYPE, CHECK_H_TYPE, CHECK_P_TYPE,
49
                        CHECK_H_LEN, CHECK_P_LEN, CHECK_OPER, CHECK_SHA, CHECK_SPA,
50
                        CHECK_THA, CHECK_TPA,
51
                        GEN_DA, GEN_SA, GEN_E_TYPE, GEN_H_TYPE, GEN_P_TYPE,
52
                        GEN_H_LEN, GEN_P_LEN, GEN_OPER, GEN_SHA, GEN_SPA,
53
                        GEN_THA, GEN_TPA);
54
 
55
    signal SA_mem, next_SA_mem                      : HA_mem_type;
56
    signal SPA_mem, next_SPA_mem                    : PA_mem_type;
57
    signal next_state, state                        : state_type;
58
    signal next_counter, counter                    : std_logic_vector(3 downto 0);
59
    signal posedge_DATA_VALID_RX                    : std_logic;
60
    signal next_DATA_VALID_TX                       : std_logic;
61
    signal next_DATA_TX                             : std_logic_vector(7 downto 0);
62
 
63
begin
64
 
65
    -- A positive edge detector for the DATA_VALID_RX signal
66
    ed_1: edge_detector
67
          port map(
68
                  din   =>  DATA_VALID_RX,
69
                  clk   =>  CLK_RX,
70
                  rst_n =>  not(ARESET),
71
                  dout  =>  posedge_DATA_VALID_RX
72
                  );
73
 
74
----------------------------------------------------------------------------------
75
-- This process describes the flow from one state to another in the FSM-----------
76
-- It also describes what the outputs should be at each state---------------------
77
----------------------------------------------------------------------------------
78
combo:process(state, posedge_DATA_VALID_RX, counter, SA_mem, SPA_mem, DATA_ACK_TX,
79
                MY_MAC, MY_IPV4)
80
begin
81
-- Hold Values by Default
82
-- These values will hold true in every state unless a state explicitly defines 
83
-- a different value for any of these signals.
84
 next_DATA_TX           <= (others => '0');
85
 next_DATA_VALID_TX     <= '0';
86
 next_counter           <= counter;
87
 next_SA_mem            <= SA_mem;
88
 next_SPA_mem           <= SPA_mem;
89
 
90
------------------------------------------------------------------
91
--State Machine Start...Please see ASM chart for State Diagram----
92
    case state is
93
 
94
        when IDLE =>
95
            if (posedge_DATA_VALID_RX ='1') then
96
              next_state                    <= CHECK_DA;
97
            else
98
              next_state                    <= IDLE;
99
            end if;
100
            next_SA_mem                     <=  ((others => '0'),(others => '0'),(others => '0'),(others => '0'),(others => '0'),(others => '0'));
101
            next_SPA_mem                    <=  ((others => '0'),(others => '0'),(others => '0'),(others => '0'));
102
            next_counter                    <=  (others => '0');
103
 
104
        when CHECK_DA =>
105
        -- Validate that the DA is a Broadcast, if not return to IDLE
106
            next_counter                    <= counter + 1;
107
            if (DATA_RX = MAC_BDCST_ADDR(conv_integer(counter))) then
108
                if (counter < 5) then
109
                    next_state              <= CHECK_DA;
110
                else
111
                    next_state              <= CHECK_SA;
112
                    next_counter            <= (others => '0');
113
                end if;
114
            else
115
                next_state                  <= IDLE;
116
                next_counter                <= (others => '0');
117
            end if;
118
 
119
        when CHECK_SA =>
120
        -- Lets store the SA so we can respond to it later
121
            next_counter                        <= counter + 1;
122
            next_state                          <= CHECK_SA;
123
            next_SA_mem(conv_integer(counter))  <= DATA_RX;
124
            if (counter >= 5) then
125
                next_state                  <= CHECK_E_TYPE;
126
                next_counter                <= (others => '0');
127
            end if;
128
 
129
        when CHECK_E_TYPE =>
130
        -- Verify that the E_TYPE is the ARP ETYPE
131
            next_counter                    <= counter + 1;
132
            if (DATA_RX = E_TYPE_ARP(conv_integer(counter))) then
133
                next_state                  <= CHECK_E_TYPE;
134
                if (counter >= 1) then
135
                    next_state              <= CHECK_H_TYPE;
136
                    next_counter            <= (others => '0');
137
                end if;
138
            else
139
                next_state                  <= IDLE;
140
                next_counter                <= (others => '0');
141
            end if;
142
 
143
        when CHECK_H_TYPE =>
144
        -- Verify that the H_TYPE is the Ethernet HTYPE
145
            next_counter                    <= counter + 1;
146
            if (DATA_RX = H_TYPE_ETH(conv_integer(counter))) then
147
                next_state                  <= CHECK_H_TYPE;
148
                if (counter >= 1) then
149
                    next_state              <= CHECK_P_TYPE;
150
                    next_counter            <= (others => '0');
151
                end if;
152
            else
153
                next_state                  <= IDLE;
154
                next_counter                <= (others => '0');
155
            end if;
156
 
157
        when CHECK_P_TYPE =>
158
        -- Verify that the P_TYPE is the IPV4 PTYPE
159
            next_counter                    <= counter + 1;
160
            if (DATA_RX = P_TYPE_IPV4(conv_integer(counter))) then
161
                next_state                  <= CHECK_P_TYPE;
162
                if (counter >= 1) then
163
                    next_state              <= CHECK_H_LEN;
164
                    next_counter            <= (others => '0');
165
                end if;
166
            else
167
                next_state                  <= IDLE;
168
                next_counter                <= (others => '0');
169
            end if;
170
 
171
        when CHECK_H_LEN =>
172
        -- Verify that the H_LEN is the Ethernet Length
173
            next_counter                    <= (others => '0');
174
            if (DATA_RX = H_TYPE_ETH_LEN) then
175
                next_state                  <= CHECK_P_LEN;
176
            else
177
                next_state                  <= IDLE;
178
            end if;
179
 
180
        when CHECK_P_LEN =>
181
        -- Verify that the P_LEN is the IPV4 Length
182
            next_counter                    <= (others => '0');
183
            if (DATA_RX = P_TYPE_IPV4_LEN) then
184
                next_state                  <= CHECK_OPER;
185
            else
186
                next_state                  <= IDLE;
187
            end if;
188
 
189
        when CHECK_OPER =>
190
        -- Verify that we received an ARP Request
191
            next_counter                    <= counter + 1;
192
            if (DATA_RX = ARP_OPER_REQ(conv_integer(counter))) then
193
                next_state                  <= CHECK_OPER;
194
                if (counter >= 1) then
195
                    next_state              <= CHECK_SHA;
196
                    next_counter            <= (others => '0');
197
                end if;
198
            else
199
                next_state                  <= IDLE;
200
                next_counter                <= (others => '0');
201
            end if;
202
 
203
        when CHECK_SHA =>
204
        -- Ignore the SHA field since we already retrieved this 
205
        -- from the Ethernet header
206
            next_counter                    <= counter + 1;
207
            next_state                      <= CHECK_SHA;
208
            if (counter >= 5) then
209
                next_counter                <= (others => '0');
210
                next_state                  <= CHECK_SPA;
211
            end if;
212
 
213
        when CHECK_SPA =>
214
        -- Lets store the SPA so we can respond to it later
215
            next_counter                        <= counter + 1;
216
            next_state                          <= CHECK_SPA;
217
            next_SPA_mem(conv_integer(counter)) <= DATA_RX;
218
            if (counter >= 3) then
219
                next_state                  <= CHECK_THA;
220
                next_counter                <= (others => '0');
221
            end if;
222
 
223
        when CHECK_THA =>
224
        -- Make sure we are the destination Hardware Address       
225
            next_counter                    <= counter + 1;
226
            if (DATA_RX = MY_MAC((47-(conv_integer(counter)*8)) downto (40-(conv_integer(counter)*8)))) then
227
                next_state                  <= CHECK_THA;
228
                if (counter >= 5) then
229
                    next_state              <= CHECK_TPA;
230
                    next_counter            <= (others => '0');
231
                end if;
232
            else
233
                next_state                  <= IDLE;
234
                next_counter                <= (others => '0');
235
            end if;
236
 
237
        when CHECK_TPA =>
238
        -- Make sure we are the destination Protocol Address       
239
            next_counter                    <= counter + 1;
240
            if (DATA_RX = MY_IPV4((31-(conv_integer(counter)*8)) downto (24-(conv_integer(counter)*8)))) then
241
                next_state                  <= CHECK_TPA;
242
                if (counter >= 3) then
243
                    next_state              <= GEN_DA;
244
                    next_counter            <= (others => '0');
245
                end if;
246
            else
247
                next_state                  <= IDLE;
248
                next_counter                <= (others => '0');
249
            end if;
250
 
251
        -- GENERATE AN ARP RESPONSE
252
 
253
        when GEN_DA =>
254
        -- Generate the DA for the response
255
            next_DATA_VALID_TX              <= '1';
256
            next_DATA_TX                    <= SA_mem(conv_integer(counter));
257
            if (DATA_ACK_TX = '0' AND counter = 0) then
258
                next_counter                <= (others => '0');
259
            else
260
                next_counter                <= counter + 1;
261
            end if;
262
            if (counter < 5) then
263
                next_state                  <= GEN_DA;
264
            else
265
                next_state                  <= GEN_SA;
266
                next_counter                <= (others => '0');
267
            end if;
268
 
269
        when GEN_SA =>
270
        -- Generate the DA for the response
271
            next_DATA_VALID_TX              <= '1';
272
            next_counter                    <= counter + 1;
273
            next_DATA_TX                    <= MY_MAC((47-(conv_integer(counter)*8)) downto (40-(conv_integer(counter)*8)));
274
            if (counter < 5) then
275
                next_state                  <= GEN_SA;
276
            else
277
                next_state                  <= GEN_E_TYPE;
278
                next_counter                <= (others => '0');
279
            end if;
280
 
281
        when GEN_E_TYPE =>
282
        -- Generate the E_TYPE for the response
283
            next_DATA_VALID_TX              <= '1';
284
            next_counter                    <= counter + 1;
285
            next_DATA_TX                    <= E_TYPE_ARP(conv_integer(counter));
286
            if (counter < 1) then
287
                next_state                  <= GEN_E_TYPE;
288
            else
289
                next_state                  <= GEN_H_TYPE;
290
                next_counter                <= (others => '0');
291
            end if;
292
 
293
        when GEN_H_TYPE =>
294
        -- Generate the H_TYPE for the response
295
            next_DATA_VALID_TX              <= '1';
296
            next_counter                    <= counter + 1;
297
            next_DATA_TX                    <= H_TYPE_ETH(conv_integer(counter));
298
            if (counter < 1) then
299
                next_state                  <= GEN_H_TYPE;
300
            else
301
                next_state                  <= GEN_P_TYPE;
302
                next_counter                <= (others => '0');
303
            end if;
304
 
305
        when GEN_P_TYPE =>
306
        -- Generate the P_TYPE for the response
307
            next_DATA_VALID_TX              <= '1';
308
            next_counter                    <= counter + 1;
309
            next_DATA_TX                    <= P_TYPE_IPV4(conv_integer(counter));
310
            if (counter < 1) then
311
                next_state                  <= GEN_P_TYPE;
312
            else
313
                next_state                  <= GEN_H_LEN;
314
                next_counter                <= (others => '0');
315
            end if;
316
 
317
        when GEN_H_LEN =>
318
            next_DATA_VALID_TX              <= '1';
319
            next_DATA_TX                    <= H_TYPE_ETH_LEN;
320
            next_state                      <= GEN_P_LEN;
321
 
322
        when GEN_P_LEN =>
323
            next_DATA_VALID_TX              <= '1';
324
            next_DATA_TX                    <= P_TYPE_IPV4_LEN;
325
            next_state                      <= GEN_OPER;
326
 
327
        when GEN_OPER =>
328
            next_DATA_VALID_TX              <= '1';
329
            next_counter                    <= counter + 1;
330
            next_DATA_TX                    <= ARP_OPER_RESP(conv_integer(counter));
331
            if (counter < 1) then
332
                next_state                  <= GEN_OPER;
333
            else
334
                next_state                  <= GEN_SHA;
335
                next_counter                <= (others => '0');
336
            end if;
337
 
338
        when GEN_SHA =>
339
            next_DATA_VALID_TX              <= '1';
340
            next_counter                    <= counter + 1;
341
            next_DATA_TX                    <= MY_MAC((47-(conv_integer(counter)*8)) downto (40-(conv_integer(counter)*8)));
342
            if (counter < 5) then
343
                next_state                  <= GEN_SHA;
344
            else
345
                next_state                  <= GEN_SPA;
346
                next_counter                <= (others => '0');
347
            end if;
348
 
349
        when GEN_SPA =>
350
            next_DATA_VALID_TX              <= '1';
351
            next_counter                    <= counter + 1;
352
            next_DATA_TX                    <= MY_IPV4((31-(conv_integer(counter)*8)) downto (24-(conv_integer(counter)*8)));
353
            if (counter < 3) then
354
                next_state                  <= GEN_SPA;
355
            else
356
                next_state                  <= GEN_THA;
357
                next_counter                <= (others => '0');
358
            end if;
359
 
360
        when GEN_THA =>
361
        -- Generate the THA for the response
362
            next_DATA_VALID_TX              <= '1';
363
            next_counter                    <= counter + 1;
364
            next_DATA_TX                    <= SA_mem(conv_integer(counter));
365
            if (counter < 5) then
366
                next_state                  <= GEN_THA;
367
            else
368
                next_state                  <= GEN_TPA;
369
                next_counter                <= (others => '0');
370
            end if;
371
 
372
        when GEN_TPA =>
373
        -- Generate the TPA for the response
374
            next_DATA_VALID_TX              <= '1';
375
            next_counter                    <= counter + 1;
376
            next_DATA_TX                    <= SPA_mem(conv_integer(counter));
377
            if (counter < 3) then
378
                next_state                  <= GEN_TPA;
379
            else
380
                next_state                  <= IDLE;
381
                next_counter                <= (others => '0');
382
            end if;
383
 
384
        when others =>
385
            next_state    <= IDLE;
386
 
387
    end case;
388
 
389
end process combo;
390
----------------------------------------------------------------------------------
391
--Sequential Logic Processes--------------------------------------------------------
392
----------------------------------------------------------------------------------
393
seq_RX:process(CLK_RX, ARESET)
394
begin
395
 
396
    if (ARESET='1') then --resetting the board
397
        state               <= IDLE;
398
        counter             <= (others => '0');
399
        SA_mem              <= ((others => '0'),(others => '0'),(others => '0'),(others => '0'),(others => '0'),(others => '0'));
400
        SPA_mem             <= ((others => '0'),(others => '0'),(others => '0'),(others => '0'));
401
 
402
    -- move next state values into registers on clock edge
403
    elsif (CLK_RX'event and CLK_RX ='1') then
404
        state               <= next_state;
405
        counter             <= next_counter;
406
        SA_mem              <= next_SA_mem;
407
        SPA_mem             <= next_SPA_mem;
408
 
409
    else
410
        NULL;
411
    end if;
412
 
413
end process seq_RX;
414
 
415
seq_TX:process(CLK_TX, ARESET)
416
begin
417
 
418
    if (ARESET='1') then --resetting the board
419
        DATA_VALID_TX       <= '0';
420
        DATA_TX             <= (others => '0');
421
    -- move next state values into registers on clock edge
422
    elsif (CLK_TX'event and CLK_TX ='1') then
423
        DATA_VALID_TX       <= next_DATA_VALID_TX;
424
        DATA_TX             <= next_DATA_TX;
425
    else
426
        NULL;
427
    end if;
428
 
429
end process seq_TX;
430
 
431
end rtl;

powered by: WebSVN 2.1.0

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