|
делитель частоты и джиттер, влияние ПЛИС на джиттер |
|
|
|
May 18 2009, 20:29
|

Знающий
   
Группа: Свой
Сообщений: 601
Регистрация: 3-07-07
Пользователь №: 28 852

|
Здравствуйте! Задача такова: имеется генератор с частотой 33 МГц и джиттером N пикосекунд (генератор подключен ко входу CLK0 ПЛИС семейства Cyclone III). требуется на ПЛИС реализовать управляемый делитель частоты (1/2, 1/4, 1/6, 1/8, 1/10, 1/12, 1/14, 1/16). Требуется на выходе делителя получить сигнал с как можно меньшим джиттером (разумеется, джиттер меньше чем N пс получить не выйдет). Моё решение: Код LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all;
ENTITY clkdiv IS GENERIC ( divsz : natural := 3 -- разрядность счетчика ); PORT ( clk: in std_logic; -- входной клок div: in std_logic_vector((divsz-1) downto 0); -- коэффициент деления sco: out std_logic -- выходной клок ); END clkdiv;
ARCHITECTURE rtl OF clkdiv IS signal CN : std_logic_vector((divsz-1) downto 0); -- счетчик signal T,Q : std_logic; BEGIN T<='1' when (CN=div) else '0'; process (clk,T) begin if (falling_edge(clk)) then -- по спаду клока if (T='1') then CN<=(others=>'0'); else CN<=CN+1; end if; end if; end process; process (clk,T) begin if (rising_edge(clk) and (T='1')) then -- по фронту клока Q<=not Q; end if; end process; sco<=Q; END rtl; Дополнительная синхронизация (та, что по переднему фронту) внесена в схему для того, чтобы время переключения выходного сигнала не зависело от скорости работы сумматора и схемы сравнения (мало ли время срабатывания зависит от значения CN и div). Вопросы: 1) насколько корректна такая реализация? 2) как такое решение может повлиять на джиттер выходного сигнала? 3) ПЛИС и джиттер - как они вообще связаны.
Эскизы прикрепленных изображений
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 28)
|
May 19 2009, 01:08
|

pontificator
     
Группа: Свой
Сообщений: 3 055
Регистрация: 8-02-05
Из: страны Оз
Пользователь №: 2 483

|
Цитата(sysel @ May 19 2009, 05:59)  (разумеется, джиттер меньше чем N пс получить не выйдет. Почему же? В принципе это возможно. Любая PLL работает как jitter cleaner. Она фильтрует джиттер с частотами выше, чем частота фильтра в петле обратной связи PLL. Если у входного клока безумно большой и высокочастотный джиттер, то Циклоновская PLL может его почистить. Цитата(sysel @ May 19 2009, 05:59)  3) ПЛИС и джиттер - как они вообще связаны. Помнится, Альтера не гарантирует, что джиттер на выходе Циклона будет меньше чем 150 пс. Сравните типичные цифры джиттера, которую добавляет логика разного типа: CODE ------------------------------------------------ тип jitter, ps rms ------------------------------------------------ FPGA 33 to 50 74LS00 5 74HCT00 2.2 74ACT00 1 MC100EL16 (PECL) 0.7 NBSG16 (ECL) 0.2
|
|
|
|
|
May 19 2009, 05:24
|

Знающий
   
Группа: Свой
Сообщений: 601
Регистрация: 3-07-07
Пользователь №: 28 852

