Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: xilinx tri mode ethernet mac
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
NSergeevich
Всем привет. Есть ли у кого-нибудь опыт в реализации проекта xilinx tri mode ethernet mac ? На RGMII гигабитный PHY.
У меня появилось несколько вопросов:
1. RGMII - Reduce Gigabit Media Independent Interface. RGMII использует половину цепей, используемых в GMII интерфейсе. Всего 12 контактов, и среди них TXD и RXD по [3:0], т.е. по 4 цепи.
Но, генерируемая корка MAC-а (tri mode ethernet mac) в xilinxe при выборе RGMII интерфейса выдает TXD и RXD по [7:0], т.е. по 8 цепей, (как обычный GMII). Вопрос, я же не могу свой PHY с 4-мя цепями коннектить только на половину цепей, что выходит из мака? Что с этим делать?
2. Если я правильно разобрался, то на GTX_CLK (клок на phy) и на tx_axi_clk (клок на mac)(опять же все применимо к rgmii) нужно подавать 125mhz clk ?
3. Я пробую протащить пакеты через MAC. Подаю на вход [7:0] tx_axis_mac_tdata (Frame data to be transmitt) вместе с tx_axis_mac_tvalid (TX Data Valid), но пакеты не попадают на PHY (и на выходе мака нету). Почему не проходят, как правильно отправить? Есть ли пример?
Заранее спасибо за терпение)
NSergeevich
Я разобрался с вопросами которые выше.
Появился новый.
Покажу две картинки. Первая иллюстрирует, что идет на вход MAC, а вторая что появляется на выходе.
Как мы помним ethernet frame состоит из следующих частей: Preamble 7 byte, Start of Frame Delimiter (SFD) 1 byte, Destination Address 6 byte, Source Address 6 byte, Length/Type 2 byte, Data 0-1500 byte, Pad 0-46 byte, FCS 4 byte
Мой MAC устроен таким образом, что я на его вход подаю только DA,SA,L/T,DATA а на выходе все остальное он добавляет сам и далее все идет на PHY Data.
Но на выходе c MAC, как мы видим на 2-ой картинке он, действительно добавляет недостающие части фрейма, например Preamble и т.д. НО! Destination Address и Source Address вместо 6 byte адреса выдает только 1 byte тоесть неполный адрес.
Есть ли идеи почему он обрезает DA и SA ? Ведь, как я понимаю, на вход PHY должен приходить адрес полностью.

1-ая картинка:
Нажмите для просмотра прикрепленного файла

2-ая картинка:
Нажмите для просмотра прикрепленного файла
Artemius_tv
Цитата(NSergeevich @ May 29 2015, 18:23) *
Мой MAC устроен таким образом, что я на его вход подаю только DA,SA,L/T,DATA а на выходе все остальное он добавляет сам и далее все идет на PHY Data.

Не помню, чтобы его можно было настраивать таким образом. Описание (ug138) сейчас посмотрел и тоже не нашел. Может покажете, как вы его так подключили.
По-моему можно задать только свой MAC-адрес и только для проверки принятых пакетов, а не отправляемых.

А еще хорошо бы в ChipScope и управляющие сигналы вывести, а не только данные, в XC6SLX100 памяти полно.

Еше раз описание посмотрел, а вы сигнала emacclienttxack дожидаетесь (Figure 7-7)?
tolik1
Цитата(NSergeevich @ May 29 2015, 18:23) *
Я разобрался с вопросами которые выше.
Появился новый.
Покажу две картинки. Первая иллюстрирует, что идет на вход MAC, а вторая что появляется на выходе.
Как мы помним ethernet frame состоит из следующих частей: Preamble 7 byte, Start of Frame Delimiter (SFD) 1 byte, Destination Address 6 byte, Source Address 6 byte, Length/Type 2 byte, Data 0-1500 byte, Pad 0-46 byte, FCS 4 byte
Мой MAC устроен таким образом, что я на его вход подаю только DA,SA,L/T,DATA а на выходе все остальное он добавляет сам и далее все идет на PHY Data.
Но на выходе c MAC, как мы видим на 2-ой картинке он, действительно добавляет недостающие части фрейма, например Preamble и т.д. НО! Destination Address и Source Address вместо 6 byte адреса выдает только 1 byte тоесть неполный адрес.
Есть ли идеи почему он обрезает DA и SA ? Ведь, как я понимаю, на вход PHY должен приходить адрес полностью.

1-ая картинка:
Нажмите для просмотра прикрепленного файла

2-ая картинка:
Нажмите для просмотра прикрепленного файла

