zvs 0 10 августа, 2011 Опубликовано 10 августа, 2011 · Жалоба У верблюда два горба, потому что жизнь - борьба! Доброго времени суток! Есть проект: Аппаратно: - отладочная плата Arria II GX Development Kit, кристалл EP2AGX125EF35C4ES; - самопальная платка с AD9272 на борту, тактовая 65 МГц. Quartus II version 11 AD9272 по LVDS отдаёт по последовательному каналу данные (s_adc_data). К данным прилагается: DCO (s_adc_clk) - тактовый сигнал (390 МГц) и FCO (s_adc_frame) - кадровая синхронизация (те же 65 МГц). 1. Проект тестовый, простецкий, один канал (из восьми доступных в АЦП), используется altddio_in, сгенерённый Мегавизардом (ddr_rx_in в коде).//altera message_off 10040 module adc_deserializer(s_adc_clk, s_adc_frame, s_adc_data, adc_data, en_adc_data); parameter WIDTH_ADC_DATA = 12;//ширина шины данных АЦП input s_adc_clk; input s_adc_frame; input s_adc_data; output [WIDTH_ADC_DATA-1:0]adc_data; output en_adc_data; reg [WIDTH_ADC_DATA/2-1:0]pos_shift_reg, odd_data; reg [WIDTH_ADC_DATA/2-1:0]neg_shift_reg, evn_data; reg en_adc_frame, en_odd_data, en_evn_data; wire en_adc_data, in_rx_p, in_rx_n; wire [WIDTH_ADC_DATA-1:0]adc_data; assign en_adc_data = en_evn_data; ddr_rx_in ddr_rx_in( .datain(s_adc_data), .inclock(s_adc_clk), .dataout_h(in_rx_p), .dataout_l(in_rx_n)); genvar i; generate for(i=0; i<WIDTH_ADC_DATA/2; i=i+1) begin: assign_adc_data assign adc_data[2*i+1:2*i] = {odd_data[i], evn_data[i]}; end endgenerate always @(posedge s_adc_clk) begin pos_shift_reg <= {pos_shift_reg, in_rx_p}; neg_shift_reg <= {neg_shift_reg, in_rx_n}; en_adc_frame <= s_adc_frame; en_odd_data <= en_adc_frame; en_evn_data <= en_odd_data; if(en_adc_frame && !en_odd_data) odd_data <= pos_shift_reg; if(en_odd_data && !en_evn_data) evn_data <= neg_shift_reg; end//always endmodule Ноги АЦП расставлены самостоятельно, s_adc_sclk заведены на dedicated clock, DIFFCLK, как положено. Выходные отданы на откуп Quartus'у. SDC файл для такого случая "классический", как в "Constraining and Analyzing Source-Synchronous Interfaces", Example 56. Собственно вот он, SDC файл: set_time_format -unit ns -decimal_places 3 create_clock -name {clk_480MHz} -period 390MHz -waveform {0.641 1.923} [get_ports {s_adc_clk}] create_clock -name {clk} -period 390MHz derive_clock_uncertainty set_input_delay -max -clock {clk} 0.300 [get_ports {s_adc_data}] set_input_delay -min -clock {clk} -0.300 [get_ports {s_adc_data}] set_input_delay -max -clock {clk} -clock_fall 0.300 [get_ports {s_adc_data}] -add_delay set_input_delay -min -clock {clk} -clock_fall -0.300 [get_ports {s_adc_data}] -add_delay set_input_delay -max -clock {clk} 0.300 [get_ports {s_adc_frame}] set_input_delay -min -clock {clk} -0.300 [get_ports {s_adc_frame}] В результате TQ заявляет, что шоколада по холду не будет: 2. Размножаем один канал так, чтобы работали все 8: module adc_deserializers(s_adc_clk, s_adc_frame, s_adc_data, adc_data, en_adc_data); parameter NUM_CHANNEL = 8;//Количество каналов parameter WIDTH_ADC_DATA = 12;//Ширина шины данных АЦП input s_adc_clk; input s_adc_frame; input [NUM_CHANNEL-1:0]s_adc_data; output [WIDTH_ADC_DATA*NUM_CHANNEL-1:0]adc_data; output [NUM_CHANNEL-1:0]en_adc_data; adc_deserializer #( .WIDTH_ADC_DATA(WIDTH_ADC_DATA)) adc_deserializer[NUM_CHANNEL-1:0]( .s_adc_clk(s_adc_clk), .s_adc_frame(s_adc_frame), .s_adc_data(s_adc_data), .adc_data(adc_data), .en_adc_data(en_adc_data)); endmodule Правим SDC, с учётом размножения (показаны изменившие строки) set_input_delay -max -clock {clk} 0.300 [get_ports {s_adc_data[*]}] set_input_delay -min -clock {clk} -0.300 [get_ports {s_adc_data[*]}] set_input_delay -max -clock {clk} -clock_fall 0.300 [get_ports {s_adc_data[*]}] -add_delay set_input_delay -min -clock {clk} -clock_fall -0.300 [get_ports {s_adc_data[*]}] -add_delay Понятное дело, лучше не стало, только теперь еще повылазили слаки для выхода ddio, который захлопывается передним фронтом :( Понятное дело, что если задрать тактовую АЦП до 80 (а нам так и надо) выползают слаки и по сетапу для того же выхода ddio.В реальном проекте, в железе, сигнал действительно рассыпается причудливым образом :( Уважаемые гуру, расскажите, что мы делаем не так и куда, собственно, копать-то? Есть еще идея поиспользовать altlvds в его синтезируемом виде, но уверенности в результате нет. Однако пробовать будем - о результатах отпишусь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zvs 0 10 августа, 2011 Опубликовано 10 августа, 2011 · Жалоба ...продолжение Собрали проект с altlvds, поскольку данные АЦП 12 бит, в SERDES это добро уже не помещается, используем "circuity in logic cells", в качестве клока для altlvds используем сигнал FCO АЦП.module adc_deserializer(s_adc_clk, s_adc_frame, s_adc_data, adc_data, en_adc_data); parameter WIDTH_ADC_DATA = 12;//ширина шины данных АЦП //input n_clr; input s_adc_clk; input s_adc_frame; input s_adc_data; //output s_adc_seal; output [WIDTH_ADC_DATA-1:0]adc_data; output en_adc_data; altlvds_ser altlvds_ser ( .rx_in(s_adc_data), .rx_inclock(s_adc_frame), .rx_out(adc_data), .rx_outclock(en_adc_data)); endmodule Соответствующий SDC файл: set_time_format -unit ns -decimal_places 3 create_clock -name {clk_65MHz} -period 65MHz [get_ports {s_adc_frame}] create_clock -name {clk} -period 390MHz derive_pll_clocks -create_base_clocks derive_clock_uncertainty set_input_delay -max -clock {clk} 0.300 [get_ports {s_adc_data}] set_input_delay -min -clock {clk} -0.300 [get_ports {s_adc_data}] set_input_delay -max -clock {clk} -clock_fall 0.300 [get_ports {s_adc_data}] -add_delay set_input_delay -min -clock {clk} -clock_fall -0.300 [get_ports {s_adc_data}] -add_delay set_input_delay -max -clock {clk} 0.300 [get_ports {s_adc_frame}] set_input_delay -min -clock {clk} -0.300 [get_ports {s_adc_frame}] И вуаля! Ничего хорошего так и не случилось: Неужели Arria II GX c таймингами "4" не может принять LVDS сигнал с частотой 390 МГц??? :smile3046: Где мы неправильно задаём констрейны? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timmy 1 10 августа, 2011 Опубликовано 10 августа, 2011 · Жалоба Неужели Arria II GX c таймингами "4" не может принять LVDS сигнал с частотой 390 МГц??? :smile3046: Где мы неправильно задаём констрейны? Констрейны вроде правильно задаёте. Подобная ситуация уже обсуждалась. Клок пока бежит по дереву, отстаёт на 1-2наносекунды, отсюда ваш слак по холду. SERDES в данном случае вряд ли поможет, так как ПМСМ использовать FCO для тактирования хуже, чем DCO, а с DCO в качестве главного клока встроенный SERDES не увидит границ слов, поэтому лучше читать FCO через обычный входной DDR триггер, и десериализировать всё "вручную". В, общем, пропустите s_adc_clk через PLL, должно заработать, а может, и в констрейны уложитесь:). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zvs 0 10 августа, 2011 Опубликовано 10 августа, 2011 · Жалоба Timmy, во первых, спасибо! Во вторых, по вашей ссылке сказано: Приём данных на такой частоте требует заведения клока через PLL/DLL с внутренним фидбэком в режиме компенсации задержки на clock tree. Не совсем понял терминологию. alt_pll может работать в режимах 1) Normal mode—The PLL feedback path source is a global or regional clock network, minimizing clock delay to registers for that clock type and specific PLL output. You can specify PLL output that is compensated. 2) Source-Synchronous mode—The data and clock signals arrive at the same time at the input pins. In this mode, the signals are guaranteed to have the same phase relationship at the clock and data ports of any Input Output Enable (IOE) register. 3) Zero-Delay Buffer mode—The PLL feedback path is confined to the dedicated PLL external output pin. The clock port driven off-chip is phase aligned with the clock input for a minimal delay between the clock input and the external clock output. 4) No Compensation mode—The PLL feedback path is confined to the PLL loop. It has no clock network or other external source. A PLL in no-compensation mode has no clock network compensation, but clock jitter is minimized. 5) External Feedback mode—The PLL compensates for the fbin feedback input to the PLL. The delay between the input clock pin and the feedback clock pin is minimized. Согласно описанию 2-4 не подходят, не так ли? 5 в Arria II GX не поддерживается... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IL-76 0 11 августа, 2011 Опубликовано 11 августа, 2011 · Жалоба Собрали проект с altlvds, поскольку данные АЦП 12 бит, в SERDES это добро уже не помещается, используем "circuity in logic cells", в качестве клока для altlvds используем сигнал FCO АЦП. И вуаля! Ничего хорошего так и не случилось: А в чем заключается неработоспособность и как она проявляется? Т.к. подобный АЦП заведен на самый дохлый по скорости Циклон 3 и все прекрасно работает. Правда частота ниже - клок для АЦП 40 МГц//выход 40 и 240МГц соответственно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bogaev_roman 0 11 августа, 2011 Опубликовано 11 августа, 2011 (изменено) · Жалоба to Гяук Почитайте блог des00 про Ваш случай, может что-то новое найдете... Было бы проще Вам помочь, если бы были приведены временные диаграммы timequest анализатора на пути, не проходящему по холду/слэку со всеми временными задержками. А насчет 390 МГц это в даташит надо смотреть, чтоб DDR "могло" работать на 780МГц. ЗЫ// И к посту 2 вопрос - почему Вы в altlvds_ser на вход тактовой подаете частоту 65МГц, тогда как данные туда поступают на 780МГц? Может я чето не понимаю...Там же DDR на входе должны стоять, которые щелкают по фронту/срезу по идее для этого случае на частоте 390МГц. ЗЫ2// Собрали проект с altlvds, поскольку данные АЦП 12 бит, в SERDES это добро уже не помещается, используем "circuity in logic cells" Вот это скорее всего и не будет работать на такой частоте... Изменено 11 августа, 2011 пользователем bogaev_roman Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zvs 0 11 августа, 2011 Опубликовано 11 августа, 2011 · Жалоба А в чем заключается неработоспособность и как она проявляется? Данные разваливаются. Совсем. Например биты 0 и 2 на выходе десериализатора повторяют друг друга от отсчёта к отсчёту. Бит 10 сбивается в случайные моменты. ...подобный АЦП заведен на самый дохлый по скорости Циклон 3 и все прекрасно работает. Правда частота ниже - клок для АЦП 40 МГц//выход 40 и 240МГц соответственно. Охотно верю. И у меня на этих частотах все прекрасно. Запас слаков по сетапу 569, по холду 262 в самом плохом варианте. Кстати, для самого быстрого Циклона все собирается (по мнению TQ) и для 65/390 МГц :( to Гяук Почитайте блог des00 про Ваш случай, может что-то новое найдете... Я с него начинал знакомство с TQ, проштудировал внимательно... Было бы проще Вам помочь, если бы были приведены временные диаграммы timequest анализатора на пути, не проходящему по холду/слэку со всеми временными задержками. Вы имеете ввиду вот это? Кстати от компиляции к компиляции слаки меняются, так что тут они уже не те, что были вчера (в первом посте). А насчет 390 МГц это в даташит надо смотреть, чтоб DDR "могло" работать на 780МГц. В datasheet написано вот так: The minimum and maximum specification depends on the clock source (for example, PLL and clock pin) and the clock routing resource you use (global, regional, or local). The I/O differential buffer and input register do not have a minimum toggle rate. You are required to calculate the leftover timing margin in the receiver by performing link timing closure analysis. You must consider the board skew margin, transmitter channel-to-channel skew, and the receiver sampling margin to determine the leftover timing margin. То бишь, не признаются :( ЗЫ// И к посту 2 вопрос - почему Вы в altlvds_ser на вход тактовой подаете частоту 65МГц, тогда как данные туда поступают на 780МГц? Может я чето не понимаю...Там же DDR на входе должны стоять, которые щелкают по фронту/срезу по идее для этого случае на частоте 390МГц. ЗЫ2// Вот это скорее всего и не будет работать на такой частоте... В altlvds я сказал какой у меня будет DataRate, какая частота клока, фазовое соотношение между клоком и данными. altlvds на основании этих данных должен завести PLL так, чтобы на ней сделать нужный для защёлкивания данных клок. И она это делает, Modelsim показывает, что данные собираются те, что были выставлены на линию данных... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bogaev_roman 0 11 августа, 2011 Опубликовано 11 августа, 2011 · Жалоба Вы имеете ввиду вот это? У меня картинка не отображается... В datasheet написано вот так Да, я это уже нашел, но по идее там в даташите для rx на serdes вообще максимальная 1250 стоит. Так что 780 не так много для ddr. В altlvds я сказал какой у меня будет DataRate, какая частота клока, фазовое соотношение между клоком и данными. altlvds на основании этих данных должен завести PLL так, чтобы на ней сделать нужный для защёлкивания данных клок. И она это делает, Modelsim показывает, что данные собираются те, что были выставлены на линию данных... 1. Modelsim на gate уровне показывает? 2. Вы уверены, что PLL формирует частоты как надо? У меня был случай, когда в мегафункции задавалась начальная фаза, но реально сдвига не было из-за особенностей реализации и quartus отчетливо в fitter report для ignored assignment говорил об этом... ЗЫ// Попробуйте сделать как Timmy сказал если реально ничего не получится. Пропустите 390 через PLL и сдвиньте ее вправо на 90* (ну или меньше/больше в зависимости от начальной фазы), чтоб она в окно попадала. Пустите тактовую с данными на DDR и на их выходе получите 6 разрядов на частоте 390, дальше сериализацию делаете вручную с помощью мультиплексоров и обычных триггеров и на выходе получите Ваши 12 разрядов на частоте 65МГц. По частоте после определенных усилий должны пройти... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timmy 1 12 августа, 2011 Опубликовано 12 августа, 2011 · Жалоба Не совсем понял терминологию. alt_pll может работать в режимах 1) Normal mode—The PLL feedback path source is a global or regional clock network, minimizing clock delay to registers for that clock type and specific PLL output. You can specify PLL output that is compensated. 2) Source-Synchronous mode—The data and clock signals arrive at the same time at the input pins. In this mode, the signals are guaranteed to have the same phase relationship at the clock and data ports of any Input Output Enable (IOE) register. У меня терминология Латтиса, там это называется clock injection delay removal. В вашем случае должно подойти 1 или 2, скорее 2, из описания не совсем понятно. Проблема в том, что у PLL джиттер великоват, а DLL Альтера не признаёт. Кстати, фазу DCO сдвигать не надо, она уже установлена, как надо, в АЦП. Хотя, может быть, надо сдвинуть чуть-чуть для попадания в середину окна. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zvs 0 12 августа, 2011 Опубликовано 12 августа, 2011 · Жалоба У меня картинка не отображается... Приаттачил к этому посту (TQ8_detail.jpg). Да, я это уже нашел, но по идее там в даташите для rx на serdes вообще максимальная 1250 стоит. Так что 780 не так много для ddr. Был всегда уверен, что serdes - это некий аппаратный блок и мешать его с обычным LVDS не стоит. В datasheet (p.1-68, table 1-53) сказано что fHSDR максимум 945 Mbps (для не DPA). "For interfacing with non-DPA receivers, the maximum supported data rate is 945 Mbps. Beyond 840 Mbps, PCB trace compensation is required." То бишь на 780 все равно работать должна. 1. Modelsim на gate уровне показывает? Да 2. Вы уверены, что PLL формирует частоты как надо? У меня был случай, когда в мегафункции задавалась начальная фаза, но реально сдвига не было из-за особенностей реализации и quartus отчетливо в fitter report для ignored assignment говорил об этом... ЗЫ// Попробуйте сделать как Timmy сказал ... По крайней мере в Ignored assignments ничего жуткого не написано. Вариант, предложенный Timmy я пробовал, но: 1) 390 никуда не двигал - она вроде как и так должна стоять как положено - первая картинка в первом посте, на всяк случай прикрепил её и к этому посту (AD9272.jpg). 2) Pll использовал в normal mode. 3) Проект с ddio для одного канала. module adc_deserializer(s_adc_clk, s_adc_frame, s_adc_data, adc_data, en_adc_data); parameter WIDTH_ADC_DATA = 12;//ширина шины данных АЦП input s_adc_clk; input s_adc_frame; input s_adc_data; output [WIDTH_ADC_DATA-1:0]adc_data; output en_adc_data; reg [WIDTH_ADC_DATA/2-1:0]pos_shift_reg, odd_data; reg [WIDTH_ADC_DATA/2-1:0]neg_shift_reg, evn_data; reg en_adc_frame, en_odd_data, en_evn_data; wire en_adc_data, in_rx_p, in_rx_n; wire [WIDTH_ADC_DATA-1:0]adc_data; assign en_adc_data = en_evn_data; align_pll align_pll ( .inclk0(s_adc_clk), .c0(pll_adc_clk)); ddr_rx_in ddr_rx_in( .datain(s_adc_data), .inclock(pll_adc_clk), .dataout_h(in_rx_p), .dataout_l(in_rx_n)); genvar i; generate for(i=0; i<WIDTH_ADC_DATA/2; i=i+1) begin: assign_adc_data assign adc_data[2*i+1:2*i] = {odd_data[i], evn_data[i]}; end endgenerate always @(posedge pll_adc_clk) begin pos_shift_reg <= {pos_shift_reg, in_rx_p}; neg_shift_reg <= {neg_shift_reg, in_rx_n}; en_adc_frame <= s_adc_frame; en_odd_data <= en_adc_frame; en_evn_data <= en_odd_data; if(en_adc_frame && !en_odd_data) odd_data <= pos_shift_reg; if(en_odd_data && !en_evn_data) evn_data <= neg_shift_reg; end//always endmodule 4) sdc файл, практически такой же как и раньше (добавлена команда derive_pll_clocks -create_base_clocks) Поправил 12.08.2011 в 15:25 set_time_format -unit ns -decimal_places 3 create_clock -name {clk_480MHz} -period 390MHz -waveform {0.641 1.923} [get_ports {s_adc_clk}] create_clock -name {clk} -period 390MHz derive_clock_uncertainty derive_pll_clocks -create_base_clocks set_input_delay -max -clock {clk} 0.300 [get_ports {s_adc_data}] set_input_delay -min -clock {clk} -0.300 [get_ports {s_adc_data}] set_input_delay -max -clock {clk} -clock_fall 0.300 [get_ports {s_adc_data}] -add_delay set_input_delay -min -clock {clk} -clock_fall -0.300 [get_ports {s_adc_data}] -add_delay set_input_delay -max -clock {clk} 0.300 [get_ports {s_adc_frame}] set_input_delay -min -clock {clk} -0.300 [get_ports {s_adc_frame}] Итог неутешительный: (на всякий случай картинку приаттачил к посту TQ_pll_detail.jpg) Все слаки только по сетапу. Вообще мне совсем не понятно отчего ему так поплохело внезапно. bogaev_roman, Timmy, спасибо за участие! :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 12 августа, 2011 Опубликовано 12 августа, 2011 · Жалоба вы бы вместо скринов проект бы выложили, что бы можно было покрутить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zvs 0 12 августа, 2011 Опубликовано 12 августа, 2011 · Жалоба Вот, пожалуйста, ddio, 8 каналов, с прикрученной pll'ю... deserializer_ddio_8.zip Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timmy 1 12 августа, 2011 Опубликовано 12 августа, 2011 · Жалоба Я попробовал собрать это для первой Арии(второй в моём допотопном Квартусе нет) и должен отменить рекомендацию про PLL. Всё и так хорошо, задержки во входных буферах данных достаточно для компенсации задерки клока, задержка автоматически настраивается, получается симметричный запас 170ps. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zvs 0 12 августа, 2011 Опубликовано 12 августа, 2011 · Жалоба Timmy, да, проверил на EP1AGX20CF484C6 - все прекрасно собирается... ArriaII - такая гадость??? :( All, звиняюсь - в предыдущем посте версия без pll. pll я прикручивал на одноканальный вариант. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bogaev_roman 0 12 августа, 2011 Опубликовано 12 августа, 2011 (изменено) · Жалоба Приаттачил к этому посту Картинки теперь отображаются. Если время будет попробую загрузить Ваш проект. Есть пока пару вопросов 1. Модуль align_pll в нормальном режиме без всяких сдвигов? 2. Фронт входных частоты и первой посылки данных совпадает или изначально смещен и если смещен, то почему это не отображается в ограничениях и нет на временной диаграмме? 3. -clock_fall -это что за ограничение, забыл? 4. На report patch, кстати, видно, что путь клока до DDR 600нс с чем-то, а данных 850нс, причем логически quartus может вставить delay chain от пина до ddr и увеличить эту задержку, а вот от пина до pll такой возможности нет (это к слову почему так все плохо стало), так что тут можно попробовать как-то влипить анализ через один период тактовой... Изменено 12 августа, 2011 пользователем bogaev_roman Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться