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

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

Line No. Rev Author Line
1 10 pjf
----------------------------------------------------------------------------------
2
-- Company: 
3
-- Engineer:            Peter Fall
4
-- 
5
-- Create Date:    12:00:04 05/31/2011 
6
-- Design Name: 
7
-- Module Name:    arp_tx - Behavioral 
8
-- Project Name: 
9
-- Target Devices: 
10
-- Tool versions: 
11
-- Description:
12
--              handle transmission of an ARP packet.
13
--
14
-- Dependencies: 
15
--
16
-- Revision: 
17
-- Revision 0.01 - File Created - refactored this arp_tx module from the complete arp v0.02 module
18
-- Additional Comments: 
19
--
20
----------------------------------------------------------------------------------
21
library IEEE;
22
use IEEE.STD_LOGIC_1164.ALL;
23
use IEEE.NUMERIC_STD.ALL;
24
use work.arp_types.all;
25
 
26
entity arp_tx is
27
    Port (
28
                        -- control signals
29
                        send_I_have                     : in std_logic;                                                                 -- pulse will be latched
30
                        arp_entry                       : in arp_entry_t;                                                                       -- arp target for I_have req (will be latched)
31
                        send_who_has            : in std_logic;                                                                 -- pulse will be latched
32
                        ip_entry                                : in STD_LOGIC_VECTOR (31 downto 0);             -- IP target for who_has req (will be latched)
33
                        -- MAC layer TX signals
34
                        mac_tx_req                      : out std_logic;                                                                        -- indicates that ip wants access to channel (stays up for as long as tx)
35
                        mac_tx_granted          : in std_logic;                                                                 -- indicates that access to channel has been granted            
36
                        data_out_ready          : in std_logic;                                                                 -- indicates system ready to consume data
37
                        data_out_valid          : out std_logic;                                                                        -- indicates data out is valid
38
                        data_out_first          : out std_logic;                                                                        -- with data out valid indicates the first byte of a frame
39
                        data_out_last           : out std_logic;                                                                        -- with data out valid indicates the last byte of a frame
40
                        data_out                                : out std_logic_vector (7 downto 0);             -- ethernet frame (from dst mac addr through to last byte of frame)
41
                        -- system signals
42
                        our_mac_address         : in STD_LOGIC_VECTOR (47 downto 0);
43
                        our_ip_address  : in STD_LOGIC_VECTOR (31 downto 0);
44
                        tx_clk                          : in std_logic;
45
                        reset                                   : in std_logic
46
                        );
47
end arp_tx;
48
 
49
architecture Behavioral of arp_tx is
50
 
51
        type count_mode_t is (RST,INCR,HOLD);
52
        type set_clr_t is (SET, CLR, HOLD);
53
        type tx_state_t is (IDLE,WAIT_MAC,SEND);
54
        type tx_mode_t is (REPLY,REQUEST);
55
 
56
        -- state variables
57
        signal tx_mac_chn_reqd  : std_logic;
58
        signal tx_state                 : tx_state_t;
59
        signal tx_count                         : unsigned (7 downto 0);
60
        signal send_I_have_reg  : std_logic;
61
        signal send_who_has_reg : std_logic;
62
        signal I_have_target            : arp_entry_t;                                                          -- latched target for "I have" request
63
        signal who_has_target   : std_logic_vector (31 downto 0);        -- latched IP for "who has" request
64
        signal tx_mode                          : tx_mode_t;                                                            -- what sort of tx to make
65
        signal target                           : arp_entry_t;                                                          -- target to send to
66
 
67
        -- busses
68
        signal next_tx_state    : tx_state_t;
69
        signal tx_mode_val              : tx_mode_t;
70
        signal target_val                       : arp_entry_t;
71
 
72
        -- tx control signals
73
        signal set_tx_state             : std_logic;
74
        signal tx_count_mode            : count_mode_t;
75
        signal set_chn_reqd             : set_clr_t;
76
        signal kill_data_out_valid      : std_logic;
77
        signal set_send_I_have  : set_clr_t;
78
        signal set_send_who_has : set_clr_t;
79
        signal set_tx_mode              : std_logic;
80
        signal set_target                       : std_logic;
81
 
82
begin
83
 
84
        tx_combinatorial : process (
85
                -- input signals
86
                send_I_have, send_who_has, arp_entry, ip_entry, data_out_ready, mac_tx_granted,
87
                our_mac_address, our_ip_address, reset,
88
                -- state variables
89
                tx_state, tx_count, tx_mac_chn_reqd, I_have_target, who_has_target,
90
                send_I_have_reg, send_who_has_reg, tx_mode, target,
91
                -- busses
92
                next_tx_state, tx_mode_val, target_val,
93
                -- control signals
94
                tx_count_mode, kill_data_out_valid, set_send_I_have, set_send_who_has,
95
                set_chn_reqd, set_tx_mode, set_target
96
                )
97
        begin
98
                -- set output followers
99
                mac_tx_req <= tx_mac_chn_reqd;
100
 
101
                -- set combinatorial output defaults
