Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Industrial programming >> VHDL

Como usar constantes e mapa genérico em VHDL


Criar módulos é uma ótima maneira de reutilizar código, mas geralmente você precisa do mesmo módulo com variações menores em todo o design. É para isso que servem os genéricos e o mapa genérico. Ele permite que você torne certas partes do módulo configuráveis ​​em tempo de compilação.

Constantes são usadas quando queremos evitar digitar o mesmo valor repetidamente. Eles podem ser usados ​​para definir larguras de bits de vetores de sinal em tempo de compilação e também podem ser mapeados para constantes genéricas. Constantes podem ser usadas no lugar de sinais e variáveis ​​em qualquer lugar do código, mas seus valores não podem ser alterados após o tempo de compilação.

Esta postagem do blog faz parte da série de tutoriais básicos de VHDL.

No tutorial anterior, criamos um módulo multiplexador de 4 entradas com largura de barramento de 8 bits. Mas e se também precisarmos de um MUX semelhante com uma largura de barramento diferente? A única solução é copiar e colar o código em um novo módulo e alterar os números?

Felizmente, não.

É possível criar constantes em VHDL usando esta sintaxe:
constant <constant_name> : <type> := <value>;

Constantes podem ser declaradas junto com sinais na parte declarativa de um arquivo VHDL, ou podem ser declaradas junto com variáveis ​​em um processo.

Constantes podem ser passadas para um módulo através da entidade usando o generic palavra-chave. A sintaxe para criar uma entidade para um módulo que aceita constantes genéricas é:
entity <entity_name> is
generic(
    <entity_constant_name> : <type> [:= default_value];
    ...
);
port(
    <entity_signal_name> : in|out|inout <type>;
    ...
);
end entity;


A sintaxe para instanciar um módulo genérico em outro arquivo VHDL é:
<label> : entity <library_name>.<entity_name>(<architecture_name>)
generic map(
    <entity_constant_name> => <value_or_constant>,
    ...
)
port map(
    <entity_signal_name> => <local_signal_name>,
    ...
);

Exercício


Neste tutorial em vídeo vamos aprender como criar e instanciar um módulo com constantes genéricas em VHDL:



O código final para o MUX genérico testbench :
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;

O código final para o módulo genérico do MUX :
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;

A janela de forma de onda no ModelSim depois que pressionamos executar e ampliamos a linha do tempo:




Análise


Criamos um módulo MUX com largura de barramento configurável. Agora, a largura do barramento é especificada em apenas um local, no arquivo testbench. Podemos alterá-lo facilmente para criar um MUX com uma largura de barramento diferente.

Se compararmos a forma de onda com a do tutorial anterior, podemos ver que o comportamento é idêntico. Isso ocorre porque não alteramos o comportamento do código.


Retirada


Ir para o próximo tutorial »

VHDL

  1. Como usar um procedimento em um processo em VHDL
  2. Como usar uma função impura em VHDL
  3. Como usar uma função em VHDL
  4. Como usar um procedimento em VHDL
  5. Como usar constantes e mapa genérico em VHDL
  6. Como usar a instanciação do mapa de portas em VHDL
  7. Como usar uma instrução Case-When em VHDL
  8. Como usar assinado e não assinado em VHDL
  9. Como instalar um simulador e editor VHDL gratuitamente
  10. Microcontrolador PIC18:o que é e como usá-lo