rolin 0 1 марта, 2016 Опубликовано 1 марта, 2016 · Жалоба Приветствую. Впервые столкнулся с необходимостью приема данных от АЦП на частоте 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 0 1 марта, 2016 Опубликовано 1 марта, 2016 · Жалоба Прошу помощи. И еще, нет ли какой готовой реализации подобного интерфейса в 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 0 1 марта, 2016 Опубликовано 1 марта, 2016 · Жалоба ЗЫ. Частота 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 0 1 марта, 2016 Опубликовано 1 марта, 2016 · Жалоба Что мешает поставить 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 0 1 марта, 2016 Опубликовано 1 марта, 2016 · Жалоба После выравнивания задержек благодаря применения ALTDDIO_IN устройство работает хорошо. Больше ничего не делал, подобрал фазу клока из АЦП и все. Плату на глаз дорожки волнами рисовал, похоже угадал. Спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 15 2 марта, 2016 Опубликовано 2 марта, 2016 · Жалоба разобрался, для альтеры это IP ALTDDIO Да. Мне, например, не удалось заставить Квартус расположить оба триггера в IOB без использования этого ядра, что для DDR критично. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bogaev_roman 0 2 марта, 2016 Опубликовано 2 марта, 2016 · Жалоба После выравнивания задержек благодаря применения ALTDDIO_IN устройство работает хорошо. Больше ничего не делал, подобрал фазу клока из АЦП и все. У Вас слаки отрицательные и Вы считаете, что все работает в штатном режиме? А если температура поменяется и это алгоритм для полета баллистической ракеты . Все-таки советую доразобраться с ограничениями, в приведенной ссылке на странице 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 0 4 марта, 2016 Опубликовано 4 марта, 2016 (изменено) · Жалоба У Вас слаки отрицательные и Вы считаете, что все работает в штатном режиме? А если температура поменяется и это алгоритм для полета баллистической ракеты . Все-таки советую доразобраться с ограничениями, в приведенной ссылке на странице 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 бит) но эти данные должны чередоваться Изменено 4 марта, 2016 пользователем rolin Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться