Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Ethernet на ПЛИС
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
Страницы: 1, 2
Alexey_pashinov
Собрал проект, реализующий Ethernet (PHY+MAC+UDP/IP). Я формирую на ПЛИС'ке данные, которые хочу подать, на UDP. При отвправке самого первого пакета при выставлении сигнала sof, UDP/IP stack формирует arp запрос получателю, далее приходит отправителю ответ и после UDP/IP выствляет сигнал dst_rdy, который говорит о том что блок UDP/IP готов к приему данных для отправки. При передаче остальных пакетов сигнал dst_rdy выставляется почти сразу же после выставления sof (промежуток времени между их выставлением равен длине формируемого заголовка). Проблема заключается в следующем. При отправке самого первого пакета сигнал dst_rdy выставляется не сразу, может выставиться аж через 3-5 мин, может меньше может больше, а может и не выставиться. Но после того как это произошло (установилось видимо связь) дальнейшая передача пакетов происходит исправно. Кстати проблема возникает не всегда, например когда проверяю работу на 100 Мбит, зачастую передача работает и редко такое возникает, а когда проверяю на 1gb то наоборот зачастую не работает и только редко начинает работать сразу. Помогите разобраться с этим, буду очень признателен).

Могу выложить описание автомата формир отправку и диаграммы
billidean
При отправке самого первого пакета Ваш стек отправляет арп-запрос для того, чтобы выяснить, какой МАК-адрес имеет девайс, которому предназначаются передаваемые далее данные. После принятия арп-ответа стек должен сохранить этот МАК-адрес в таблице ассоциации IP-адресов и МАК-адресов. Где-то в этом месте должен и выставляться сигнал dst_rdy. А уже при передаче следующих пакетов стек знает, какой МАК-адрес у девайса с IP-адресом, на который будут переданы данные, и поэтому пауза далее идет минимальная. Я не знаю, что из себя представляет Ваш UDP/IP stack, но логика работы должна быть такая.

Длительная пауза при первом обмене может быть связана с посылкой-приемом арп-запросов/ответов. Нужно смотреть сниффером (wireshark), что происходит на линии езернета, какой сформирован арп-запрос, какой приходит арп-ответ, время между ними и т.п.

Диаграммы можно было бы посмотреть, может они что-нибудь прояснят.
Alexey_pashinov
Это я и пояснил во вступлении чтобы было понятно о чем речь, проблема в том что бывает так что пауза при отправке arp бывет неприлично долгой, т.е. arp ответ получает сразу он поступает на UDP, а сигнал dst_rdy выставляться не хочет, точнее делает это через большой промежуток времени
billidean
Имея картину от сниффера (сохраненный файл), можно было бы полнее проанализировать ситуацию.
Т.е. может не в самом стеке дело, не в том, что он так долго анализирует принятый арп-ответ, а в том, что творится на линии.
Socrates
FPGA Triple speed ethernet MAC + Micrel KSZ9021/KSZ9031 + UDP port to Avalon-ST channel splitter + Nios II + LwIP 1.41.
Alexey_pashinov
Привожу скрин wireshark, в обоих случаях arp запросы и ответы идентичны (физ адрес разный т.к рабочий выриант был подключен к 100 мбит а нерабочий к 1 Гбит).

Ниже привожу пример реализации автомата. Сигнал i нужен для задержки сигнала src_rdy чтобы синхронизировать данные поступающие из памяти на udp, остальные сигналы должны быть понятны. И в этой реализации автомат застревает в состоянии state_1 где ждет сигнал dst_rdy, чтобы перейти в state_2. И как я уже упоминал может дождаться его через минут 5 и потом уже передача любого количества пакетов проходит нормально.
Код
process_udp_state : process(tx_clk_i)
                    begin
                        if(rising_edge(tx_clk_i)) then
                            case (state_udp) is
                                
                                when idle =>
                                    if (start_data_tx = '1') then
                                        state_udp <= state_1;
                                    end if;
                                    
                                when state_1 =>
                                    if (udp_tx_dst_rdy = '1') then
                                        state_udp <= state_2;
                                    end if;
                                
                                when state_2 =>
                                    if (i = 3) then
                                        state_udp <= state_3;
                                    end if;
                                    
                                when state_3 =>
                                        if (m = 255) then
                                            state_udp <= idle;
                                        end if;
                                                
                            end case;
                        end if;
                end process;
                    
                process_udp : process(tx_clk_i)
                    begin
                        if(rising_edge(tx_clk_i)) then
                            case (state_udp) is
                                
                                when idle =>
                                    udp_tx_src_rdy <= '0';
                                    udp_tx_eof <= '0';
                                    
                                    m <= 0;
                                    
                                    udp_tx_data_crc <= x"0000";
                                    udp_tx_dst_ip <= x"C0A80103";
                                    udp_tx_dst_port <= x"0000";
                                    udp_tx_src_port <= x"0000";
                                    udp_tx_fragment_offset <= "0000000000000";
                                    udp_tx_more_fragments <= '0';
                                    udp_tx_data_length <= x"0100";
                                    udp_tx_data <= x"00";
                                    
                                when state_1 =>
                                        udp_tx_sof <= '1';
                                
                                when state_2 =>
                                    udp_tx_sof <= '0';
                                    if (i = 3) then
                                        i <= 0;
                                    else
                                        i <= i + 1;
                                    end if;
                                    
                                when state_3 =>
                                        udp_tx_src_rdy <= '1';

                                        if (m = 255) then
                                            udp_tx_eof <= '1';
                                            udp_tx_data <= udp_tx_data_mem;
                                        else
                                            udp_tx_data <= udp_tx_data_mem;
                                            m <= m + 1;
                                        end if;

                            end case;
                        end if;
                end process;

