Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Приём Serial-LVDS данных
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
Art55555
Имеется АЦП 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
doublekey
Код
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
Спасибо за развёрнутый ответ, да ещё и в виде кода.
Скажите, а это на частотах DCO в 200 МГц реально работает? Дело в том, что таким образом я тоже пытался сделать систему приёма. 2 разных процесса (один по переднему, один по заднему фронтам) защёлкивают данные, а третий процесс (во избежании мультисоурсов) забирает по фрейму и упаковывает в переменную и даёт на выход. Работает до 100-130 МГц DCO (т.е. до 60-65 МГц реального клока для АЦП), далее всё плывёт. После этого я и принял решение сделать что-то по-другому.
doublekey
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
а как ПЛИС отреагирует, если иногда уровень на линии(со всеми вытекающими) увеличивается в два раза?
Art55555
Цитата(doublekey @ Feb 13 2013, 07:00) *
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 фронтам?

Цитата(stu @ Feb 13 2013, 09:38) *
а как ПЛИС отреагирует, если иногда уровень на линии(со всеми вытекающими) увеличивается в два раза?


Не понял вопроса. Поясните, пожалуйста.
doublekey
Art55555, принимал данные по параллельной DDR шине с AD6657 на частоте 200 МГц, но там немного другой формат.
Попробуйте, у вас же есть железка.
Art55555
Цитата(doublekey @ Feb 13 2013, 15:51) *
Art55555, принимал данные по параллельной DDR шине с AD6657 на частоте 200 МГц, но там немного другой формат.
Попробуйте, у вас же есть железка.

Я понял. Попробовал. При увеличении тактовой частоты более 60 МГц (т.е. DCO становится больше 120) данные "плывут" в данной реализации. Может, и железо плохое, но пока хотелось бы построить такую же систему на ISERDES и IODELAY
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.