|
|
  |
Double Rate CMOS fast input, компенсация задержек. |
|
|
|
Mar 1 2016, 14:28
|
Участник

Группа: Участник
Сообщений: 36
Регистрация: 31-01-09
Пользователь №: 44 224

|
Приветствую. Впервые столкнулся с необходимостью приема данных от АЦП на частоте 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, может это решит все проблемы ?
|
|
|
|
|
Mar 1 2016, 15:12
|
Профессионал
    
Группа: Свой
Сообщений: 1 088
Регистрация: 20-10-09
Из: Химки
Пользователь №: 53 082

|
Цитата(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]));
|
|
|
|
|
Mar 1 2016, 15:58
|
Участник

Группа: Участник
Сообщений: 36
Регистрация: 31-01-09
Пользователь №: 44 224

|
Цитата(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}]
|
|
|
|
|
Mar 1 2016, 17:48
|
Участник

Группа: Участник
Сообщений: 36
Регистрация: 31-01-09
Пользователь №: 44 224

|
Цитата(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 нс
|
|
|
|
|
Mar 1 2016, 22:35
|
Участник

Группа: Участник
Сообщений: 36
Регистрация: 31-01-09
Пользователь №: 44 224

|
После выравнивания задержек благодаря применения ALTDDIO_IN устройство работает хорошо. Больше ничего не делал, подобрал фазу клока из АЦП и все. Плату на глаз дорожки волнами рисовал, похоже угадал. Спасибо.
|
|
|
|
|
Mar 2 2016, 06:10
|
Профессионал
    
Группа: Свой
Сообщений: 1 088
Регистрация: 20-10-09
Из: Химки
Пользователь №: 53 082

|
Цитата(rolin @ Mar 2 2016, 01:35)  После выравнивания задержек благодаря применения 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 градусов, эти ограничения Вы взяли из спецификации?
|
|
|
|
|
Mar 4 2016, 23:14
|
Участник

Группа: Участник
Сообщений: 36
Регистрация: 31-01-09
Пользователь №: 44 224

|
Цитата(bogaev_roman @ Mar 2 2016, 09:10)  У Вас слаки отрицательные и Вы считаете, что все работает в штатном режиме? А если температура поменяется и это алгоритм для полета баллистической ракеты  . Все-таки советую доразобраться с ограничениями, в приведенной ссылке на странице 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 бит) но эти данные должны чередоваться
Сообщение отредактировал rolin - Mar 4 2016, 23:20
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|