Так же пробовал немного по другому, сначала я просто выставлял сигнал sof, для того чтобы отправился arp запрос и возвращался в idle (так обнулялся sof, и по идее записывался в arp таблицу адрес получателя), после этого уже выставлял заново sof и проходил по вышеприведенному автомату. Результаты были следующими, первые три раза все работало и данные отправлялись, после того как прошил плис 4-й раз по сигналу sof не начинал формироваться заголовок пакета, т.е. можно предположить что в arp таблицу ничего не записалось((
Проект UDP/IP stack взят с opencores, он там один такой. Кстати было бы неплохо выслушать комментарии по стилю написания всего вышеизложенного, грамотно ли это?
billidean
Эта картинка, как я понимаю, когда у Вас все хорошо и все работает, времена между пакетами маленькие. Видно арп-запрос, затем арп-ответ, и далее уже идет пакет данных на девайс.

Но посмотреть бы картину при длительной паузе, можно в виде файла. а не картинки.

И еще, при переводе Вашего стека в режим 1Г Вы все необходимые сигналы/частоты/настройки выставили в необходимое состояние?
Alexey_pashinov
Проблема решилась. Оказывается неправильно подавал сигналы
udp_tx_data_crc <= x"0000";
udp_tx_dst_ip <= x"C0A80103";
udp_tx_dst_port <= x"0000";
udp_tx_src_port <= x"0000";
udp_tx_fragment_offset <= "0000000000000";
udp_tx_more_fragments <= '0';
udp_tx_data_length <= x"0100";
udp_tx_data <= x"00";

В состоянии idle их обнулил а значения которые выше подавал когда выставлялся сигнал udp_tx_sof = '1', т.е. в состоянии state_1
HFSE
Всем Привет.
Я сейчас занимаюсь тем же самым что и вы Алексей.
Но у меня вот какой вопрос:
Я формирую пакеты для UDP в MAC. Посылаю их сразу как только Micrel KSZ9021/KSZ9031 дает добро что Линк установился.
Но на компе wireshark мне ничего не показывает, что что-то приходит от FPGA. Сначало думал что пакеты создаю не правильно.
Пакеты генерировал при помощи одной програмки.
И теперь не знаю где ошибка. Может кто нибудь подскажет.
Зарание благодарен.

P.C. Насколько важны ARP запросы/ответы, если связь идет на прямую FPGA <-> PC
doom13
Если плата отправляет пакет, то wireshark должен его увидеть (не увидит если только пакет совсем неправильный - оба мак адреса нули). Если в качестве интерфейса MAC-PHY используется RGMII, то стоит посмотреть (подвигать) задержку клока относительно данных.
HFSE
Да, спасибо доом13, я это уже пробовал к сожалению без изменений.
Вчера сделал простой автомат, который просто тупо выкидывает в сторону Micrel KSZ9021/KSZ9031 нужные данные через GMII<->RGMII преобразователь.
У меня такое чуство что я где-то что-то забыл или не то сделал.
Если кто сможет: просмотрите пожайлуста мой код. Буду очень благодарен.


CODE
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity fsm is
Port (
RESET : in STD_LOGIC;
CLK_IN : in STD_LOGIC;
CLK_IN_90 : in STD_LOGIC;
LINK_EN : in STD_LOGIC;
TX_DATA_OUT : out STD_LOGIC_VECTOR (7 downto 0);
TX_ERR_OUT : out STD_LOGIC;
TX_EN_OUT : out STD_LOGIC;
TX_CLK_OUT : out STD_LOGIC
);
end fsm;

architecture Behavioral of fsm is

type FSM_STATE is ( A1, A2, A3, A4, A5, A6, A7, A8, A9, A10,
A11, A12, A13, A14, A15, A16, A17, A18, A19, A20,
A21, A211, A222, A22, A23, A24, A25, A26, A27, A28, A29, A30,
A31, A32, A33, A34, A35, A36, A37, A38, A39, A40,
A41, A42, A43, A44, A45, A46, A47, A48, A49, A50,
A51, A52, A53, A54, A55, A56, A57, A58, A59, A60,
A61, A62, A63, A64, A65, A66, A67, A68, A69, A70,
A71, A72, A73, A74, A75, A76, A77, A78, A79, A80,
A81, A82, A83, A84, A85, A86, A87, A88, A89, A90,
A91, A92, A93, A94, A95, A96, A97, A98, A99
);

signal STATE : FSM_STATE := A1;
signal NEXT_STATE : FSM_STATE;

signal data_buffer : std_logic_vector(7 downto 0) := x"00";

begin

Z : process(RESET, CLK_IN, LINK_EN)
begin

if (RESET = '0') then
STATE <= A1;
elsif (rising_edge(CLK_IN)) then
if (LINK_EN = '0') then
STATE <= NEXT_STATE;
else
STATE <= A1;
end if;
end if;

end process Z;

TX_DATA_OUT <= data_buffer;

FSM_PROC: process (STATE, CLK_IN, CLK_IN_90)
begin
case STATE is
-- Preable
when A1 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= '0'; NEXT_STATE <= A2;
when A2 => data_buffer <= x"55"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A3;
when A3 => data_buffer <= x"55"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A4;
when A4 => data_buffer <= x"55"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A5;
when A5 => data_buffer <= x"55"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A6;
when A6 => data_buffer <= x"55"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A7;
when A7 => data_buffer <= x"55"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A8;
when A8 => data_buffer <= x"55"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A9;
when A9 => data_buffer <= x"D5"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A10;
-- MAC Destination
when A10 => data_buffer <= x"54"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A11;
when A11 => data_buffer <= x"EE"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A12;
when A12 => data_buffer <= x"75"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A13;
when A13 => data_buffer <= x"30"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A14;
when A14 => data_buffer <= x"86"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A15;
when A15 => data_buffer <= x"60"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A16;
--MAC Source
when A16 => data_buffer <= x"FF"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A17;
when A17 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A18;
when A18 => data_buffer <= x"12"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A19;
when A19 => data_buffer <= x"34"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A20;
when A20 => data_buffer <= x"56"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A21;
when A21 => data_buffer <= x"78"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A211;
-- Ethernet Typ <=> IP
when A211 => data_buffer <= x"08"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A222;
when A222 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A22;
-- IP Header
when A22 => data_buffer <= x"45"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A23; -- Version + IHL
when A23 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A24; -- TOS
when A24 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A25; -- Total Lengh
when A25 => data_buffer <= x"3A"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A26; -- Total Lengh
when A26 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A27; -- Identification
when A27 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A28; -- Identification
when A28 => data_buffer <= x"01"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A29; -- Flags
when A29 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A30; -- Fragment offset
when A30 => data_buffer <= x"FF"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A31; -- TTL
when A31 => data_buffer <= x"11"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A32; -- Protocol <=> UDP
-- IP Header Check Sum = IP Header + IP Source + IP Destin in Format x"0000"
when A32 => data_buffer <= x"1C"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A33;
when A33 => data_buffer <= x"CA"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A34;
--IP Source
when A34 => data_buffer <= x"C4"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A35;
when A35 => data_buffer <= x"FF"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A36;
when A36 => data_buffer <= x"0A"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A37;
when A37 => data_buffer <= x"01"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A38;
-- IP Dest
when A38 => data_buffer <= x"C4"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A39;
when A39 => data_buffer <= x"FF"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A40;
when A40 => data_buffer <= x"0A"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A41;
when A41 => data_buffer <= x"05"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A42;
--Port Source
when A42 => data_buffer <= x"C3"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A43;
when A43 => data_buffer <= x"50"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A44;
-- Port Dest
when A44 => data_buffer <= x"C3"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A45;
when A45 => data_buffer <= x"50"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A46;
-- UDP Lengh Payload = Port Source + Port Dest + Lengh Payload + UDP Checksum + Payload <=> 26
when A46 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A47;
when A47 => data_buffer <= x"1C"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A48;
-- UDP Checksum
when A48 => data_buffer <= x"62"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A49;
when A49 => data_buffer <= x"8D"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A50;
-- UDP Payload
when A50 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A51;
when A51 => data_buffer <= x"01"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A52;
when A52 => data_buffer <= x"02"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A53;
when A53 => data_buffer <= x"03"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A54;
when A54 => data_buffer <= x"04"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A55;
when A55 => data_buffer <= x"05"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A56;
when A56 => data_buffer <= x"06"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A57;
when A57 => data_buffer <= x"07"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A58;
when A58 => data_buffer <= x"08"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A59;
when A59 => data_buffer <= x"09"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A60;
when A60 => data_buffer <= x"10"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A61;
when A61 => data_buffer <= x"11"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A62;
when A62 => data_buffer <= x"12"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A63;
when A63 => data_buffer <= x"13"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A64;
when A64 => data_buffer <= x"14"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A65;
when A65 => data_buffer <= x"15"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A66;
when A66 => data_buffer <= x"16"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A67;
when A67 => data_buffer <= x"17"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A68;
when A68 => data_buffer <= x"18"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A69;
when A69 => data_buffer <= x"19"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A70;
-- CRC32 Checksum
when A70 => data_buffer <= x"B5"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A71;
when A71 => data_buffer <= x"B6"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A72;
when A72 => data_buffer <= x"5E"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A73;
when A73 => data_buffer <= x"B5"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A74;

when A74 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A75;
when A75 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A76;
when A76 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A77;
when A77 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A78;
when A78 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A79;
when A79 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A80;
when A80 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A81;
when A81 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A82;
when A82 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A83;
when A83 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A84;
when A84 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A85;
when A85 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A86;
when A86 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A87;
when A87 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A88;
when A88 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A89;
when A89 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A90;
when A90 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A91;
when A91 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A92;
when A92 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A93;
when A93 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A94;
when A94 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= '0'; NEXT_STATE <= A95;
when A95 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= '0'; NEXT_STATE <= A96;
when A96 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= '0'; NEXT_STATE <= A97;
when A97 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= '0'; NEXT_STATE <= A98;
when A98 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= '0'; NEXT_STATE <= A99;
when A99 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= '0'; NEXT_STATE <= A1;



when others => NEXT_STATE <= A1;

end case;

end process FSM_PROC;



end Behavioral;
Bad0512
Цитата(HFSE @ Jun 18 2015, 01:42) *
Код
library IEEE;
.......
end Behavioral;

Жесть какая-то... Не проще ли пакет в инициализируемой блочной памяти держать и играть его оттуда чем плодить FSM на 99 состояний?
HFSE
Цитата(Bad0512 @ Jun 18 2015, 02:16) *
Жесть какая-то... Не проще ли пакет в инициализируемой блочной памяти держать и играть его оттуда чем плодить FSM на 99 состояний?


Хорошо педметил, biggrin.gif Да полностью согласен, ПОЛНАЯ ЖЕСТь. Это всего лишь тест автомат, мне так легче было им управлять. В оригинале все идет через блочную память.
Но я просто понять не могу, почему когда посылаешь вот такой пакет, wireshark ничего не видет. Где может быть косяк. sad.gif
vadimuzzz
Цитата(HFSE @ Jun 18 2015, 11:01) *
Но я просто понять не могу, почему когда посылаешь вот такой пакет, wireshark ничего не видет. Где может быть косяк. sad.gif

например, в кривых констрейнах на I/O
HFSE
Цитата(vadimuzzz @ Jun 18 2015, 05:03) *
например, в кривых констрейнах на I/O


Я это уже проверял выглядит вроде все в порядке.
Я так сделал чтобы фронт вападал как раз по середине (см. фото).

На фото показаны сигналы после GMII<-> RGMII преобразователя.
mobidev
Цитата(HFSE @ Jun 16 2015, 23:46) *
P.C. Насколько важны ARP запросы/ответы, если связь идет на прямую FPGA <-> PC


Сразу оговорюсь, я пока что не специалист по FPGA, однако, как Вы без ARP собираетесь согласовывать IP адреса, поддерживать линк и прочее?
HFSE
Цитата(HFSE @ Jun 18 2015, 06:22) *
Я это уже проверял выглядит вроде все в порядке.
Я так сделал чтобы фронт вападал как раз по середине (см. фото).

На фото показаны сигналы после GMII<-> RGMII преобразователя.



А вот так выглядят сигналы до GMII<-> RGMII преобразователя.

Цитата(mobidev @ Jun 18 2015, 06:30) *
Сразу оговорюсь, я пока что не специалист по FPGA, однако, как Вы без ARP собираетесь согласовывать IP адреса, поддерживать линк и прочее?


В этом и есть вопрос.
Если я правильно понял ARP нужен только для того что бы согласовать в сети какой МАC имеет какой IP.
Ну а если я например знаю точно какой МАC и IP адресс у PC.
Разве я не могу просто тупо послать в сторону PC UDP Пакет сразу после того как установилься Link . Для wireshark это должно быть все равно.
Или сетевая карта настолько умна что пока не получит ответ на ARP, все остальное просто игнорирует?
doom13
Цитата(HFSE @ Jun 18 2015, 09:41) *
Если я правильно понял ARP нужен только для того что бы согласовать в сети какой МАC имеет какой IP.
Ну а если я например знаю точно какой МАC и IP адресс у PC.
Разве я не могу просто тупо послать в сторону PC UDP Пакет сразу после того как установилься Link . Для wireshark это должно быть все равно.
Или сетевая карта настолько умна что пока не получит ответ на ARP, все остальное просто игнорирует?

Для нормального определения устройства в сети ARP нужен, в Вашем случае дело пока не в нём, а в железе. Wireshark будет видеть пакеты, если они есть в сети.
Для большей уверенности, что проблема не в компе, можете попробовать посылать пакеты с broadcast MAC-address.
mobidev
Цитата(HFSE @ Jun 18 2015, 10:41) *
Если я правильно понял ARP нужен только для того что бы согласовать в сети какой МАC имеет какой IP.
Ну а если я например знаю точно какой МАC и IP адресс у PC.
Разве я не могу просто тупо послать в сторону PC UDP Пакет сразу после того как установилься Link .

Не только согласовать, но и поддерживать, иначе, если речь в итоге будет идти к коммерческому изделию, свичи и прочая сетевая инфраструктура будет сходить с ума от таких железок.

Цитата(HFSE @ Jun 18 2015, 10:41) *
Для wireshark это должно быть все равно.
Или сетевая карта настолько умна что пока не получит ответ на ARP, все остальное просто игнорирует?


... а вот wireshark должен видеть любые пакеты, если он "сидит на маршруте трафика".
HFSE
Всем сапсибо за советы.
Но до сих пор я не вижу пакетов в wireshark.
Вот как я это делал:
1. Сначало вбил данные в генератор пакетов
2. Сгенерировал пакет
3. Залил VHDL код в FPGA -> wireshark ничего не показывает, НО ...
При просмотре Interface Details обнаружил что пакеты приходят, но они все с ошибками.
Что я не так посылаю, или точней как послать правильно?
Зарание благодарен.

CODE


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity fsm is
Port (
RESET : in STD_LOGIC;
CLK_IN : in STD_LOGIC;
CLK_IN_90 : in STD_LOGIC;
LINK_EN : in STD_LOGIC;
TX_DATA_OUT : out STD_LOGIC_VECTOR (7 downto 0);
TX_ERR_OUT : out STD_LOGIC;
TX_EN_OUT : out STD_LOGIC;
TX_CLK_OUT : out STD_LOGIC
);
end fsm;

architecture Behavioral of fsm is

type FSM_STATE is ( A1, A2, A3, A4, A5, A6, A7, A8, A9, A10,
A11, A12, A13, A14, A15, A16, A17, A18, A19, A20,
A21, A211, A222, A22, A23, A24, A25, A26, A27, A28, A29, A30,
A31, A32, A33, A34, A35, A36, A37, A38, A39, A40,
A41, A42, A43, A44, A45, A46, A47, A48, A49, A50,
A51, A52, A53, A54, A55, A56, A57, A58, A59, A60,
A61, A62, A63, A64, A65, A66, A67, A68, A69, A70,
A71, A72, A73, A74, A75, A76, A77, A78, A79, A80,
A81, A82, A83, A84, A85, A86, A87, A88, A89, A90,
A91, A92, A93, A94, A95, A96, A97, A98, A99
);

signal STATE : FSM_STATE := A1;
signal NEXT_STATE : FSM_STATE;
signal COUNTER_1 : integer range 0 to 100000 := 0;

signal data_buffer : std_logic_vector(7 downto 0) := x"00";

begin

Z : process(RESET, CLK_IN, LINK_EN)
begin

if (RESET = '0') then
STATE <= A1;
elsif (rising_edge(CLK_IN)) then
if (LINK_EN = '0') then
STATE <= NEXT_STATE;
else
STATE <= A1;
end if;
end if;

end process Z;

TX_DATA_OUT <= data_buffer;

FSM_PROC: process (STATE, CLK_IN, CLK_IN_90)
begin
case STATE is
-- Preable
when A1 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= '0'; NEXT_STATE <= A2;
when A2 => data_buffer <= x"55"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A3;
when A3 => data_buffer <= x"55"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A4;
when A4 => data_buffer <= x"55"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A5;
when A5 => data_buffer <= x"55"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A6;
when A6 => data_buffer <= x"55"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A7;
when A7 => data_buffer <= x"55"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A8;
when A8 => data_buffer <= x"55"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A9;
when A9 => data_buffer <= x"D5"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A10;
-- MAC Destination
when A10 => data_buffer <= x"FF"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A11;
when A11 => data_buffer <= x"FF"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A12;
when A12 => data_buffer <= x"FF"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A13;
when A13 => data_buffer <= x"FF"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A14;
when A14 => data_buffer <= x"FF"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A15;
when A15 => data_buffer <= x"FF"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A16;
--MAC Source
when A16 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A17;
when A17 => data_buffer <= x"12"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A18;
when A18 => data_buffer <= x"34"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A19;
when A19 => data_buffer <= x"56"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A20;
when A20 => data_buffer <= x"78"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A21;
when A21 => data_buffer <= x"90"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A211;
-- Ethernet Typ <=> IP
when A211 => data_buffer <= x"08"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A222;
when A222 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A22;
-- IP Header
when A22 => data_buffer <= x"45"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A23; -- Version + IHL
when A23 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A24; -- TOS
when A24 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A25; -- Total Lengh
when A25 => data_buffer <= x"30"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A26; -- Total Lengh
when A26 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A27; -- Identification
when A27 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A28; -- Identification
when A28 => data_buffer <= x"01"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A29; -- Flags
when A29 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A30; -- Fragment offset
when A30 => data_buffer <= x"80"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A31; -- TTL
when A31 => data_buffer <= x"11"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A32; -- Protocol <=> UDP
-- IP Header Check Sum = IP Header + IP Source + IP Destin in Format x"0000"
when A32 => data_buffer <= x"A3"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A33;
when A33 => data_buffer <= x"B8"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A34;
--IP Source
when A34 => data_buffer <= x"C0"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A35;
when A35 => data_buffer <= x"FF"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A36;
when A36 => data_buffer <= x"0A"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A37;
when A37 => data_buffer <= x"01"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A38;
-- IP Dest
when A38 => data_buffer <= x"C0"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A39;
when A39 => data_buffer <= x"FF"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A40;
when A40 => data_buffer <= x"0A"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A41;
when A41 => data_buffer <= x"05"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A42;
--Port Source
when A42 => data_buffer <= x"13"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A43;
when A43 => data_buffer <= x"88"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A44;
-- Port Dest
when A44 => data_buffer <= x"13"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A45;
when A45 => data_buffer <= x"88"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A46;
-- UDP Lengh Payload = Port Source + Port Dest + Lengh Payload + UDP Checksum + Payload <=> 26
when A46 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A47;
when A47 => data_buffer <= x"1C"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A48;
-- UDP Checksum
when A48 => data_buffer <= x"CA"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A49;
when A49 => data_buffer <= x"1E"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A50;
-- UDP Payload
when A50 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A51;
when A51 => data_buffer <= x"01"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A52;
when A52 => data_buffer <= x"02"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A53;
when A53 => data_buffer <= x"03"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A54;
when A54 => data_buffer <= x"04"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A55;
when A55 => data_buffer <= x"05"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A56;
when A56 => data_buffer <= x"06"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A57;
when A57 => data_buffer <= x"07"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A58;
when A58 => data_buffer <= x"08"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A59;
when A59 => data_buffer <= x"09"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A60;
when A60 => data_buffer <= x"10"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A61;
when A61 => data_buffer <= x"11"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A62;
when A62 => data_buffer <= x"12"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A63;
when A63 => data_buffer <= x"13"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A64;
when A64 => data_buffer <= x"14"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A65;
when A65 => data_buffer <= x"15"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A66;
when A66 => data_buffer <= x"16"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A67;
when A67 => data_buffer <= x"17"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A68;
when A68 => data_buffer <= x"18"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A69;
when A69 => data_buffer <= x"19"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A70;
-- CRC32 Checksum
when A70 => data_buffer <= x"82"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A71; -- 82
when A71 => data_buffer <= x"0A"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A72; -- 0A
when A72 => data_buffer <= x"C9"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A73; -- C9
when A73 => data_buffer <= x"C2"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '1'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A74; -- C2

when A74 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A75;
when A75 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A76;
when A76 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A77;
when A77 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A78;
when A78 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A79;
when A79 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A80;
when A80 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A81;
when A81 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A82;
when A82 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A83;
when A83 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A84;
when A84 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A85;
when A85 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A86;
when A86 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A87;
when A87 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A88;
when A88 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A89;
when A89 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A90;
when A90 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A91;
when A91 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A92;
when A92 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A93;
when A93 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= CLK_IN_90; NEXT_STATE <= A94;
when A94 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= '0'; NEXT_STATE <= A95;
when A95 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= '0'; NEXT_STATE <= A96;
when A96 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= '0'; NEXT_STATE <= A97;
when A97 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= '0';

if rising_edge(CLK_IN) then
if (COUNTER_1 = 100000) then
COUNTER_1 <= 0;
NEXT_STATE <= A98;
else
COUNTER_1 <= COUNTER_1 + 1;
end if;
end if;

when A98 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= '0'; NEXT_STATE <= A99;
when A99 => data_buffer <= x"00"; TX_ERR_OUT <= '0'; TX_EN_OUT <= '0'; TX_CLK_OUT <= '0'; NEXT_STATE <= A1;



when others => NEXT_STATE <= A1;

end case;

end process FSM_PROC;
end Behavioral;
doom13
Пробуйте проверять соединение в разных сечениях (loopback mode). Для начала можно перевести PHY в режим line loopback, чтобы он плевал пакеты обратно в сеть, и мониторить Wireshark-ом возврат пакета (проверите саму линию связи ПК<->PHY). Потом пробовать включать MAC loopback (проверите что MAC принимает/отправляет пакеты правильно) и PHY local loopback (проверите приём передачу по RGMII), но тут Вам понадобится packet checker (или внутрисхемным отладчиком можно пробовать подключиться), можно заюзать стандартные генератор и чекер (довольно простые, но на первое время хватит).
Sergey_Bekrenyov
А зачем Вы TX_CLK_OUT в ноль опускаете? PHY не сможет линк установить, так и будет туда-сюда дергаться

FSM_PROC: process (STATE, CLK_IN, CLK_IN_90) - частоты уберите из списка чувствительности
HFSE
Цитата(Sergey_Bekrenyov @ Jun 19 2015, 15:30) *
А зачем Вы TX_CLK_OUT в ноль опускаете? PHY не сможет линк установить, так и будет туда-сюда дергаться

FSM_PROC: process (STATE, CLK_IN, CLK_IN_90) - частоты уберите из списка чувствительности

Добрый день, Сергей.
Спасибо большое за совет a14.gif , все заработало. 08.gif
Проблема действительно была с клоком.
Sergey_Bekrenyov
Цитата(HFSE @ Jun 22 2015, 10:19) *
Добрый день, Сергей.
Спасибо большое за совет a14.gif , все заработало. 08.gif
Проблема действительно была с клоком.

Не за что, главное не останавливайтесь. Удачи!
NSergeevich
Всем привет! Мой проект (MAC + Phy) настроен только на отправку пакетов. (никакие ответные я не принимаю и не обрабатываю), также нигде не указываю ip адреса, только маки
Отправляю обычный ethernet пакет (со всеми преамбулами, контрольными суммами и т.д.) c указанием DA (мак компа),SA(мак плис),L/T(длина полез данных) и DATA(сами данные)
Сам фрейм проверен и соответствует стандарту.

Значит, при присоединении напрямую плис к компу. Происходит несколько секунд установка соединения (диоды на eth плис одновременно мигают красный и оранжевый) и после этого, левый зеленый просто горит, а правый оранжевый начинает неистово моргать,
а на wireshark-e вижу следующее:
Нажмите для просмотра прикрепленного файла

Пакеты не доходят? Что там за question? Вот и не понятно, что нужно сделать, чтобы паеты нормально пачками запихивались, а у меня останавливается все на MDNS "QM" question
Заранее спасибо за советы.
gosu-art
А promiscuous mode у вас включен? У меня, например, на win8 без ARP ничего не принимается. Делал железный UDP/IP.
NSergeevich
Цитата(gosu-art @ Jun 22 2015, 13:30) *
А promiscuous mode у вас включен? У меня, например, на win8 без ARP ничего не принимается. Делал железный UDP/IP.


Что за мод? Где включается? Я на линуксе
NSergeevich
C этим модом тоже самое
mobidev
Цитата(NSergeevich @ Jun 22 2015, 14:18) *
при присоединении напрямую плис к компу. Происходит несколько секунд установка соединения (диоды на eth плис одновременно мигают красный и оранжевый) и после этого, левый зеленый просто горит, а правый оранжевый начинает неистово моргать, а на wireshark-e вижу следующее:
Нажмите для просмотра прикрепленного файла

Пакеты не доходят? Что там за question? Вот и не понятно, что нужно сделать, чтобы паеты нормально пачками запихивались, а у меня останавливается все на MDNS "QM" question
Заранее спасибо за советы.


QM question это как я понимаю пытается отрабатывать upnp, но Ваша проблема иная, пк и железка хотят поиметь IP, посему и засыпают arp-запросы. Как собираетесь общаться с пк, если оно хочет ip, а ip никто не согласовал!
NSergeevich
Цитата(mobidev @ Jun 22 2015, 14:31) *
QM question это как я понимаю пытается отрабатывать upnp, но Ваша проблема иная, пк и железка хотят поиметь IP, посему и засыпают arp-запросы. Как собираетесь общаться с пк, если оно хочет ip, а ip никто не согласовал!


Ага, значит без arp не обойтись. Есть ли дока подробная? Буду разбераться куда его в ethernet frame вставлять и вообще что с ним делать
mobidev
Цитата(NSergeevich @ Jun 22 2015, 15:41) *
Ага, значит без arp не обойтись. Есть ли дока подробная? Буду разбераться куда его в ethernet frame вставлять и вообще что с ним делать


Если нужна подробная дока именно по ARP, то наверно правильнее читать соответствующий RFC.
Например, начать с RFC 826 https://tools.ietf.org/html/rfc826

P.S. а вообще наверняка есть готовые решения.
doom13
Цитата(NSergeevich @ Jun 22 2015, 14:41) *
Ага, значит без arp не обойтись. Есть ли дока подробная? Буду разбераться куда его в ethernet frame вставлять и вообще что с ним делать

Руками IP-адрес пропишите и если не появятся пакеты в Wireshark, то ищите проблему на плате (в проекте).
NSergeevich
Цитата(doom13 @ Jun 22 2015, 15:27) *
Руками IP-адрес пропишите и если не появятся пакеты в Wireshark, то ищите проблему на плате (в проекте).

Я бы и прописал руками, вот только куда? Я так понимаю если в ethernet frame добавлять arp то и будет куда прописать ip.
HFSE
Цитата(NSergeevich @ Jun 22 2015, 11:50) *
C этим модом тоже самое


Sergeevich, скачайте прогу PackETH.
Там сможите потренироваться с этими пакетами. Можно создавать UDP, ARP или свои собственные.
Я долго парился, высчитывал. А с ней все пошло как по маслу. Там же можно и проверяться, правильно ли посчитали UDP Checksumme или Frame Check (CRC32).
http://packeth.sourceforge.net/packeth/Home.html
И да еще один важный момент:
Попробуйте поменять местами 5D <-> D5 в Preable.
У меня работает вот этот вариант : 55 55 55 55 55 55 55 D5
gosu-art
Код
/// size 14 bytes

logic  [7:0] ether_hdr_da[5:0];              // destination MAC address
logic  [7:0] ether_hdr_sa[5:0];              // source MAC address
logic  [7:0] ether_hdr_type_code[1:0];     // type code - 0x0800 is IP      

/// size 20 bytes    

logic  [7:0] ip_hdr_ver_hlen;                // version - 4 bits;  IP hdr len - 4 bits // IPv4 with 20 byte header 0x45  
logic  [7:0] ip_hdr_tos;                     // Type of service
logic  [7:0] ip_hdr_tlen[1:0];                // Size of datagram (header + data)
logic  [7:0] ip_hdr_id[1:0];                 // together with sa, uniequly identifies pkt
logic  [7:0] ip_hdr_frag_off[1:0];            // flags - 3 bits; fragment offset - 13 bits
logic  [7:0] ip_hdr_ttl;                    // time to live
logic  [7:0] ip_hdr_proto;                    // protocol UDP_PROTO    0x11
logic  [7:0] ip_hdr_csum[1:0];                // header checksum
logic  [7:0] ip_hdr_sa[3:0];                // IP source address
logic  [7:0] ip_hdr_da[3:0];                // IP dest address                            

/// size 8 bytes

logic [7:0]  udp_hdr_sp[1:0];                 // Source port             
logic [7:0]  udp_hdr_dp[1:0];                // Destination port         
logic [7:0]  udp_hdr_len[1:0];                 // length of packet
logic [7:0]  udp_hdr_csum[1:0];             // checksum


Код
  always_comb begin
    case (cnt_words_tx)
        0: aso_out0_data = {        ether_hdr_da[5],            ether_hdr_da[4],            ether_hdr_da[3],        ether_hdr_da[2]    };
        1: aso_out0_data = {        ether_hdr_da[1],            ether_hdr_da[0],            ether_hdr_sa[5],        ether_hdr_sa[4]    };
        2: aso_out0_data = {        ether_hdr_sa[3],            ether_hdr_sa[2],            ether_hdr_sa[1],        ether_hdr_sa[0]    };
        3: aso_out0_data = {        ether_hdr_type_code[1],     ether_hdr_type_code[0],    ip_hdr_ver_hlen,        ip_hdr_tos            };
        4: aso_out0_data = {     ip_hdr_tlen[1],            ip_hdr_tlen[0],            ip_hdr_id[1],            ip_hdr_id[0]        };
        5: aso_out0_data = {        ip_hdr_frag_off[1],        ip_hdr_frag_off[0],        ip_hdr_ttl,                ip_hdr_proto        };
        6: aso_out0_data = {        ip_hdr_csum[1],            ip_hdr_csum[0],            ip_hdr_sa[3],            ip_hdr_sa[2]        };
        7: aso_out0_data = {        ip_hdr_sa[1],                ip_hdr_sa[0],                ip_hdr_da[3],            ip_hdr_da[2]        };
        8: aso_out0_data = {        ip_hdr_da[1],                ip_hdr_da[0],                udp_hdr_sp[1],            udp_hdr_sp[0]        };
        9: aso_out0_data = {        udp_hdr_dp[1],                udp_hdr_dp[0],                udp_hdr_len[1],        udp_hdr_len[0]        };
      10: aso_out0_data = {        udp_hdr_csum[1],            udp_hdr_csum[0],            aso_out0_data_tx[31:16]};
        
        default: aso_out0_data = aso_out0_data_tx;
    endcase
end
mobidev
Цитата(HFSE @ Jun 22 2015, 16:53) *
правильно ли посчитали UDP Checksumme


Сделаю небольшую подсказку, протоколом UDP предусматривается один из вариантов обмена без обязательного подсчёта контрольной суммы заголовка udp-пакета, но только его!

Но это отступление от темы Mac+ip.
krux
для формирования пакетов есть ещё такая интересная вещь:
https://code.google.com/p/ostinato/
NSergeevich
Цитата(HFSE @ Jun 22 2015, 15:53) *
Sergeevich, скачайте прогу PackETH.
Там сможите потренироваться с этими пакетами. Можно создавать UDP, ARP или свои собственные.
Я долго парился, высчитывал. А с ней все пошло как по маслу. Там же можно и проверяться, правильно ли посчитали UDP Checksumme или Frame Check (CRC32).
http://packeth.sourceforge.net/packeth/Home.html
И да еще один важный момент:
Попробуйте поменять местами 5D <-> D5 в Preable.
У меня работает вот этот вариант : 55 55 55 55 55 55 55 D5


У меня преамбулу добавляет сама корка мака

gosu-art, мне это уже понятно. Теперь не понятно какими данными заполнять :
Код
logic  [7:0] ip_hdr_ver_hlen;                // version - 4 bits;  IP hdr len - 4 bits // IPv4 with 20 byte header 0x45
logic  [7:0] ip_hdr_tos;                     // Type of service
logic  [7:0] ip_hdr_tlen[1:0];                // Size of datagram (header + data)
logic  [7:0] ip_hdr_id[1:0];                 // together with sa, uniequly identifies pkt
logic  [7:0] ip_hdr_frag_off[1:0];            // flags - 3 bits; fragment offset - 13 bits
logic  [7:0] ip_hdr_ttl;                    // time to live
logic  [7:0] ip_hdr_proto;                    // protocol UDP_PROTO    0x11
logic  [7:0] ip_hdr_csum[1:0];                // header checksum


откуда они берутся, в частности вот этот длинный header, как считать checksum и тд

И вообще может быть есть у xilinx-а готовые корки на ip/udp, чтобы делали все сами, а я только дату пихал?
Corvus
Цитата(NSergeevich @ Jun 22 2015, 18:02) *
И вообще может быть есть у xilinx-а готовые корки на ip/udp, чтобы делали все сами, а я только дату пихал?


http://opencores.org/project,udp_ip__core
NSergeevich
подкиньте ресурс, где можно былобы почитать о всех этих хеадерах и чексуммах
gosu-art
Основные параметры
Код
localparam    SIZE_ETHER_HDR        = 14;
localparam    SIZE_IP_HDR            = 20;
localparam    SIZE_UDP_HDR        = 8;

  
localparam    UDP_PROTO            = 8'h11;
localparam    ETH_TYPE                = 16'h0800;
localparam    IP_VER                = 8'h45;
localparam    IP_TTL                = 8'hFF;

assign    {ip_hdr_ver_hlen}                                          = IP_VER;
assign    {ether_hdr_type_code[1],ether_hdr_type_code[0]}                              = ETH_TYPE;
assign    ip_hdr_proto                                                  = UDP_PROTO;
assign    ip_hdr_ttl                                                    = IP_TTL;


Расчет чек суммы для IP и UDP
Код
module udp_check_summ
(                                            
    input                   iclk,
    input     [15:0]        packet_in,
    output [15:0]        check_summ_out,
    input                    data_valid,
    input                    sop
                                                
);

logic [15:0] accum_rg;
logic [16:0] carry_check;
logic          carry_16;

assign    carry_check    = accum_rg + packet_in;
assign  check_summ_out = 16'hFFFF - accum_rg;

///

  always_ff @ (posedge iclk) begin
//        if (sop && data_valid)
//            accum_rg <= packet_in;
//        else if (sop && !data_valid)
        if (sop)
            accum_rg <= '0;
        else begin
            if(data_valid) begin
                    accum_rg <= accum_rg + packet_in + carry_check[16];
            end
        end
    end

endmodule


Далее просто заполнить поля вашими значениями

Код
        if(avs_s0_write && avs_s0_chipselect) begin
            unique case(avs_s0_address)
                `ADDR_ETHER_DEST_MAC_0        :    ether_hdr_da[0] <= avs_s0_writedata[7:0];    
                `ADDR_ETHER_DEST_MAC_1        :    ether_hdr_da[1] <= avs_s0_writedata[7:0];
                `ADDR_ETHER_DEST_MAC_2        :    ether_hdr_da[2] <= avs_s0_writedata[7:0];
                `ADDR_ETHER_DEST_MAC_3        :    ether_hdr_da[3] <= avs_s0_writedata[7:0];
                `ADDR_ETHER_DEST_MAC_4        :    ether_hdr_da[4] <= avs_s0_writedata[7:0];
                `ADDR_ETHER_DEST_MAC_5        :    ether_hdr_da[5] <= avs_s0_writedata[7:0];
                
                `ADDR_ETHER_SOURCE_MAC_0    :    ether_hdr_sa[0] <= avs_s0_writedata[7:0];        
                `ADDR_ETHER_SOURCE_MAC_1    :     ether_hdr_sa[1] <= avs_s0_writedata[7:0];
                `ADDR_ETHER_SOURCE_MAC_2    :    ether_hdr_sa[2] <= avs_s0_writedata[7:0];
                `ADDR_ETHER_SOURCE_MAC_3    :    ether_hdr_sa[3] <= avs_s0_writedata[7:0];
                `ADDR_ETHER_SOURCE_MAC_4    :    ether_hdr_sa[4] <= avs_s0_writedata[7:0];
                `ADDR_ETHER_SOURCE_MAC_5    :    ether_hdr_sa[5] <= avs_s0_writedata[7:0];
                ///
                `ADDR_IP_TOS                    :    {ip_hdr_tos[1], ip_hdr_tos[0]}                             <= avs_s0_writedata[15:0];                     
                //`ADDR_IP_TLEN                    :    {ip_hdr_tlen[1],ip_hdr_tlen[0]}                            <= avs_s0_writedata[15:0];
                `ADDR_IP_ID                        :    {ip_hdr_id[1],ip_hdr_id[0]}                                      <= avs_s0_writedata[15:0];
                `ADDR_IP_FRAG_OFF_            :    {ip_hdr_frag_off[1],ip_hdr_frag_off[0]}                    <= avs_s0_writedata[15:0];
                `ADDR_IP_SOURCE_ADDRESS        :    {ip_hdr_sa[3],ip_hdr_sa[2],ip_hdr_sa[1],ip_hdr_sa[0]} <= avs_s0_writedata;
                `ADDR_IP_DEST_ADDRESS        :    {ip_hdr_da[3],ip_hdr_da[2],ip_hdr_da[1],ip_hdr_da[0]} <= avs_s0_writedata;
                ///
                `ADDR_UDP_SOURCE_PORT        :    {udp_hdr_sp[1],udp_hdr_sp[0]}                                <= avs_s0_writedata[15:0];
                `ADDR_UDP_DEST_PORT            :    {udp_hdr_dp[1],udp_hdr_dp[0]}                                <= avs_s0_writedata[15:0];         
            endcase
        end

UPD:
Структура для IP чек суммы
Код
always_comb begin
    case (cnt_check_words)
        0: next_check_ipv4_word = {ip_hdr_ver_hlen, ip_hdr_tos};
        1: next_check_ipv4_word = {ip_hdr_tlen[1],ip_hdr_tlen[0]};
        2: next_check_ipv4_word = {ip_hdr_id[1],ip_hdr_id[0]};
        3: next_check_ipv4_word = {ip_hdr_frag_off[1],ip_hdr_frag_off[0]};
        4: next_check_ipv4_word = {ip_hdr_ttl,ip_hdr_proto};
        5: next_check_ipv4_word = {ip_hdr_sa[3],ip_hdr_sa[2]};
        6: next_check_ipv4_word = {ip_hdr_sa[1],ip_hdr_sa[0]};
        7: next_check_ipv4_word = {ip_hdr_da[3],ip_hdr_da[2]};
        8: next_check_ipv4_word = {ip_hdr_da[1],ip_hdr_da[0]};
        default: next_check_ipv4_word = '0;
    endcase
end


Структура для UDP чек суммы (если не хотите возиться с ней то можно занулить)
Код
case (cnt_check_words)
         //udp pseudo header
        0: next_check_udp_word = {ip_hdr_sa[3],ip_hdr_sa[2]};
        1: next_check_udp_word = {ip_hdr_sa[1],ip_hdr_sa[0]};
        2: next_check_udp_word = {ip_hdr_da[3],ip_hdr_da[2]};
        3: next_check_udp_word = {ip_hdr_da[1],ip_hdr_da[0]};
        4: next_check_udp_word = {16'h00,ip_hdr_proto};
        5: next_check_udp_word = {udp_hdr_len[1],udp_hdr_len[0]};
        //udp header
        6: next_check_udp_word = {udp_hdr_sp[1],udp_hdr_sp[0]};
        7: next_check_udp_word = {udp_hdr_dp[1],udp_hdr_dp[0]};
        8: next_check_udp_word = {udp_hdr_len[1],udp_hdr_len[0]};
        
        default: next_check_udp_word = данные;
doom13
Цитата(NSergeevich @ Jun 22 2015, 19:00) *
подкиньте ресурс, где можно былобы почитать о всех этих хеадерах и чексуммах

На Википедии можно почитать: Ethernet, IP и UDP.

Вообще, при отправке пакета Ethernet, чтобы Wireshark его видел, достаточно подать на MAC пакет состоящий из DST MAC, SRC MAC, тип пакета (08 00) и произвольные данные (минимум 46 байт, если меньше MAC добивает нулями недостающие). Далее MAC дополнияет всё это преамбулой, SFD и CFS и выдаёт на PHY. Т.е. если эти условия выполнены, то никакие арпы и т.д. не нужны, Вы увидите свой пакет в Wireshark.
Если нет - ищите проблему где-то в проекте/железе:
1) Включен ли передатчик MAC-контроллера?
2) Выдаёт ли MAC данные на PHY?
3) Какой интерфейс MAC-PHY используется в системе?
4) Правильно ли настроен PHY?
5) и т.д.

