Como Construir um Testbench de Auto-Verificação em VHDL – Guia Prático
Um testbench de auto-verificação é um programa VHDL que verifica a correção de um device under test (DUT) sem inspeção manual. Uma vez executado, ele relata automaticamente um status OK ou Falhou, tornando-se uma ferramenta essencial para desenvolvimento VHDL confiável.
Todo módulo VHDL deve ter um testbench de auto-verificação associado. Isso garante que qualquer alteração — seja no próprio DUT, em um submódulo ou em uma interface — não introduza regressões silenciosamente. Um testbench bem elaborado é a primeira linha de defesa contra bugs sutis.
O Device Under Test
Usaremos um DUT simples, mas ilustrativo: um conversor de código binário para Gray. Abaixo está a implementação RTL completa.
library ieee; use ieee.std_logic_1164.all; entity gray_converter is port ( bin : in std_logic_vector; gray : out std_logic_vector ); end gray_converter; architecture rtl of gray_converter is begin process(bin) is begin gray(gray'high) <= bin(bin'high); for i in bin'high - 1 downto bin'low loop gray(i) <= bin(i + 1) xor bin(i); end loop; end process; end architecture; Código Gray é um esquema de codificação binária onde apenas um bit muda entre valores sucessivos, minimizando a probabilidade de erro em comunicação serial e contadores digitais. A tabela abaixo demonstra o mapeamento para valores de 4 bits.
| Decimal | Binário | Gray |
|---|---|---|
| 0 | 0000 | 0000 |
| 1 | 0001 | 0001 |
| 2 | 0010 | 0011 |
| 3 | 0011 | 0010 |
| 4 | 0100 | 0110 |
| 5 | 0101 | 0111 |
| 6 | 0110 | 0101 |
| 7 | 0111 | 0100 |
| 8 | 1000 | 1100 |
| 9 | 1001 | 1101 |
| 10 | 1010 | 1111 |
| 11 | 1011 | 1110 |
| 12 | 1100 | 1010 |
| 13 | 1101 | 1011 |
| 14 | 1110 | 1001 |
| 15 | 1111 | 1000 |
O Esqueleto do Testbench
Abaixo está um testbench mínimo que instancia o DUT e declara os sinais necessários. Observe a inclusão de std.env.finish, um recurso do VHDL-2008 que termina a simulação de forma limpa.
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use std.env.finish; entity gray_converter_tb is end gray_converter_tb; architecture sim of gray_converter_tb is signal bin : std_logic_vector(3 downto 0) := (others => '0'); signal gray : std_logic_vector(3 downto 0); DUT : entity work.gray_converter(rtl) port map ( bin => bin, gray => gray ); end architecture; Se você compilar este arquivo em um simulador compatível com VHDL-2008 como o ModelSim, pode precisar definir a versão da linguagem do arquivo para 2008. No ModelSim, clique com o botão direito no arquivo, escolha Properties → VHDL → Use 1076-2008.
Gerando Entradas Exaustivas
O próximo passo é produzir uma varredura completa de todos os valores possíveis de 4 bits. Um teste exaustivo é preferido porque garante que todos os casos de canto sejam exercitados.
PROC_SEQUENCE : process begin -- Iterar sobre cada valor de 4 bits for i in 0 to 2**bin'length - 1 loop bin <= std_logic_vector(to_unsigned(i, bin'length)); wait for 10 ns; end loop; -- Volta ao estado inicial bin <= (others => '0'); wait for 10 ns; report "Test: OK"; finish; end process; O atraso de 10 ns é arbitrário; qualquer valor positivo serve porque o DUT é puramente combinacional. A declaração final finish encerra a simulação graciosamente.
Verificando a Saída do DUT
Simplesmente imprimir "Test: OK" seria sem sentido se a saída estivesse errada. Para impor correção, comparamos a saída Gray do DUT contra a propriedade fundamental do código Gray: saídas sucessivas devem diferir em exatamente um bit.
PROC_CHECKER : process variable prev : std_logic_vector(gray'range); variable count : integer; begin wait on bin; prev := gray; -- Permitir que a lógica combinacional se resolva wait for 1 ns; count := 0; for i in gray'range loop if gray(i) /= prev(i) then count := count + 1; end if; end loop; assert count = 1 report integer'image(count) & " bits changed, should have been 1" severity failure; end process; Este processo monitora mudanças em bin, captura a saída Gray anterior, espera a propagação, conta bits diferentes e asserta que a contagem é exatamente um. Se a asserção falhar, o simulador para imediatamente, impedindo que a mensagem "Test: OK" apareça.
Executando o Testbench
No ModelSim, inicie a simulação e execute run -all. Uma execução bem-sucedida termina com:
VSIM 1> run -all # ** Note: Test: OK # Time: 170 ns Iteration: 0 Instance: /gray_converter_tb
Testando a Robustez do Testbench
Para confirmar que o verificador detecta falhas, introduza temporariamente um erro no DUT — por exemplo, force gray(3) para zero.
process(bin) is begin gray(gray'high) <= bin(bin'high); for i in bin'high - 1 downto bin'low loop gray(i) <= bin(i + 1) xor bin(i); end loop; -- Emular uma falha stuck-at-zero gray(3) <= '0'; end process; Executando o testbench agora dispara a falha de asserção, exibindo o número exato de bits que mudaram:
VSIM 2> run -all # ** Failure: 0 bits changed, should have been 1 # Time: 81 ns Iteration: 0 Process: /gray_converter_tb/PROC_CHECKER File: gray_converter_tb.vhd # Break in Process PROC_CHECKER at ray_converter_tb.vhd line 61
Começando com Testbenches de Auto-Verificação
Adote o hábito de escrever testbenches de auto-verificação para cada módulo VHDL. Eles economizam tempo capturando regressões cedo e fornecem um registro claro da intenção do design. Embora testbenches não precisem ser sintetizáveis, devem ser claros, manteníveis e usar os construtos VHDL mais recentes para legibilidade e eficiência.
Para aprendizado mais profundo, considere cursos avançados que cobrem o fluxo de design completo — da especificação ao protótipo FPGA — enquanto enfatizam práticas rigorosas de verificação.
Atualizado em 12 de outubro de 2020: Completei o curso de VHDL e FPGA. Clique na imagem abaixo para saber mais.
Saiba mais sobre o curso VHDL e FPGA de Matriz de Pontos aqui!
Início:
A ser decidido.
VHDL
- Crie Seu Primeiro Template AWS CloudFormation — Um Guia Prático
- Construindo um Cloud Center of Excellence: Estratégias para Migração Bem-sucedida e Sucesso do Cliente
- Construa um Plano Estratégico de Adoção de Nuvem
- Criando Experiências de Usuário sem Atrito: Um Guia de Design UX
- Criando Listas de Strings em VHDL: Boas Práticas e Exemplo
- Criando um Testbench Dirigido por Tcl para um Módulo Code-Lock VHDL
- Finalizando Graciosamente uma Simulação de Testbench VHDL
- Implementando Lista Encadeada Dinâmica em VHDL com Tipos Protegidos e Ponteiros de Acesso
- Construindo Cidades Inteligentes Centradas no Humano: Um Blueprint Estratégico
- Criando Array de Objetos em Java: Guia Passo a Passo