1 -- Builds outbound ARP response
3 -- Dave Sankey, July 2012
6 use ieee.std_logic_1164.
all;
7 use ieee.numeric_std.
all;
13 mac_rx_data: in (7 downto 0);
18 MAC_addr: in (47 downto 0);
19 My_IP_addr: in (31 downto 0);
20 arp_data: out (7 downto 0);
21 arp_addr: out (12 downto 0);
23 arp_end_addr: out (12 downto 0);
30 signal arp_we_sig, set_addr: ;
31 signal send_buf, load_buf: ;
32 signal buf_to_load: (47 downto 0);
33 signal address, addr_to_set: (5 downto 0);
38 arp_addr <= ("0000000" & address);
40 send_packet:
process (mac_clk)
41 variable send_pending, send_i: ;
42 variable end_addr_i: (12 downto 0);
44 if rising_edge(mac_clk) then
45 send_i := send_pending;
46 if send_pending = '1' then
47 end_addr_i := (to_unsigned(41, 13));
49 end_addr_i := (Others => '0');
51 send_pending := mac_rx_last and not (pkt_drop_arp or mac_rx_error);
52 arp_end_addr <= end_addr_i
53 -- pragma translate_off
55 -- pragma translate_on
58 -- pragma translate_off
60 -- pragma translate_on
66 -- Ethernet DST_MAC(6), SRC_MAC(
6), Ether_Type = x"0806"
69 -- HLEN = x"06", PLEN = x"04"
75 address_block:
process(mac_clk)
76 variable addr_to_set_int: (5 downto 0);
77 variable set_addr_int: ;
79 if rising_edge(mac_clk) then
80 if (rx_reset = '1') then
82 addr_to_set_int := to_unsigned(6, 6);
83 elsif (mac_rx_valid = '1') and (pkt_drop_arp = '0') then
84 -- Because address is buffered this logic needs to switch a byte early...
85 case to_integer(address) is
86 -- RX Ethernet Dest MAC bytes 0 to 5 => TX write Source MAC bytes
6 to 11...
89 addr_to_set_int := to_unsigned(0, 6);
90 -- RX Ethernet Source MAC bytes 6 to 11 => TX copy
to Dest MAC bytes
0 to 5...
93 addr_to_set_int := to_unsigned(12, 6);
94 -- RX Eth_Type tho' to ARP Op Code hi bytes 12 to 20 => TX copy data bytes
12 to 20...
97 addr_to_set_int := to_unsigned(32, 6);
98 -- RX ARP sender MAC and IP addr bytes 22 to 31 => TX copy
to target MAC
99 -- and IP addr bytes 32 to 41...
102 addr_to_set_int := to_unsigned(22, 6);
103 -- RX ARP target MAC and IP addr bytes 32 to 41 => TX copy
to sender...
106 addr_to_set_int := to_unsigned(42, 6);
107 -- RX end of packet, just copy safely...
110 addr_to_set_int := (Others => '0');
114 addr_to_set_int := (Others => '0');
116 set_addr <= set_addr_int
117 -- pragma translate_off
119 -- pragma translate_on
121 addr_to_set <= addr_to_set_int
122 -- pragma translate_off
124 -- pragma translate_on
129 build_packet:
process (mac_clk)
130 variable buf_to_load_int: (47 downto 0);
131 variable load_buf_int, send_buf_int, arp_we_i: ;
133 if rising_edge(mac_clk) then
134 if (rx_reset = '1') then
137 buf_to_load_int := MAC_addr;
138 elsif (mac_rx_valid = '1') and (pkt_drop_arp = '0') then
139 -- Because address is buffered this logic needs to switch a byte early...
140 case to_integer(address) is
141 -- RX Ethernet Dest MAC bytes 0 to 5 => TX write Source MAC bytes
6 to 11...
144 -- RX Eth_Type tho' to ARP Op Code hi bytes 12 to 20 => TX copy data bytes
12 to 20...
148 buf_to_load_int := x"020000000000";
149 -- RX ARP Op Code lo byte 21 => TX send '2' byte
21...
152 -- RX ARP sender MAC and IP addr bytes 22 to 31 => TX copy
to target MAC
153 -- and IP addr bytes 32 to 41...
157 buf_to_load_int := MAC_addr;
158 -- RX ARP target MAC bytes 32 to 37 => TX write sender MAC bytes
22 to 27...
161 buf_to_load_int := My_IP_addr & x"0000";
162 -- RX ARP target IP addr bytes 38 to 41 => TX write sender IP addr bytes
28 to 31...
171 arp_we_sig <= arp_we_i
172 -- pragma translate_off
174 -- pragma translate_on
176 load_buf <= load_buf_int
177 -- pragma translate_off
179 -- pragma translate_on
181 buf_to_load <= buf_to_load_int
182 -- pragma translate_off
184 -- pragma translate_on
186 send_buf <= send_buf_int
187 -- pragma translate_off
189 -- pragma translate_on
194 next_addr:
process(mac_clk)
195 variable addr_int, next_addr, addr_to_set_buf: (5 downto 0);
196 variable set_addr_buf: ;
198 if rising_edge(mac_clk) then
199 if set_addr = '1' then
200 addr_to_set_buf := addr_to_set;
203 if rx_reset = '1' or mac_rx_valid = '1' then
204 if set_addr_buf = '1' then
205 addr_int := addr_to_set_buf;
207 elsif pkt_drop_arp = '0' then
208 addr_int := next_addr;
212 -- pragma translate_off
214 -- pragma translate_on
216 next_addr := addr_int + 1;
220 write_data:
process(mac_clk)
221 variable shift_buf: (47 downto 0);
222 variable data_to_send: (7 downto 0);
224 if rising_edge(mac_clk) then
225 data_to_send := (Others => '0');
226 if load_buf = '1' then
227 shift_buf := buf_to_load;
229 if mac_rx_valid = '1' and pkt_drop_arp = '0' then
230 if send_buf = '1' then
231 data_to_send := shift_buf(47 downto 40);
233 data_to_send := mac_rx_data;
235 shift_buf := shift_buf(39 downto 0) & x"00";
237 arp_data <= data_to_send
238 -- pragma translate_off
240 -- pragma translate_on