Como usar a instanciação do mapa de portas em VHDL
Um módulo é uma unidade independente de código VHDL. Os módulos se comunicam com o mundo exterior por meio da entidade . Mapa do porto é a parte da instanciação do módulo onde você declara a quais sinais locais as entradas e saídas do módulo devem ser conectadas.
Nos tutoriais anteriores desta série, escrevemos todo o nosso código no arquivo VHDL principal, mas normalmente não faríamos isso. Criamos lógica com o objetivo de usá-la em um projeto FPGA ou ASIC, não para o simulador.
Um módulo VHDL criado para ser executado em um simulador geralmente não possui sinais de entrada ou saída. É totalmente independente. É por isso que a entidade de nossos designs está vazia. Não houve nada entre o
entity
e a tag end entity;
marcação. Esta postagem do blog faz parte da série de tutoriais básicos de VHDL.
Um módulo sem qualquer sinal de entrada ou saída não pode ser usado em um projeto real. Seu único propósito é nos permitir executar código VHDL em um simulador. Portanto, é referido como um testbench . Para simular um módulo com sinais de entrada e saída temos que instanciar -lo em uma bancada de teste.
Módulos e testbenches geralmente vêm em pares e são armazenados em arquivos diferentes. Um esquema de nomenclatura comum é chamar o testbench pelo nome do módulo com “Tb” anexado e nomear a arquitetura “sim”. Se o módulo for chamado de “MyModule”, o testbench será chamado de “MyModuleTb”. Consequentemente, os nomes dos arquivos se tornam “MyModuleTb.vhd” e “MyModule.vhd”.
Com a ajuda do código do testbench podemos verificar se o módulo está funcionando corretamente em um ambiente de simulação. O módulo que está sendo testado é comumente referido como o dispositivo em teste (DUT).
Os módulos também podem ser instanciados em outros módulos. Particionar o código em módulos permite que ele seja instanciado várias vezes. Você pode criar várias instâncias de um módulo no mesmo design e ele pode ser reutilizado em vários designs.
A sintaxe para uma entidade com uma porta em VHDL é:
entity <entity_name> is
port(
<entity_signal_name> : in|out|inout <signal_type>;
...
);
end entity;
A sintaxe para instanciar tal módulo em outro arquivo VHDL é:
<label> : entity <library_name>.<entity_name>(<architecture_name>) port map(
<entity_signal_name> => <local_signal_name>,
...
);
O
<label>
pode ser qualquer nome e aparecerá na janela de hierarquia no ModelSim. O <library_name>
para um módulo é definido no simulador, não no código VHDL. Por padrão, cada módulo é compilado no work
biblioteca. O <entity_name>
e <architecture_name>
deve corresponder ao módulo do qual estamos criando uma instância. Finalmente, cada um dos sinais de entidade deve ser mapeado para um nome de sinal local. Existem outras maneiras de instanciar um módulo em VHDL, mas esta é a sintaxe básica para instanciação explícita.
Exercício
Neste tutorial em vídeo vamos aprender como criar e instanciar um módulo em VHDL:
O código final para o MUX testbench :
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity T15_PortMapTb is end entity; architecture sim of T15_PortMapTb is signal Sig1 : unsigned(7 downto 0) := x"AA"; signal Sig2 : unsigned(7 downto 0) := x"BB"; signal Sig3 : unsigned(7 downto 0) := x"CC"; signal Sig4 : unsigned(7 downto 0) := x"DD"; signal Sel : unsigned(1 downto 0) := (others => '0'); signal Output : unsigned(7 downto 0); begin -- An instance of T15_Mux with architecture rtl i_Mux1 : entity work.T15_Mux(rtl) 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 do MUX :
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity T15_Mux is port( -- Inputs Sig1 : in unsigned(7 downto 0); Sig2 : in unsigned(7 downto 0); Sig3 : in unsigned(7 downto 0); Sig4 : in unsigned(7 downto 0); Sel : in unsigned(1 downto 0); -- Outputs Output : out unsigned(7 downto 0)); end entity; architecture rtl of T15_Mux 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
Como podemos ver pela forma de onda, o módulo multiplexador (MUX) funciona conforme o esperado. A forma de onda é idêntica à do tutorial anterior que criamos sem usar módulos.
Agora há uma separação clara entre o módulo de design e o testbench. O módulo que contém o MUX é o que pretendemos usar em um projeto, e o único propósito do testbench é permitir executá-lo em um simulador. Existe um processo no testbench que usa
wait
instruções para criar atrasos de tempo artificiais na simulação. O módulo de design não tem noção de tempo, apenas reage a estímulos externos. Nomeamos a arquitetura do testbench
sim
, para simulação. A arquitetura do módulo de design foi denominada rtl
, que significa nível de transferência de registro. Estas são apenas convenções de nomenclatura. Quando você vê um arquivo com esse nome, sabe imediatamente se é um testbench ou um módulo de design. Diferentes empresas podem ter diferentes convenções de nomenclatura. Retirada
- Os sinais de entrada e saída são especificados na entidade de um módulo
- Um módulo sem sinais de entrada/saída é chamado de testbench , e só pode ser usado em um simulador
- Um módulo com sinais de entrada/saída geralmente não pode ser executado diretamente em um simulador
Ir para o próximo tutorial »
VHDL
- Como usamos o molibdênio?
- Como criar uma lista de strings em VHDL
- Como criar um testbench orientado por Tcl para um módulo de bloqueio de código VHDL
- Como parar a simulação em um testbench VHDL
- Como criar um controlador PWM em VHDL
- Como gerar números aleatórios em VHDL
- Como usar um procedimento em um processo em VHDL
- Como usar uma função impura em VHDL
- Como usar uma função em VHDL
- Como usar um moedor de corte