Да, какую FPGA используете? Есть стандартные генераторы Ethernet трафика, можно попробовать загрузить сеть данными генератора.

Чтобы проверить соединение PC-PHY, можно включить PHY в режим Line Loopback и побросать пакеты с компа на плату.
gosu-art
Цитата(doom13 @ Jun 22 2015, 22:03) *
Вообще, при отправке пакета Ethernet, чтобы Wireshark его видел, достаточно подать на MAC пакет состоящий из DST MAC, SRC MAC, тип пакета (08 00)

Не факт. На старой машине + ХР - да, видел что все принимается в том числе и RAW без всяких ARP
Как только обновил комп + win8. то пакеты начинают приниматься только после того как откроешь socket на определенный IP. После вызова ф-ции в VisualStudio посылается ARP запрос.
doom13
Цитата(gosu-art @ Jun 22 2015, 22:23) *
Не факт. На старой машине + ХР - да, видел что все принимается в том числе и RAW без всяких ARP
Как только обновил комп + win8. то пакеты начинают приниматься только после того как откроешь socket на определенный IP. После вызова ф-ции в VisualStudio посылается ARP запрос.

На новой машине + Win 7 это так (Wireshark всё видит), а с Win 8 не работал. Но что-то мне кажется, что Wireshark или любой другой сниффер будет видеть пакеты и без открытия сокета (на Win7 работает именно так). А на основании данных ARP заполняется ARP-таблица, настраивается фильтр MAC-контроллера на фильтрацию ненужного трафика и пропуск заданных MAC-адресов. Задача сниффера - мониторить весь трафик в сети, так что он должен видеть все пакеты (исключение только те, что перенаправляются сетевым коммутатором сразу на другой/нужный ПК). Ну а уж если и стоит галка promiscuous mode, то точно должен принимать все пакеты (возможно только если мак-адрес все нули задать, только тогда работать не будет).