К сожалению я затрудняюсь сказать что-либо глядя на Ваши картинки, но когда я с ним разбирался я взял за основу пример который генерится визардом (AddresSwap как то так этот модуль называется). я с одной стороны подключил Chip scope с другой комп с Wireshark. Mac в исполнении Xilinx формирует преамбулу, SFD и FCS. все остальное тело пакета надо грузить через интерфейс данных.
Trashy_2
Вы в хексе напишите, что вы получаете, вместе с приамбулами и т.д. А, то нет желания побитово декодировать. Всю посылку.
От себя добавлю,когда парился с RGMII, ждал ETHERNET пакета. Мне приходили данные, я ничё понять не мог - заголовки и тело не соответствовали формату пакетов ethernet, пока не допёрло: ПРОЦ сначала шлёт ARP запрос на предмет "прозвонки" связи. И только после этого слал нужные мне данные.

Ещё! Не забываем, что RGMII - даблрэйт. Первый нибл забираем по переднему фронту, а второй нибл по заднему.
egorman44
Цитата(tolik1 @ Jun 1 2015, 11:03) *
К сожалению я затрудняюсь сказать что-либо глядя на Ваши картинки, но когда я с ним разбирался я взял за основу пример который генерится визардом (AddresSwap как то так этот модуль называется). я с одной стороны подключил Chip scope с другой комп с Wireshark. Mac в исполнении Xilinx формирует преамбулу, SFD и FCS. все остальное тело пакета надо грузить через интерфейс данных.
очень верный способ, на мой взгляд. Плюс ко всему там тестбенч написан, который можете запустить даже в Isim и посмотреть что к чему. Так же есть дока официальная на корку UG138 "LogiCORE IP Tri-Mode Ethernet MAC v4.5" там все ответы на интересующие Вас вопросы.
NSergeevich
Не успел написать. Я разобрался, в чем дело, на прошлой неделе. Но косяк еще не устранил, т.к. в программировании я оч. слаб.
Там дело в том, что первые байты DA и SA уже прошли а handshaking приходит позже, соответственно эти первые байты на выходе обрезались.
Теперь нужно сделать так, чтобы первый байт отправлялся до тех пор пока не придет handshaking и далее остальное.

А по поводу модуля AddresSwap, надо глянуть.

Глянул, не нашел. Есть только Multiply Adder и Adder Subtracter.

Как написать простой код, чтобы первый байт отправлялся до тех пор пока не придет какой-либо внешний сигнал, а как только он приходит отправляются следующие байты? =)
Trashy_2
Цитата(egorman44 @ Jun 1 2015, 13:51) *
"LogiCORE IP Tri-Mode Ethernet MAC v4.5"


А что бы эту корку юзать, надо денежку заносить куда то или она халявная?
NSergeevich
Цитата(Trashy_2 @ Jun 1 2015, 18:08) *
А что бы эту корку юзать, надо денежку заносить куда то или она халявная?


webpack покупаешь и все в нем халява
NSergeevich
Как на Verilog описать задержку первого байта до прихода emacclienttxack ?

Нажмите для просмотра прикрепленного файла
NSergeevich
Может быть, кто-нибудь использовал конструкцию The wait statement в верилоге ?
egorman44
Цитата(NSergeevich @ Jun 2 2015, 13:09) *
Как на Verilog описать задержку первого байта до прихода emacclienttxack ?

Нажмите для просмотра прикрепленного файла


можно написать конечный автомат, который будет висеть в состояние до того момента как придет emacclienttxack, и находясь в новом состоянии будет выдавать новые данные на clientemactxd. Опять же настоятельно рекомендую посмотреть пример. В примере между MAC контроллером и модулем client_side вставлен FIFO, и соблюдение всех рукопожатий ложится на этот модуль, Вам же остается просто кидать данные в FIFO и следить чтобы он не переполнился, если вы работаете на передачу.

Цитата(NSergeevich @ Jun 2 2015, 15:21) *
Может быть, кто-нибудь использовал конструкцию The wait statement в верилоге ?


Для верификации сколько хош sm.gif

UPD: я может чего не так понял , если вы пользуете ядро под номером 4.6 то в папке куда у вас сгенирировалась корка есть папка example_design в ней и смотрите пример
NSergeevich
Цитата(egorman44 @ Jun 2 2015, 16:48) *
можно написать конечный автомат, который будет висеть в состояние до того момента как придет emacclienttxack, и находясь в новом состоянии будет выдавать новые данные на clientemactxd. Опять же настоятельно рекомендую посмотреть пример. В примере между MAC контроллером и модулем client_side вставлен FIFO, и соблюдение всех рукопожатий ложится на этот модуль, Вам же остается просто кидать данные в FIFO и следить чтобы он не переполнился, если вы работаете на передачу.



Для верификации сколько хош sm.gif

UPD: я может чего не так понял , если вы пользуете ядро под номером 4.6 то в папке куда у вас сгенирировалась корка есть папка example_design в ней и смотрите пример



