Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Double Rate CMOS fast input
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
rolin
Приветствую. Впервые столкнулся с необходимостью приема данных от АЦП на частоте 122.8 (период 8.138 нс) да еще и Double Rate, то есть требования к задержкам возросли вдвое. Естественно - не работает как надо, данные идут с ошибками.
Реализация защелки и разделения данных простейшая:
Код
always @(negedge adc_clock)
   begin
           reg_adc1_data[0]  <= adc1_data[0];
            reg_adc1_data[2]  <= adc1_data[1];
            reg_adc1_data[4]  <= adc1_data[2];
            reg_adc1_data[6]  <= adc1_data[3];
            reg_adc1_data[8]  <= adc1_data[4];
            reg_adc1_data[10] <= adc1_data[5];
            reg_adc1_data[12] <= adc1_data[6];
            reg_adc1_data[14] <= adc1_data[7];
            //
            reg_adc2_data[0]  <= adc2_data[0];
            reg_adc2_data[2]  <= adc2_data[1];
            reg_adc2_data[4]  <= adc2_data[2];
            reg_adc2_data[6]  <= adc2_data[3];
            reg_adc2_data[8]  <= adc2_data[4];
            reg_adc2_data[10] <= adc2_data[5];
            reg_adc2_data[12] <= adc2_data[6];
            reg_adc2_data[14] <= adc2_data[7];
            adc1_of <= adc_OF;
   end
    always @(posedge adc_clock)
    begin
           reg_adc1_data[1]  <= adc1_data[0];
            reg_adc1_data[3]  <= adc1_data[1];
            reg_adc1_data[5]  <= adc1_data[2];
            reg_adc1_data[7]  <= adc1_data[3];
            reg_adc1_data[9]  <= adc1_data[4];
            reg_adc1_data[11] <= adc1_data[5];
            reg_adc1_data[13] <= adc1_data[6];
            reg_adc1_data[15] <= adc1_data[7];
            //
            reg_adc2_data[1]  <= adc2_data[0];
            reg_adc2_data[3]  <= adc2_data[1];
            reg_adc2_data[5]  <= adc2_data[2];
            reg_adc2_data[7]  <= adc2_data[3];
            reg_adc2_data[9]  <= adc2_data[4];
            reg_adc2_data[11] <= adc2_data[5];
            reg_adc2_data[13] <= adc2_data[6];
            reg_adc2_data[15] <= adc2_data[7];
            adc2_of <= adc_OF;
    end


Кое-как отфазировал клок из АЦП, работает но с ошибками. TimeQuest показывает сильную разницу между заржками к двум буферам. Проблема в том, что вход один, а регистров два. Один квартус сделал как Fast Input а второй где придется.


Один из входных пинов не может использовать FastInput и регистры используются одинаковые, в результате разница в задержках мизерная.
Я думаю, что если как-то запретить квартусу использовать FastInput, то можно получить неравномерность в пределах 1 нс, чего будет достаточно.
Я в TimeQuest только первые шаги делаю и не совсем понятно,
как задержать входной клок на 5 нс, чтобы все эти данные вовремя под фронты попадали
а еще вероятно нужно будет менять задержки для каждой линии из-за неоптимальной разводки на плате. Не знаю, как это и возможно ли вообще.
Прошу помощи.
И еще, нет ли какой готовой реализации подобного интерфейса в IP, может это решит все проблемы ?
bogaev_roman
Цитата(rolin @ Mar 1 2016, 17:28) *
Прошу помощи.
И еще, нет ли какой готовой реализации подобного интерфейса в IP, может это решит все проблемы ?

