Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Industrial programming >> VHDL

Cómo crear un temporizador en VHDL

En tutoriales anteriores hemos usado el wait for declaración para retrasar el tiempo en la simulación. Pero, ¿qué pasa con los módulos de producción? El wait for declaración no se puede utilizar para eso. Eso solo funciona en la simulación porque no podemos simplemente decirles a los electrones en un circuito que se detengan por un tiempo determinado. Entonces, ¿cómo podemos hacer un seguimiento del tiempo en un módulo de diseño?

La respuesta es simplemente contar ciclos de reloj. Todo diseño digital tiene acceso a una señal de reloj que oscila a una frecuencia fija y conocida. Por lo tanto, si sabemos que la frecuencia del reloj es de 100 MHz, podemos medir un segundo contando cien millones de ciclos de reloj.

Esta publicación de blog es parte de la serie Tutoriales básicos de VHDL.

Para contar segundos en VHDL, podemos implementar un contador que cuente la cantidad de períodos de reloj que pasan. Cuando este contador alcanza el valor de la frecuencia del reloj, 100 millones por ejemplo, sabemos que ha pasado un segundo y es hora de incrementar otro contador. Llamemos a esto el contador de segundos.

Para contar los minutos, podemos implementar otro contador de minutos que se incremente cuando hayan pasado 60 segundos. Del mismo modo, podemos crear un contador de horas para contar las horas, aumentando cuando hayan pasado 60 minutos.

Podemos continuar con este enfoque para contar días, semanas y meses también. Estamos limitados por los recursos físicos disponibles en la tecnología subyacente, así como por la longitud del contador frente a la frecuencia del reloj.

A medida que aumenta la longitud de los contadores, obviamente consume más recursos. Pero también reaccionará más lentamente porque la cadena de eventos se vuelve más larga.

Ejercicio

En este video tutorial aprenderemos a crear un módulo de temporizador en VHDL:

El código final para el temporizador 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;

El código final para el módulo del temporizador :

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;

La forma de onda se acercó al Seconds señal:

La forma de onda ampliada en el Minutes señal:

La forma de onda se acercó al Hours señal:

Análisis

Para ejecutar una simulación de 50 horas, le dimos el comando run 50 hr en la consola de ModelSim. Cincuenta horas es una simulación realmente larga y, por lo tanto, tuvimos que bajar la frecuencia del reloj en el banco de pruebas a 10 Hz. Si lo hubiéramos dejado a 100 MHz, la simulación hubiera tardado días. Tales adaptaciones a veces son necesarias para permitirnos simular un diseño.

Hicimos clic derecho en la línea de tiempo en la forma de onda y seleccionamos "Grid, Timeline &Cursor Control". Al cambiar la unidad de tiempo de ns a segundos, minutos y horas, pudimos ver que el temporizador estaba funcionando en tiempo real.

El tiempo del temporizador está ligeramente desplazado del tiempo de simulación debido al reinicio del módulo al comienzo de la simulación. Es visible en la primera forma de onda donde la marca de 60 segundos en la línea de tiempo está un poco antes cuando la señal de segundos llega a 0.

Tenga en cuenta que en la simulación, los valores del contador se actualizan en tiempo cero en el flanco ascendente del reloj. En el mundo real, el valor del contador necesitará algún tiempo para propagarse desde el primer bit del contador hasta el último. A medida que aumentamos la longitud de los contadores, consumimos del tiempo disponible de un período de reloj.

Si la longitud acumulada de todos los contadores en cascada se vuelve demasiado larga, se producirá un error en el paso de lugar y ruta después de la compilación. La duración de un contador que puede implementar antes de consumir todo el período del reloj depende de la arquitectura FPGA o ASIC y la velocidad del reloj.

Una mayor velocidad de reloj significa que la cadena del contador será más larga. También significa que el período de tiempo del reloj será más corto, lo que le dará a la cadena de contadores aún menos tiempo para completarse.

Para llevar

Ir al siguiente tutorial »


VHDL

  1. Cómo crear una lista de cadenas en VHDL
  2. Cómo crear un banco de pruebas controlado por Tcl para un módulo de bloqueo de código VHDL
  3. Cómo detener la simulación en un banco de pruebas VHDL
  4. Cómo crear un controlador PWM en VHDL
  5. Cómo generar números aleatorios en VHDL
  6. Cómo crear un FIFO de búfer de anillo en VHDL
  7. Cómo crear un banco de pruebas de autocomprobación
  8. Cómo crear una lista enlazada en VHDL
  9. Cómo usar un procedimiento en un proceso en VHDL
  10. Cómo usar una función impura en VHDL
  11. Cómo usar una función en VHDL