102
                data_out_first <= '0';
103
 
104
                case tx_state is
105
                        when SEND   =>
106
                                if data_out_ready = '1' and kill_data_out_valid = '0' then
107
                                        data_out_valid <= '1';
108
                                else
109
                                        data_out_valid <= '0';
110
                                end if;
111
                        when OTHERS =>  data_out_valid <= '0';
112
                end case;
113
 
114
                -- set bus defaults
115
                next_tx_state <= IDLE;
116
                tx_mode_val <= REPLY;
117
                target_val.ip <= (others => '0');
118
                target_val.mac <= (others => '0');
119
 
120
                -- set signal defaults
121
                set_tx_state <= '0';
122
                tx_count_mode <= HOLD;
123
                data_out <= x"00";
124
                data_out_last <= '0';
125
                set_chn_reqd <= HOLD;
126
                kill_data_out_valid <= '0';
127
                set_send_I_have <= HOLD;
128
                set_send_who_has <= HOLD;
129
                set_tx_mode <= '0';
130
                set_target <= '0';
131
 
132
                -- process requests in regardless of FSM state
133
                if send_I_have = '1' then
134
                        set_send_I_have <= SET;
135
                end if;
136
                if send_who_has = '1' then
137
                        set_send_who_has <= SET;
138
                end if;
139
 
140
                -- TX FSM
141
                case tx_state is
142
                        when IDLE =>
143
                                tx_count_mode <= RST;
144
                                if send_I_have_reg = '1' then
145
                                        set_chn_reqd <= SET;
146
                                        tx_mode_val <= REPLY;
147
                                        set_tx_mode <= '1';
148
                                        target_val <= I_have_target;
149
                                        set_target <= '1';
150
                                        set_send_I_have <= CLR;
151
                                        next_tx_state <= WAIT_MAC;
152
                                        set_tx_state <= '1';
153
                                elsif send_who_has_reg = '1' then
154
                                        set_chn_reqd <= SET;
155
                                        tx_mode_val <= REQUEST;
156
                                        set_tx_mode <= '1';
157
                                        target_val.ip <= who_has_target;
158
                                        target_val.mac <= (others => '0');
159
                                        set_target <= '1';
160
                                        set_send_who_has <= CLR;
161
                                        next_tx_state <= WAIT_MAC;
162
                                        set_tx_state <= '1';
163
                                else
164
                                        set_chn_reqd <= CLR;
165
                                end if;
166
 
167
                        when WAIT_MAC =>
168
                                tx_count_mode <= RST;
169
                                if mac_tx_granted = '1' then
170
                                        next_tx_state <= SEND;
171
                                        set_tx_state <= '1';
172
                                end if;
173
                                -- TODO - should handle timeout here
174
 
175
                        when SEND =>
176
                                if data_out_ready = '1' then
177
                                                tx_count_mode <= INCR;
178
                                end if;
179
                                case tx_count is
180
                                        when x"00"  =>
181
                                                data_out_first <= data_out_ready;
182
                                                data_out <= x"ff";                                                                                                      -- dst = broadcast
183
 
184
                                        when x"01"  => data_out <= x"ff";
185
                                        when x"02"  => data_out <= x"ff";
186
                                        when x"03"  => data_out <= x"ff";
187
                                        when x"04"  => data_out <= x"ff";
188
                                        when x"05"  => data_out <= x"ff";
189
                                        when x"06"  => data_out <= our_mac_address (47 downto 40);      -- src = our mac
190
                                        when x"07"  => data_out <= our_mac_address (39 downto 32);
191
                                        when x"08"  => data_out <= our_mac_address (31 downto 24);
192
                                        when x"09"  => data_out <= our_mac_address (23 downto 16);
193
                                        when x"0a"  => data_out <= our_mac_address (15 downto 8);
194
                                        when x"0b"  => data_out <= our_mac_address (7 downto 0);
195
                                        when x"0c"  => data_out <= x"08";                                                                       -- pkt type = 0806 : ARP
196
                                        when x"0d"  => data_out <= x"06";
197
                                        when x"0e"  => data_out <= x"00";                                                                       -- HW type = 0001 : eth
198
                                        when x"0f"  => data_out <= x"01";
199
                                        when x"10"  => data_out <= x"08";                                                                       -- protocol = 0800 : ip
200
                                        when x"11"  => data_out <= x"00";
201
                                        when x"12"  => data_out <= x"06";                                                                       -- HW size = 06
202
                                        when x"13"  => data_out <= x"04";                                                                       -- prot size = 04
203
 
204
                                        when x"14"  =>  data_out <= x"00";                                                                      -- opcode =             
205
                                        when x"15"  =>
206
                                                if tx_mode = REPLY then
207
                                                        data_out <= x"02";                                                                                                                                                      -- 02 : REPLY
208
                                                else
209
                                                        data_out <= x"01";                                                                                                                                                      -- 01 : REQ
210
                                                end if;
211
 
212
                                        when x"16" => data_out <= our_mac_address (47 downto 40);       -- sender mac
