100base-tx приемник, PHY + разбор MAC/IP/UDP-заголовка для выделения нужных пакетов - на логике, ~200ЛЕ на все, без использования блочной памяти и софт-процессора. Проверил посылкой байта на светодиоды, загораются, как надо.
PHY, правда, не полностью отладил - только для случая, когда опорная частота приемника в ПЛИС выше опорной частоты передатчика в компе (для другого варианта нет подходящего компа под рукой).
Затраты ЛЕ: разбор 50-байтового заголовка ~50 ЛЕ, синхронизация ~50 ЛЕ, остальное сложно разделить, тк не в отдельных модулях, а свалено в топ-модуль. Потом разделю на более мелкие модули.
UPD: модуль разбора заголовка для фильтрации пакетов.
h - эталонные значения полей,
b - маска проверяемых полей.
В данном случае проверяется адресация приемника в ПЛИС:
MAC-адрес, IP-адрес, протокол, порт.
module chk(clk,clr,en,d,ok,err);
input clk,clr,en;
input [3:0] d;
output reg ok,err;
localparam N=100-1;
reg [N:0][3:0] h = {
64'h_55555555555555D5, // преамбула+SFD
48'h_112233445566, // dst MAC
48'h_000000000000,
16'h_0800, // IP
16'h_4500, // IP
16'h_0000,
16'h_0000,
16'h_0000,
16'h_0011, // UDP
16'h_0000,
32'h_00000000,
32'h_C0010102, //dst IP
16'h_0000,
16'h_1DE6, //dst PORT
16'h_0000,
16'h_0000};
reg [N:0] b = {
16'b_1111111111111111, // SFD
12'b_111111111111, // dst MAC
12'b_000000000000,
4'b_1111, // IP
4'b_1111, // IP
4'b_0000,
4'b_0000,
4'b_0000,
4'b_0011, // UDP
4'b_0000,
8'b_00000000,
8'b_11111111, //dst IP
4'b_0000,
4'b_1111, //dst PORT
4'b_0000,
4'b_0000};
reg [6:0] cnt;
always@(posedge clk)begin
if(clr)begin
cnt <= N;
ok <= 0;
err <= 0;
end else if(en&~err&~ok)begin
if(cnt == 0) ok <= 1; else cnt <= cnt-1;
if((b[cnt^1]!=0)&&(d!=h[cnt^1])) err <= 1;
end
end
endmodule
Чтобы комп отправил пакет без ARP-запросов, надо дать консольную команду "arp -s" c нужными аргументами.
Упакованные массивы только в SystemVerilog, поэтому в Квартусе надо включить поддержку SV.