ARP запрос после вызова Вашей функции отправляется для определения MAC-адреса удалённого устройства, т.е. чтобы знать какой MAC-адрес забивать в отправляемый пакет для соответствующего IP. (IP Вы знаете, MAC определяет система с помощью ARP запроса).
NSergeevich
Цитата(doom13 @ Jun 22 2015, 22:03) *
Вообще, при отправке пакета Ethernet, чтобы Wireshark его видел, достаточно подать на MAC пакет состоящий из DST MAC, SRC MAC, тип пакета (08 00) и произвольные данные (минимум 46 байт, если меньше MAC добивает нулями недостающие). Далее MAC дополнияет всё это преамбулой, SFD и CFS и выдаёт на PHY. Т.е. если эти условия выполнены, то никакие арпы и т.д. не нужны, Вы увидите свой пакет в Wireshark.
Если нет - ищите проблему где-то в проекте/железе:
1) Включен ли передатчик MAC-контроллера?
2) Выдаёт ли MAC данные на PHY?
3) Какой интерфейс MAC-PHY используется в системе?
4) Правильно ли настроен PHY?
5) и т.д.

Да, какую FPGA используете? Есть стандартные генераторы Ethernet трафика, можно попробовать загрузить сеть данными генератора.

Чтобы проверить соединение PC-PHY, можно включить PHY в режим Line Loopback и побросать пакеты с компа на плату.


