Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: делитель частоты и джиттер
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
sysel
Здравствуйте!
Задача такова: имеется генератор с частотой 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=
Цитата(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
sysel
В своём вопросе я не конкретизировал джиттер. Я точно не могу его оценить, но думаю генератор даёт джиттер порядка <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 пс.
=AK=
Цитата(sysel @ May 19 2009, 14:54) *
Откуда такая информация?


Analog Devices AN-501


Цитата(sysel @ May 19 2009, 14:54) *
Как я понимаю, джиттер, который добавляет FPGA зависит в первую очередь не от кристалла, а от прошивки.

От кристалла. Значительная часть джиттера возникает за счет пологих фронтов на выходах и плавающего порога срабатывания по входам. Земля и питание внутри больших кристалллов сильно болтаются, поэтому пороги срабатывания FPGA плавают. А еще джиттера добавляет crosstalk. И т.д.
Boris_TS


Мдааа. Конечно, я с Cyclon 3 не работал, но визуально схема - отвратительная (на уровне начинающего):
1. Выходной триггер имеет обратную связь, в нормальных ПЛИС в IOB это не ложиться (или у Cyclon 3 нет выходных триггеров ?) - соответственно будет прирост jitter'а за счет передачи логического сигнала к выходному буферу (обычно clock распространяеста по ПЛИС с меньшим jitter'ом, чем все остальные сигналы).
2. Э-хе-хе... Кто ж так делитель делает ??! Нормальные люди используют выходной перенос (назовём его CY) загружаемого счетчика: сам CY подается на счетный триггер, сигнал с которого подается на дополнительный выходной триггер (обязательно выходной триггер, иначе дополнительный прирост jitter’а). Дополнительно CY подаётся на вход Load это загружаемого счётчика, а вот значением, которое загружается - выбирается количество тактов, которое счетчик будет досчитывать до переноса (т.е. коэффициент деления). Такая схема значительно компактнее и быстродейственней... если конечно суметь правильно сделать тот самый загружаемый счетчик.
SM
Цитата(Boris_TS @ May 19 2009, 18:25) *
1. Выходной триггер имеет обратную связь, в нормальных ПЛИС в IOB это не ложиться (или у Cyclon 3 нет выходных триггеров ?)

Как раз в нормальных ПЛИС это с легкостью ложится в IOE, так как обратная связь из IOE предусмотрена. Или ложится туда через register duplication (когда на вход регистра в IOE идет тот же сигнал, что и на вход регистра-копии в LE, что делается незаметно для разработчика при place/route).

Ну а в остальном, по архитектуре схемы, согласен.
Boris_TS
Цитата(SM @ May 19 2009, 17:33) *
Или ложится туда через register duplication (когда на вход регистра в IOE идет тот же сигнал, что и на вход регистра-копии в LE, что делается незаметно для разработчика при place/route).

Да есть такой метод (и очень хорошо помогает), но в данном случае это обязательное требование (наличие Output FF), поэтому, на мой взгляд, теневое register duplication не подходит - это надо делать в явном виде, а потом еще и проконтролировать, что после оптимизаций всё получилось как задумано.
SM
Цитата(Boris_TS @ May 19 2009, 20:47) *
теневое register duplication не подходит - это надо делать в явном виде

Так достаточен assignment "Fast Output Register = on" для выходного пина, что и будет тем самым "явным видом", и потом хоть контролируй, хоть нет, а гарантия того, что выходной регистр сидит в IOE 100%. А уж каким методом там это в результате оптимизаций сделано IMHO не важно, хоть дупликацией, хоть фидбеком с выхода IOE. То есть, что я имею в виду - если указан констрейн, что Fast Output Register, то он ляжет в IOE, и никаких гвоздей. Не может быть регистров, которые туда не ложатся (за исключением того, что слишком много регистров одновременно пытаются запихать)
sazh
Цитата(Boris_TS @ May 19 2009, 18:25) *
Нормальные люди используют выходной перенос (назовём его CY) загружаемого счетчика: сам CY подается на счетный триггер, сигнал с которого подается на дополнительный выходной триггер (обязательно выходной триггер, иначе дополнительный прирост jitter’а). Дополнительно CY подаётся на вход Load это загружаемого счётчика, а вот значением, которое загружается - выбирается количество тактов, которое счетчик будет досчитывать до переноса (т.е. коэффициент деления). Такая схема значительно компактнее и быстродейственней... если конечно суметь правильно сделать тот самый загружаемый счетчик.


