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 2

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

Line No. Rev Author Line
1 2 jrwagz
----------------------------------------------------------------------------------
2
-- Company: Eastern Washington University, Cheney, WA 
3
-- 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
-- Description: Project for Job application to XR Trading
12
--
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
                        CHECK_THA, CHECK_TPA,
52
                        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
    signal next_DATA_VALID_TX                       : std_logic;
62
    signal next_DATA_TX                             : std_logic_vector(7 downto 0);
63
 
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
                next_state                  <= CHECK_THA;
221
                next_counter                <= (others => '0');
222
            end if;
223
 
224
        when CHECK_THA =>
225
        -- Make sure we are the destination Hardware Address       
226
            next_counter                    <= counter + 1;
227
            if (DATA_RX = MY_MAC((47-(conv_integer(counter)*8)) downto (40-(conv_integer(counter)*8)))) then
228
                next_state                  <= CHECK_THA;
229
                if (counter >= 5) then
230
                    next_state              <= CHECK_TPA;
231
                    next_counter            <= (others => '0');
232
                end if;
233
            else
234
                next_state                  <= IDLE;
235
                next_counter                <= (others => '0');
236
            end if;
237
 
238
        when CHECK_TPA =>
239
        -- Make sure we are the destination Protocol Address       
240
            next_counter                    <= counter + 1;
241
            if (DATA_RX = MY_IPV4((31-(conv_integer(counter)*8)) downto (24-(conv_integer(counter)*8)))) then
242
                next_state                  <= CHECK_TPA;
243
                if (counter >= 3) then
244
                    next_state              <= GEN_DA;
245
                    next_counter            <= (others => '0');
246
                end if;
247
            else
248
                next_state                  <= IDLE;
249
                next_counter                <= (others => '0');
250
            end if;
251
 
252
        -- GENERATE AN ARP RESPONSE
253
 
254
        when GEN_DA =>
255
        -- Generate the DA for the response
256
            next_DATA_VALID_TX              <= '1';
257
            next_DATA_TX                    <= SA_mem(conv_integer(counter));
258
            if (DATA_ACK_TX = '0' AND counter = 0) then
259
                next_counter                <= (others => '0');
260
            else
261
                next_counter                <= counter + 1;
262
            end if;
263
            if (counter < 5) then
264
                next_state                  <= GEN_DA;
265
            else
266
                next_state                  <= GEN_SA;
267
                next_counter                <= (others => '0');
268
            end if;
269
 
270
        when GEN_SA =>
271
        -- Generate the DA for the response
272
            next_DATA_VALID_TX              <= '1';
273
            next_counter                    <= counter + 1;
274
            next_DATA_TX                    <= MY_MAC((47-(conv_integer(counter)*8)) downto (40-(conv_integer(counter)*8)));
275
            if (counter < 5) then
276
                next_state                  <= GEN_SA;
277
            else
278
                next_state                  <= GEN_E_TYPE;
279
                next_counter                <= (others => '0');
280
            end if;
281
 
282
        when GEN_E_TYPE =>
283
        -- Generate the E_TYPE for the response
284
            next_DATA_VALID_TX              <= '1';
285
            next_counter                    <= counter + 1;
286
            next_DATA_TX                    <= E_TYPE_ARP(conv_integer(counter));
287
            if (counter < 1) then
288
                next_state                  <= GEN_E_TYPE;
289
            else
290
                next_state                  <= GEN_H_TYPE;
291
                next_counter                <= (others => '0');
292
            end if;
293
 
294
        when GEN_H_TYPE =>
295
        -- Generate the H_TYPE for the response
296
            next_DATA_VALID_TX              <= '1';
297
            next_counter                    <= counter + 1;
298
            next_DATA_TX                    <= H_TYPE_ETH(conv_integer(counter));
299
            if (counter < 1) then
300
                next_state                  <= GEN_H_TYPE;
301
            else
302
                next_state                  <= GEN_P_TYPE;
303
                next_counter                <= (others => '0');
304
            end if;
305
 
306
        when GEN_P_TYPE =>
307
        -- Generate the P_TYPE for the response
308
            next_DATA_VALID_TX              <= '1';
309
            next_counter                    <= counter + 1;
310
            next_DATA_TX                    <= P_TYPE_IPV4(conv_integer(counter));
311
            if (counter < 1) then
312
                next_state                  <= GEN_P_TYPE;
313
            else
314
                next_state                  <= GEN_H_LEN;
315
                next_counter                <= (others => '0');
316
            end if;
317
 
318
        when GEN_H_LEN =>
319
            next_DATA_VALID_TX              <= '1';
320
            next_DATA_TX                    <= H_TYPE_ETH_LEN;
321
            next_state                      <= GEN_P_LEN;
322
 
323
        when GEN_P_LEN =>
324
            next_DATA_VALID_TX              <= '1';
325
            next_DATA_TX                    <= P_TYPE_IPV4_LEN;
326
            next_state                      <= GEN_OPER;
327
 
328
        when GEN_OPER =>
329
            next_DATA_VALID_TX              <= '1';
330
            next_counter                    <= counter + 1;
331
            next_DATA_TX                    <= ARP_OPER_RESP(conv_integer(counter));
332
            if (counter < 1) then
333
                next_state                  <= GEN_OPER;
334
            else
335
                next_state                  <= GEN_SHA;
336
                next_counter                <= (others => '0');
337
            end if;
338
 
339
        when GEN_SHA =>
340
            next_DATA_VALID_TX              <= '1';
341
            next_counter                    <= counter + 1;
342
            next_DATA_TX                    <= MY_MAC((47-(conv_integer(counter)*8)) downto (40-(conv_integer(counter)*8)));
343
            if (counter < 5) then
344
                next_state                  <= GEN_SHA;
345
            else
346
                next_state                  <= GEN_SPA;
347
                next_counter                <= (others => '0');
348
            end if;
349
 
350
        when GEN_SPA =>
351
            next_DATA_VALID_TX              <= '1';
352
            next_counter                    <= counter + 1;
353
            next_DATA_TX                    <= MY_IPV4((31-(conv_integer(counter)*8)) downto (24-(conv_integer(counter)*8)));
354
            if (counter < 3) then
355
                next_state                  <= GEN_SPA;
356
            else
357
                next_state                  <= GEN_THA;
358
                next_counter                <= (others => '0');
359
            end if;
360
 
361
        when GEN_THA =>
362
        -- Generate the THA for the response
363
            next_DATA_VALID_TX              <= '1';
364
            next_counter                    <= counter + 1;
365
            next_DATA_TX                    <= SA_mem(conv_integer(counter));
366
            if (counter < 5) then
367
                next_state                  <= GEN_THA;
368
            else
369
                next_state                  <= GEN_TPA;
370
                next_counter                <= (others => '0');
371
            end if;
372
 
373
        when GEN_TPA =>
374
        -- Generate the TPA for the response
375
            next_DATA_VALID_TX              <= '1';
376
            next_counter                    <= counter + 1;
377
            next_DATA_TX                    <= SPA_mem(conv_integer(counter));
378
            if (counter < 3) then
379
                next_state                  <= GEN_TPA;
380
            else
381
                next_state                  <= IDLE;
382
                next_counter                <= (others => '0');
383
            end if;
384
 
385
        when others =>
386
            next_state    <= IDLE;
387
 
388
    end case;
389
 
390
end process combo;
391
----------------------------------------------------------------------------------
392
--Sequential Logic Processes--------------------------------------------------------
393
----------------------------------------------------------------------------------
394
seq_RX:process(CLK_RX, ARESET)
395
begin
396
 
397
    if (ARESET='1') then --resetting the board
398
        state               <= IDLE;
399
        counter             <= (others => '0');
400
        SA_mem              <= ((others => '0'),(others => '0'),(others => '0'),(others => '0'),(others => '0'),(others => '0'));
401
        SPA_mem             <= ((others => '0'),(others => '0'),(others => '0'),(others => '0'));
402
 
403
    -- move next state values into registers on clock edge
404
    elsif (CLK_RX'event and CLK_RX ='1') then
405
        state               <= next_state;
406
        counter             <= next_counter;
407
        SA_mem              <= next_SA_mem;
408
        SPA_mem             <= next_SPA_mem;
409
 
410
    else
411
        NULL;
412
    end if;
413
 
414
end process seq_RX;
415
 
416
seq_TX:process(CLK_TX, ARESET)
417
begin
418
 
419
    if (ARESET='1') then --resetting the board
420
        DATA_VALID_TX       <= '0';
421
        DATA_TX             <= (others => '0');
422
    -- move next state values into registers on clock edge
423
    elsif (CLK_TX'event and CLK_TX ='1') then
424
        DATA_VALID_TX       <= next_DATA_VALID_TX;
425
        DATA_TX             <= next_DATA_TX;
426
    else
427
        NULL;
428
    end if;
429
 
430
end process seq_TX;
431
 
432
end rtl;

powered by: WebSVN 2.1.0

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