Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial programming >> VHDL

Как создать таймер в VHDL

В предыдущих уроках мы использовали wait for оператор для задержки времени в моделировании. А как же производственные модули? wait for оператор не может быть использован для этого. Это работает только в моделировании, потому что мы не можем просто сказать электронам в цепи остановиться на заданное время. Итак, как мы можем отслеживать время в модуле дизайна?

Ответ заключается в простом подсчете тактов. Каждый цифровой дизайн имеет доступ к тактовому сигналу, который колеблется с фиксированной известной частотой. Следовательно, если мы знаем, что тактовая частота составляет 100 МГц, мы можем измерить одну секунду, сосчитав сто миллионов тактовых циклов.

Эта запись в блоге является частью серии учебных пособий по основам VHDL.

Для подсчета секунд в VHDL мы можем реализовать счетчик, который подсчитывает количество прошедших тактов. Когда этот счетчик достигает значения тактовой частоты, например 100 миллионов, мы знаем, что прошла секунда и пришло время увеличить другой счетчик. Назовем это счетчиком секунд.

Для подсчета минут мы можем реализовать еще один счетчик минут, который увеличивается по прошествии 60 секунд. Точно так же мы можем создать счетчик часов для подсчета часов, который увеличивается по истечении 60 минут.

Мы можем продолжить этот подход и для подсчета дней, недель и месяцев. Мы ограничены доступными физическими ресурсами базовой технологии, а также длиной счетчика по сравнению с тактовой частотой.

По мере увеличения длины счетчиков, очевидно, потребляется больше ресурсов. Но он также будет реагировать медленнее, потому что цепочка событий становится длиннее.

Упражнение

В этом видеоуроке мы узнаем, как создать модуль таймера на VHDL:

Окончательный код таймера testbench :

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity T18_TimerTb is
end entity;

architecture sim of T18_TimerTb is

    -- We're slowing down the clock to speed up simulation time
    constant ClockFrequencyHz : integer := 10; -- 10 Hz
    constant ClockPeriod      : time := 1000 ms / ClockFrequencyHz;

    signal Clk     : std_logic := '1';
    signal nRst    : std_logic := '0';
    signal Seconds : integer;
    signal Minutes : integer;
    signal Hours   : integer;

begin

    -- The Device Under Test (DUT)
    i_Timer : entity work.T18_Timer(rtl)
    generic map(ClockFrequencyHz => ClockFrequencyHz)
    port map (
        Clk     => Clk,
        nRst    => nRst,
        Seconds => Seconds,
        Minutes => Minutes,
        Hours   => Hours);

    -- Process for generating the clock
    Clk <= not Clk after ClockPeriod / 2;

    -- Testbench sequence
    process is
    begin
        wait until rising_edge(Clk);
        wait until rising_edge(Clk);

        -- Take the DUT out of reset
        nRst <= '1';

        wait;
    end process;

end architecture;

Окончательный код для модуля таймера :

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity T18_Timer is
generic(ClockFrequencyHz : integer);
port(
    Clk     : in std_logic;
    nRst    : in std_logic; -- Negative reset
    Seconds : inout integer;
    Minutes : inout integer;
    Hours   : inout integer);
end entity;

architecture rtl of T18_Timer is

    -- Signal for counting clock periods
    signal Ticks : integer;

begin

    process(Clk) is
    begin
        if rising_edge(Clk) then

            -- If the negative reset signal is active
            if nRst = '0' then
                Ticks   <= 0;
                Seconds <= 0;
                Minutes <= 0;
                Hours   <= 0;
            else

                -- True once every second
                if Ticks = ClockFrequencyHz - 1 then
                    Ticks <= 0;

                    -- True once every minute
                    if Seconds = 59 then
                        Seconds <= 0;

                        -- True once every hour
                        if Minutes = 59 then
                            Minutes <= 0;

                            -- True once a day
                            if Hours = 23 then
                                Hours <= 0;
                            else
                                Hours <= Hours + 1;
                            end if;

                        else
                            Minutes <= Minutes + 1;
                        end if;

                    else
                        Seconds <= Seconds + 1;
                    end if;

                else
                    Ticks <= Ticks + 1;
                end if;

            end if;
        end if;
    end process;

end architecture;

Форма сигнала увеличена на Seconds сигнал:

Форма сигнала увеличена на Minutes сигнал:

Форма волны увеличена на Hours сигнал:

Анализ

Чтобы запустить 50-часовую симуляцию, мы дали команду run 50 hr в консоли ModelSim. Пятьдесят часов — это очень долгая симуляция, и поэтому нам пришлось понизить тактовую частоту в тестовом стенде до 10 Гц. Если бы мы оставили его на частоте 100 МГц, симуляция заняла бы дни. Такие адаптации иногда необходимы, чтобы мы могли смоделировать дизайн.

Мы щелкнули правой кнопкой мыши временную шкалу в форме волны и выбрали «Сетка, временная шкала и управление курсором». При изменении единицы измерения времени с нс на секунды, минуты и часы мы могли видеть, что таймер действительно работает в режиме реального времени.

Время таймера немного смещено от времени моделирования из-за сброса модуля в начале моделирования. Это видно на первой осциллограмме, где 60-секундная отметка на временной шкале находится немного раньше, чем сигнал секунд переходит в 0.

Обратите внимание, что в моделировании значения счетчика обновляются в нулевое время на нарастающем фронте часов. В реальном мире значению счетчика потребуется некоторое время, чтобы распространиться от первого бита счетчика к последнему. Поскольку мы увеличиваем длину счетчиков, мы потребляем доступное время тактового периода.

Если суммарная длина всех каскадных счетчиков станет слишком большой, после компиляции на шаге места и маршрута будет выдана ошибка. Как долго вы можете реализовать счетчик, прежде чем использовать весь тактовый период, зависит от архитектуры FPGA или ASIC и тактовой частоты.

Повышенная тактовая частота означает, что цепь счетчика будет длиннее. Это также означает, что период времени будет короче, что даст цепочке счетчиков еще меньше времени для завершения.

Вывод

Перейти к следующему руководству »


VHDL

  1. Как создать список строк в VHDL
  2. Как создать управляемый Tcl тестовый стенд для модуля кодовой блокировки VHDL
  3. Как остановить симуляцию в тестовом стенде VHDL
  4. Как создать ШИМ-контроллер на VHDL
  5. Как генерировать случайные числа в VHDL
  6. Как создать кольцевой буфер FIFO в VHDL
  7. Как создать самопроверяющийся тестовый стенд
  8. Как создать связанный список в VHDL
  9. Как использовать процедуру в процессе в VHDL
  10. Как использовать функцию в VHDL