Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Virtex 6. Прием данных с АЦП. Констрейны
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
Ethereal
Здравствуйте.

Имеется проект на шестом виртексе с параллельными АЦП на 400 МГц.
Выходная шина АЦП 10 бит, сопровождаются тактом 200 МГц с привязкой к центру UI. Сигналы дифференциальные. Передача идет с удвоенной скоростью. tsu, th относительно переднего фронта синхросигнала 1нс

В проекте, соответственно реализован приемник.
Дифференциальная шина пропускается сначала через IBUFDS.
С выхода IBUFDS она идет на IDDR и далее на синхронизатор на FIFO.

Клок от АЦП пропускается через IBUFDS и далее идет на клок IDDR, на котором защелкивается входная шина.

В .ucf описаны констрейны:

Код
NET InputAdcClockPos TNM_NET = TnmAdcClockPos;
TIMESPEC TsAdcClockPos = PERIOD TnmAdcClockPos 200 Mhz HIGH 50%;

TIMEGRP GrpRiseAdcClockPos = RISING TnmAdcClockPos;
TIMEGRP GrpFallAdcClockPos = FALLING TnmAdcClockPos;

OFFSET = IN 750 ps VALID 1500 ps BEFORE InputAdcClockPos TIMEGRP GrpRiseAdcClockPos;
OFFSET = IN 750 ps VALID 1500 ps BEFORE InputAdcClockPos TIMEGRP GrpFallAdcClockPos;


Описал с запасом на разбег в длинах проводников, хотя он там настолько влиять не должен.

При этом PAR долго разводит, а потом фейлит констрейны.

После этого клок стал пропускать не через IBUFDS, а IBUFGDS, и стало намного лучше в части скорости работы, но фейл с констрейнами остался.
Например.

Код
Slack (setup path):     -1.144ns (requirement - (data path - clock path - clock arrival + uncertainty))
  Source:               InputAdcDataPos<3> (PAD)
  Destination:          GenDdr[3].IDDR_inst (FF)
  Destination Clock:    AdcClock rising at 0.000ns
  Requirement:          0.750ns
  Data Path Delay:      5.235ns (Levels of Logic = 1)
  Clock Path Delay:     3.366ns (Levels of Logic = 2)
  Clock Uncertainty:    0.025ns


где AdcClock - это клок на выходе IBUFGDS.

Tsu всей шины на переднем фронте болтается в районе 1.86нс. Th в районе минус 0.1.

Не подскажете, чем можно вылечить данную проблему?

Заранее спасибо.
Bad0512
Цитата(Ethereal @ Jul 10 2014, 22:14) *
Здравствуйте.

Имеется проект на шестом виртексе с параллельными АЦП на 400 МГц.
Выходная шина АЦП 10 бит, сопровождаются тактом 200 МГц с привязкой к центру UI. Сигналы дифференциальные. Передача идет с удвоенной скоростью. tsu, th относительно переднего фронта синхросигнала 1нс

В проекте, соответственно реализован приемник.
Дифференциальная шина пропускается сначала через IBUFDS.
С выхода IBUFDS она идет на IDDR и далее на синхронизатор на FIFO.

Клок от АЦП пропускается через IBUFDS и далее идет на клок IDDR, на котором защелкивается входная шина.

В .ucf описаны констрейны:

Код
NET InputAdcClockPos TNM_NET = TnmAdcClockPos;
TIMESPEC TsAdcClockPos = PERIOD TnmAdcClockPos 200 Mhz HIGH 50%;

TIMEGRP GrpRiseAdcClockPos = RISING TnmAdcClockPos;
TIMEGRP GrpFallAdcClockPos = FALLING TnmAdcClockPos;

OFFSET = IN 750 ps VALID 1500 ps BEFORE InputAdcClockPos TIMEGRP GrpRiseAdcClockPos;
OFFSET = IN 750 ps VALID 1500 ps BEFORE InputAdcClockPos TIMEGRP GrpFallAdcClockPos;


Описал с запасом на разбег в длинах проводников, хотя он там настолько влиять не должен.

При этом PAR долго разводит, а потом фейлит констрейны.

После этого клок стал пропускать не через IBUFDS, а IBUFGDS, и стало намного лучше в части скорости работы, но фейл с констрейнами остался.
Например.

Код
Slack (setup path):     -1.144ns (requirement - (data path - clock path - clock arrival + uncertainty))
  Source:               InputAdcDataPos<3> (PAD)
  Destination:          GenDdr[3].IDDR_inst (FF)
  Destination Clock:    AdcClock rising at 0.000ns
  Requirement:          0.750ns
  Data Path Delay:      5.235ns (Levels of Logic = 1)
  Clock Path Delay:     3.366ns (Levels of Logic = 2)
  Clock Uncertainty:    0.025ns


где AdcClock - это клок на выходе IBUFGDS.

Tsu всей шины на переднем фронте болтается в районе 1.86нс. Th в районе минус 0.1.

Не подскажете, чем можно вылечить данную проблему?

Заранее спасибо.

Довольно странная картина у вас получается.
Обычно задержка по клоку больше чем по данным.
Советы такие :
1. Задержку можно увеличить с помощью IDELAY макро как по клоку, так и по данным.
2. Пользуйте региональные клоки - для вашей задачи это то, что нужно.

Ethereal
Цитата(Bad0512 @ Jul 11 2014, 06:14) *
Довольно странная картина у вас получается.
Обычно задержка по клоку больше чем по данным.
Советы такие :
1. Задержку можно увеличить с помощью IDELAY макро как по клоку, так и по данным.
2. Пользуйте региональные клоки - для вашей задачи это то, что нужно.

Пробовал руками ставить IODELAYE1 в разрыв между IBUFDS и IDDR в режиме "DEFAULT".
Кроме почти восьмикратного увеличения времени компиляции получилась еще большая разбежка по времени.
Вообще, я сейчас думаю, что может неправильно вставил.
На схемах указано, что делей вставляется между IBUF и IDDR. Но, возможно, что для дифференциального входа порядок иной?
Или вообще не нужно руками ставить?

Еще пробовал использовать DCM и затактировать вход его выходом.
В итоге получил предупреждение, что клок ничего не тактирует и игнор всех констреинтов в .ucf.
Ethereal
А так получается с региональным клоком.

Setup path:
Код
  Requirement:          0.750ns
  Data Path Delay:      0.753ns (Levels of Logic = 1)
  Clock Path Delay:     3.487ns (Levels of Logic = 2)
  Clock Uncertainty:    0.025ns


Hold path:
Код
  Requirement:          0.750ns
  Data Path Delay:      0.877ns (Levels of Logic = 1)(Component delays alone exceeds constraint)
  Clock Path Delay:     6.155ns (Levels of Logic = 2)
  Clock Uncertainty:    0.025ns


А так с региональным клоком и IODELAY на все линии, кроме самого клока.

Setup:
Код
  Requirement:          0.750ns
  Data Path Delay:      5.231ns (Levels of Logic = 2)
  Clock Path Delay:     5.690ns (Levels of Logic = 2)
  Clock Uncertainty:    0.025ns


Hold:
Код
  Requirement:          0.750ns
  Data Path Delay:      4.384ns (Levels of Logic = 2)(Component delays alone exceeds constraint)
  Clock Path Delay:     6.403ns (Levels of Logic = 2)
  Clock Uncertainty:    0.025ns
Timmy
Цитата(Ethereal @ Jul 11 2014, 12:17) *
А так получается с региональным клоком.

Setup path:
Код
  Requirement:          0.750ns
  Data Path Delay:      0.753ns (Levels of Logic = 1)
  Clock Path Delay:     3.487ns (Levels of Logic = 2)
  Clock Uncertainty:    0.025ns


Hold path:
Код
  Requirement:          0.750ns
  Data Path Delay:      0.877ns (Levels of Logic = 1)(Component delays alone exceeds constraint)
  Clock Path Delay:     6.155ns (Levels of Logic = 2)
  Clock Uncertainty:    0.025ns