213
                                        when x"17" => data_out <= our_mac_address (39 downto 32);
214
                                        when x"18" => data_out <= our_mac_address (31 downto 24);
215
                                        when x"19" => data_out <= our_mac_address (23 downto 16);
216
                                        when x"1a" => data_out <= our_mac_address (15 downto 8);
217
                                        when x"1b" => data_out <= our_mac_address (7 downto 0);
218
                                        when x"1c" => data_out <= our_ip_address (31 downto 24);        -- sender ip
219
                                        when x"1d" => data_out <= our_ip_address (23 downto 16);
220
                                        when x"1e" => data_out <= our_ip_address (15 downto 8);
221
                                        when x"1f" => data_out <= our_ip_address (7 downto 0);
222
                                        when x"20" => data_out <= target.mac (47 downto 40);    -- target mac
223
                                        when x"21" => data_out <= target.mac (39 downto 32);
224
                                        when x"22" => data_out <= target.mac (31 downto 24);
225
                                        when x"23" => data_out <= target.mac (23 downto 16);
226
                                        when x"24" => data_out <= target.mac (15 downto 8);
227
                                        when x"25" => data_out <= target.mac (7 downto 0);
228
                                        when x"26" => data_out <= target.ip  (31 downto 24);    -- target ip
229
                                        when x"27" => data_out <= target.ip   (23 downto 16);
230
                                        when x"28" => data_out <= target.ip   (15 downto 8);
231
 
232
                                        when x"29" =>
233
                                                data_out <= target.ip(7 downto 0);
234
                                                data_out_last <= '1';
235
 
236
                                        when x"2a" =>
237
                                                kill_data_out_valid <= '1';     -- data is no longer valid
238
                                                next_tx_state <= IDLE;
239
                                                set_tx_state <= '1';
240
 
241
                                        when others =>
242
                                                next_tx_state <= IDLE;
243
                                                set_tx_state <= '1';
244
                                end case;
245
                end case;
246
        end process;
247
 
248
        tx_sequential : process (tx_clk)
249
        begin
250
                if rising_edge(tx_clk) then
251
                        if reset = '1' then
252
                                -- reset state variables
253
                                tx_state <= IDLE;
254
                                tx_count <= (others => '0');
255
                                tx_mac_chn_reqd <= '0';
256
                                send_I_have_reg <= '0';
257
                                send_who_has_reg <= '0';
258
                                who_has_target <= (others => '0');
259
                                I_have_target.ip <= (others => '0');
260
                                I_have_target.mac <= (others => '0');
261
                                target.ip <= (others => '0');
262
                                target.mac <= (others => '0');
263
 
264
                        else
265
                                -- normal (non reset) processing
266
 
267
                                -- Next tx_state processing
268
                                if set_tx_state = '1' then
269
                                        tx_state <= next_tx_state;
270
                                else
271
                                        tx_state <= tx_state;
272
                                end if;
273
 
274
                                -- input request latching
275
                                case set_send_I_have is
276
                                        when SET  =>
277
                                                send_I_have_reg <= '1';
278
                                                I_have_target <= arp_entry;
279
                                        when CLR =>
280
                                                send_I_have_reg <= '0';
281
                                                I_have_target <= I_have_target;
282
                                        when HOLD =>
283
                                                send_I_have_reg <= send_I_have_reg;
284
                                                I_have_target <= I_have_target;
285
                                end case;
286
 
287
                                case set_send_who_has is
288
                                        when SET  =>
289
                                                send_who_has_reg <= '1';
290
                                                who_has_target <= ip_entry;
291
                                        when CLR =>
292
                                                send_who_has_reg <= '0';
293
                                                who_has_target <= who_has_target;
294
                                        when HOLD =>
295
                                                send_who_has_reg <= send_who_has_reg;
296
                                                who_has_target <= who_has_target;
297
                                end case;
298
 
299
                                -- tx mode
300
                                if set_tx_mode = '1' then
301
                                        tx_mode <= tx_mode_val;
302
                                else
303
                                        tx_mode <= tx_mode;
304
                                end if;
305
 
306
                                -- target latching
307
                                if set_target = '1' then
308
                                        target <= target_val;
309
                                else
310
                                        target <= target;
311
                                end if;
312
 
313
                                -- tx_count processing
314
                                case tx_count_mode is
315
                                        when RST =>
316
                                                tx_count <= x"00";
317
                                        when INCR =>
318
                                                tx_count <= tx_count + 1;
319
                                        when HOLD =>
320
                                                tx_count <= tx_count;
321
                                end case;
322
 
323
                                -- control access request to mac tx chn
324
                                case set_chn_reqd is
325
                                        when SET => tx_mac_chn_reqd <= '1';
326
                                        when CLR => tx_mac_chn_reqd <= '0';
327
                                        when HOLD => tx_mac_chn_reqd <= tx_mac_chn_reqd;
328
                                end case;
329
 
330
                        end if;
331
                end if;
332
        end process;
333
 
334
 
335
end Behavioral;
336
 

powered by: WebSVN 2.1.0

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