реклама на сайте
подробности

 
 
> Передача данных с Marvell'a в режиме GMII, проходит без сбоев лишь каждый 3-ий ... 5-ый пакет
ovs_pavel
сообщение Oct 5 2012, 05:02
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 275
Регистрация: 19-05-06
Пользователь №: 17 249



Утро доброе. Коллеги, с приемом вроде бы разобрался (пакеты принимаются без сбоев), теперь отлаживаю передачу. Проходит без сбоев порядка 20% ... 30% информации. По аналогии с приемом сделал констрейны на передающие пины.

Регистры поместил в IOB'ы:
INST "U9/GM_TxD*" IOB = true ;
INST "U9/GM_TxEn" IOB = true ;

и задал фронты на выходных пинах:
Net "Phy_TxD<?>" SLEW = FAST;
Net "Phy_TxEn" SLEW = FAST;

Ошибка заключается в "выпадении" некоторых битах, хотя на приемопередатчик байты данных и CRC идут правильно (ставил ФИФО - ловушку непосредственно на передаваемый пакет данных уже у самих выходных регистрах; обратным чтением прочитал - все отлично). Но на персоналку приходят пакеты с ошибками.

Тактирую передающую часть частотой, той же самой, которая через буфер ODDR2 подается на Marvell 88E1111. Может ее надо пропустить через DCM с определенным сдвигом (больно Marvell капризен по времени установки)?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Boris_TS
сообщение Oct 5 2012, 05:10
Сообщение #2


Злополезный
****

Группа: Свой
Сообщений: 608
Регистрация: 19-06-06
Из: Russia Taganrog
Пользователь №: 18 188



По какому фронту TX_CLK, изменяются TX_EN и TX_D<*> ?
Через какие триггера выдаются TX_CLK, TX_EN, TX_D<*> ? (можно кусок кода привести – глядишь еще чего заметим)
И что-то я запамятовал: Какую ПЛИС используете
Go to the top of the page
 
+Quote Post
ovs_pavel
сообщение Oct 5 2012, 05:57
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 275
Регистрация: 19-05-06
Пользователь №: 17 249



Цитата(Boris_TS @ Oct 5 2012, 08:10) *
По какому фронту TX_CLK, изменяются TX_EN и TX_D<*> ?
Через какие триггера выдаются TX_CLK, TX_EN, TX_D<*> ? (можно кусок кода привести – глядишь еще чего заметим)
И что-то я запамятовал: Какую ПЛИС используете


ПЛИС применяется Spartan6 - XC6SLX45.

Схема формирования частот - следующая:
1. На ПЛИС приходит частота от внешнего генератора - 125МГц.
2. Эта частота подается на DCM, с помощью которого формируется две частоты - 125 МГц (проходит через CLK0) и 25 МГц (проходит через CLKFX) и далее эти эти частоты через BUFG и ODDR2 подаются на Marvell. Передающая часть также синхронизируется от частоты 125МГц полученной с модуля DCM и пропущенной через буфер BUFG.

Ниже приводиться передающая часть. Данные в ФИФО набиваются от внешнего МП (стек TCP обрабатывается внешним контроллером; стек UDP обрабатывается внутри ПЛИС - видеопоток). Могу если интересно привести код CRC.
CODE

module Frame_Prd (
//------------------------- Сигналы синхронизации. -------------------------//
input Clk_125_MHz, // Тактовая частота 125 МГц.

//--------------- Сигналы модуля управления интерфейсом AVR. ---------------//
input Eth_ON, // Сигнал разрешения работы модуля (устанавливается AVR; активный уровень "1").

input [10:0] Len_Frm_Prd, // Длина передаваемого кадра (в байтах).

input [31:0] FIFO_Prd_AVR, // Данные, предназначенные для передачи по интерфейсу Ethernet (предварительно записываются в ФИФО).
input Wr_FIFO_Prd, // Сигнал разрешения записи в ФИФО передачи пакета.

input Prd_PKG_Rdy, // Сигнал начала выдачи кадра.
output reg Prd_PKG_Busy, // Сигнал активности операции передачи кадра (активный уровень "1"; выдается в регистр состояния AVR).

//----------------------- Интерфейс Ethernet 1Gb/s. ------------------------//
output [7:0] Phy_TxD, //
output Phy_TxEn, //
output Phy_TxEr, //

//---------------------------- Тестовые сигналы. ---------------------------//
output [7:0] test_Dout_FIFO, // Данные тестового ФИФО.
input test_Clr_FIFO, // Сигнал сброса тестового ФИФО (запись в 62-ой регистр).
input test_Rd_FIFO // Сигнал разрешения чтения тестового ФИФО (чтение 62-го регистра).

);


