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

Aprovechando constantes y generic maps en VHDL para diseño de módulos flexibles

Crear módulos reutilizables es una piedra angular del diseño VHDL eficiente, sin embargo, variaciones menores a menudo demandan código duplicado. Los genéricos y generic maps resuelven esto permitiéndole configurar los parámetros de un módulo en tiempo de compilación, manteniendo su código DRY y mantenible.

Las constantes ayudan a evitar codificar duro el mismo valor repetidamente. Son ideales para definir anchos de bus de señales u otros parámetros en tiempo de compilación, e incluso pueden mapearse a constantes genéricas. A diferencia de señales o variables, el valor de una constante es inmutable después de la elaboración, asegurando consistencia a lo largo del diseño.

Este artículo es parte de la serie Tutoriales Básicos de VHDL.

En nuestro tutorial anterior construimos un multiplexor de 4 entradas con ancho de bus de 8 bits. Si ahora necesita un MUX similar con un ancho diferente, copiar y pegar el módulo entero no es la única opción.

En su lugar, declare una constante que contenga el ancho de bus deseado, luego pase esa constante al módulo a través de un genérico. El único lugar donde necesita cambiar el ancho es la declaración de constante en su testbench.

A continuación se muestra la sintaxis para declarar una constante en VHDL:

constant <constant_name> : <type> := <value>;

Las constantes pueden aparecer junto a señales en la parte declarativa de un archivo, o con variables dentro de un proceso.

Para exponer una constante a un módulo, use la palabra clave generic en la declaración de entidad:

entity <entity_name> is
  generic(
    <entity_constant_name> : <type> [:= default_value];
    ...
  );
  port(
    <entity_signal_name> : in|out|inout <type>;
    ...
  );
end entity;

Instancie el módulo genérico en otro lugar usando un generic map y port map:

<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 tutorial en video recorreremos la creación e instanciación de un módulo MUX 4-a-1 genérico en VHDL.

Testbench – MUX Genérico

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
  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
    );
  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;

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(
    -- Entradas
    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);
    -- Salida
    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 => Output <= (others => 'X');
    end case;
  end process;
end architecture;

Forma de onda de ModelSim después de ejecutar la simulación (zoom en la línea de tiempo):

Aprovechando constantes y generic maps en VHDL para diseño de módulos flexibles

Análisis

Al definir DataWidth una vez en el testbench, podemos adaptar el mismo MUX para cualquier ancho de bus sin tocar el código del módulo. La forma de onda confirma funcionalidad idéntica a la versión con ancho fijo.

Aprovechando constantes y generic maps en VHDL para diseño de módulos flexibles

Conclusión

Proceda al siguiente tutorial »

VHDL

  1. Microcontroladores PIC18: Características, Rendimiento y Cómo Usarlos
  2. Aprovechando procedimientos en-proceso para diseños FSM más limpios en VHDL
  3. Uso de funciones impuras en VHDL: Mejorando legibilidad y mantenibilidad de FSM
  4. Dominando funciones VHDL: Guía práctica para diseño eficiente
  5. Uso de procedimientos en VHDL: Simplifique su diseño con código reutilizable
  6. Aprovechando constantes y generic maps en VHDL para diseño de módulos flexibles
  7. Dominando la instanciación con port map en VHDL: Guía práctica
  8. Dominando la sentencia Case-When en VHDL: Diseño eficiente de multiplexores
  9. Dominando tipos Signed y Unsigned en VHDL: Guía práctica
  10. Dominando lógica condicional en VHDL: If-Then-Elsif-Else explicado
  11. Configuración gratis de simulador y editor VHDL: Guía para estudiantes