AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
All Classes Variables
udp_packet_parser.vhd
1 -- Parses first 42 bytes of incoming ethernet packet for supported protocols
2 --
3 -- Dave Sankey, June 2012, March 2013
4 
5 library ieee;
6 use ieee.std_logic_1164.all;
7 
9  generic(
10  IPBUSPORT: std_logic_vector(15 DOWNTO 0) := x"C351";
11  SECONDARYPORT: std_logic := '0'
12  );
13  port (
14  mac_clk: in std_logic;
15  rx_reset: in std_logic;
16  enable_125: std_logic;
17  mac_rx_data: in std_logic_vector(7 downto 0);
18  mac_rx_valid: in std_logic;
19  MAC_addr: in std_logic_vector(47 downto 0);
20  My_IP_addr: in std_logic_vector(31 downto 0);
21  next_pkt_id: in std_logic_vector(15 downto 0);
22  pkt_broadcast: out std_logic;
23  pkt_byteswap: out std_logic;
24  pkt_drop_arp: out std_logic;
25  pkt_drop_ipbus: out std_logic;
26  pkt_drop_payload: out std_logic;
27  pkt_drop_ping: out std_logic;
28  pkt_drop_rarp: out std_logic;
29  pkt_drop_reliable: out std_logic;
30  pkt_drop_resend: out std_logic;
31  pkt_drop_status: out std_logic
32  );
33 end udp_packet_parser;
34 
35 architecture v3 of udp_packet_parser is
36 
37  signal pkt_drop_arp_sig, pkt_drop_rarp_sig, pkt_drop_ping_sig: std_logic;
38  signal pkt_drop_ip_sig, pkt_drop_ipbus_sig: std_logic;
39  signal pkt_drop_payload_sig, pkt_payload_drop_sig: std_logic;
40  signal pkt_drop_reliable_sig, pkt_reliable_drop_sig: std_logic;
41  signal ipbus_status_mask, ipbus_hdr_mask: std_logic;
42 
43 begin
44 
45  pkt_drop_arp <= pkt_drop_arp_sig or SECONDARYPORT;
46  pkt_drop_rarp <= pkt_drop_rarp_sig or SECONDARYPORT;
47  pkt_drop_ping <= pkt_drop_ping_sig or SECONDARYPORT;
48  pkt_drop_ipbus <= pkt_drop_ipbus_sig;
49  pkt_drop_payload <= pkt_drop_payload_sig and pkt_payload_drop_sig;
50  pkt_drop_reliable <= pkt_drop_reliable_sig and pkt_reliable_drop_sig;
51  pkt_byteswap <= pkt_drop_payload_sig;
52 
53 -- ARP:
54 -- Ethernet DST_MAC(6), SRC_MAC(6), Ether_Type = x"0806"
55 -- HTYPE = x"0001"
56 -- PTYPE = x"0800"
57 -- HLEN = x"06", PLEN = x"04"
58 -- OPER = x"0001"
59 -- SHA(6)
60 -- SPA(4)
61 -- THA(6)
62 -- TPA(4) = MY_IP(4)
63 arp: process (mac_clk)
64  variable pkt_data: std_logic_vector(111 downto 0);
65  variable pkt_mask: std_logic_vector(41 downto 0);
66  variable pkt_drop: std_logic;
67  begin
68  if rising_edge(mac_clk) then
69  if rx_reset = '1' then
70  pkt_mask := "111111" & "111111" & "00" &
71  "00" & "00" & "00" & "00" & "111111" &
72  "1111" & "111111" & "0000";
73  pkt_data := x"0806" & x"0001" & x"0800" & x"0604" & x"0001" & My_IP_addr;
74  pkt_drop := not enable_125;
75  elsif mac_rx_valid = '1' then
76  if pkt_mask(41) = '0' then
77  if pkt_data(111 downto 104) /= mac_rx_data then
78  pkt_drop := '1';
79  end if;
80  pkt_data := pkt_data(103 downto 0) & x"00";
81  end if;
82  pkt_mask := pkt_mask(40 downto 0) & '1';
83  end if;
84  pkt_drop_arp_sig <= pkt_drop
85 -- pragma translate_off
86  after 4 ns
87 -- pragma translate_on
88  ;
89  end if;
90  end process;
91 
92 -- RARP:
93 -- Ethernet DST_MAC(6), SRC_MAC(6), Ether_Type = x"8035"
94 -- HTYPE = x"0001"
95 -- PTYPE = x"0800"
96 -- HLEN = x"06", PLEN = x"04"
97 -- OPER = x"0004"
98 -- SHA(6)
99 -- SPA(4)
100 -- THA(6) = MAC_addr
101 -- TPA(4) = MY_IP(4)
102 rarp: process (mac_clk)
103  variable pkt_data: std_logic_vector(127 downto 0);
104  variable pkt_mask: std_logic_vector(37 downto 0);
105  variable pkt_drop: std_logic;
106  begin
107  if rising_edge(mac_clk) then
108  if rx_reset = '1' then
109  pkt_mask := "111111" & "111111" & "00" &
110  "00" & "00" & "00" & "00" & "111111" &
111  "1111" & "000000";
112  pkt_data := x"8035" & x"0001" & x"0800" & x"0604" & x"0004" & MAC_addr;
113  pkt_drop := not enable_125;
114  elsif mac_rx_valid = '1' then
115  if pkt_mask(37) = '0' then
116  if pkt_data(127 downto 120) /= mac_rx_data then
117  pkt_drop := '1';
118  end if;
119  pkt_data := pkt_data(119 downto 0) & x"00";
120  end if;
121  pkt_mask := pkt_mask(36 downto 0) & '1';
122  end if;
123  pkt_drop_rarp_sig <= pkt_drop
124 -- pragma translate_off
125  after 4 ns
126 -- pragma translate_on
127  ;
128  end if;
129  end process;
130 
131 -- IP packet:
132 -- Ethernet DST_MAC(6), SRC_MAC(6), Ether_Type = x"0800"
133 -- IP VERS = x"4", HL = x"5", TOS = x"00"
134 -- IP LEN
135 -- IP ID
136 -- IP FLAG-FRAG = x"4000" or x"0000"
137 -- IP TTL, PROTO
138 -- IP CKSUM
139 -- IP SPA(4)
140 -- IP DPA(4)
141 ip_pkt: process (mac_clk)
142  variable pkt_data: std_logic_vector(127 downto 0);
143  variable pkt_mask: std_logic_vector(33 downto 0);
144  variable msk_data: std_logic_vector(7 downto 0);
145  variable msk_mask: std_logic_vector(9 downto 0);
146  variable pkt_drop: std_logic;
147  begin
148  if rising_edge(mac_clk) then
149  if rx_reset = '1' then
150  pkt_mask := "000000" & "111111" & "00" &
151  "00" & "11" & "11" & "00" & "1" & "1" & "11" &
152  "1111" & "0000";
153  msk_mask := "111111" & "11" & "10";
154  pkt_data := MAC_addr & x"0800" & x"4500" & x"0000" & My_IP_addr;
155  msk_data := (Others => '1');
156  pkt_drop := not enable_125;
157  elsif mac_rx_valid = '1' then
158  if pkt_mask(33) = '0' then
159  if pkt_data(127 downto 120) /= (mac_rx_data and msk_data) then
160  pkt_drop := '1';
161  end if;
162  pkt_data := pkt_data(119 downto 0) & x"00";
163  if msk_mask(9) = '0' then
164  msk_data := "10111111";
165  else
166  msk_data := (Others => '1');
167  end if;
168  msk_mask := msk_mask(8 downto 0) & '1';
169  end if;
170  pkt_mask := pkt_mask(32 downto 0) & '1';
171  end if;
172  pkt_drop_ip_sig <= pkt_drop
173 -- pragma translate_off
174  after 4 ns
175 -- pragma translate_on
176  ;
177  end if;
178  end process;
179 
180 -- Ping:
181 -- Ethernet
182 -- IP VERS, HL, TOS
183 -- IP LEN
184 -- IP ID
185 -- IP FLAG-FRAG
186 -- IP TTL, PROTO = x"01"
187 -- IP CKSUM
188 -- IP SPA(4)
189 -- IP DPA(4)
190 -- ICMP TYPE = "08", CODE = "00"
191 -- ICMP CKSUM
192 -- ICMP data...
193 ping: process (mac_clk)
194  variable pkt_data: std_logic_vector(23 downto 0);
195  variable pkt_mask: std_logic_vector(35 downto 0);
196  variable pkt_drop: std_logic;
197  begin
198  if rising_edge(mac_clk) then
199  if rx_reset = '1' then
200  pkt_mask := "111111" & "111111" & "11" &
201  "11" & "11" & "11" & "11" & "1" & "0" & "11" &
202  "1111" & "1111" & "00";
203  pkt_data := x"01" & x"0800";
204  pkt_drop := not enable_125;
205  elsif mac_rx_valid = '1' then
206  if pkt_drop_ip_sig = '1' then
207  pkt_drop := '1';
208  elsif pkt_mask(35) = '0' then
209  if pkt_data(23 downto 16) /= mac_rx_data then
210  pkt_drop := '1';
211  end if;
212  pkt_data := pkt_data(15 downto 0) & x"00";
213  end if;
214  pkt_mask := pkt_mask(34 downto 0) & '1';
215  end if;
216  pkt_drop_ping_sig <= pkt_drop
217 -- pragma translate_off
218  after 4 ns
219 -- pragma translate_on
220  ;
221  end if;
222  end process;
223 
224 -- UDP packet to IPbus port:
225 -- Ethernet
226 -- IP VERS, HL, TOS
227 -- IP LEN
228 -- IP ID
229 -- IP FLAG-FRAG
230 -- IP TTL, PROTO = x"11"
231 -- IP CKSUM
232 -- IP SPA(4)
233 -- IP DPA(4)
234 -- UDP SRCPORT
235 -- UDP DSTPORT (50001)
236 ipbus_pkt: process (mac_clk)
237  variable pkt_data: std_logic_vector(23 downto 0);
238  variable pkt_mask: std_logic_vector(37 downto 0);
239  variable pkt_drop: std_logic;
240  begin
241  if rising_edge(mac_clk) then
242  if rx_reset = '1' then
243  pkt_mask := "111111" & "111111" & "11" &
244  "11" & "11" & "11" & "11" & "1" & "0" & "11" &
245  "1111" & "1111" & "11" & "00";
246  pkt_data := x"11" & IPBUSPORT;
247  pkt_drop := not enable_125;
248  elsif mac_rx_valid = '1' then
249  if pkt_drop_ip_sig = '1' then
250  pkt_drop := '1';
251  elsif pkt_mask(37) = '0' then
252  if pkt_data(23 downto 16) /= mac_rx_data then
253  pkt_drop := '1';
254  end if;
255  pkt_data := pkt_data(15 downto 0) & x"00";
256  end if;
257  pkt_mask := pkt_mask(36 downto 0) & '1';
258  end if;
259  pkt_drop_ipbus_sig <= pkt_drop
260 -- pragma translate_off
261  after 4 ns
262 -- pragma translate_on
263  ;
264  end if;
265  end process;
266 
267 -- IPbus header parsers (switch 1 tick earlier...)
268 ipbus_mask: process(mac_clk)
269  variable pkt_mask: std_logic_vector(44 downto 0);
270  variable last_mask, header_sel: std_logic;
271  begin
272  if rising_edge(mac_clk) then
273  if rx_reset = '1' then
274  pkt_mask := "111111" & "111111" & "11" &
275  "11" & "11" & "11" & "11" & "1" & "1" & "11" &
276  "1111" & "1111" & "11" & "1" & "00" & "11" & "0000";
277  last_mask := '1';
278  header_sel := '1';
279  elsif mac_rx_valid = '1' then
280  if pkt_mask(44) = '1' and last_mask = '0' then
281  header_sel := '0';
282  end if;
283  last_mask := pkt_mask(44);
284  pkt_mask := pkt_mask(43 downto 0) & '1';
285  end if;
286  ipbus_status_mask <= last_mask
287 -- pragma translate_off
288  after 4 ns
289 -- pragma translate_on
290  ;
291  ipbus_hdr_mask <= last_mask or header_sel
292 -- pragma translate_off
293  after 4 ns
294 -- pragma translate_on
295  ;
296  end if;
297  end process;
298 
299 -- UDP payload:
300 -- IPBus packet header x"20nnnnF0" or x"200000F0"
301 -- IPBus data...
302 bigendian: process (mac_clk)
303  variable reliable_data: std_logic_vector(31 downto 0);
304  variable unreliable_data: std_logic_vector(31 downto 0);
305  variable pkt_drop_reliable_i, pkt_drop_unreliable: std_logic;
306  begin
307  if rising_edge(mac_clk) then
308  if rx_reset = '1' then
309  reliable_data := x"20" & next_pkt_id & x"F0";
310  unreliable_data := x"200000F0";
311  pkt_drop_reliable_i := not enable_125;
312  pkt_drop_unreliable := not enable_125;
313  elsif mac_rx_valid = '1' then
314  if pkt_drop_ipbus_sig = '1' then
315  pkt_drop_reliable_i := '1';
316  pkt_drop_unreliable := '1';
317  elsif ipbus_hdr_mask = '0' then
318  if reliable_data(31 downto 24) /= mac_rx_data then
319  pkt_drop_reliable_i := '1';
320  end if;
321  if unreliable_data(31 downto 24) /= mac_rx_data then
322  pkt_drop_unreliable := '1';
323  end if;
324  reliable_data := reliable_data(23 downto 0) & x"00";
325  unreliable_data := unreliable_data(23 downto 0) & x"00";
326  end if;
327  end if;
328  pkt_drop_reliable_sig <= pkt_drop_reliable_i
329 -- pragma translate_off
330  after 4 ns
331 -- pragma translate_on
332  ;
333  pkt_drop_payload_sig <= pkt_drop_reliable_i and pkt_drop_unreliable
334 -- pragma translate_off
335  after 4 ns
336 -- pragma translate_on
337  ;
338  end if;
339  end process;
340 
341 -- UDP payload:
342 -- IPBus packet header x"F0nnnn20" or x"F0000020"
343 -- IPBus data...
344 littleendian: process (mac_clk)
345  variable reliable_data: std_logic_vector(31 downto 0);
346  variable unreliable_data: std_logic_vector(31 downto 0);
347  variable pkt_drop_reliable_i, pkt_drop_unreliable: std_logic;
348  begin
349  if rising_edge(mac_clk) then
350  if rx_reset = '1' then
351  reliable_data := x"F0" & next_pkt_id(7 downto 0) &
352  next_pkt_id(15 downto 8) & x"20";
353  unreliable_data := x"F0000020";
354  pkt_drop_reliable_i := not enable_125;
355  pkt_drop_unreliable := not enable_125;
356  elsif mac_rx_valid = '1' then
357  if pkt_drop_ipbus_sig = '1' then
358  pkt_drop_reliable_i := '1';
359  pkt_drop_unreliable := '1';
360  elsif ipbus_hdr_mask = '0' then
361  if reliable_data(31 downto 24) /= mac_rx_data then
362  pkt_drop_reliable_i := '1';
363  end if;
364  if unreliable_data(31 downto 24) /= mac_rx_data then
365  pkt_drop_unreliable := '1';
366  end if;
367  reliable_data := reliable_data(23 downto 0) & x"00";
368  unreliable_data := unreliable_data(23 downto 0) & x"00";
369  end if;
370  end if;
371  pkt_reliable_drop_sig <= pkt_drop_reliable_i
372 -- pragma translate_off
373  after 4 ns
374 -- pragma translate_on
375  ;
376  pkt_payload_drop_sig <= pkt_drop_reliable_i and pkt_drop_unreliable
377 -- pragma translate_off
378  after 4 ns
379 -- pragma translate_on
380  ;
381  end if;
382  end process;
383 
384 -- UDP status request:
385 -- UDP LEN (72 = x"48")
386 -- IPBus packet header x"200000F1"
387 status_request: process (mac_clk)
388  variable pkt_data: std_logic_vector(47 downto 0);
389  variable pkt_drop: std_logic;
390  begin
391  if rising_edge(mac_clk) then
392  if rx_reset = '1' then
393  pkt_data := x"0048200000F1";
394  pkt_drop := not enable_125;
395  elsif mac_rx_valid = '1' then
396  if pkt_drop_ipbus_sig = '1' then
397  pkt_drop := '1';
398  elsif ipbus_status_mask = '0' then
399  if pkt_data(47 downto 40) /= mac_rx_data then
400  pkt_drop := '1';
401  end if;
402  pkt_data := pkt_data(39 downto 0) & x"00";
403  end if;
404  end if;
405  pkt_drop_status <= pkt_drop
406 -- pragma translate_off
407  after 4 ns
408 -- pragma translate_on
409  ;
410  end if;
411  end process;
412 
413 -- UDP resend request:
414 -- IPBus packet header x"20XXXXF2"
415 resend: process (mac_clk)
416  variable pkt_data: std_logic_vector(15 downto 0);
417  variable pkt_mask: std_logic_vector(3 downto 0);
418  variable pkt_drop: std_logic;
419  begin
420  if rising_edge(mac_clk) then
421  if rx_reset = '1' then
422  pkt_data := x"20F2";
423  pkt_mask := "0110";
424  pkt_drop := not enable_125;
425  elsif mac_rx_valid = '1' then
426  if pkt_drop_ipbus_sig = '1' then
427  pkt_drop := '1';
428  elsif ipbus_hdr_mask = '0' then
429  if pkt_mask(3) = '0' then
430  if pkt_data(15 downto 8) /= mac_rx_data then
431  pkt_drop := '1';
432  end if;
433  pkt_data := pkt_data(7 downto 0) & x"00";
434  end if;
435  pkt_mask := pkt_mask(2 downto 0) & '1';
436  end if;
437  end if;
438  pkt_drop_resend <= pkt_drop
439 -- pragma translate_off
440  after 4 ns
441 -- pragma translate_on
442  ;
443  end if;
444  end process;
445 
446 broadcast: process (mac_clk)
447  variable pkt_mask: std_logic_vector(5 downto 0);
448  variable broadcast_int: std_logic;
449  begin
450  if rising_edge(mac_clk) then
451  if rx_reset = '1' then
452  pkt_mask := (Others => '0');
453  broadcast_int := '1';
454  elsif mac_rx_valid = '1' and pkt_mask(5) = '0' then
455  if mac_rx_data /= x"FF" then
456  broadcast_int := '0';
457  end if;
458  pkt_mask := pkt_mask(4 downto 0) & '1';
459  end if;
460  pkt_broadcast <= broadcast_int
461 -- pragma translate_off
462  after 4 ns
463 -- pragma translate_on
464  ;
465  end if;
466  end process;
467 
468 end v3;