У меня все так и сделано и MAC все добавляет. Я уже об этом писал. При подключении диоды мигают, а на wireshark следующее: Нажмите для просмотра прикрепленного файла
Интерфейс у меня RGMII. В настройке phy на 100% я НЕ уверен, т.к. на 100% не понимаю какой регистр кофигурировать и как правильно это делать.
Пробовал и не конфигурируя phy(т.к. где-то вычитал, что конфигурировать не обязательно) и конфигурируя 0-ой регистр control (там я указал скорость передачи и full дуплексный мод).
У меня AR8035 Нажмите для просмотра прикрепленного файла
Я работаю со Spartan-ом 6-ым XC6SLX100
doom13
Цитата(NSergeevich @ Jun 23 2015, 10:39) *
Интерфейс у меня RGMII. В настройке phy на 100% я НЕ уверен, т.к. на 100% не понимаю какой регистр кофигурировать и как правильно это делать.

Вот тут большая вероятность того, что нужно "подвинуть" клок (TXC) относительно данных (TXD). Это можно делать через соответствующий регистр PHY по MDIO или можете попробовать подвигать его PLL. Ещё, прописаны ли временные ограничения?

Еще, может быть проблема со сбросом, при подаче питания PHY какое-то время (см. доку) надо подержать в ресете.
NSergeevich
Цитата(doom13 @ Jun 23 2015, 11:17) *
Вот тут большая вероятность того, что нужно "подвинуть" клок (TXC) относительно данных (TXD). Это можно делать через соответствующий регистр PHY по MDIO или можете попробовать подвигать его PLL. Ещё, прописаны ли временные ограничения?

