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

Generar ejemplo de inhibidor de extractos

La declaración de generación en VHDL puede duplicar automáticamente un bloque de código para cierres con señales, procesos e instancias idénticas. Es un bucle for para la región de la arquitectura que puede crear procesos encadenados o instancias de módulos.

A diferencia de un bucle for regular, que solo puede existir en un proceso o un subprograma, la declaración de generación se coloca directamente en la región de arquitectura del archivo VHDL. Cuando se usa junto con los genéricos, se convierte en una poderosa herramienta para diseñar módulos VHDL personalizables que permiten la reutilización entre diseños.

Generar sintaxis de declaraciones

La sintaxis de la declaración de generación es la siguiente:

[label :] for <constant_name> in <range> generate
  [declarations_local_to_each_loop_iteration]
[begin]
  <processes_and_instantiations>
end generate [label];

Las partes encerradas entre corchetes son opcionales. Por lo tanto, puede omitir la región declarativa y el begin palabra clave si no desea declarar ningún objeto local. El el marcador de posición representa un rango de enteros estándar usando to o downto .

Antirrebote de interruptor de un bit

Antes de comenzar con la declaración de generación, presentaré un módulo simple que usaremos como ejemplo a lo largo de este artículo. Es un antirrebote capaz de eliminar el rebote de una sola entrada de interruptor.

Para que se pueda usar a cualquier velocidad de reloj, agregué una entrada genérica llamada timeout_cycles . Esta constante especifica cuántos ciclos de reloj será el tiempo de espera después de que cambie la entrada del interruptor. El antirrebote ignorará cualquier cambio adicional en el valor del interruptor durante el período de tiempo de espera.

La siguiente lista muestra la entidad del antirrebote módulo. Hay un interruptor que rebota entrada, y luego está el limpio switch_debounced salida.

entity debouncer is
  generic (
    timeout_cycles : positive
    );
  port (
    clk : in std_logic;
    rst : in std_logic;
    switch : in std_logic;
    switch_debounced : out std_logic
  );
end debouncer;

El módulo antirrebote se basa en un contador de enteros para lograr el período de tiempo de espera. La longitud del contador la señal sigue a la constante genérica. Eso es lo que hace la duración del tiempo de espera especificado durante la instanciación.

Porque necesitamos leer el valor de switch_debounced salida interna, he declarado una señal de sombra llamada rebotada , que usaremos en su lugar. Esa es una solución más limpia que la otra opción, que es establecer inout modo en switch_debounce en la entidad.

Finalmente, implementamos el comportamiento antirrebote en un solo proceso, como se muestra en el código a continuación.

architecture rtl of debouncer is

  signal debounced : std_logic;
  signal counter : integer range 0 to timeout_cycles - 1;

begin

  -- Copy internal signal to output
  switch_debounced <= debounced;

  DEBOUNCE_PROC : process(clk)
  begin
    if rising_edge(clk) then
      if rst = '1' then
        counter <= 0;
        debounced <= switch;
        
      else
        
        if counter < timeout_cycles - 1 then
          counter <= counter + 1;
        elsif switch /= debounced then
          counter <= 0;
          debounced <= switch;
        end if;

      end if;
    end if;
  end process;

end architecture;

La siguiente forma de onda muestra una simulación del rebote módulo en ModelSim. Podemos ver que el switch_debounced la salida sigue al interruptor entrada, pero ignora el comportamiento de rebote inmediato después del primer cambio:elimina el rebote de la señal.

Utilice el siguiente formulario para descargar el código VHDL de este artículo. Cuando ingrese su dirección de correo electrónico, recibirá un archivo Zip que contiene todo el proyecto ModelSim con bancos de prueba y un script de ejecución rápida. Recibirá futuras actualizaciones de VHDLwhiz y puede darse de baja en cualquier momento.

Generar bucle for con instanciaciones

Para crear un antirrebote para una serie de conmutadores, vamos a utilizar una declaración de generación para crear varias instancias de nuestro módulo antirrebote de un bit.

La siguiente lista muestra la entidad de nuestro nuevo módulo antirrebote de matriz o vector. Es similar al antirrebote de un bit, pero hay una entrada genérica adicional:switch_count . Especifica cuántas instancias del módulo antirrebote se deben crear. Debería haber uno para cada interruptor.

Además, he cambiado el nombre de la entrada y salida del interruptor a las versiones plurales de la palabra, y ahora son vectores en lugar de bits individuales.

