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 18

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 10 pjf
----------------------------------------------------------------------------------
2
-- Company: 
3 18 pjf
-- Engineer:            Peter Fall
4 10 pjf
-- 
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 18 pjf
--              handle transmission of an ARP packet.
13 10 pjf
--
14
-- Dependencies: 
15
--
16
-- Revision: 
17 18 pjf
-- Revision 0.01 - File Created - refactored this arp_tx module from the complete arp v0.02 module
18 10 pjf
-- Additional Comments: 
19
--
20
----------------------------------------------------------------------------------
21 18 pjf
  library IEEE;
22
use IEEE.STD_LOGIC_1164.all;
23
use IEEE.NUMERIC_STD.all;
24 10 pjf
use work.arp_types.all;
25
 
26
entity arp_tx is
27 18 pjf
  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 10 pjf
end arp_tx;
48
 
49
architecture Behavioral of arp_tx is
50
 
51 18 pjf
  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 10 pjf
 
56 18 pjf
  -- 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 10 pjf
 
67 18 pjf
  -- 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 10 pjf
 
72 18 pjf
  -- 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 10 pjf
 
84 18 pjf
  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 10 pjf
 
101 18 pjf
    -- 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 => '1');
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 => '1');
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" => data_out_first <= data_out_ready;
181
                        data_out <= target.mac (47 downto 40);       -- target mac--data_out       <= x"ff";    -- dst = broadcast            
182
          when x"01" => data_out <= target.mac (39 downto 32);                    --data_out <= x"ff";
183
          when x"02" => data_out <= target.mac (31 downto 24);                    --data_out <= x"ff";
184
          when x"03" => data_out <= target.mac (23 downto 16);                    --data_out <= x"ff";
185
          when x"04" => data_out <= target.mac (15 downto 8);                     --data_out <= x"ff";
186
          when x"05" => data_out <= target.mac (7 downto 0);                      --data_out <= x"ff";
187
          when x"06" => data_out <= our_mac_address (47 downto 40);  -- src = our mac
188
          when x"07" => data_out <= our_mac_address (39 downto 32);
189
          when x"08" => data_out <= our_mac_address (31 downto 24);
190
          when x"09" => data_out <= our_mac_address (23 downto 16);
191
          when x"0a" => data_out <= our_mac_address (15 downto 8);
192
          when x"0b" => data_out <= our_mac_address (7 downto 0);
193
          when x"0c" => data_out <= x"08";                           -- pkt type = 0806 : ARP
194
          when x"0d" => data_out <= x"06";
195
          when x"0e" => data_out <= x"00";                           -- HW type = 0001 : eth
196
          when x"0f" => data_out <= x"01";
197
          when x"10" => data_out <= x"08";                           -- protocol = 0800 : ip
198
          when x"11" => data_out <= x"00";
199
          when x"12" => data_out <= x"06";                           -- HW size = 06
200
          when x"13" => data_out <= x"04";                           -- prot size = 04
201
 
202
          when x"14" => data_out <= x"00";  -- opcode =             
203
          when x"15" =>
204
            if tx_mode = REPLY then
205
              data_out <= x"02";            -- 02 : REPLY
206
            else
207
              data_out <= x"01";            -- 01 : REQ
208
            end if;
209
 
210
          when x"16" => data_out <= our_mac_address (47 downto 40);  -- sender mac
211
          when x"17" => data_out <= our_mac_address (39 downto 32);
212
          when x"18" => data_out <= our_mac_address (31 downto 24);
213
          when x"19" => data_out <= our_mac_address (23 downto 16);
214
          when x"1a" => data_out <= our_mac_address (15 downto 8);
215
          when x"1b" => data_out <= our_mac_address (7 downto 0);
216
          when x"1c" => data_out <= our_ip_address (31 downto 24);   -- sender ip
217
          when x"1d" => data_out <= our_ip_address (23 downto 16);
218
          when x"1e" => data_out <= our_ip_address (15 downto 8);
219
          when x"1f" => data_out <= our_ip_address (7 downto 0);
