sysel 0 18 мая, 2009 Опубликовано 18 мая, 2009 · Жалоба Здравствуйте! Задача такова: имеется генератор с частотой 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) ПЛИС и джиттер - как они вообще связаны. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=AK= 12 19 мая, 2009 Опубликовано 19 мая, 2009 · Жалоба (разумеется, джиттер меньше чем N пс получить не выйдет. Почему же? В принципе это возможно. Любая PLL работает как jitter cleaner. Она фильтрует джиттер с частотами выше, чем частота фильтра в петле обратной связи PLL. Если у входного клока безумно большой и высокочастотный джиттер, то Циклоновская PLL может его почистить. 3) ПЛИС и джиттер - как они вообще связаны. Помнится, Альтера не гарантирует, что джиттер на выходе Циклона будет меньше чем 150 пс. Сравните типичные цифры джиттера, которую добавляет логика разного типа: ------------------------------------------------ тип jitter, ps rms ------------------------------------------------ FPGA 33 to 50 74LS00 5 74HCT00 2.2 74ACT00 1 MC100EL16 (PECL) 0.7 NBSG16 (ECL) 0.2 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sysel 0 19 мая, 2009 Опубликовано 19 мая, 2009 · Жалоба В своём вопросе я не конкретизировал джиттер. Я точно не могу его оценить, но думаю генератор даёт джиттер порядка <30 пикосекунд. Если у входного клока безумно большой и высокочастотный джиттер, то Циклоновская PLL может его почистить. Если говорить о циклоновской PLL - то она добавит джиттера. Помнится, Альтера не гарантирует, что джиттер на выходе Циклона будет меньше чем 150 пс. Сравните типичные цифры джиттера, которую добавляет логика разного типа: ------------------------------------------------ тип 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 пс. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=AK= 12 19 мая, 2009 Опубликовано 19 мая, 2009 · Жалоба Откуда такая информация? Analog Devices AN-501 Как я понимаю, джиттер, который добавляет FPGA зависит в первую очередь не от кристалла, а от прошивки. От кристалла. Значительная часть джиттера возникает за счет пологих фронтов на выходах и плавающего порога срабатывания по входам. Земля и питание внутри больших кристалллов сильно болтаются, поэтому пороги срабатывания FPGA плавают. А еще джиттера добавляет crosstalk. И т.д. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Beby 5 19 мая, 2009 Опубликовано 19 мая, 2009 · Жалоба Мдааа. Конечно, я с Cyclon 3 не работал, но визуально схема - отвратительная (на уровне начинающего): 1. Выходной триггер имеет обратную связь, в нормальных ПЛИС в IOB это не ложиться (или у Cyclon 3 нет выходных триггеров ?) - соответственно будет прирост jitter'а за счет передачи логического сигнала к выходному буферу (обычно clock распространяеста по ПЛИС с меньшим jitter'ом, чем все остальные сигналы). 2. Э-хе-хе... Кто ж так делитель делает ??! Нормальные люди используют выходной перенос (назовём его CY) загружаемого счетчика: сам CY подается на счетный триггер, сигнал с которого подается на дополнительный выходной триггер (обязательно выходной триггер, иначе дополнительный прирост jitter’а). Дополнительно CY подаётся на вход Load это загружаемого счётчика, а вот значением, которое загружается - выбирается количество тактов, которое счетчик будет досчитывать до переноса (т.е. коэффициент деления). Такая схема значительно компактнее и быстродейственней... если конечно суметь правильно сделать тот самый загружаемый счетчик. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 19 мая, 2009 Опубликовано 19 мая, 2009 · Жалоба 1. Выходной триггер имеет обратную связь, в нормальных ПЛИС в IOB это не ложиться (или у Cyclon 3 нет выходных триггеров ?) Как раз в нормальных ПЛИС это с легкостью ложится в IOE, так как обратная связь из IOE предусмотрена. Или ложится туда через register duplication (когда на вход регистра в IOE идет тот же сигнал, что и на вход регистра-копии в LE, что делается незаметно для разработчика при place/route). Ну а в остальном, по архитектуре схемы, согласен. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Beby 5 19 мая, 2009 Опубликовано 19 мая, 2009 · Жалоба Или ложится туда через register duplication (когда на вход регистра в IOE идет тот же сигнал, что и на вход регистра-копии в LE, что делается незаметно для разработчика при place/route). Да есть такой метод (и очень хорошо помогает), но в данном случае это обязательное требование (наличие Output FF), поэтому, на мой взгляд, теневое register duplication не подходит - это надо делать в явном виде, а потом еще и проконтролировать, что после оптимизаций всё получилось как задумано. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 19 мая, 2009 Опубликовано 19 мая, 2009 · Жалоба теневое register duplication не подходит - это надо делать в явном виде Так достаточен assignment "Fast Output Register = on" для выходного пина, что и будет тем самым "явным видом", и потом хоть контролируй, хоть нет, а гарантия того, что выходной регистр сидит в IOE 100%. А уж каким методом там это в результате оптимизаций сделано IMHO не важно, хоть дупликацией, хоть фидбеком с выхода IOE. То есть, что я имею в виду - если указан констрейн, что Fast Output Register, то он ляжет в IOE, и никаких гвоздей. Не может быть регистров, которые туда не ложатся (за исключением того, что слишком много регистров одновременно пытаются запихать) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sazh 3 19 мая, 2009 Опубликовано 19 мая, 2009 · Жалоба Нормальные люди используют выходной перенос (назовём его CY) загружаемого счетчика: сам CY подается на счетный триггер, сигнал с которого подается на дополнительный выходной триггер (обязательно выходной триггер, иначе дополнительный прирост jitter’а). Дополнительно CY подаётся на вход Load это загружаемого счётчика, а вот значением, которое загружается - выбирается количество тактов, которое счетчик будет досчитывать до переноса (т.е. коэффициент деления). Такая схема значительно компактнее и быстродейственней... если конечно суметь правильно сделать тот самый загружаемый счетчик. Примерчик можно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 19 мая, 2009 Опубликовано 19 мая, 2009 · Жалоба Примерчик можно? Я думаю, что речь о чем-то типа того: reg [2:0] tckg_prediv; reg tckg_en; reg [11:0] tckg_div_coeff; reg [10:0] tckg_coeff_a, tckg_coeff_b, tckg_coeff; reg [10:0] tckg_cnt; reg tckg_cnt_z; reg ckg_reg_a; // coefficient for even halfwave always @(posedge tckg_clk) tckg_coeff_b <= tckg_div_coeff[11:1] + tckg_div_coeff[0]; // coefficient for odd halfwave always @(posedge tckg_clk) tckg_coeff_a <= tckg_div_coeff[11:1]; // additional optional pre-divider with enable (control[7]) always @(posedge tckg_clk) tckg_prediv <= control[7] ? (tckg_prediv + 1'b1) : 3'h0; // pre-divider zero pass always @(posedge tckg_clk) tckg_en <= !(|tckg_prediv); // main divider zero pass always @(posedge tckg_clk) tckg_cnt_z <= tckg_cnt == 11'h001; // 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; // coefficient mux for even/odd halfwaves always @(posedge tckg_clk) if (tckg_en && tckg_cnt_z) tckg_coeff <= ckg_reg_a ? tckg_coeff_b : tckg_coeff_a; // carry pipeline for main divider reg [1:0] cntc; always @(posedge tckg_clk) if (tckg_en) begin cntc[0] <= tckg_cnt[3:0] == 4'h1; cntc[1] <= tckg_cnt[7:0] == 8'h1; end // main divider itself always @(posedge tckg_clk) if (tckg_en) if (tckg_cnt_z) tckg_cnt <= tckg_coeff; else begin tckg_cnt[3:0] <= tckg_cnt[3:0] - 1'b1; tckg_cnt[7:4] <= tckg_cnt[7:4] - cntc[0]; tckg_cnt[10:8] <= tckg_cnt[10:8] - cntc[1]; end Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sazh 3 19 мая, 2009 Опубликовано 19 мая, 2009 · Жалоба Я думаю, что речь о чем-то типа того: Счетчик впечатляет конечно. Но речь ведь шла о выходном клоке. Самого интересного нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 19 мая, 2009 Опубликовано 19 мая, 2009 · Жалоба Но речь ведь шла о выходном клоке. Самого интересного нет. Для тех, кто в танке, повторяю кусок кода еще раз методом 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", а кто-то пропускает через еще один триггер, указывая видимо констрейн уже ему, но это мелочи, не заслуживающие внимания. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sazh 3 19 мая, 2009 Опубликовано 19 мая, 2009 · Жалоба Для тех, кто в танке, повторяю кусок кода еще раз методом copy-paste: Конечно, это не Корней Чуковский. Но все равно спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dvladim 0 19 мая, 2009 Опубликовано 19 мая, 2009 · Жалоба То есть, что я имею в виду - если указан констрейн, что Fast Output Register, то он ляжет в IOE, и никаких гвоздей. Не может быть регистров, которые туда не ложатся (за исключением того, что слишком много регистров одновременно пытаются запихать) Совсем не уверен. Если триггер не может туда лечь, он не ляжет, причем без предупреждений. (Altera, IMHO, проверять лениво) Я думаю, что речь о чем-то типа того: Более чем впечатляет. Я бы так: always @(posedge clk) begin if (counter == 3'b0) begin out <= ~out; counter <= (divider[3:1] - 1'b1); end else counter <= counter - 1'b1; end А если есть желание избавиться от джиттера ПЛИС, то надо вынести последний триггер за пределы ПЛИС. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 19 мая, 2009 Опубликовано 19 мая, 2009 · Жалоба Совсем не уверен. Если триггер не может туда лечь, он не ляжет, причем без предупреждений. (Altera, IMHO, проверять лениво) А я уверен. Если насильно register duplication не отключили, то если триггер не может туда лечь, то туда ложится копия этого триггера. Если отключили, то сами виноваты, констрейны это святое ;) По крайней мере вышеприведенный ckg_reg_a ложится и в альтере (cyclone-ii), и в LatticeXP без каких либо противопоказаний. Я бы так: Ну да, в контексте конкретной задачи от автора поста самое оно, и десяток строк против килобайта текста. Моя же цель была слегка посложнее, и на частотах аццких. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться