Создание делителя частоты в VHDL - PullRequest
1 голос
/ 07 июня 2011

ОСНОВНЫЕ РЕДАКТИРОВАТЬ:

Проблема была решена после прочтения комментария Уилла Дина. Оригинальный вопрос ниже пересмотренного кода:

-- REVISED CODE (NOW WORKS)
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

entity CLOCK_DIVIDER is
    port(
        reset   :   in std_logic;
        clk :   in std_logic;
        half_clk    :   out std_logic
        );
end CLOCK_DIVIDER;


architecture CLOCK_DIVIDER of CLOCK_DIVIDER is
signal tick : std_logic;

begin

    process(clk, reset)
    begin
        if reset = '1' then
            tick <= '0';
        elsif clk = '1' and clk'EVENT then
            if tick = '0' then
                tick <= '1';
            elsif tick = '1' then
                tick <= '0';
            end if;
        end if;
    end process;

    process(tick)
    begin
        half_clk <= tick;
    end process

end CLOCK_DIVIDER;

Синтезированный логический блок пересмотренного кода представляет собой одиночный DFF с асинхронным сбросом, который принимает half_clk в качестве вывода и инвертированный half_clk в качестве ввода, что означает, что значение half_clk изменяется на каждом переднем фронте clk.

Спасибо, Уилл Дин:)

==== ==== ==== ==== ====

Оригинальный вопрос ниже:

==== ==== ==== ==== ====

Мне нужен простой делитель часов (просто делим на два), и вместо того, чтобы использовать шаблон, я подумал, что попытаюсь написать его самостоятельно, чтобы продолжать обучение.

К сожалению, синтезированный логический блок не работает - я представляю логический блок и код (который, я думаю, должен работать), в таком порядке.

логический блок http://img808.imageshack.us/img808/3333/unledly.png

Что мне действительно интересно, так это то, что у дьявола с "тиковым" DFF - он, очевидно, берет свой вклад от селектора мультиплексора, который ... Да.

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

entity CLOCK_DIVIDER is
    port(
        reset   :   in std_logic;
        clk :   in std_logic;
        half_clk    :   out std_logic
        );
end CLOCK_DIVIDER;


architecture CLOCK_DIVIDER of CLOCK_DIVIDER is
signal tick : std_logic;

begin
    process(clk, reset)
    begin
        if reset = '1' then
            half_clk <= '0';
            tick <= '0';
        elsif clk = '1' and clk'EVENT then
            if tick = '0' then
                half_clk <= '0';
                tick <= '1';
            elsif tick = '1' then
                half_clk <= '1';
                tick <= '0';
            end if;
        end if;
    end process;
end CLOCK_DIVIDER;

Я уверен, что ошибка в коде очевидна, но я слепо пытался ее найти.

Ответы [ 4 ]

3 голосов
/ 07 июня 2011

Если halfclk должен использоваться в качестве разрешения, а не настоящих часов, не обращайте внимания на этот совет ...

Если это для цели FPGA, а "half_clk" действительно используетсяиспользуется в качестве часов (например, идет к выводу часов на DFF, а не к выводу включения) ... Не делайте этого .

Создание производных часов с использованием общей логики FPGA /fabic приведет к проблемам со средствами сборки и может в конечном итоге привести к сбоям сборки (не будет соответствовать времени) или сборкам, которые не будут работать так, как ожидалось, поскольку ограничения неправильно переданы во все сети синхронизации.

Вместо этогоИспользуйте блоки управления часами, которые встроены в матрицу ПЛИС специально для этой цели.В мире запчастей Xilinx они называются цифровыми тактовыми менеджерами (DCM) или смешанными режимами диспетчеров синхронизации (MMCM).Я не уверен, что эквивалентный компонент Altera.Ознакомьтесь с документацией, чтобы определить оптимальное использование для вашего приложения.

1 голос
/ 10 июня 2011

На основании вашего пересмотренного кода я предлагаю эту модификацию архитектуры:

-- REVISED CODE (NOW WORKS) and simplified and synthesisable
architecture CLOCK_DIVIDER of CLOCK_DIVIDER is
    signal tick : std_logic;
begin
    process(clk, reset)
    begin
        if reset = '1' then
            tick <= '0';
        elsif rising_edge(clk) then -- use of rising_edge() is the correct idiom these days
            tick <= not tick;
        end if;
    end process;

    half_clk <= tick;
end CLOCK_DIVIDER;

Я удалил этот процесс и заменил параллельным назначением:

    process(tick)
    begin
        half_clk <= tick;
    end process

так как то, что он запрашивает, это триггер с обоими краями tick.

Будет казаться, что вы достигаете того, что вы хотите, с точки зрения того, что формы сигналов покачиваются так, как вы хотите, но не синтезируют. Это также добавляет дополнительную дельта-задержку к выходу, которая может или не может вызвать проблемы, если вы используете его как часы «в будущем». Как прокомментировали другие, в большинстве архитектур это не очень хороший план (но для некоторых это «правильный путь»).

0 голосов
/ 17 ноября 2011

Простой счетчик делает свое дело (конечно, DCM):

signal cnt : std_logic_vector(3 downto 0);

...

clk_div_2  <= cnt(0);
clk_div_4  <= cnt(1);
clk_div_8  <= cnt(2);
clk_div_16 <= cnt(3);

...

process(clk)
 if clk'event and clk = '1' then
  cnt <= cnt + 1;
 end if;
end process;
0 голосов
/ 07 июня 2011

Вы уверены, что сбрасываете при запуске?То, как вы определили условие для тика, ничего не произойдет, если тик не равен нулю или единице (т. Е. Это может быть U, Z, X и т. Д.).

Я обычно рекомендую охватить все случаис вашими условными выражениями, например:

        if tick = '0' then
            half_clk <= '0';
            tick <= '1';
        else 
            half_clk <= '1';
            tick <= '0';
        end if;

или

        if tick = '0' then
            half_clk <= '0';
            tick <= '1';
        elsif tick = '1' then
            half_clk <= '1';
            tick <= '0';
        else
            -- Throw error or something here
        end if;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...