|
В своём вопросе я не конкретизировал джиттер. Я точно не могу его оценить, но думаю генератор даёт джиттер порядка <30 пикосекунд. Цитата(=AK= @ May 19 2009, 05:08)  Если у входного клока безумно большой и высокочастотный джиттер, то Циклоновская PLL может его почистить. Если говорить о циклоновской PLL - то она добавит джиттера. Цитата(=AK= @ May 19 2009, 05:08)  Помнится, Альтера не гарантирует, что джиттер на выходе Циклона будет меньше чем 150 пс. Сравните типичные цифры джиттера, которую добавляет логика разного типа: CODE ------------------------------------------------ тип jitter, ps rms ------------------------------------------------ FPGA 33 to 50 74LS00 5 74HCT00 2.2 74ACT00 1 MC100EL16 (PECL) 0.7 NBSG16 (ECL) 0.2
Откуда такая информация? Как я понимаю, джиттер, который добавляет FPGA зависит в первую очередь не от кристалла, а от прошивки. По идее, в моей реализации джиттер будет зависить от джиттера переднего фронта clk и триггера Q. Прошу исправить, если я где ошибаюсь. P.S. У меня задача стоит тактировать сигма-дельта АЦП AD7764, судя по даташиту, джиттер на входе не должен превышать 50 пс.
|
|
|
|
|
May 19 2009, 14:25
|
Злополезный
   
Группа: Свой
Сообщений: 608
Регистрация: 19-06-06
Из: Russia Taganrog
Пользователь №: 18 188

|
 Мдааа. Конечно, я с Cyclon 3 не работал, но визуально схема - отвратительная (на уровне начинающего): 1. Выходной триггер имеет обратную связь, в нормальных ПЛИС в IOB это не ложиться (или у Cyclon 3 нет выходных триггеров ?) - соответственно будет прирост jitter'а за счет передачи логического сигнала к выходному буферу (обычно clock распространяеста по ПЛИС с меньшим jitter'ом, чем все остальные сигналы). 2. Э-хе-хе... Кто ж так делитель делает ??! Нормальные люди используют выходной перенос (назовём его CY) загружаемого счетчика: сам CY подается на счетный триггер, сигнал с которого подается на дополнительный выходной триггер (обязательно выходной триггер, иначе дополнительный прирост jitter’а). Дополнительно CY подаётся на вход Load это загружаемого счётчика, а вот значением, которое загружается - выбирается количество тактов, которое счетчик будет досчитывать до переноса (т.е. коэффициент деления). Такая схема значительно компактнее и быстродейственней... если конечно суметь правильно сделать тот самый загружаемый счетчик.
|
|
|
|
|
May 19 2009, 16:47
|
Злополезный
   
Группа: Свой
Сообщений: 608
Регистрация: 19-06-06
Из: Russia Taganrog
Пользователь №: 18 188

|
Цитата(SM @ May 19 2009, 17:33)  Или ложится туда через register duplication (когда на вход регистра в IOE идет тот же сигнал, что и на вход регистра-копии в LE, что делается незаметно для разработчика при place/route). Да есть такой метод (и очень хорошо помогает), но в данном случае это обязательное требование (наличие Output FF), поэтому, на мой взгляд, теневое register duplication не подходит - это надо делать в явном виде, а потом еще и проконтролировать, что после оптимизаций всё получилось как задумано.
|
|
|
|
|
May 19 2009, 16:56
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(Boris_TS @ May 19 2009, 20:47)  теневое register duplication не подходит - это надо делать в явном виде Так достаточен assignment "Fast Output Register = on" для выходного пина, что и будет тем самым "явным видом", и потом хоть контролируй, хоть нет, а гарантия того, что выходной регистр сидит в IOE 100%. А уж каким методом там это в результате оптимизаций сделано IMHO не важно, хоть дупликацией, хоть фидбеком с выхода IOE. То есть, что я имею в виду - если указан констрейн, что Fast Output Register, то он ляжет в IOE, и никаких гвоздей. Не может быть регистров, которые туда не ложатся (за исключением того, что слишком много регистров одновременно пытаются запихать)
|
|
|
|
|
May 19 2009, 20:03
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(sazh @ May 19 2009, 23:25)  Но речь ведь шла о выходном клоке. Самого интересного нет. Для тех, кто в танке, повторяю кусок кода еще раз методом copy-paste: Код // output T-ff; ckg_reg_a is output of generated frequency always @(posedge tckg_clk) if (tckg_en && tckg_cnt_z) ckg_reg_a <= ~ckg_reg_a; Способ засовывания этого триггера в IOE уже дело вкуса. Я предпочитаю констрейн "Fast Output Register", а кто-то пропускает через еще один триггер, указывая видимо констрейн уже ему, но это мелочи, не заслуживающие внимания.
|
|
|
|
|
May 19 2009, 20:12
|
Знающий
   
