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 usar constantes y mapas genéricos en VHDL

La creación de módulos es una excelente manera de reutilizar el código, pero a menudo necesita el mismo módulo con variaciones más pequeñas a lo largo de su diseño. Para eso están los genéricos y el mapa genérico. Le permite configurar ciertas partes del módulo en tiempo de compilación.

Las constantes se utilizan cuando queremos evitar escribir el mismo valor una y otra vez. Se pueden usar para definir anchos de bits de vectores de señal en tiempo de compilación, e incluso se pueden asignar a constantes genéricas. Las constantes se pueden usar en lugar de señales y variables en cualquier parte del código, pero sus valores no se pueden cambiar después del tiempo de compilación.

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

En el tutorial anterior, creamos un módulo multiplexor de 4 entradas con un ancho de bus de 8 bits. Pero, ¿y si también necesitamos un MUX similar con un ancho de bus diferente? ¿La única solución es copiar y pegar el código en un módulo nuevo y cambiar los números?

Afortunadamente, no.

Es posible crear constantes en VHDL usando esta sintaxis:
constant <constant_name> : <type> := <value>;

Las constantes se pueden declarar junto con las señales en la parte declarativa de un archivo VHDL, o se pueden declarar junto con las variables en un proceso.

Las constantes se pueden pasar a un módulo a través de la entidad usando el generic palabra clave. La sintaxis para crear una entidad para un módulo que acepta constantes genéricas es:
entity <entity_name> is
generic(
    <entity_constant_name> : <type> [:= default_value];
    ...
);
port(
    <entity_signal_name> : in|out|inout <type>;
    ...
);
end entity;

La sintaxis para instanciar un módulo genérico en otro archivo VHDL es:
<label> : entity <library_name>.<entity_name>(<architecture_name>)
generic map(
    <entity_constant_name> => <value_or_constant>,
    ...
)
port map(
    <entity_signal_name> => <local_signal_name>,
    ...
);

Ejercicio

En este video tutorial aprenderemos a crear e instanciar un módulo con constantes genéricas en VHDL:

El código final para el testbench genérico de MUX :

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

entity T16_GenericMapTb is
end entity;

architecture sim of T16_GenericMapTb is

    constant DataWidth : integer := 8;

    signal Sig1 : signed(DataWidth-1 downto 0) := x"AA";
    signal Sig2 : signed(DataWidth-1 downto 0) := x"BB";
    signal Sig3 : signed(DataWidth-1 downto 0) := x"CC";
    signal Sig4 : signed(DataWidth-1 downto 0) := x"DD";

    signal Sel : signed(1 downto 0) := (others => '0');

    signal Output : signed(DataWidth-1 downto 0);

begin

    -- An Instance of T16_GenericMux with architecture rtl
    i_Mux1 : entity work.T16_GenericMux(rtl)
    generic map(DataWidth => DataWidth)
    port map(
        Sel    => Sel,
        Sig1   => Sig1,
        Sig2   => Sig2,
        Sig3   => Sig3,
        Sig4   => Sig4,
        Output => Output);

    -- Testbench process
    process is
    begin
        wait for 10 ns;
        Sel <= Sel + 1;
        wait for 10 ns;
        Sel <= Sel + 1;
        wait for 10 ns;
        Sel <= Sel + 1;
        wait for 10 ns;
        Sel <= Sel + 1;
        wait for 10 ns;
        Sel <= "UU";
        wait;
    end process;

end architecture;

El código final para el módulo MUX genérico :

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

entity T16_GenericMux is
generic(DataWidth : integer);
port(
    -- Inputs
    Sig1 : in signed(DataWidth-1 downto 0);
    Sig2 : in signed(DataWidth-1 downto 0);
    Sig3 : in signed(DataWidth-1 downto 0);
    Sig4 : in signed(DataWidth-1 downto 0);

    Sel  : in signed(1 downto 0);

    -- Outputs
    Output : out signed(DataWidth-1 downto 0));
end entity;

architecture rtl of T16_GenericMux is
begin

    process(Sel, Sig1, Sig2, Sig3, Sig4) is
    begin

        case Sel is
            when "00" =>
                Output <= Sig1;
            when "01" =>
                Output <= Sig2;
            when "10" =>
                Output <= Sig3;
            when "11" =>
                Output <= Sig4;
            when others => -- 'U', 'X', '-', etc.
                Output <= (others => 'X');
        end case;

    end process;

end architecture;

La ventana de forma de onda en ModelSim después de presionar Ejecutar y hacer zoom en la línea de tiempo:

Análisis

Creamos un módulo MUX con un ancho de bus configurable. Ahora, el ancho del bus se especifica en un solo lugar, en el archivo del banco de pruebas. Podemos cambiarlo fácilmente para crear un MUX con un ancho de bus diferente.

Si comparamos la forma de onda con la del tutorial anterior, podemos ver que el comportamiento es idéntico. Esto se debe a que no hemos cambiado el comportamiento del código en absoluto.

Para llevar

Ir al siguiente tutorial »


VHDL

  1. Cómo usar un procedimiento en un proceso en VHDL
  2. Cómo usar una función impura en VHDL
  3. Cómo usar una función en VHDL
  4. Cómo usar un procedimiento en VHDL
  5. Cómo usar constantes y mapas genéricos en VHDL
  6. Cómo usar la creación de instancias de mapas de puertos en VHDL
  7. Cómo usar una instrucción Case-When en VHDL
  8. Cómo usar Firmado y Sin firmar en VHDL
  9. Cómo usar sentencias condicionales en VHDL:If-Then-Elsif-Else
  10. Cómo instalar un simulador y editor VHDL gratis
  11. Microcontrolador PIC18:qué es y cómo usarlo