//--------------------------------------------------------------------------//
//--------------- Сигнал активности операции передачи кадра. ---------------//
//--------------------------------------------------------------------------//
reg Clr_PKG_Busy; // Сброс сигнала активности операции передачи кадра (также обнуляет ФИФО передачи кадра; на всякий случай).
always @ (posedge Clk_125_MHz or posedge Clr_PKG_Busy)
begin
if (Clr_PKG_Busy)
Prd_PKG_Busy <= 1'b0;
else if (Prd_PKG_Rdy)
Prd_PKG_Busy <= 1'b1;
end


//--------------------------------------------------------------------------//
//------------------- Счетчик длины передаваемого кадра. -------------------//
//--------------------------------------------------------------------------//
reg Dec_Cnt_FRM; // Сигнал декремента счетчика длины передаваемого кадра.
reg [10:0] Cnt_FRM; // Счетчик длины переданного кадра.
always @ (posedge Clk_125_MHz or negedge Eth_ON)
begin
if (~Eth_ON)
Cnt_FRM <= 11'd0;
else if (Prd_PKG_Rdy)
Cnt_FRM <= Len_Frm_Prd;
else if (Dec_Cnt_FRM)
Cnt_FRM <= Cnt_FRM - 1'd1;
end


//--------------------------------------------------------------------------//
//-------------------------- ФИФО передачи кадра. --------------------------//
//--------------------------------------------------------------------------//
reg Rd_FIFO_Prd; // Сигнал чтения ФИФО передачи кадра.
wire [31:0] w_FIFO_Prd;

FIFO_Prd U1 (
.clk (Clk_125_MHz),
.rst (Clr_PKG_Busy),
.din (FIFO_Prd_AVR),
.wr_en (Wr_FIFO_Prd),
.rd_en (Rd_FIFO_Prd),
.dout (w_FIFO_Prd),
.full (),
.empty ()
);


//--------------------------------------------------------------------------//
//--------------- Счетчик числа переданных ниблов преамбулы. ---------------//
//--------------------------------------------------------------------------//
reg [2:0] Cnt_Pream; // Счетчик числа переданных ниблов преамбулы.
reg Clr_Cnt_Pream; // Сброса счетчика числа переданных ниблов преамбулы.
always @(posedge Clk_125_MHz or negedge Clr_Cnt_Pream)
begin
if (~Clr_Cnt_Pream)
Cnt_Pream <= 3'd0;
else
Cnt_Pream <= Cnt_Pream + 1'b1;
end


//--------------------------------------------------------------------------//
//------------ Управление мультиплексором ФИФО передачи данных. ------------//
//--------------------------------------------------------------------------//
// ФИФО 4-х байтное, а интерфейс Ethernet - байтовый. Поэтому необходимо
// считывать слово данных один раз за 4 такта.
reg [1:0] Cnt_MUX; // Счетчик управления мультиплексором ФИФО передачи данных.
always @(posedge Clk_125_MHz or negedge Dec_Cnt_FRM)
begin
if (~Dec_Cnt_FRM)
Cnt_MUX <= 2'd0;
else
Cnt_MUX <= Cnt_MUX + 1'b1;
end