Группа: Свой
Сообщений: 654
Регистрация: 24-01-07
Из: Воронеж
Пользователь №: 24 737

|
Цитата(SM @ May 19 2009, 20:56)  То есть, что я имею в виду - если указан констрейн, что Fast Output Register, то он ляжет в IOE, и никаких гвоздей. Не может быть регистров, которые туда не ложатся (за исключением того, что слишком много регистров одновременно пытаются запихать) Совсем не уверен. Если триггер не может туда лечь, он не ляжет, причем без предупреждений. (Altera, IMHO, проверять лениво)Цитата(SM @ May 19 2009, 22:25)  Я думаю, что речь о чем-то типа того: Более чем впечатляет. Я бы так: Код always @(posedge clk) begin if (counter == 3'b0) begin out <= ~out; counter <= (divider[3:1] - 1'b1); end else counter <= counter - 1'b1; end А если есть желание избавиться от джиттера ПЛИС, то надо вынести последний триггер за пределы ПЛИС.
|
|
|
|
|
May 19 2009, 20:34
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(dvladim @ May 20 2009, 00:12)  Совсем не уверен. Если триггер не может туда лечь, он не ляжет, причем без предупреждений. (Altera, IMHO, проверять лениво) А я уверен. Если насильно register duplication не отключили, то если триггер не может туда лечь, то туда ложится копия этого триггера. Если отключили, то сами виноваты, констрейны это святое  По крайней мере вышеприведенный ckg_reg_a ложится и в альтере (cyclone-ii), и в LatticeXP без каких либо противопоказаний. Цитата(dvladim @ May 20 2009, 00:12)  Я бы так: Ну да, в контексте конкретной задачи от автора поста самое оно, и десяток строк против килобайта текста. Моя же цель была слегка посложнее, и на частотах аццких.
|
|
|
|
|
May 20 2009, 07:14
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(_Anatoliy @ May 20 2009, 08:52)  Можно поинтересоваться какой частоты удалось достичь? Цитата(des00 @ May 20 2009, 10:21)  я правильно понимаю при нечетных tckg_div_coeff скважность выходного сигнала не 50/50 ? и вас это устраивало? Работает эта шняга в реальном устройстве на 210 МГц на LatticeXP (LFXP3E-3TN100C, самая медленная из них) (при оценке STA в 254 МГц и макс. допустимой частоте регистра 320 МГц ), и максимально формируемая частота 52,5 МГц (т.е. мин. коэфф. деления 4, это уже мое ограничение, произрастающее из Fmax того, что от этого работает). Это, если уж совсем конкретно, формирователь TCK в сау510усб-исо, из которого я повырезал все, связанное с адаптивным тактированием, кстати критический путь в результате тоже вырезался, именно эта схема д.б. еще быстрее. Не 50/50 при нечетных коэфф. меня мало волнует, так как разница между полупериодами всего 1 клок, меня больше волнует возможность как можно более плавно задавать частоту. Цитата(des00 @ May 20 2009, 10:21)  т.к. описан самый оптимальный синхронный счетчик для фпга с 4-х входовым лютом Еще не самый... Там компаратор второго переноса 8-битный, можно еще наконвейеризировать.
|
|
|
|
|
May 20 2009, 11:14
|
Злополезный
   
Группа: Свой
Сообщений: 608
Регистрация: 19-06-06
Из: Russia Taganrog
Пользователь №: 18 188

