signal e variable são formas de se representar dados em VHDL, um signal pode ser sintetizado como um flip-flop, fios de interconexão ou até mesmo em lógica combinacional dependendo da situação.
Já um variable nem sempre tem correspondência direta em hardware, cabe ao compilador interpretar e ver no que aquilo pode ser sintetizado. Via de regra variables só podem ser utilizadas dentro de um process e as mesmas representam uma parte COMBINACIONAL do circuito, é muito importante saber a diferença entre circuito COMBINACIONAL e circuito SEQUENCIAL. Uma variable jamais deve ser pensada como algo que armazena dados estilo um Flip-Flop.
Uma variable utiliza o operador de atribuição := enquanto um signal utiliza o operador de atribuição <=.
- No caso de signal as atribuições são sobrescritas e somente a ultima é validada após o final do processo.
- No caso de variable as atribuição são instantâneas e são validadas imediatamente.
1: signal a : integer := 0; -- Apenas para facilitar a simulação
2: process(clk)
3: variable b : integer := 0;
4: begin
5: if rising_edge(clk) then
6: a <= 10;
7: a <= a + 90;
8: a <= a + 1;
9: b := 10;
10: b := b + 90;
11: b := b + 1;
12: end if;
13: end process;
Você consegue adivinhar que circuito será gerado neste process? Se você simular este código você vai ver o sinal A incrementando em 1 a cada pulso de clock pois somente a última atribuição acontece de fato, já a variable B tera como resultado 101 para sempre.
Outro exemplo, dentro de um processo síncrono há diferenças entre A <= B and C e A := B and C:
- A <= B and C; gera um circuito combinacional (B and C) e o resultado é armazenado no registrador A a cada pulso de clock (sequencial)
- A := B and C; gera somente um circuito combinacional, ou seja não há valor armazenado em lugar algum. Claro que nada te impede de mais tarde no código atribuir A a um registrador mas é bom ter consciência de que por si só não há registradores.
Já no código abaixo temos um problema ainda mais grave pois há diferença de comportamento entre a Simulação e a Síntese do circuito, o sintetizador pode inferir uma constante enquanto a simulação mostraria um contador.
1: process(clk)
2: variable s : integer := 0;
3: begin
4: if rising_edge(clk) then
5: s := s + 1;
6: op <= s;
7: end if;
8: end process;
O valor é armazenado no registrador OP e não em s e s é inicializado com 0. Não há elementos de armazenamento associados a s e s permanece constante em 1.
Trocando para s := op + 1 funcionaria corretamente pois é a soma do conteúdo armazenado no registrador com 1.
Espero que tenha ficado mais claro o funcionamento de variables e os problemas que podem acontecer quando a mesma for mal utilizada, boa parte desta discussão foi retirada do forum oficial da altera neste link.
Qualquer dúvida é bem vinda nos comentários!
Abraços
Muito bom André. Você poderia comentar no último exemplo como ficaria em VHDL um circuito que funcionasse com o resultado esperado. No mais, tá tudo ótimo.
ResponderExcluirNa verdade ali embaixo é possível ver como ficaria certo:
ExcluirTrocando para s := op + 1 funcionaria corretamente pois é a soma do conteúdo armazenado no registrador com 1.
Abraço
Eu li em um livro do Volnei, que a inicialização de variable e signal não é sintetizável.
ResponderExcluirEste comentário foi removido pelo autor.
ExcluirRealmente não é recomendado inicializar signals e variables pois podem ocorrer diferenças entre a sintese e a simulação.
ResponderExcluirO correto é atribuir um valor a eles no reset do seu process ou então configurar a ferramenta de CAD para inferir um valor inicial a eles.
Até por isto comentei ali "apenas para facilitar a simulação".