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

Подключение матрицы с DDR Интерфейсом

Пытаюсь заставить заработать матрицу со Spartan-6 LX45.
Матрица типа GSеnsе2011/2022, распаяна на самодельной платке и присоединена к отладочному
набору TЕ0600/0603.
Матрица выдает 8 пар данных, клок и пиксельную частоту.

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

Часть картинки "frame.png"

На картинке видно дрожание данных.
Остался последний этап - выравнивание данных.

Текст модуля приема выкладываю целиком "data_chanel.v"

Принцип приема простой: 
1) С дифференциального тактового сигнала с помошю IBUFGDS получил два противофазных тактирующих сигнала;
2) Входные пары данны принял через IBUFDS;
3) Принятые сигналы через c IDDR2 выделил в виде "обычных";
4) Сигналы сложил в 32 разрядные слова и записал в BRAM;

В начале попробовал пример от производителя. В нем есть механизм поиска "глазка" и подстройки IODELAY2
Точнее часть примера. Ждал сборку проекта более двух часов - не дождался.

Выбросил все надстройки, оставил только 4 модуля IODELAY2 (половина входных данных) - дождался отрицательного ответа:
файл "aerosol_top.unroutes"
WARNING:ParHelpers:360 - Design is not completely routed.

       HG_KG/pix_clk_DDR
       sys_clk


Взял пример XAPP1064. Исходники от 2009, новее не удается скачать.
Почему то десериализацию 1:12 не производит. Решил, что пусть уже буде 1:8.
Тоже не разводится

ERROR:Place:1170 - The BUFIO instance <HG_KG/serdes/inst_clkin/bufio2_inst>
   needs to have all of its IOB loads placed into its same half IO bank.
   However, due to user-specified constraints, the BUFIO instance
   <HG_KG/serdes/inst_clkin/bufio2_inst> and its IOB load <GS_OUT_TP<1>> cannot
   be placed in the same half IO bank. These constraints could be LOCATION or
   AREA constraints on <HG_KG/serdes/inst_clkin/bufio2_inst>, or <GS_OUT_TP<1>>,
   or other components connected to them, which could impose an implicit
   constraint on them. Please check user-specified constraints on all of these
   components to ensure their combination is not infeasible.

"Обвинение" посерьезнее - требует переразвести плату.

Нашел xapp524_mods_12bit_4ch, на VHDL, я в VHDL не силен :-(
Нашел xapp1071_V6_ADC_DAC_LVDS.pdf и исходник к нему. но почему-то архив запаролен.

Вроде как и информациии и примеров много и "почти все работает", а не выходит каменный цветок.
Есть ли где проверенный вариант примера приема DDR данных с подобных устройств?

Мне только IOBUF2 прикрутить. ;-)

 

frame.png

data_chanel.v

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


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

Для ddr есть готовые примитивы  iddr и oddr . Используйте их. 

Вот похожая тема вроде на этом форуме Spartan 6 и АЦП DDR, также на Хабре статья Подключение ацп.

А вообще-то непонятно что конкретно у вас не получается, данные в ddr формате принять?

 

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


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

Я как-то для DVI делал модуль, который умеет находить середину "глаза". Делал для altera Cyclone 5, двигал частоту. На Xilinx можно сделать аналогично, только двигать не частоту, а данные. Думаю Вам может помочь описание моего алгоритма: 

CENTER_DATA_ALIGNER ОПИСАНИЕ.odt

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


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

Спасибо всем за ответы.

Попробую уточнить вопрос. Я написал прием данных полностью. Мне нужно выровнять данные из за разной длины дорожек - сдвинуть данные так чтобы они не дрожали. Потом я подровняю биты. При установке хотя-бы элемента IODELAY2 проект перестает разводиться. То есть вопрос не в банках и входах. Я уже проверял на "наполненность" ПЛИС обрезанием "лишних" узлов.

Считаю, что вопрос именно в разводке IODELAY2.

Читаю UG381, ищу слова delay и получаю:

Вариант 1

 Figure 1-1: Spartan-6 FPGA I/O Tile - нарисован прямой путь PAD->IOB->ISERDES2, а IODELAY2 сбоку.

Вариант 2

Figure 2-1: SelectIO Logic Resources within the I/O Input Tile - idelay расположен  между IOB и De-serializer ISERDES2

Вариант 3

 страница 70Each IOB in the Spartan-6 FPGA contains a delay line that can be configured either for use as an input delay or output delay, и картинка   Figure 2-19: Delay Line Building Block

Вариант 4

 страница 72: A calibration mechanism is built into each IOB to compensate for the effects of temperature, voltage and process on the individual delays in the IODELAY2 block. This mechanism allows calibration of the IODELAY2 block against a known signal. In this mechanism the I/O clock applied to the IODELAY2 block is used as the known signal.   

Вот сижу  и думаю- где расположен механизм задержки, один ли он, как его включить и настроить?

Читаю xapp1064, вроде два механизма задержки. Вначале выравниваем клок на "ноль" на входной задержке, а потом используем IODELAY2.

The Spartan-6 FPGA data capture mechanism is based on the input delay primitives (IODELAY2). The individual delay taps are not constant over PVT and therefore require regular calibration. Mechanisms to perform the regular calibration that allow continuous data capture are described in this section and shown in Figure 8. In this sort of data capture, it is important that the capture clock and input data delays are closely matched. To achieve this, the input clock must be routed through an input delay that is set to zero before being routed to either a BUFIO2 or a PLL through a BUFIO2. With this method, the insertion delay in the clock and data paths are equal, and the data delays can be varied to ensure data capture occurs in the middle of the data eye.

Что такое "ноль" ?

Короче, как мне вставить "модуль задержки" и управлять задержкой в сигнале(ах) данных?

 

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


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

Приветствую!

1 hour ago, misyachniy said:

Короче, как мне вставить "модуль задержки" и управлять задержкой в сигнале(ах) данных?

Для использования IODELAY2 нужно соблюдать ряд условий с размещением,  и разводкой клоков. Если у вас проект не разводится надо смотреть что за ошибки при этом в логах.

Затем вы решаете как вы будете настраивать эти задержки. Статически на этапе компиляции или динамически через запись задержек со стороны CPU или FSM  при калибровке по патерну или при непрерывном контроле "глаза". 

Удачи! Rob.

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


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

Давайте для начала покажите картинку, что данные у вас дрожат, как вы ее получаете? Какие именно биты сбоят; как часто; зависит от температуры; может у вас обработка данных неправильная?

1) Итак при приеме данных от АЦП в ddr режиме связка IOB+iserdes  разводится намного лучше чем Iob + iddr. 

2) желательно прикрутить в проект iodelay, он имеет, насколько помню, 32 градации и в зависимости от тактовой может сделать 32 шага задержки, меняя тактовую можно увеличить/уменьшить шаг.

3) чтобы понять насколько накрутить задержку, надо подать сопровождающий данные с АЦП синхросигнал (обычно отдельная lvds пара) на триггер , сам триггер тактировать внутренней тактовой частотой). Когда сопровождающий сигнал совпадает с внутренним, то на выходе триггера константа. Ваша задача добавлять задержку пока не появится случайный сигнал на триггере ( значит вы добрались до фронта сигнала). Запоминаете задержку( пусть будет 5) и добавляете ещё пока не появится константа, а потом опять случайные данные. Так вы найдете второй фронт синхросигнала( пусть, например, задержка будет равна 12). Тогда понятно, что если выставить задержку равную 8, то будете в центре синхросигнала.

Если все дорожки одинаковые, то всем контактам с iodelay ставите такую задержку. Сначала поэкспериментируйте с ручной настройкой, потом напишите контроллер, чтобы он автоматически при каждом включении проделывал это всё за вас.

В случае большого разбега длинны задержка у каждого контакта будет своя, но когда вы ее подберёте ( для каждого контакта) она будет на одну и ту же величину ( у каждого контакта своя) отличаться от задержки контрольного контакта (тактового сигнала) при разном включении. Просто добавите соответствующую надбавку к каждому контакту.

4) насколько большой разбег длин дорожек у вас и на какой частоте работаете? Для стеклотекстолита задержка 7 пс/мм длины, посчитайте сколько пикасекунд у вас разбег и критичен ли он для вашей частоты.

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


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

On 12/19/2019 at 4:38 PM, RobFPGA said:

Для использования IODELAY2 нужно соблюдать ряд условий с размещением,  и разводкой клоков. Если у вас проект не разводится надо смотреть что за ошибки при этом в логах.

Я не против утверждения, что нужно соблюдать условия. Вопрос в чем же проблема? При разводке проекта,  около 1,5 часа происходит попытка развести проект, потом останов с ошибкой, что некоторые цепи не разведены. Когда я заводил тактирование от кварцевого генератора в ПЛИС, то при разводке получал сообщение, что нужно использовать dedicated input.

Картинку я выложил в стартовом посте. Разбираться с настройкой захвата/сдвига пока не получится, так как проект не собирается.

//====

Сегодня разбирался с не разведенными сигналами и тактированием. Экспериментируя с отдельно взятым модулем нашел "уязвимое" место проекта. Если использовать для тактирования IODELAY2 примитив IBUFGDS то проект не собирается. Вот это место:

Quote