Где этот пример-то посмотреть? У меня в папке экземпл дезайна нету.
И модуль дополнительный мне не нужен т.к. код осуществляющий передачу ethernet frame-а простой и не грамоздкий. Только нужно понять как этот конечный автомат правильно написать, чтобы первый байт отправлялся непрерывно пока не придет внешний emacclienttxack, а как пришел - все остальное
egorman44
Цитата(NSergeevich @ Jun 3 2015, 09:56) *
Только нужно понять как этот конечный автомат правильно написать, чтобы первый байт отправлялся непрерывно пока не придет внешний emacclienttxack, а как пришел - все остальное

А чего тут такого сложного ? Берете карандаш ,листок , бумагу ... Рисуете состояния и правила перехода из них, затем плавно переносите на HDL. Тема fsm verilog/VHDL гуглится хорошо. Я же вроде бы писал :
Цитата(egorman44 @ Jun 2 2015, 16:48) *
можно написать конечный автомат, который будет висеть в состояние до того момента как придет emacclienttxack, и находясь в новом состоянии будет выдавать новые данные на clientemactxd.


Или Вам еще не доводилось описывать конечные автоматы ? Вы на каком языке собрались это делать ?
NSergeevich
Цитата(egorman44 @ Jun 3 2015, 14:12) *
А чего тут такого сложного ? Берете карандаш ,листок , бумагу ... Рисуете состояния и правила перехода из них, затем плавно переносите на HDL. Тема fsm verilog/VHDL гуглится хорошо. Я же вроде бы писал :


Или Вам еще не доводилось описывать конечные автоматы ? Вы на каком языке собрались это делать ?



Verilog. Делал светофор на диодах =))
egorman44
Я бы Вам рекомендовал почитать что-нибудь от Sunburst Design - у этих ребят много рассуждений по поводу реализации конечного автомата на Verilog и SV, конечно если с английским хорошо. У Iosifk на сайте есть краткий курс , там тоже описаны FSM'ки. Да собственно по первому же запросу в Google на тему "fsm verilog" вывалился пример от Altera.
Я думаю лучше самому понять как это работает, потому что конечный автомат - есть очень важный момент в цифровой схемотехнике. sm.gif
NSergeevich
Цитата(egorman44 @ Jun 3 2015, 14:55) *
Я бы Вам рекомендовал почитать что-нибудь от Sunburst Design - у этих ребят много рассуждений по поводу реализации конечного автомата на Verilog и SV, конечно если с английским хорошо. У Iosifk на сайте есть краткий курс , там тоже описаны FSM'ки. Да собственно по первому же запросу в Google на тему "fsm verilog" вывалился пример от Altera.
Я думаю лучше самому понять как это работает, потому что конечный автомат - есть очень важный момент в цифровой схемотехнике. sm.gif


Будьте добры не отсылайте меня в школу. У меня много литературы по верилогу, в том числе и о конечных автоматах.
Мне интеречно где может быть у меня ошибка...
Часть кода:
Код
parameter S1 = 1'b0;
parameter S2 = 1'b1;