Еще, может быть проблема со сбросом, при подаче питания PHY какое-то время (см. доку) надо подержать в ресете.


Что за временные ограничения ?
Клок пробовал двигать относительно данных конфигурируя регистр - без результатно.
А phy у меня в ресете при включении некоторое время.
doom13
Цитата(NSergeevich @ Jun 23 2015, 11:48) *
Что за временные ограничения ?

UCF или XDC файл с описанием клоков. Если xdc, то
Код
create_clock -name sys_clk -period 10 [get_ports sys_clk_p]
,
где перечисляются все клоки используемые в проекте. Но у меня в начале работало и без них, а вот сдвиг клока помогал.

Цитата(NSergeevich @ Jun 23 2015, 11:48) *
А phy у меня в ресете при включении некоторое время.

Согласно Вашей доке reset должен быть минимум 1 мс + время на запуск клока. Если сделано с запасом, то проблем в этом нет.

Попробуйте ещй включить режим Remote PHY Loopback и побросать на плату пакеты с ПК.
NSergeevich
Может кто-нибудь сталкивался со следующей проблемой?:
Если я подтягиваю выводы данных, на ножки phy при помощи команды PULLUP в ucf файле, то у MAC на выходе нету данных которые я на вход пускаю.
А если просто "биндю" на ножки (без PULLUP) то MAC выдает данные и дальше они на phy идут.

Вот только phy, видимо, без PULLUP не работает.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.