// тактирование фаза
IBUFGDS #(.IOSTANDARD("LVDS_33"), .IBUF_DELAY_VALUE("0"), .DIFF_TERM("TRUE")) 
clk_ddr (
        .I(GS_CLKP_OUT), 
          .IB(GS_CLKN_OUT), 
          .O(pix_clk_DDR));        // строб пиксела

Заменил  IBUFGDS на IBUFDS. Кроме этого просмотрел сигнал sys_clk, который тоже не разводился. sys_clk формировался с 200 МГц выхода PLL делением на 2. Я перекомпоновал PLL на 100МГц и выбросил делитель. Проект стал "несобираться" заметно быстрее. Если раньше не менее 1,5 часа то сейчас, с размещенными 4-мя IODELAY2 в проекте, за 20 минут вылетает ошибка.

Quote

generate
        for (i = 0; i < 4; i = i+1) begin:loop
    
    // Instantiate iodelay2
    IODELAY2 #(
        .DATA_RATE          ("DDR"),
        .IDELAY_VALUE       (0),
        .IDELAY2_VALUE      (0),
        .IDELAY_MODE        ("NORMAL" ),
        .ODELAY_VALUE       (0),
        .IDELAY_TYPE        ("VARIABLE_FROM_ZERO"),        // автоподстройка под тактирование
        .COUNTER_WRAPAROUND ("WRAPAROUND" ),
        .DELAY_SRC          ("IDATAIN" ),
        .SIM_TAPDELAY_VALUE (75)
     )
    iodelay_T (
        .IDATAIN        (top_d),
        .TOUT           (),
        .DOUT           (),
        .T              (1'b0),
        .ODATAIN        (1'b0),
        .DATAOUT        (top_d_out),
        .DATAOUT2       (),         
        .IOCLK0         (pix_clk_DDR),     
        .IOCLK1         (~pix_clk_DDR),  
     
        .CLK            (sys_clk),        
        .CAL            (iodelay2_cal),              // запустить калибровку
        .INC            (1'b1),        // направление сдвига
        .CE             (iodelay2_ce), // пододвинуть на один внутренний такт
        .RST            (iodelay2_rst),
        .BUSY           (iodelay2_busy)
    );

Ошибка на каждый установленный IODELAY2:

ERROR:PhysDesignRules:2164 - Issue with pin connections and/or configuration on block:<HG_KG/loop[0].iodelay_T>:<IODELAY2_IODELAY2>.  The use of attribute
   DATA_RATE set DDR requires connectivity for the input pins CLK, IOCLK0 and IOCLK1.

Клоки у меня подключены, проверил варнинги - нет выброшенных цепей.

Ошибка "PhysDesignRules:2164" в Интернете дает всего 3 ссылки и только одна на английском. 

Проблема была в нарисованой схеме (adcinput_schematic.pdf) и решена.

Вот совет:

For debug purposes you can set the variable XIL_MAP_NODRC to bypass the error and produce an NCD file that can be examined in FPGA Editor. If there are connections on the clock net that are being removed between the logical design (input netlist) and the physical design (NCD) then it might help to apply an "S" property in the UCF file.

Вот как им воспользовались:

Doing this did allow me to find out which signal was missing (adc_fclk).

Наверное у меня тоже сигнал отбрасывается из проекта. Завтра я установлю XIL_MAP_NODRC в 1 и посмотрю что получиться. Не понятно куда приложить "S" в ucf файле?

Не понятно также почему в adcinput_schematic.pdf сигналы кадра и данных сразу не переводиться в одиночный вид, а отдельно каждый выравнивается?

 

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


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

Приветствую!

13 minutes ago, misyachniy said:

Я не против утверждения, что нужно соблюдать условия. Вопрос в чем же проблема? При разводке проекта,  около 1,5 часа

Такие вещи лучше изучать/делать на маленьком тест проекте в котором есть только минимум элементов -  клок, входные цепи и  DDR триггера.  

Удачи! Rob.

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


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

Заменять ibufgds на ibufds очень плохо. Напишите какая точно ошибка выскакивает при этом. И на какой контакт, какой конкретной плис вы его подключили. Было бы интересно получить также по паре контактов ddr данных и контакты всех клоков приходящих из вне.

В проекте, как вам тут советуют,   обязательно удалите всё лишнее. Оставьте только 1 бит входных данных и обвязку к нему и добейтесь, чтобы проект скручивался без ошибок.

Обязательно установите какие конкретно биты сбоят, если у вас конечный результат не работает это ещё не значит, что дрожат данные. Если есть возможность послать конкретное тестовое число ( лучше много раз) и принять его , сравнив с образцом, прям сразу после буферов, без какой-либо обработки, сделайте так. Возможно iserdes и iodelay не понадобятся ( хотя их потом все равно лучше прикрутить)

 

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


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

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

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

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

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

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

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

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

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

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