entity debouncer_gen_inst is
  generic (
    switch_count : positive;
    timeout_cycles : positive
    );
  port (
    clk : in std_logic;
    rst : in std_logic;
    switches : in std_logic_vector(switch_count - 1 downto 0);
    switches_debounced : out std_logic_vector(switch_count - 1 downto 0)
  );
end debouncer_gen_inst;

En la arquitectura, es hora de usar la declaración de generación. Funciona como un bucle for regular, solo que con la palabra "generar" reemplazando la palabra "bucle". Pero a diferencia de un bucle for regular, puede contener instancias de módulos.

El bucle for se ejecuta en tiempo de compilación y genera una instancia del módulo antirrebote para cada iteración. Pero debido a que la constante "i" será diferente para cada iteración, podemos usarla para asignar las entradas y salidas de los antirrebotes a bits individuales en los vectores de interruptores, como se muestra a continuación.

architecture rtl of debouncer_gen_inst is
begin

  MY_GEN : for i in 0 to switch_count - 1 generate

    DEBOUNCER : entity work.debouncer(rtl)
    generic map (
      timeout_cycles => timeout_cycles
    )
    port map (
      clk => clk,
      rst => rst,
      switch => switches(i),
      switch_debounced => switches_debounced(i)
    );

  end generate;

end architecture;

Tenga en cuenta que es opcional etiquetar la declaración de generación, pero puede ser conveniente hacerlo. La etiqueta aparece en la jerarquía del simulador y el registro de síntesis, lo que facilita la identificación de la instancia específica durante la depuración.

La siguiente forma de onda muestra una simulación del vector antirrebote. Podemos ver que la etiqueta "MY_GEN" vuelve a aparecer aquí, con índices agregados para cada una de las ocho instancias de antirrebote.

Este banco de pruebas solo cambia la entrada del interruptor número 3, eso es lo que ve en la forma de onda y por qué he expandido solo el grupo MY_GEN(3).

Puede ejecutar rápidamente este ejemplo en su computadora si tiene instalado ModelSim. ¡Utilice el siguiente formulario para descargar el código fuente y el proyecto ModelSim!

Generar procesos que contienen bucles

En el último ejemplo de este artículo, usaremos una declaración de generación para realizar una serie de procesos idénticos. En lugar de crear instancias del módulo antirrebote de un bit, le quité el código VHDL. La entidad es la misma que en el ejemplo anterior, al igual que el comportamiento, pero la implementación es diferente.

Podemos ver que moví el proceso DEBOUNCE_PROC dentro de la declaración de generación y lo cambié ligeramente en el código a continuación. Esta vez estoy declarando dos señales locales dentro de la declaración de generación:rebotado y contador .

Cada iteración del ciclo for creará una copia adicional de las señales y el proceso. El uso de estos nombres de señal dentro del proceso hará referencia a los que se encuentran dentro del alcance de esa iteración de bucle específica.

Finalmente, estoy asignando el recuperado std_logic señal al bit correcto de switches_debounced salida del módulo usando una declaración concurrente sobre el proceso.

architecture rtl of debouncer_gen_proc is
begin

  MY_GEN : for i in 0 to switch_count - 1 generate

    signal debounced : std_logic;
    signal counter : integer range 0 to timeout_cycles - 1;

  begin

    switches_debounced(i) <= debounced;

    DEBOUNCE_PROC : process(clk)
    begin
      if rising_edge(clk) then
        if rst = '1' then
          counter <= 0;
          debounced <= switches(i);

        else

          if counter < timeout_cycles - 1 then
            counter <= counter + 1;
          elsif switches(i) /= debounced then
            counter <= 0;
            debounced <= switches(i);
          end if;

        end if;
      end if;
    end process;

  end generate;

end architecture;

Omití la forma de onda de la simulación porque se ve exactamente igual que en el ejemplo anterior usando la creación de instancias del módulo. El comportamiento es idéntico.

Puede descargar todo el código utilizando el siguiente formulario. Cuando ingresa su dirección de correo electrónico, se suscribe a las actualizaciones de VHDLwhiz. Pero no te preocupes, hay un enlace para cancelar la suscripción en cada correo electrónico que envío.

¡Deje un comentario a continuación si tiene otra aplicación útil para generar declaraciones para compartir! ?


VHDL

  1. Declaración de procedimiento:ejemplo de VHDL
  2. Registros:ejemplo de VHDL
  3. Variables - Ejemplo de VHDL
  4. Circuito con un interruptor
  5. Diodo de conmutación
  6. Opciones de análisis
  7. Tipos de cambio
  8. Declaración de cambio de C#
  9. Declaración de interrupción de C#
  10. Declaración de continuación de C#
  11. Declaración de caso de cambio de C ++ con EJEMPLO