parameter [7:0] DA1[0:0] = {8'b1111000};
parameter [7:0] DA2[0:4] = {8'b100100,8'b10101111,8'b111100,8'b1101110,8'b10101000};//{7'b1111000,6'b100100,8'b10101111,6'b111100,7'b1101110,8'b10101000};
parameter [7:0] SA[0:5] = {8'b11010,8'b11011,8'b11100,8'b11101,8'b11110,8'b11111};//{5'b11010,5'b11011,5'b11100,5'b11101,5'b11110,5'b11111};
parameter [7:0] L_T[0:1] = {8'b1000,8'b0};
parameter [7:0] DATA[0:47] =

{

8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010

};

parameter [7:0] frame[0:60] = {DA2[0:4], SA[0:5], L_T[0:1], DATA[0:47]};  

always @(posedge handshake)
begin
    got_handshake <= 1;
end
    
    

always @(*)
begin
   if (counter_next > 1024)
       begin
                counter_next <= 0;
      end
    else
      counter_next <= counter + 1'b1;
end

reg [0:0] state, next_state;
always@(*)
begin
      if (rst) begin
         out <= 0;
         out2 <= 0;
         counter <= 0;
            state <= S1;
      end
      else
          case (state)
            S1 : begin
                  out <= DA1[counter];
                        out2 <= 1'h1;
                        next_state = got_handshake ? S2 : S1;  
                        counter <= counter_next;
                 end              
                S2 : begin
                  out <= frame[counter];
                        out2 <= 1'h1;
                        next_state = S1;
                        counter <= 0;
                      end
          endcase                      
end


Почемуто автомат не переходит во 2-е состояние (S2), судя по всему handshke не приходит. А должен так как первый byte на MAC приходит.
doom13
У Вас тут асинхронщина какая-то:
Код
always@(*)

Так точно работать не будет.
Artemius_tv
Выложите весь исходник.
Вот так:
Цитата(NSergeevich @ Jun 3 2015, 18:03) *
Код
always @(posedge handshake)
begin
    got_handshake <= 1;
end

точно нельзя делать.
NSergeevich
Код
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date:    13:41:36 03/26/2015
// Design Name:
// Module Name:    tx_data
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module tdata(
input clk,
input rst,
output [7:0]data,
input handshake,
output data_valid
    );
reg [31:0]counter;

reg [31:0]counter_next;
reg [7:0]out;
reg out2;
reg got_handshake;


parameter S1 = 1'b0;
parameter S2 = 1'b1;


parameter [7:0] DA1[0:0] = {8'b1111000};
parameter [7:0] DA2[0:4] = {8'b100100,8'b10101111,8'b111100,8'b1101110,8'b10101000};
parameter [7:0] SA[0:5] = {8'b11010,8'b11011,8'b11100,8'b11101,8'b11110,8'b11111};
parameter [7:0] DATA[0:47] =

{

8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010,
8'b10101010,8'b10101010,8'b10101010

};

parameter [7:0] frame[0:60] = {DA2[0:4], SA[0:5], L_T[0:1], DATA[0:47]};  

always @(handshake)
begin
    got_handshake <= 1;
end
    
always @(posedge clk)
begin
   if (counter_next > 1024)
       begin
                counter_next <= 0;
      end
  
  else
      counter_next <= counter + 1'b1;
end

reg [0:0] state, next_state;
always@(*)
begin
      if (rst) begin
         out <= 0;
         out2 <= 0;
         counter <= 0;
            state <= S1;
      end
      else
          case (state)
            S1 : begin
                  out <= DA1[counter];
                        out2 <= 1'h1;
                        next_state = (got_handshake == 1) ? S2 : S1;  
                        counter <= counter_next;
                 end              
                S2 : begin
                  out <= frame[counter];
                        out2 <= 1'h1;
                        next_state = S1;
                        counter <= 0;
                      end
          endcase                      
end

assign data = out;      
assign data_valid = out2;

endmodule
egorman44
Код
always @(posedge handshake)
begin
    got_handshake <= 1;
end


Не уверен, что сигнал с названием handshake является тактовым. Вы в клоковое дерево вашей ПЛИС пытаетесь завести сигнал handshake так делать нельзя. Такое ощущение, что здесь вы хотите синтезировать защелку по сигналу handshake, так и синтезируйте, если очень конечно нужно:
Код
always @(*)
if(handshake)
  got_handshake = 1;


Код
always @(*)
begin
   if (counter_next > 1024)
       begin
                counter_next <= 0;
      end
    else
      counter_next <= counter + 1'b1;
end

reg [0:0] state, next_state;
always@(*)
begin
      if (rst) begin
         out <= 0;
         out2 <= 0;
         counter <= 0;
            state <= S1;
      end
      else
          case (state)
            S1 : begin
                  out <= DA1[counter];
                        out2 <= 1'h1;
                        next_state = got_handshake ? S2 : S1;  
                        counter <= counter_next;
                 end              
                S2 : begin
                  out <= frame[counter];
                        out2 <= 1'h1;
                        next_state = S1;
                        counter <= 0;
                      end
          endcase                      
end

очень странно, что вы пытаетесь сделать автомат и счетчик асинхронными, у Вас отсутствует кварц на плате ? sm.gif Такой автомат работать не будет. Посмотрели бы пример от Altera хотяб:
Код
always @(posedge clk or posedge reset)
     begin
          if (reset)
               state = zero;
          else
               case (state)
                    zero:
                         state = one;
                    one:
                         if (in)
                              state = zero;
                         else
                              state = two;
                    two:
                         state = three;
                    three:
                         state = zero;
               endcase
     end

Откуда видно, что автомат из состояния в состояние переходит по переднему фронту clk, ну еще и асинхронно сбрасывается по reset.

Я так думал что когда описываешь комбинаторную логику пользуешься блокирующим присваиванием (=). И собственно использовать оба типа присваивания в одном always блоке , тоже не особо приветствуется:
Код
S2 : begin
                  out <= frame[counter];
                  out2 <= 1'h1;
                  next_state = S1;
                  counter <= 0;
         end

Я так полагаю Вы не особо тщательно смотрели ваши книги по верилогу sm.gif Для начала бы Вам разобраться в синтезе комбинаторной и последовательной логики (combinational and sequential logic) ну и с блокирующим и неблокирующим присвоением соответственно.
NSergeevich
Кому интересно, почитайте очень интересную статью на тему always @

Нажмите для просмотра прикрепленного файла
egorman44
Цитата(NSergeevich @ Jun 4 2015, 14:26) *
Кому интересно, почитайте очень интересную статью на тему always @

Нажмите для просмотра прикрепленного файла


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