Примерчик можно?
SM
Цитата(sazh @ May 19 2009, 22:04) *
Примерчик можно?


Я думаю, что речь о чем-то типа того:

Код
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
Цитата(SM @ May 19 2009, 22:25) *
Я думаю, что речь о чем-то типа того:


Счетчик впечатляет конечно.
Но речь ведь шла о выходном клоке. Самого интересного нет.
SM
Цитата(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", а кто-то пропускает через еще один триггер, указывая видимо констрейн уже ему, но это мелочи, не заслуживающие внимания.
sazh
Цитата(SM @ May 20 2009, 00:03) *
Для тех, кто в танке, повторяю кусок кода еще раз методом copy-paste:


Конечно, это не Корней Чуковский. Но все равно спасибо.
dvladim
Цитата(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

А если есть желание избавиться от джиттера ПЛИС, то надо вынести последний триггер за пределы ПЛИС.
SM
Цитата(dvladim @ May 20 2009, 00:12) *
Совсем не уверен. Если триггер не может туда лечь, он не ляжет, причем без предупреждений. (Altera, IMHO, проверять лениво)

А я уверен. Если насильно register duplication не отключили, то если триггер не может туда лечь, то туда ложится копия этого триггера. Если отключили, то сами виноваты, констрейны это святое wink.gif По крайней мере вышеприведенный ckg_reg_a ложится и в альтере (cyclone-ii), и в LatticeXP без каких либо противопоказаний.

Цитата(dvladim @ May 20 2009, 00:12) *
Я бы так:

Ну да, в контексте конкретной задачи от автора поста самое оно, и десяток строк против килобайта текста. Моя же цель была слегка посложнее, и на частотах аццких.
_Anatoliy
Цитата(SM @ May 19 2009, 21:34) *
Моя же цель была слегка посложнее, и на частотах аццких.


Можно поинтересоваться какой частоты удалось достичь?
Maverick
посмотрите это Может поможет
des00
Цитата(_Anatoliy @ May 19 2009, 22:52) *
Можно поинтересоваться какой частоты удалось достичь?


думаю что очень большой, т.к. описан самый оптимальный синхронный счетчик для фпга с 4-х входовым лютом

2 SM

я правильно понимаю при нечетных tckg_div_coeff скважность выходного сигнала не 50/50 ? и вас это устраивало?
SM
Цитата(_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-битный, можно еще наконвейеризировать.
Boris_TS
Цитата(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 со схемным редактором при смене версий тоже не всё гладко. А код на языке - он для всех версий одинаков (и можно после работы в более новой среде безболезненно возвращаться к предшествующим).
SM
Цитата(Boris_TS @ May 20 2009, 15:14) *
необычностью данного счетчика является то, что инкремент производиться всегда, а вход L задает что сейчас необходимо инкрементировать: текущее значение счетчика (L := '0'), или входные данные - D (L := '1'). Т.к. цепи переноса никогда не блокируются, а вся логика в каждом разряде использует только 1 LUT - то достигается предельно возможное быстродействие).


А зачем делать так хитро, не проще ли просто задействовать предразведенный вход разрешения синхронной загрузки триггера? Который также не трогает цепей переноса, и позволяет прогрузить данное непосредственно со входа без инкремента? (привешиваю для понятности того, о чем речь, пример этой цепи из одного из семейств ПЛИСов)
Boris_TS
Цитата(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 и работу на достаточно невысокой частоте. Мы же несколько отклонились от темы - как-то нехорошо получается.
SM
Цитата(Boris_TS @ May 20 2009, 16:10) *
Мы же несколько отклонились от темы - как-то нехорошо получается.

Ну просто по ходу дела возникают вопросы по предложенным схемам... Я просто интересуюсь нюансами построения, так как я любитель копания в железе до самого низкого уровня. Не думаю, чтобы это ыбло большим отвлечением, если речь про нюансы построения того, что по теме.
sysel
Всем спасибо за помощь и конструктивную критику.
Я не делал никаких "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) *
А если есть желание избавиться от джиттера ПЛИС, то надо вынести последний триггер за пределы ПЛИС.

Очень здоровая мысль! Мне требуется маленький джиттер только на одном из фронтов, по другому фронту малый джиттер не интересен.
dvladim
Цитата(SM @ May 20 2009, 00:34) *
А я уверен. Если насильно register duplication не отключили, то если триггер не может туда лечь, то туда ложится копия этого триггера. Если отключили, то сами виноваты, констрейны это святое wink.gif

Это смотря в каком случае. Если тактовый вход хитрый (формируется логикой), а глобальных линий не хватает, то не ляжет. И копия регистра не ляжет. Поэтому надо или знать арихитектуру и иметь опыт соответствующий или смотреть результаты трассировки.

Цитата(sysel @ May 20 2009, 22:30) *
Очень здоровая мысль! Мне требуется маленький джиттер только на одном из фронтов, по другому фронту малый джиттер не интересен.

Джиттер на обойх фронтах будет примерно одинаковый. Здесь основной плюс в том, что джиттер не будет зависеть от прошики в ПЛИС, а только от выбранной схемы для последнего триггера, трассировки платы и разводки питания.
atlantic
Похоже вопрос в неправильной ветке задан(надо к аналоговикам), если требуется джитер ~50ps, то никакая плис не подойдет. Как правило собственный минимальный джитер clk c PLL/DCM +-300ps, а что касается счетчиков, то вообще джитер не специфицируется.
SM
Цитата(dvladim @ May 20 2009, 23:25) *
надо или знать арихитектуру

Архитектуру надо знать прежде, чем начнешь работать с ПЛИСиной. Причем изучить очень внимательно. Это главное в нашем деле smile.gif
Andr2I
Цитата(des00 @ May 20 2009, 10:21) *
т.к. описан самый оптимальный синхронный счетчик для фпга с 4-х входовым лютом


А можно спросить в плане самообразования? - как я понял, увеличение быстродействия связано с изменением состояния счетчика на единицу (думаю не важно увеличение или уменьшение biggrin.gif ) - не нужен сумматор (довольно много логических связей), и момент достижения порога отлавливается внутренними средствами ячейки - перенос (не требуется компаратор)?
Попутно - если описан компаратор, который сравнивает состояние регистра с нулем всегда будет использоваться бит переноса или иногда будет вставляться компаратор?
SM
Цитата(Andr2I @ May 21 2009, 22:50) *
А можно спросить в плане самообразования? - как я понял, увеличение быстродействия связано с изменением состояния счетчика на единицу (думаю не важно увеличение или уменьшение biggrin.gif ) - не нужен сумматор (довольно много логических связей), и момент достижения порога отлавливается внутренними средствами ячейки - перенос (не требуется компаратор)?
Попутно - если описан компаратор, который сравнивает состояние регистра с нулем всегда будет использоваться бит переноса или иногда будет вставляться компаратор?

Чего-то Вы все в кучу смели.
Увеличение быстродействия достигается за счет уменьшения разрядности сумматоров, и укорочения длины цепочек переноса исходя из компромиса между длиной цепочки переноса (она хоть и очень быстрая, но все же не с нулевой задержкой) и задержкой управления от соседнего LUT, конвейеризирующего перенос через локальную разводку. Увеличение на единицу делается тоже сумматором. Точнее цепочкой полусумматоров, но для ПЛИС разницы в данном случае особой нет. И в сумматоре, реализованном в ПЛИС, нет "довольно много логических связей", ПЛИСы (LUT-based) оптимизированы в первую очередь на построение сумматоров. В общем изучайте внутреннюю структуру ПЛИС, задержки по разным цепям... Анализируйте...
Сравнение состояния регистра с любой константой, если требуется только равенство - это просто логическая функция всех его выходов. Сравнение с переменной величиной - это тот же сумматор между первой величиной и дополнением второй, выход переноса показывает < или >=. Равенство анализируется отдельно по нулевому результату выхода сумматора, т.е. логическому ИЛИ-НЕ всех его выходов.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.