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

Virtex 6. Прием данных с АЦП. Констрейны

Здравствуйте.

 

Имеется проект на шестом виртексе с параллельными АЦП на 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.

 

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

 

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

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


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

Здравствуйте.

 

Имеется проект на шестом виртексе с параллельными АЦП на 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. Пользуйте региональные клоки - для вашей задачи это то, что нужно.

 

 

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


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

Довольно странная картина у вас получается.

Обычно задержка по клоку больше чем по данным.

Советы такие :

1. Задержку можно увеличить с помощью IDELAY макро как по клоку, так и по данным.

2. Пользуйте региональные клоки - для вашей задачи это то, что нужно.

Пробовал руками ставить IODELAYE1 в разрыв между IBUFDS и IDDR в режиме "DEFAULT".

Кроме почти восьмикратного увеличения времени компиляции получилась еще большая разбежка по времени.

Вообще, я сейчас думаю, что может неправильно вставил.

На схемах указано, что делей вставляется между IBUF и IDDR. Но, возможно, что для дифференциального входа порядок иной?

Или вообще не нужно руками ставить?

 

Еще пробовал использовать DCM и затактировать вход его выходом.

В итоге получил предупреждение, что клок ничего не тактирует и игнор всех констреинтов в .ucf.

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


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

А так получается с региональным клоком.

 

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

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


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

А так получается с региональным клоком.

 

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_input.7z

Хитрость в том, что 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;

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


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

Региональный клок - это BUFR или BUFIO? По идее тут надо использовать BUFIO.

BUFR.

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

Но при этом PAR вылетает с ошибкой.

 

Я как-то проверял, как быстро может работать S6 при выравнивании клока на DCM. Вот примерчик, как подключать и констрейнить DCM, SERDES там скорее всего нерабочий, меня он не интересовал.dcm_input.7z

Хитрость в том, что 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;

Спасибо, попробую.

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


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

А в шестых виртексах у MMCM есть режим синхронной компенсации?

То что я нашел - это zero hold. Оно, конечно, позволяет сделать clock path примерно равным нулю, но data path delay при этом не компенсируется.

Или нужно руками фазу подгонять?

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


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

А в шестых виртексах у MMCM есть режим синхронной компенсации?

То что я нашел - это zero hold. Оно, конечно, позволяет сделать clock path примерно равным нулю, но data path delay при этом не компенсируется.

Или нужно руками фазу подгонять?

Вот, попробовал на досуге синхронный приёмник под V6:

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.

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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