220
          when x"20" => data_out <= target.mac (47 downto 40);       -- target mac
221
          when x"21" => data_out <= target.mac (39 downto 32);
222
          when x"22" => data_out <= target.mac (31 downto 24);
223
          when x"23" => data_out <= target.mac (23 downto 16);
224
          when x"24" => data_out <= target.mac (15 downto 8);
225
          when x"25" => data_out <= target.mac (7 downto 0);
226
          when x"26" => data_out <= target.ip (31 downto 24);        -- target ip
227
          when x"27" => data_out <= target.ip (23 downto 16);
228
          when x"28" => data_out <= target.ip (15 downto 8);
229
 
230
          when x"29" =>
231
            data_out      <= target.ip(7 downto 0);
232
            data_out_last <= '1';
233
 
234
          when x"2a" =>
235
            kill_data_out_valid <= '1';  -- data is no longer valid
236
            next_tx_state       <= IDLE;
237
            set_tx_state        <= '1';
238
 
239
          when others =>
240
            next_tx_state <= IDLE;
241
            set_tx_state  <= '1';
242
        end case;
243
    end case;
244
  end process;
245
 
246
  tx_sequential : process (tx_clk)
247
  begin
248
    if rising_edge(tx_clk) then
249
      if reset = '1' then
250
        -- reset state variables
251
        tx_state          <= IDLE;
252
        tx_count          <= (others => '0');
253
        tx_mac_chn_reqd   <= '0';
254
        send_I_have_reg   <= '0';
255
        send_who_has_reg  <= '0';
256
        who_has_target    <= (others => '0');
257
        I_have_target.ip  <= (others => '0');
258
        I_have_target.mac <= (others => '0');
259
        target.ip         <= (others => '0');
260
        target.mac        <= (others => '1');
261
 
262
      else
263
        -- normal (non reset) processing
264
 
265
        -- Next tx_state processing
266
        if set_tx_state = '1' then
267
          tx_state <= next_tx_state;
268
        else
269
          tx_state <= tx_state;
270
        end if;
271
 
272
        -- input request latching
273
        case set_send_I_have is
274
          when SET =>
275
            send_I_have_reg <= '1';
276
            I_have_target   <= arp_entry;
277
          when CLR =>
278
            send_I_have_reg <= '0';
279
            I_have_target   <= I_have_target;
280
          when HOLD =>
281
            send_I_have_reg <= send_I_have_reg;
282
            I_have_target   <= I_have_target;
283
        end case;
284
 
285
        case set_send_who_has is
286
          when SET =>
287
            send_who_has_reg <= '1';
288
            who_has_target   <= ip_entry;
289
          when CLR =>
290
            send_who_has_reg <= '0';
291
            who_has_target   <= who_has_target;
292
          when HOLD =>
293
            send_who_has_reg <= send_who_has_reg;
294
            who_has_target   <= who_has_target;
295
        end case;
296
 
297
        -- tx mode
298
        if set_tx_mode = '1' then
299
          tx_mode <= tx_mode_val;
300
        else
301
          tx_mode <= tx_mode;
302
        end if;
303
 
304
        -- target latching
305
        if set_target = '1' then
306
          target <= target_val;
307
        else
308
          target <= target;
309
        end if;
310
 
311
        -- tx_count processing
312
        case tx_count_mode is
313
          when RST =>
314
            tx_count <= x"00";
315
          when INCR =>
316
            tx_count <= tx_count + 1;
317
          when HOLD =>
318
            tx_count <= tx_count;
319
        end case;
320
 
321
        -- control access request to mac tx chn
322
        case set_chn_reqd is
323
          when SET  => tx_mac_chn_reqd <= '1';
324
          when CLR  => tx_mac_chn_reqd <= '0';
325
          when HOLD => tx_mac_chn_reqd <= tx_mac_chn_reqd;
326
        end case;
327
 
328
      end if;
329
    end if;
330
  end process;
331
 
332
 
333 10 pjf
end Behavioral;
334
 

powered by: WebSVN 2.1.0

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