Региональный клок - это BUFR или BUFIO? По идее тут надо использовать BUFIO.
Я как-то проверял, как быстро может работать S6 при выравнивании клока на DCM. Вот примерчик, как подключать и констрейнить DCM, SERDES там скорее всего нерабочий, меня он не интересовал.Нажмите для просмотра прикрепленного файла
Хитрость в том, что DCM связывает свои выходные клоки, тактирующие входные триггеры, только с восходящим фронтом входного клока(в соответствии с логикой фазового детектора), и констрейны тоже могут быть привязаны только к восходящему фронту входного клока.
Код
NET "clk_p" TNM_NET = "clk_p";
TIMESPEC TS_clk = PERIOD "clk_p" 200 MHz HIGH 50 %;
TIMEGRP "TG_clk_io"   = RISING "dcm_clk90";
TIMEGRP "TG_clk_io_n" = RISING "dcm_clk270";
NET "data[0]" OFFSET = IN -0.25 ns VALID 2 ns BEFORE "clk_p" TIMEGRP TG_clk_io;
NET "data[0]" OFFSET = IN -2.75 ns VALID 2 ns BEFORE "clk_p" TIMEGRP TG_clk_io_n;
Ethereal
Цитата(Timmy @ Jul 11 2014, 12:56) *
Региональный клок - это BUFR или BUFIO? По идее тут надо использовать BUFIO.

BUFR.
Пробовал ставить BUFIO для IDDR, и BUFR/BUFG для фифо (туда же BUFIO клок не дойдет?).
Но при этом PAR вылетает с ошибкой.

Цитата
Я как-то проверял, как быстро может работать S6 при выравнивании клока на DCM. Вот примерчик, как подключать и констрейнить DCM, SERDES там скорее всего нерабочий, меня он не интересовал.Нажмите для просмотра прикрепленного файла
Хитрость в том, что DCM связывает свои выходные клоки, тактирующие входные триггеры, только с восходящим фронтом входного клока(в соответствии с логикой фазового детектора), и констрейны тоже могут быть привязаны только к восходящему фронту входного клока.
Код
NET "clk_p" TNM_NET = "clk_p";
TIMESPEC TS_clk = PERIOD "clk_p" 200 MHz HIGH 50 %;
TIMEGRP "TG_clk_io"   = RISING "dcm_clk90";
TIMEGRP "TG_clk_io_n" = RISING "dcm_clk270";
NET "data[0]" OFFSET = IN -0.25 ns VALID 2 ns BEFORE "clk_p" TIMEGRP TG_clk_io;
NET "data[0]" OFFSET = IN -2.75 ns VALID 2 ns BEFORE "clk_p" TIMEGRP TG_clk_io_n;

Спасибо, попробую.
Ethereal
А в шестых виртексах у MMCM есть режим синхронной компенсации?
То что я нашел - это zero hold. Оно, конечно, позволяет сделать clock path примерно равным нулю, но data path delay при этом не компенсируется.
Или нужно руками фазу подгонять?
Timmy
Цитата(Ethereal @ Jul 11 2014, 19:17) *
А в шестых виртексах у MMCM есть режим синхронной компенсации?
То что я нашел - это zero hold. Оно, конечно, позволяет сделать clock path примерно равным нулю, но data path delay при этом не компенсируется.
Или нужно руками фазу подгонять?

Вот, попробовал на досуге синхронный приёмник под V6:
CODE
module top(
clk_p,clk_n,d_i_p,d_i_n,d_o
);
input clk_p,clk_n, d_i_p, d_i_n;
output d_o;
wire d_i;
IBUFDS #(
.DIFF_TERM("FALSE"), // Differential Termination
.IOSTANDARD("DEFAULT") // Specify the input I/O standard
) d_i_ibuf (
.O(d_i), // Buffer output
.I(d_i_p), // Diff_p buffer input (connect directly to top-level port)
.IB(d_i_n) // Diff_n buffer input (connect directly to top-level port)
);
wire clk_i;
IBUFDS #(
.DIFF_TERM("FALSE"), // Differential Termination
.IOSTANDARD("DEFAULT") // Specify the input I/O standard
) clk_ibuf (
.O(clk_i), // Buffer output
.I(clk_p), // Diff_p buffer input (connect directly to top-level port)
.IB(clk_n) // Diff_n buffer input (connect directly to top-level port)
);
wire clk_io;
BUFIO clk_bufio (
.O(clk_io), // Clock buffer output
.I(clk_i) // Clock buffer input
);