Дело не в готовой реализации. Вам нужно грамотно прописать временные ограничения, чтобы квартус сам все вытянул, Вы их прописали? Если нет, то советую посмотреть, каким образом это делается, например здесь - http://embedders.org/content/timequest-dly...rfeisov-raznykh.
ЗЫ. Частота 122,88 сейчас невысокая. Что мешает поставить DDR регистр на вход, который тактируется adc_clock (которую пропускаете через pll и сдвигаете на 90 градусов)?
Ну для xilinx примерно так:
Код
IDDR #(
    .DDR_CLK_EDGE ("SAME_EDGE_PIPELINED"),
    .INIT_Q1 (1'b0),
    .INIT_Q2 (1'b0),
    .SRTYPE ("ASYNC"))
  i_rx_data_iddr (
    .CE (1'b1),
    .R (1'b0),
    .S (1'b0),
    .C (ADC_clk),
    .D (rx_data_ibuf_s[l_inst]),
    .Q1 (rx_data_p_s[l_inst]),
    .Q2 (rx_data_n_s[l_inst]));

rolin
Цитата(bogaev_roman @ Mar 1 2016, 19:12) *
ЗЫ. Частота 122,88 сейчас невысокая. Что мешает поставить DDR регистр на вход, который тактируется adc_clock (которую пропускаете через pll и сдвигаете

TimeQuest мне сообщает, что максимальная используемая частота в данном случае 176МГц, это циклон 3, а так как у меня 122 и double rate, то тайминги эквивалентны 256 МГц. Но не суть, может я неправильно понимаю.
Приведенный вами код похож на описание некоего примитива, тут у меня знаний нет к сожалению.

Требования по таймингам прописал как
Код
set_input_delay -add_delay -max -clock [get_clocks {adc_clock}]  7.138 [get_ports {adc_d1[0]}]
set_input_delay -add_delay -min -clock [get_clocks {adc_clock}]  1.000 [get_ports {adc_d1[0]}]

set_max_delay -from [get_ports {adc_d1[0]}] 1.000
set_min_delay -from [get_ports {adc_d1[0]}] 0.500


когда задаю задержку для клока, то ничего не меняется
Код
set_clock_latency -source   5.000 [get_clocks {adc_clock}]
rolin
Цитата(bogaev_roman @ Mar 1 2016, 19:12) *
Что мешает поставить DDR регистр на вход, который тактируется adc_clock (которую пропускаете через pll и сдвигаете на 90 градусов)?

разобрался, для альтеры это IP ALTDDIO
получилось так
Код
         wire [7:0] adc1_data_buffer_h, adc1_data_buffer_l;
         wire [7:0] adc2_data_buffer_h, adc2_data_buffer_l;
     adc_ddr_reg ddr_reg1  (adc1_data, clock, adc1_data_buffer_h, adc1_data_buffer_l);
     adc2_ddr_reg ddr_reg2 (adc2_data, clock, adc2_data_buffer_h, adc2_data_buffer_l);
     adc_of_ddr_reg ddr_of (adc_OF, clock, adc2_of, adc1_of);


Теперь задержки выровнялись



осталось скомпенсировать общую задержку > 5 нс
rolin
После выравнивания задержек благодаря применения ALTDDIO_IN устройство работает хорошо.
Больше ничего не делал, подобрал фазу клока из АЦП и все.
Плату на глаз дорожки волнами рисовал, похоже угадал.
Спасибо.
andrew_b
Цитата(rolin @ Mar 1 2016, 20:48) *
разобрался, для альтеры это IP ALTDDIO
Да. Мне, например, не удалось заставить Квартус расположить оба триггера в IOB без использования этого ядра, что для DDR критично.
bogaev_roman
Цитата(rolin @ Mar 2 2016, 01:35) *
После выравнивания задержек благодаря применения ALTDDIO_IN устройство работает хорошо.
Больше ничего не делал, подобрал фазу клока из АЦП и все.

У Вас слаки отрицательные и Вы считаете, что все работает в штатном режиме? А если температура поменяется и это алгоритм для полета баллистической ракеты biggrin.gif . Все-таки советую доразобраться с ограничениями, в приведенной ссылке на странице 5 именно Ваш случай - System-Synchronus Input.
Не забыли прописать, что-то типа

Код
derive_pll_clocks
derive_clock_uncertainty
create_clock -period 122.88MHz -name {clk} [get_ports {clk}]
create_generated_clock -name {adc_clk} -source [get_ports {clk}] [get_ports {adc_clk}]

Судя по ограничениям
Код
set_input_delay -add_delay -max -clock [get_clocks {adc_clock}]  7.138 [get_ports {adc_d1[0]}]
set_input_delay -add_delay -min -clock [get_clocks {adc_clock}]  1.000 [get_ports {adc_d1[0]}]

у Вас фронт/срез тактовой примерно совпадает с переходами данных, но в большинстве случаев тактовая должна быть посредине окна данных, т.е. сдвинута на 90 градусов, эти ограничения Вы взяли из спецификации?
rolin
Цитата(bogaev_roman @ Mar 2 2016, 09:10) *
У Вас слаки отрицательные и Вы считаете, что все работает в штатном режиме? А если температура поменяется и это алгоритм для полета баллистической ракеты biggrin.gif . Все-таки советую доразобраться с ограничениями, в приведенной ссылке на странице 5 именно Ваш случай - System-Synchronus Input.

Так они ж одинаково отрицательные, мне главное чтобы данные выровненные были , а клок я могу из АЦП двигать с шагом 45 град.
Но в общем опять не работает оно, рано обрадовался.
Писать по примеру я не могу, так как квартус тоже как бы хочет писать в cds и в итоге фигня получается. Выдал мне 150 ошибок по каким-то внутренним несоответствиям, причем сам написал мне строки в файле а потом по ним же и слаки выдал. Короче снес я cds и разницы не заметил.
Проблема сейчас такова, решил включить паттерны на АЦП, чтобы убедиться что все хорошо, а оно не хорошо.
Согласно паттерну, АЦП выдает поочередно 1111_1111_1111_000 и 0000_0000_0000_0000
Крутил фазу клока из АЦП от 0 до 275 град, зафиксировал следующие данные
1010_1010_1010_0000
1111_1111_1111_0000
Но самое главное, что данные не чередуются, всегда FFF0 или AAA0, что-то с DDR неправильно у меня.
Код
adc_ddr_reg ddr_reg1  (adc1_data, clock, adc1_data_buffer_h, adc1_data_buffer_l);
assign reg_adc1_data[0]  = adc1_data_buffer_l[0];
    assign reg_adc1_data[2]  = adc1_data_buffer_l[1];
    assign reg_adc1_data[4]  = adc1_data_buffer_l[2];
    assign reg_adc1_data[6]  = adc1_data_buffer_l[3];
    assign reg_adc1_data[8]  = adc1_data_buffer_l[4];
    assign reg_adc1_data[10]  = adc1_data_buffer_l[5];
    assign reg_adc1_data[12]  = adc1_data_buffer_l[6];
    assign reg_adc1_data[14]  = adc1_data_buffer_l[7];
    //
    assign reg_adc1_data[1]  = adc1_data_buffer_h[0];
    assign reg_adc1_data[3]  = adc1_data_buffer_h[1];
    assign reg_adc1_data[5]  = adc1_data_buffer_h[2];
    assign reg_adc1_data[7]  = adc1_data_buffer_h[3];
    assign reg_adc1_data[9]  = adc1_data_buffer_h[4];
    assign reg_adc1_data[11]  = adc1_data_buffer_h[5];
    assign reg_adc1_data[13]  = adc1_data_buffer_h[6];
    assign reg_adc1_data[15]  = adc1_data_buffer_h[7];

Данные для обработки захватываю из регистров со сдвигом 45 град относительно клока АЦП, но это похоже ни к чему.
На выходе АЦП на шине меандр 61.44 МГц, а значит при клоке 128.88 можно в зависимости от фазы получить следующие данные:
AAA0, 5550, FFF0, 0000 (АЦП 14 бит)
но эти данные должны чередоваться
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.