//--------------------------------------------------------------------------//
//------------------- Сигнал чтения ФИФО передачи кадра. -------------------//
//--------------------------------------------------------------------------//
always @ (posedge Clk_125_MHz or negedge Eth_ON)
begin
if (~Eth_ON)
Rd_FIFO_Prd <= 1'b0;
else
Rd_FIFO_Prd <= (Cnt_MUX == 2'd2);
end


//--------------------------------------------------------------------------//
//------------ Мультиплексор выбора данных ФИФО передачи кадра. ------------//
//--------------------------------------------------------------------------//
reg [7:0] Mux_FIFO_Prd; // Байт данных ФИФО передачи кадра.
always @(Cnt_MUX or w_FIFO_Prd)
begin
case (Cnt_MUX)
2'd0: Mux_FIFO_Prd <= w_FIFO_Prd[31:24];
2'd1: Mux_FIFO_Prd <= w_FIFO_Prd[23:16];
2'd2: Mux_FIFO_Prd <= w_FIFO_Prd[15:8];
2'd3: Mux_FIFO_Prd <= w_FIFO_Prd[7:0];
endcase
end


//--------------------------------------------------------------------------//
//--------- Управление мультиплексором регистра контрольной суммы. ---------//
//--------------------------------------------------------------------------//
reg [1:0] Cnt_CRC; // Счетчик управления мультиплексором регистра контрольной суммы.
always @(posedge Clk_125_MHz or posedge Dec_Cnt_FRM)
begin
if (Dec_Cnt_FRM)
Cnt_CRC <= 2'd0;
else
Cnt_CRC <= Cnt_CRC + 1'b1;
end


//--------------------------------------------------------------------------//
//-------- Мультиплексор выбора данных регистра контрольной суммы. ---------//
//--------------------------------------------------------------------------//
reg [7:0] Mux_KS; // Байт данных регистра контрольной суммы.
wire [31:0] Rg_CRC; // Регистр контрольной суммы.
always @(Cnt_CRC or Rg_CRC)
begin
case (Cnt_CRC)
3'd0: Mux_KS <= ~Rg_CRC[7:0];
3'd1: Mux_KS <= ~Rg_CRC[15:8];
3'd2: Mux_KS <= ~Rg_CRC[23:16];
3'd3: Mux_KS <= ~Rg_CRC[31:24];
endcase
end


//--------------------------------------------------------------------------//
//------------------ Выходной мультиплексор выбора данных. -----------------//
//--------------------------------------------------------------------------//
// Мультиплексирует данные преамбулы, начала кадра, ФИФО передачи и регистра
// контрольной суммы.
reg [1:0] Upr_D; // Регистр управления выходным мультиплексором выбора данных.
reg [7:0] Mux_D;
always @(Upr_D or Mux_FIFO_Prd or Mux_KS)
begin
case (Upr_D)
2'd0: Mux_D <= 8'b01010101;
2'd1: Mux_D <= 8'b11010101;
2'd2: Mux_D <= Mux_FIFO_Prd;
2'd3: Mux_D <= Mux_KS;
endcase
end


//--------------------------------------------------------------------------//
//---------------- Объявление регистров автомата состояний. ----------------//
//--------------------------------------------------------------------------//
reg Rg_TxEn; // Сигнал передачи действительных данных.


//--------------------------------------------------------------------------//
//--------------------- Объявление автомата состояний. ---------------------//
//--------------------------------------------------------------------------//
reg [2:0] CState;
parameter [2:0]
CS_Idle = 3'd0,
CS_Pream = 3'd1,
CS_SOF = 3'd2,
CS_Data = 3'd3,
CS_CRC = 3'd4,
CS_End = 3'd5;


//--------------------------------------------------------------------------//
//--------------------------- Автомат состояний. ---------------------------//
//--------------------------------------------------------------------------//
always @ (posedge Clk_125_MHz or negedge Eth_ON)
begin
if (~Eth_ON)
begin
CState <= CS_Idle;
Rg_TxEn <= 1'b0; // Сигнал передачи действительных данных.
Clr_Cnt_Pream <= 1'b0; // Сброса счетчика числа переданных ниблов преамбулы.
Dec_Cnt_FRM <= 1'b0; // Сигнал декремента счетчика длины передаваемого кадра.
Clr_PKG_Busy <= 1'b0; // Сброс сигнала активности операции передачи кадра (также обнуляет ФИФО передачи кадра; на всякий случай).
Upr_D <= 2'd0; // Регистр управления выходным мультиплексором выбора данных.
end
else
begin
case (CState)
CS_Idle: // ОЖИДАНИЕ СИГНАЛА НАЧАЛА ВЫДАЧИ КАДРА.
begin
if (Prd_PKG_Rdy)
begin
CState <= CS_Pream;
Rg_TxEn <= 1'b1;
Clr_Cnt_Pream <= 1'b1;
end
else
CState <= CS_Idle;
end

CS_Pream: // ФОРМИРОВАНИЕ ПРЕАМБУЛЫ.
begin
if (Cnt_Pream == 3'd6)
begin
CState <= CS_SOF;
Clr_Cnt_Pream <= 1'b0;
Upr_D <= 2'd1;
end
else
CState <= CS_Pream;
end

CS_SOF: // ФОРМИРОВАНИЕ СОСТОЯНИЯ "SOF".
begin
CState <= CS_Data;
Upr_D <= 2'd2;
Dec_Cnt_FRM <= 1'b1;
end

CS_Data: // ВЫДАЧА ДАННЫХ.
begin
if (Cnt_FRM == 11'd1)
begin
CState <= CS_CRC;
Upr_D <= 2'd3;
Dec_Cnt_FRM <= 1'b0;
end
else
CState <= CS_Data;
end

CS_CRC:
begin
if (Cnt_CRC == 2'd3)
begin
CState <= CS_End;
Rg_TxEn <= 1'b0;
Upr_D <= 2'd0;
Clr_PKG_Busy <= 1'b1;
end
else
CState <= CS_CRC;
end

CS_End:
begin
CState <= CS_Idle;
Clr_PKG_Busy <= 1'b0;
end

default:
begin
CState <= CS_Idle;
Rg_TxEn <= 1'b0;
Clr_Cnt_Pream <= 1'b0;
Dec_Cnt_FRM <= 1'b0;
Clr_PKG_Busy <= 1'b0;
Upr_D <= 2'd0;
end
endcase
end
end


//--------------------------------------------------------------------------//
//-------------- Привязка выходных данных к тактовой частоте. --------------//
//--------------------------------------------------------------------------//
reg GM_TxEn;
reg [7:0] GM_TxD;
always @ (posedge Clk_125_MHz or negedge Eth_ON)
begin
if (~Eth_ON)
begin
GM_TxEn <= 1'b0;
GM_TxD <= 8'd0;
end
else
begin
GM_TxEn <= Rg_TxEn;
GM_TxD <= Mux_D;
end
end

assign Phy_TxD = GM_TxD;
assign Phy_TxEn = GM_TxEn;


//--------------------------------------------------------------------------//
//------ Модуль вычисления CRC пакета передаваемого по сети Ethernet. -------//
//--------------------------------------------------------------------------//
wire [31:0] w_Rg_CRC;

my_crc_prd U2 (
.Clk_125_MHz (Clk_125_MHz),
.Eth_ON (Eth_ON),
.Clr_CRC (Clr_PKG_Busy),
.D_In (Mux_FIFO_Prd),
.En_CRC (Dec_Cnt_FRM),
.Rg_CRC (w_Rg_CRC)
);

assign Rg_CRC = w_Rg_CRC;


//--------------------------------------------------------------------------//
//--------------------- Назначение выходных сигналов. ----------------------//
//--------------------------------------------------------------------------//
assign Phy_TxEr = 1'b0;


//--------------------------------------------------------------------------//
//-------------------------- ФИФО передачи кадра. --------------------------//
//--------------------------------------------------------------------------//
wire [7:0] w_test_fifo;

test_fifo U_test (
.clk (Clk_125_MHz),
.rst (test_Clr_FIFO),
.din (Mux_D),
.wr_en (Rg_TxEn),
.rd_en (test_Rd_FIFO),
.dout (w_test_fifo),
.full (),
.empty ()
);

assign test_Dout_FIFO = w_test_fifo;

endmodule



Да, забыл, все тактируется положительным фронтом сигнала 125МГц.
Причина редактирования: используйте теги для оформления кода (с) модератор
Go to the top of the page
 
+Quote Post
Boris_TS
сообщение Oct 5 2012, 07:02
Сообщение #4


Злополезный
****

Группа: Свой
Сообщений: 608
Регистрация: 19-06-06
Из: Russia Taganrog
Пользователь №: 18 188



Цитата(ovs_pavel @ Oct 5 2012, 09:57) *
ПЛИС применяется Spartan6 - XC6SLX45.

Схема формирования частот - следующая:
1. На ПЛИС приходит частота от внешнего генератора - 125МГц.
2. Эта частота подается на DCM, с помощью которого формируется две частоты - 125 МГц (проходит через CLK0) и 25 МГц (проходит через CLKFX) и далее эти эти частоты через BUFG и ODDR2 подаются на Marvell. Передающая часть также синхронизируется от частоты 125МГц полученной с модуля DCM и пропущенной через буфер BUFG.

1. Попробуйте сделать вот такие времянки для TX GMII интерфейса:
Прикрепленное изображение

Этот вариант должен помочь со стабильность передачи данных в Eth Phy.
В Вашем исходнике я не заметил constaint'ов IOB для GM_TxD, GM_TxEn, если этих constaint'ов нет где-то в другом месте, то их необходимо добавить.

2. 88E1111 имеет очень жесткие требования к XTAL1, и меня берут жестокие сомнения, что после пропускания CLK через DCM получится что-то подходящее. Поэтому предлагаю 2 выхода:
1) завести на XTAL1 первородный входной Clock, который вы сейчас подаёте на DCM - в этом случае 88E1111 получит наиболее чистый clock. Правда для этого прийдётся ногу SEL_FREQ посадить на землю.
2) поделить входной Clock (не прошедший DCM) на триггерах и через ODDR (тактируемую первородным входным Clock'ом) выдать наружу.
На всякий случай посоветую еще раз внимательно просмотреть раздел XTAL1 Input Clock Timing 88E1111 Datasheet - особенно с три сноски внизу.

3. Для работы с 88E1111 GMII/RGMII я использовал Spartan-3A/Virtex-5/Virtex-6, и во всех случаях для всех сигналов использовал LVCMOS25, Drive=8,12, Slew=slow - так меньше звона стоит в линиях.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 17:57
Рейтинг@Mail.ru


Страница сгенерированна за 0.0142 секунд с 7
ELECTRONIX ©2004-2016