wire di_dl;
(* IODELAY_GROUP = "DL_GRP" *) // Specifies group name for associated IODELAYs and IDELAYCTRL
IODELAYE1 #(
.CINVCTRL_SEL("FALSE"), // Enable dynamic clock inversion ("TRUE"/"FALSE")
.DELAY_SRC("I"), // Delay input ("I", "CLKIN", "DATAIN", "IO", "O")
.HIGH_PERFORMANCE_MODE("TRUE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE")
.IDELAY_TYPE("FIXED"), // "DEFAULT", "FIXED", "VARIABLE", or "VAR_LOADABLE"
.IDELAY_VALUE(10), // Input delay tap setting (0-32)
.ODELAY_TYPE("FIXED"), // "FIXED", "VARIABLE", or "VAR_LOADABLE"
.ODELAY_VALUE(0), // Output delay tap setting (0-32)
.REFCLK_FREQUENCY(200.0), // IDELAYCTRL clock input frequency in MHz
.SIGNAL_PATTERN("DATA") // "DATA" or "CLOCK" input signal
)
di_delay (
.CNTVALUEOUT(), // 5-bit output - Counter value for monitoring purpose
.DATAOUT(di_dl), // 1-bit output - Delayed data output
.C(1'b0), // 1-bit input - Clock input
.CE(1'b0), // 1-bit input - Active high enable increment/decrement function
.CINVCTRL(1'b0), // 1-bit input - Dynamically inverts the Clock © polarity
.CLKIN(1'b0), // 1-bit input - Clock Access into the IODELAY
.CNTVALUEIN(5'b0), // 5-bit input - Counter value for loadable counter application
.DATAIN(1'b0), // 1-bit input - Internal delay data
.IDATAIN(d_i), // 1-bit input - Delay data input
.INC(1'b0), // 1-bit input - Increment / Decrement tap delay
.ODATAIN(1'b0), // 1-bit input - Data input for the output datapath from the device
.RST(1'b0), // 1-bit input - Active high, synchronous reset, resets delay chain to IDELAY_VALUE/
// ODELAY_VALUE tap. If no value is specified, the default is 0.
.T(1'b1) // 1-bit input - 3-state input control. Tie high for input-only or internal delay or
// tie low for output only.

);

wire Q1,Q2;
IDDR #(
.DDR_CLK_EDGE("OPPOSITE_EDGE"), // "OPPOSITE_EDGE", "SAME_EDGE"
// or "SAME_EDGE_PIPELINED"
.INIT_Q1(1'b0), // Initial value of Q1: 1'b0 or 1'b1
.INIT_Q2(1'b0), // Initial value of Q2: 1'b0 or 1'b1
.SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC"
) d_IDDR (
.Q1(Q1), // 1-bit output for positive edge of clock
.Q2(Q2), // 1-bit output for negative edge of clock
.C(clk_io), // 1-bit clock input
.CE(1'b1), // 1-bit clock enable input
.D(di_dl), // 1-bit DDR data input
.R(1'b0), // 1-bit reset
.S(1'b0) // 1-bit set
);
assign d_o = Q1 ^ Q2;

wire clk;
// End of IBUFDS_inst instantiation
BUFG clk_bufg(.I(clk_i),.O(clk));
(* IODELAY_GROUP = "DL_GRP" *) // Specifies group name for associated IODELAYs and IDELAYCTRL
IDELAYCTRL IDELAYCTRL_inst (
.RDY(), // 1-bit Ready output
.REFCLK(clk), // 1-bit Reference clock input
.RST(1'b0) // 1-bit Reset input
);

endmodule
BUFIO и BUFG включённые в параллель нормально разводятся, максимальная задержка IO клока при этом в пределах 3.5 нс. Возможно, у вас распиновка не подходит под использование IO clock-а. Для точной компенсации задерки клока можно параллельно завести клок на IDDR(с отрицательного выхода IBUFDS_DIFF_OUT) через IODELAY и "программным" фазовым детектором подкрутить задержку так, чтобы клок приходил на IDDR в одно время через BUFIO и прямо через IODELAY. Это же значение задержки следует выставить на всех линиях данных, которые окажутся почти идеально выровнены с клоком. Если BUFIO не разводится, можно точно такое же провернуть, пропуская клок через MMCM, чтобы убрать 3 нс задержки в BUFG.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.