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

Dominando Declarações Generate em VHDL: Construa Debouncers Reutilizáveis com Facilidade

A declaração generate do VHDL permite que projetistas repliquem automaticamente um bloco de código em múltiplas instâncias, cada uma conectada a sinais distintos. Pense nela como um loop for em tempo de compilação que pode criar processos encadeados ou instâncias de módulos, reduzindo drasticamente o código repetitivo e melhorando a manutenibilidade.

Diferente de um loop tradicional, que fica confinado a um processo ou subprograma, o generate fica diretamente na região de arquitetura. Quando combinado com genéricos, torna-se um mecanismo poderoso para criar componentes VHDL altamente configuráveis e reutilizáveis.

Sintaxe da Declaração Generate

[label :] for <constant_name> in <range> generate [declarations_local_to_each_loop_iteration] [begin] <processes_and_instantiations> end generate [label];

Elementos opcionais estão entre colchetes. Você pode omitir a região declarativa e a palavra-chave begin se nenhum objeto local for declarado. O <range> segue a sintaxe inteira padrão usando to ou downto.

Debouncer de Chave de Um Bit

Antes de mergulhar no generate, vamos revisar um debouncer simples que limpa uma única entrada de chave. Um genérico timeout_cycles permite que o módulo se adapte a qualquer frequência de clock. O debouncer suprime transientes que ocorrem quando uma chave mecânica transiciona.

entity debouncer is generic ( timeout_cycles : positive ); port ( clk : in std_logic; rst : in std_logic; switch : in std_logic; switch_debounced : out std_logic ); end debouncer;

A implementação depende de um contador inteiro cuja largura é ditada pelo genérico. Um sinal sombra debounced é usado internamente para manter a lógica de saída limpa.

architecture rtl of debouncer is signal debounced : std_logic; signal counter : integer range 0 to timeout_cycles - 1; begin -- Copy internal signal to output switch_debounced <= debounced; DEBOUNCE_PROC : process(clk) begin if rising_edge(clk) then if rst = '1' then counter <= 0; debounced <= switch; else if counter < timeout_cycles - 1 then counter <= counter + 1; elsif switch /= debounced then counter <= 0; debounced <= switch; end if; end if; end if; end process; end architecture;

A simulação no ModelSim confirma que switch_debounced segue a entrada apenas após o timeout especificado, filtrando efetivamente artefatos de bouncing.

Dominando Declarações Generate em VHDL: Construa Debouncers Reutilizáveis com Facilidade

Baixe o projeto completo do ModelSim, incluindo testbenches, fornecendo seu endereço de e-mail abaixo. Todas as atualizações são enviadas do VHDLwhiz, e você pode cancelar a inscrição a qualquer momento.

Loop Generate com Instanciações

Para estender o debouncer a um array de chaves, usamos uma declaração generate para criar múltiplas instâncias automaticamente.

entity debouncer_gen_inst is generic ( switch_count : positive; timeout_cycles : positive ); port ( clk : in std_logic; rst : in std_logic; switches : in std_logic_vector(switch_count - 1 downto 0); switches_debounced : out std_logic_vector(switch_count - 1 downto 0) ); end debouncer_gen_inst;

A arquitetura usa um loop generate para instanciar debouncer para cada bit da chave. Cada instância compartilha o mesmo clock e reset, mas conecta a um elemento distinto do vetor.

architecture rtl of debouncer_gen_inst is begin MY_GEN : for i in 0 to switch_count - 1 generate DEBOUNCER : entity work.debouncer(rtl) generic map ( timeout_cycles => timeout_cycles ) port map ( clk => clk, rst => rst, switch => switches(i), switch_debounced => switches_debounced(i) ); end generate; end architecture;

Rotular o bloco generate (ex: MY_GEN) melhora a legibilidade na hierarquia do simulador e relatórios de síntese, facilitando a depuração.

Dominando Declarações Generate em VHDL: Construa Debouncers Reutilizáveis com Facilidade

O testbench alterna apenas a chave 3, então a forma de onda foca em MY_GEN(3). Execute este exemplo no ModelSim para ver a lógica de debouncing em ação.

Loop Generate Contendo Processos

Alternativamente, você pode elevar a lógica do debouncer para dentro do bloco generate, eliminando instanciações de componentes separadas. Esta abordagem demonstra que um loop generate também pode criar processos idênticos com sinais locais.

architecture rtl of debouncer_gen_proc is begin MY_GEN : for i in 0 to switch_count - 1 generate signal debounced : std_logic; signal counter : integer range 0 to timeout_cycles - 1; begin switches_debounced(i) <= debounced; DEBOUNCE_PROC : process(clk) begin if rising_edge(clk) then if rst = '1' then counter <= 0; debounced <= switches(i); else if counter < timeout_cycles - 1 then counter <= counter + 1; elsif switches(i) /= debounced then counter <= 0; debounced <= switches(i); end if; end if; end if; end process; end generate; end architecture;

O comportamento resultante corresponde à abordagem de instanciação de módulo, mas o código é autocontido na arquitetura. Ambos os métodos são válidos; escolha o que melhor se alinha ao seu estilo de projeto.

Todos os exemplos de código, incluindo o projeto completo do ModelSim, estão disponíveis para download via formulário abaixo. Inscreva-se no VHDLwhiz para atualizações, e sinta-se à vontade para cancelar a inscrição a qualquer momento.

Tem um uso criativo para generate? Compartilhe suas ideias nos comentários abaixo!

VHDL

  1. Exemplo de Procedure VHDL: Incrementando um Standard Logic Vector
  2. Aproveitando Records VHDL para Interfaces FIFO Limpas e Reutilizáveis
  3. Variáveis VHDL Explicadas: Exemplos Práticos & Regras para Design Confiável
  4. Circuito com Chave: Guia Prático para Circuitos Elétricos Básicos
  5. Configuração de Análise AC: Curvas, Pontos e Parâmetros de Varredura de Frequência
  6. Entendendo Chaves Elétricas: Tipos, Funções e Aplicações
  7. Dominando a Instrução Switch em C#: Sintaxe, Exemplos e Boas Práticas
  8. Instrução Break em C#: Como e Quando Usar
  9. Dominando a Instrução Continue em C#: Como Pular Iterações de Loop Eficazmente
  10. Dominando Switch-Case em C++: Sintaxe, Uso e Exemplos Práticos