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 4

Details | Compare with Previous | View Log

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