|
Цитата(sazh @ May 19 2009, 21:04)  Примерчик можно? Вот пример подобного делителя (на 2,4,6,8,10,12,14,16). Код library IEEE; use IEEE.std_logic_1164.all; library unisim; use unisim.vcomponents.all; library work; use work.HardSynP.all;
entity DIV is port ( DIV_RG_D: in std_logic_vector(2 downto 0); DIV_RG_CE: in std_logic; CLK: in std_logic; OUT_CLK: out std_logic ); end entity;
architecture Tushka of DIV is signal DIV_RG: std_logic_vector(2 downto 0);
signal DIV_CB_CY: std_logic; signal DIV_CB_CY_L: std_logic;
signal OUT_CLK_INT_FF: std_logic := '0'; signal OUT_CLK_IOB_FF: std_logic := '0';
attribute IOB of OUT_CLK_IOB_FF: signal is "true"; begin DIV_RG_I: entity HS_FD(FDRE) generic map ( nInit => 0, nX => 1, nY => 0, sUSet => "DIV_CB" ) port map ( D => DIV_RG_D, CE => DIV_RG_CE, C => CLK, INIT => '0', Q => DIV_RG ); DIV_CB_CY_FF: entity HS_CB_CI_FD(CB_CI_FD) generic map ( nInit => 0, nX => 0, nY => 3, sUSet => "DIV_CB" ) port map ( CE => '1', C => CLK, INIT => '0', Q => DIV_CB_CY_L, CI => DIV_CB_CY); DIV_CB: entity HS_CBRELIO(CBRELIO) generic map ( nInit => 0, nX => 0, nY => 0, sUSet => "DIV_CB" ) port map ( D => DIV_RG, L => DIV_CB_CY_L, CE => '1', C => CLK, INIT => '0', CI => '1', CO => DIV_CB_CY ); OUT_CLK_INT_FF <= not(OUT_CLK_INT_FF) when rising_edge(CLK) and DIV_CB_CY = '1'; OUT_CLK_IOB_FF <= not(OUT_CLK_INT_FF) when rising_edge(CLK) and DIV_CB_CY = '1'; OUT_CLK_OBUF: component OBUF port map ( I => OUT_CLK_IOB_FF, O => OUT_CLK); end architecture; Если необходимо еще выше поднять рабочую частоту, то тогда вместо DIV_CB_CY необходимо использовать DIV_CB_CY_L: Код OUT_CLK_INT_FF <= not(OUT_CLK_INT_FF) when rising_edge(CLK) and DIV_CB_CY_L = '1'; OUT_CLK_IOB_FF <= not(OUT_CLK_INT_FF) when rising_edge(CLK) and DIV_CB_CY_L = '1'; Думаю необходимо дать следующие пояснения: 1. Это переработанное ядро управляемого делителя частоты (в оригинале был 24 разрядный делитель, да и использовался сам сигнал DIV_CB_CY_L) 2. Описанная выше схема использует мою собственную библиотеку HardSyn. Эта библиотека имеет набор различных элементов оптимизированных под конкретные кристаллы (в приведенном примере для Xilinx Spartan-3x). 3. Почти все примитивы в элементах библиотеки имеют constraint RLOC, что позволяет задать взаимное расположение элементов (sUSet - задает название группы, а nX и nY - относительное положение "вершины" элемента). 4. HS_FD(FDRE) - просто D триггера. 5. HS_CBRELIO(CBRELIO) - загружаемый счетчик (необычностью данного счетчика является то, что инкремент производиться всегда, а вход L задает что сейчас необходимо инкрементировать: текущее значение счетчика (L := '0'), или входные данные - D (L := '1'). Т.к. цепи переноса никогда не блокируются, а вся логика в каждом разряде использует только 1 LUT - то достигается предельно возможное быстродействие). 6. HS_CB_CI_FD(CB_CI_FD) - триггер, предназначенный для поимки выходного переноса счетчика (использует dedicated линии переноса - имеющие "нулевую" задержку). Да, понимаю, при таком подходе лучше, конечно, использовать схемное отображение соединения блоков - нагляднее и красивее... но, видать не судьба. Со схемными редакторами есть проблемы при обновлении ПО, а эта библиотека пережила Xilinx ISE от 5.1 до 11.1, да и у AHDL со схемным редактором при смене версий тоже не всё гладко. А код на языке - он для всех версий одинаков (и можно после работы в более новой среде безболезненно возвращаться к предшествующим).
|
|
|
|
|
May 20 2009, 11:33
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(Boris_TS @ May 20 2009, 15:14)  необычностью данного счетчика является то, что инкремент производиться всегда, а вход L задает что сейчас необходимо инкрементировать: текущее значение счетчика (L := '0'), или входные данные - D (L := '1'). Т.к. цепи переноса никогда не блокируются, а вся логика в каждом разряде использует только 1 LUT - то достигается предельно возможное быстродействие). А зачем делать так хитро, не проще ли просто задействовать предразведенный вход разрешения синхронной загрузки триггера? Который также не трогает цепей переноса, и позволяет прогрузить данное непосредственно со входа без инкремента? (привешиваю для понятности того, о чем речь, пример этой цепи из одного из семейств ПЛИСов)
Эскизы прикрепленных изображений
|
|
|
|
|
May 20 2009, 12:10
|
Злополезный
   
