Джиттер это дрожание фронта тактового сигнала. Чем меньше джиттер тем лучше. Большой джиттер ухудшает параметры АЦП, ухудшает трассировку ПЛИС. Однако есть ситуации когда джиттер полезен. Например его можно использовать при автоматической подстройке тактовой частоты.
Давайте рассмотрим классическую задачу подключения АЦП по параллельной шине.
В общем виде схема подключения выглядит так:
Шина данных АЦП поступает на выводы ПЛИС, непосредственно внутри блока ввода-вывода находится DDR триггер или десериализатор и далее по параллельной шине данные поступают на FIFO. Проблема заключается в прохождении тактового сигнала. Если использовать глобальный буфер, то время распространения сигнала до буфера и обратно может составлять 5 нс. Это очень много. Это сравнимо с периодом тактовой частоты, которая легко может составлять 200-500 МГц.
Несколько слов почему это плохо. В общем случае АЦП должно работать в некотором диапазоне частот. Рассмотрим для примера ситуацию с задержкой такта на 2.8 нс, при тактовой частоте 500 МГц.
На первый взгляд всё прекрасно, данные АЦП прекрасно защёлкиваются. Но вот что произойдёт если частота уменьшиться до 357 МГц, это как раз и составит 2.8 нс?
Данные наезжают на фронт и мы получаем искажение данных. При дальнейшем уменьшении частоты наезд исчезнет и данные снова будут правильными.
Есть два классических способа решения проблемы:
1. В блоке IOB есть элемент задержки, он может установить задержку до 2.4 нс. В большинстве случаев этого достаточно.
2. Существуют специальные элементы bufio, через них путь тактовой частоты становиться гораздо короче.
К сожалению этого не всегда достаточно. Задержка может превышать 2.4 нс, особенно на больших ПЛИС. И не всегда тактовый сигнал заведён на вывод bufio.
Существует простое и элегантное решение этой проблемы. Для этого достаточно сделать так, что бы фаза внутреннего тактового сигнала всегда точно совпадала с фазой тактового сигнала АЦП. Существующие внутри ПЛИС узлы DCM, MMCM, или PLL умеют плавно изменять фазу. А вот датчиком может служить D-триггер внутри блока IOB. Вот схема включения:
Входной сигнал тактовой частоты проходит сквозь IOB и поступает на вход DCM, одновременно он же поступает на вход D-триггера. На тактовый вход D-триггера поступает сигнал после DCM, этот же сигнал поступает на триггеры шины данных АЦП. И вот что происходит, рассмотрим несколько ситуаций:
Ситуация 1 – фронт глобального сигнала значительно левее фронта входного сигнала. На выходе триггера – нули.
Ситуация 2 – фронт глобального сигнала в зоне джиттера. На выходе – случайная последовательность. Именно это и есть то самое полезное свойство джиттера. По факту появления случайной последовательности можно определить факт подстройки тактовой частоты.
Ситуация 3 – фронт глобального сигнала значительно правее входного сигнала. На выходе – единицы.
Все эти ситуации легко обрабатывается конечным автоматом. В моей реализации существует цикл накопления, в течении 1024 тактов производится подсчёт 1. Если значение счётчика больше 576, то производится сдвиг фазы влево. Если значение счётчика меньше 448, то происходит сдвиг фазы вправо.
На рисунке представлен результат моделирования компонента.
Видно, что после подстройки существует небольшой колебательный процесс — сдвиг в пределах одного значения. В реальных системах в установившемся режиме также наблюдается изменение фазы в пределах одного-двух отсчётов. Перед началом подстройки было так:
Видно, что есть большое смещение между частотами. А после подстройки так:
Частоты совпадают.
» Готовые компоненты представлены на GitHub:
Я выложил два компонента:
Несколько слов про моделирование. Поскольку в основе лежит случайный процесс, то это создаёт некоторые проблемы. Но они решаемые. В стенде используется компонент model_line_v1, который как раз формирует джиттер на тактовом сигнале. Для формирования джиттера используется функция UNIFORM из библиотеки math_real.
В заключении хочу отметить, что эти компоненты используются во многих наших проектах. И они нам сильно помогают.
Давайте рассмотрим классическую задачу подключения АЦП по параллельной шине.
В общем виде схема подключения выглядит так:
Шина данных АЦП поступает на выводы ПЛИС, непосредственно внутри блока ввода-вывода находится DDR триггер или десериализатор и далее по параллельной шине данные поступают на FIFO. Проблема заключается в прохождении тактового сигнала. Если использовать глобальный буфер, то время распространения сигнала до буфера и обратно может составлять 5 нс. Это очень много. Это сравнимо с периодом тактовой частоты, которая легко может составлять 200-500 МГц.
Несколько слов почему это плохо. В общем случае АЦП должно работать в некотором диапазоне частот. Рассмотрим для примера ситуацию с задержкой такта на 2.8 нс, при тактовой частоте 500 МГц.
На первый взгляд всё прекрасно, данные АЦП прекрасно защёлкиваются. Но вот что произойдёт если частота уменьшиться до 357 МГц, это как раз и составит 2.8 нс?
Данные наезжают на фронт и мы получаем искажение данных. При дальнейшем уменьшении частоты наезд исчезнет и данные снова будут правильными.
Есть два классических способа решения проблемы:
1. В блоке IOB есть элемент задержки, он может установить задержку до 2.4 нс. В большинстве случаев этого достаточно.
2. Существуют специальные элементы bufio, через них путь тактовой частоты становиться гораздо короче.
К сожалению этого не всегда достаточно. Задержка может превышать 2.4 нс, особенно на больших ПЛИС. И не всегда тактовый сигнал заведён на вывод bufio.
Существует простое и элегантное решение этой проблемы. Для этого достаточно сделать так, что бы фаза внутреннего тактового сигнала всегда точно совпадала с фазой тактового сигнала АЦП. Существующие внутри ПЛИС узлы DCM, MMCM, или PLL умеют плавно изменять фазу. А вот датчиком может служить D-триггер внутри блока IOB. Вот схема включения:
Входной сигнал тактовой частоты проходит сквозь IOB и поступает на вход DCM, одновременно он же поступает на вход D-триггера. На тактовый вход D-триггера поступает сигнал после DCM, этот же сигнал поступает на триггеры шины данных АЦП. И вот что происходит, рассмотрим несколько ситуаций:
Ситуация 1 – фронт глобального сигнала значительно левее фронта входного сигнала. На выходе триггера – нули.
Ситуация 2 – фронт глобального сигнала в зоне джиттера. На выходе – случайная последовательность. Именно это и есть то самое полезное свойство джиттера. По факту появления случайной последовательности можно определить факт подстройки тактовой частоты.
Ситуация 3 – фронт глобального сигнала значительно правее входного сигнала. На выходе – единицы.
Все эти ситуации легко обрабатывается конечным автоматом. В моей реализации существует цикл накопления, в течении 1024 тактов производится подсчёт 1. Если значение счётчика больше 576, то производится сдвиг фазы влево. Если значение счётчика меньше 448, то происходит сдвиг фазы вправо.
На рисунке представлен результат моделирования компонента.
Сигнал clk_in1 – это входная тактовая частота
clk0 – подстроенная частота
clk_fd – детектор фазы
Сигнал phase_locked=1 означает что достигнута подстройка фазы.
psen – сдвиг фазы DCM
psincdec – направление сдвига фазы
shift0 – текущее значение счётчика фазы
Видно, что после подстройки существует небольшой колебательный процесс — сдвиг в пределах одного значения. В реальных системах в установившемся режиме также наблюдается изменение фазы в пределах одного-двух отсчётов. Перед началом подстройки было так:
Видно, что есть большое смещение между частотами. А после подстройки так:
Частоты совпадают.
» Готовые компоненты представлены на GitHub:
Я выложил два компонента:
ctrl_dcm_phase_v6 –DCM установлен внутри. Это для ПЛИС Spartan 3, Virtex 4, Virtex 5
ctrl_dcm_phase_v8 – внешний DCM или MMCM, это для Virtex 6, Kintex 7.
Несколько слов про моделирование. Поскольку в основе лежит случайный процесс, то это создаёт некоторые проблемы. Но они решаемые. В стенде используется компонент model_line_v1, который как раз формирует джиттер на тактовом сигнале. Для формирования джиттера используется функция UNIFORM из библиотеки math_real.
В заключении хочу отметить, что эти компоненты используются во многих наших проектах. И они нам сильно помогают.