Art55555 0 12 февраля, 2013 Опубликовано 12 февраля, 2013 (изменено) · Жалоба Имеется АЦП LTC2195. Данные Serial LVDS. Выбран режим 4-lane out. АЦП тактируется 100 Мгц. Соотвественно, клоковый сигнал DCO из неё выходит 200 Мгц, и приём должен осуществляться по 2 фронтам. ПЛИС – SPARTAN-6- 100 -3fgg484. Нужно сделать десереализацию всего этого и в итоге получить чистый 16-битный поток из параллельных данных в формате 2s. Итак, с АЦП приходят: DCO DATA_A DATA_B DATA_C DATA_D FRAME Было много метаний, а именно: попытки прянять сигнал «в лоб», по разным фронтам, попытки умножить частоту DCO и дальнейшая работа по ней и несколько ещё не очень грамотных способов приёма. Видели «плывущие» данные относительно друг друга и прочую фигню. В итоге остановились на необходимости использования связки IODELAY2 и ISERDES2. За основу был взят документ XAPP1064 (приём таких данных Спартаном 6), вариант с PLL. (Рис 1) Рис. 1 Принимать с АЦП нужно следующее: Рис.2 Также за основу кода были приняты примеры, которые укзаны в данном ксапе. (https://secure.xilinx.com/webreg/clickthrough.do?cid=140956). В нём 2 основных блока – первый занимается клоком, подстройкой и контролем сдвига, второй непосредственным приёмом данных. Параметры блоков удобно настраевыемы через переменные. Итак, на первый (клоковый) блок я подаю: DCO (p и n) На порт pattern – значение 1100 – (значение фрейма, когда данные с АЦП актуальны) Сигнал bitslip для этого блока является выходным, и, согласно , документу идёт на блок приёма данных Есть внутренние настройки – PLLX (установил 2), PLLD(установил 1), CLKIN_PERIOD = 5.000 Из данного блока выходят RXIOCLK - основная частота (удвоена, т.к. режим, в котором работает принимающий данные ISERDES -SDR) RX-SERDESSTROBE - строб для приёма данных DATAIN –выходной порт, не понятно куда его девать (4 бита) BUFFG_PLL_X1 – глобальный клок BITSLIP- бит сдвига, выходной Все эти сигналы являются входными для блока приёма данных (нижний блок на картинке 1) Тут я задал основные параметры как количество входных бит данных (указал 5 – 4 данные и 1 фрейм, который я также пустил на десереализатор) и глубину десереализации – 4. Данный блок формирует вектор data_out (20 бит) по своему алгоритму (он понятен) , в последствии я его разбираю (убираю фрейм и переставляю некоторые биты данных АЦП – они пакуются хитрым образом самой микросхемой, поэтому приходится переставлять). После этого сигнал пропускается на выход. Не работает. На что я сразу хотел обратить внимание – в данной реализации у меня никуда не идёт frame (т.е. в других версиях она шла на отдельный блок ISERDES+IODELAY, результатом работы этого блока был 4 битный вектор, который анализировался и использовался для формирования bitslip в блоке с данными) в данной реализации блок формирования bitslip находится в «верхнем, тактовом» блоке и как этот bitslip (а точнее, на основании чего формируется) я так и не понял. Единственное, что я ему указал в поле Pattern – это то, что данные надо подстраивать под 1100. Собственно, вопросы: 1) Что в данной реализации я делаю неправильно? 2) Какие ещё есть варианты приёма подобных данных? Ниже прилагаю ссылку на код основного блока. http://files.mail.ru/7727AD63C6604CBD906067D5CD07969C Изменено 12 февраля, 2013 пользователем Art55555 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
doublekey 0 12 февраля, 2013 Опубликовано 12 февраля, 2013 · Жалоба module ltc2195_rx ( input rst, // Reset input. input dco, // Clock input. input fr, // Frame sync signal. input [ 3:0] rxd, // Serial data. output reg [15:0] data, // Parallel data. output reg done // Data recieved flag. ); reg [1:0][3:0] data_p; // Positive edge data. reg [1:0][3:0] data_n; // Negative edge data. always_ff @(negedge dco, posedge rst) if (rst) data_n[1:0] <= '0; else data_n[1:0] <= {data_n[0], rxd}; // Recieve data at negative edge. always_ff @(posedge dco, posedge rst) if (rst) begin data_p <= '0; data <= '0; done <= '0; end else begin data_p[1:0] <= {data_p[0], rxd}; // Recieve data at positive edge. if (fr) // Store data to output register. {data[15], data[14], data[ 7], data[ 6], data[13], data[12], data[ 5], data[ 4], data[11], data[10], data[ 3], data[ 2], data[ 9], data[ 8], data[ 1], data[ 0] } <= {data_p[1], data_n[1], data_p[0], data_n[0]}; done <= fr; // Set recieved flag. end endmodule И читать данные из выходного регистра по сигналу done. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Art55555 0 12 февраля, 2013 Опубликовано 12 февраля, 2013 · Жалоба Спасибо за развёрнутый ответ, да ещё и в виде кода. Скажите, а это на частотах DCO в 200 МГц реально работает? Дело в том, что таким образом я тоже пытался сделать систему приёма. 2 разных процесса (один по переднему, один по заднему фронтам) защёлкивают данные, а третий процесс (во избежании мультисоурсов) забирает по фрейму и упаковывает в переменную и даёт на выход. Работает до 100-130 МГц DCO (т.е. до 60-65 МГц реального клока для АЦП), далее всё плывёт. После этого я и принял решение сделать что-то по-другому. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
doublekey 0 13 февраля, 2013 Опубликовано 13 февраля, 2013 · Жалоба Synplify вот что говорит: Performance Summary ******************* Worst slack in design: -0.441 Requested Estimated Requested Estimated Clock Clock Starting Clock Frequency Frequency Period Period Slack Type Group ------------------------------------------------------------------------------------------------------------------------- ltc2195_rx|dco 1000.0 MHz 531.2 MHz 1.000 1.883 -0.441 inferred Autoconstr_clkgroup_0 ================================================================================ ========================================= Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
stu 0 13 февраля, 2013 Опубликовано 13 февраля, 2013 · Жалоба а как ПЛИС отреагирует, если иногда уровень на линии(со всеми вытекающими) увеличивается в два раза? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Art55555 0 13 февраля, 2013 Опубликовано 13 февраля, 2013 · Жалоба Synplify вот что говорит: Performance Summary ******************* Worst slack in design: -0.441 Requested Estimated Requested Estimated Clock Clock Starting Clock Frequency Frequency Period Period Slack Type Group ------------------------------------------------------------------------------------------------------------------------- ltc2195_rx|dco 1000.0 MHz 531.2 MHz 1.000 1.883 -0.441 inferred Autoconstr_clkgroup_0 ================================================================================ ========================================= Это я понял, а реально удалось принять сигнал с частотой DCO около 200 МГц по 2 фронтам? а как ПЛИС отреагирует, если иногда уровень на линии(со всеми вытекающими) увеличивается в два раза? Не понял вопроса. Поясните, пожалуйста. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
doublekey 0 13 февраля, 2013 Опубликовано 13 февраля, 2013 · Жалоба Art55555, принимал данные по параллельной DDR шине с AD6657 на частоте 200 МГц, но там немного другой формат. Попробуйте, у вас же есть железка. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Art55555 0 14 февраля, 2013 Опубликовано 14 февраля, 2013 · Жалоба Art55555, принимал данные по параллельной DDR шине с AD6657 на частоте 200 МГц, но там немного другой формат. Попробуйте, у вас же есть железка. Я понял. Попробовал. При увеличении тактовой частоты более 60 МГц (т.е. DCO становится больше 120) данные "плывут" в данной реализации. Может, и железо плохое, но пока хотелось бы построить такую же систему на ISERDES и IODELAY Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться