Перейти к содержанию
    

Передача данных с Marvell'a в режиме GMII

Утро доброе. Коллеги, с приемом вроде бы разобрался (пакеты принимаются без сбоев), теперь отлаживаю передачу. Проходит без сбоев порядка 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 капризен по времени установки)?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По какому фронту TX_CLK, изменяются TX_EN и TX_D<*> ?

Через какие триггера выдаются TX_CLK, TX_EN, TX_D<*> ? (можно кусок кода привести – глядишь еще чего заметим)

И что-то я запамятовал: Какую ПЛИС используете

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По какому фронту 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.

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МГц.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Схема формирования частот - следующая:

1. На ПЛИС приходит частота от внешнего генератора - 125МГц.

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

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

post-18188-1349418459_thumb.png

Этот вариант должен помочь со стабильность передачи данных в 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 - так меньше звона стоит в линиях.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

post-18188-1349418459_thumb.png

Этот вариант должен помочь со стабильность передачи данных в 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 - так меньше звона стоит в линиях.

 

Да, к сожалению ногу SEL_FREQ на землю посадить не удаться, т.к. корпус BGA (с многослойкой это проблемы). Вот не думал, что DCM так может сорить?

 

Судя по вашим времянкам, вы работаете от отрицательного фронта (либо подгоняете фронт под данные, т.к. после клока - падающего фронта, время установи данных равно практически 0). А в чем симулите - моделсим?

Просто я с 12-ой версии айса симулю его встроенным, вроде как от моделсима отошел.

Спасибо за советы, буду пробовать. Отпишусь что получилось.

 

 

 

Насчет констрейнов - я их добавил в файл .usf, т.е. с констрейнами все нормально.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, к сожалению ногу SEL_FREQ на землю посадить не удаться, т.к. корпус BGA (с многослойкой это проблемы). Вот не думал, что DCM так может сорить?
Я скажу по другому - он не может выдавать чистый сигнал. Если входной сигнал совсем поганый - то DCM его хорошенько почистит,.. а если входной сигнал чистый, то, соответственно, несколько испоганит.

Но тут вопрос не столько в DCM, сколько в жёстких требованиях 88E1111 - у них, похоже, система чувствительна в jitter'у определённой частоты, т.е. во времена разработки 88E1111 явно предполагалось, что к ней будет подвешен кварц, а частоту будут брать уже с 88E1111 для своих целей - и нога для этого есть специальная. И я её даже пользовал в проекте со Spartan-3A: 88E1111 из 25МГц делал весьма чистенькие 125МГц.

 

Судя по вашим времянкам, вы работаете от отрицательного фронта (либо подгоняете фронт под данные, т.к. после клока - падающего фронта, время установи данных равно практически 0). А в чем симулите - моделсим?
Да, ModelSim.

На самом деле всё у меня работает тоже по положительному фронту... просто GTX_CLK выдаётся инверсным (на ODDR 1 и 0 на D местами поменяны).

 

Насчет констрейнов - я их добавил в файл .usf, т.е. с констрейнами все нормально.
Это хорошо. Но на будущее, моя практика показала, что лучше такие constaint'ы добавлять прямо в код - тогда код лучше (грамотнее) XST синтезируется.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...