Группа: Свой
Сообщений: 608
Регистрация: 19-06-06
Из: Russia Taganrog
Пользователь №: 18 188

|
Цитата(SM @ May 20 2009, 14:33)  А зачем делать так хитро, не проще ли просто задействовать предразведенный вход разрешения синхронной загрузки триггера? Который также не трогает цепей переноса, и позволяет прогрузить данное непосредственно со входа без инкремента? (привешиваю для понятности того, о чем речь, пример этой цепи из одного из семейств ПЛИСов) Вообще-то так (с мультиплексором до инкремента) даже проще получается,.. надо только привыкнуть (коэффициент для загрузки вычислять проще: Load_Data = 2^N - X, где N - разрядность счетчика, X - коэффициант деления этого счетчика). Цитата(Boris_TS @ May 20 2009, 14:14)  2. Описанная выше схема использует мою собственную библиотеку HardSyn. Эта библиотека имеет набор различных элементов оптимизированных под конкретные кристаллы (в приведенном примере для Xilinx Spartan-3x). У Xilinx несколько другое построение Logic Cell (там Slice'ы)... в которых нет SLOAD (LAB Wide), и поэтому приходиться делать именно так, как я описал. Но, собственно говоря, вопрос был про Jitter и работу на достаточно невысокой частоте. Мы же несколько отклонились от темы - как-то нехорошо получается.
|
|
|
|
|
May 20 2009, 18:30
|

Знающий
   
Группа: Свой
Сообщений: 601
Регистрация: 3-07-07
Пользователь №: 28 852

|
Всем спасибо за помощь и конструктивную критику. Я не делал никаких "assignment" - этот RTL  Квартус навалял с настройками по умолчанию. Цитата(Boris_TS @ May 19 2009, 18:25)  Нормальные люди используют выходной перенос (назовём его CY) загружаемого счетчика: сам CY подается на счетный триггер, сигнал с которого подается на дополнительный выходной триггер (обязательно выходной триггер, иначе дополнительный прирост jitter’а). Дополнительно CY подаётся на вход Load это загружаемого счётчика, а вот значением, которое загружается - выбирается количество тактов, которое счетчик будет досчитывать до переноса (т.е. коэффициент деления). Спасибо за совет! Теперь у меня есть реальный шанс стать нормальным человеком! Кажется таким образом в 51-м микроконтроллере счетчики реализованы. Цитата(SM @ May 20 2009, 00:34)  Ну да, в контексте конкретной задачи от автора поста самое оно, и десяток строк против килобайта текста. Моя же цель была слегка посложнее, и на частотах аццких. У меня аццких частот тут нет, всё по-божески. Цитата(dvladim @ May 20 2009, 00:12)  А если есть желание избавиться от джиттера ПЛИС, то надо вынести последний триггер за пределы ПЛИС. Очень здоровая мысль! Мне требуется маленький джиттер только на одном из фронтов, по другому фронту малый джиттер не интересен.
|
|
|
|
|
May 20 2009, 19:25
|
Знающий
   
Группа: Свой
Сообщений: 654
Регистрация: 24-01-07
Из: Воронеж
Пользователь №: 24 737

|
Цитата(SM @ May 20 2009, 00:34)  А я уверен. Если насильно register duplication не отключили, то если триггер не может туда лечь, то туда ложится копия этого триггера. Если отключили, то сами виноваты, констрейны это святое  Это смотря в каком случае. Если тактовый вход хитрый (формируется логикой), а глобальных линий не хватает, то не ляжет. И копия регистра не ляжет. Поэтому надо или знать арихитектуру и иметь опыт соответствующий или смотреть результаты трассировки. Цитата(sysel @ May 20 2009, 22:30)  Очень здоровая мысль! Мне требуется маленький джиттер только на одном из фронтов, по другому фронту малый джиттер не интересен. Джиттер на обойх фронтах будет примерно одинаковый. Здесь основной плюс в том, что джиттер не будет зависеть от прошики в ПЛИС, а только от выбранной схемы для последнего триггера, трассировки платы и разводки питания.
|
|
|
|
|
May 21 2009, 18:50
|
Местный
  
Группа: Свой
Сообщений: 368
Регистрация: 16-11-06
Из: Тверь
Пользователь №: 22 379

|
Цитата(des00 @ May 20 2009, 10:21)  т.к. описан самый оптимальный синхронный счетчик для фпга с 4-х входовым лютом А можно спросить в плане самообразования? - как я понял, увеличение быстродействия связано с изменением состояния счетчика на единицу (думаю не важно увеличение или уменьшение  ) - не нужен сумматор (довольно много логических связей), и момент достижения порога отлавливается внутренними средствами ячейки - перенос (не требуется компаратор)? Попутно - если описан компаратор, который сравнивает состояние регистра с нулем всегда будет использоваться бит переноса или иногда будет вставляться компаратор?
|
|
|
|
|
May 21 2009, 19:10
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(Andr2I @ May 21 2009, 22:50)  А можно спросить в плане самообразования? - как я понял, увеличение быстродействия связано с изменением состояния счетчика на единицу (думаю не важно увеличение или уменьшение  ) - не нужен сумматор (довольно много логических связей), и момент достижения порога отлавливается внутренними средствами ячейки - перенос (не требуется компаратор)? Попутно - если описан компаратор, который сравнивает состояние регистра с нулем всегда будет использоваться бит переноса или иногда будет вставляться компаратор? Чего-то Вы все в кучу смели. Увеличение быстродействия достигается за счет уменьшения разрядности сумматоров, и укорочения длины цепочек переноса исходя из компромиса между длиной цепочки переноса (она хоть и очень быстрая, но все же не с нулевой задержкой) и задержкой управления от соседнего LUT, конвейеризирующего перенос через локальную разводку. Увеличение на единицу делается тоже сумматором. Точнее цепочкой полусумматоров, но для ПЛИС разницы в данном случае особой нет. И в сумматоре, реализованном в ПЛИС, нет "довольно много логических связей", ПЛИСы (LUT-based) оптимизированы в первую очередь на построение сумматоров. В общем изучайте внутреннюю структуру ПЛИС, задержки по разным цепям... Анализируйте... Сравнение состояния регистра с любой константой, если требуется только равенство - это просто логическая функция всех его выходов. Сравнение с переменной величиной - это тот же сумматор между первой величиной и дополнением второй, выход переноса показывает < или >=. Равенство анализируется отдельно по нулевому результату выхода сумматора, т.е. логическому ИЛИ-НЕ всех его выходов.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|