Diferença entre declaração If-else e Case em VHDL

11

Eu quero entender como diferentes construções no código VHDL são sintetizadas em RTL.

  • Alguém pode me dizer a diferença entre a construção If-Else e a instrução Case de um processo em VHDL em termos de como o código é inferido no circuito RTL pela ferramenta de síntese?
  • Considere o caso de vários if-else aninhados e misture instruções de caso com a construção if-else dentro de um processo.
  • Também quando usar qual construção?

PS: Eu vi uma pergunta relacionada "Múltiplas declarações if em andamento no vhdl", mas isso não responde à minha pergunta de qualquer maneira.

nurabha
fonte
Não posso comentar como as portas físicas seriam configuradas, mas na maioria dos compiladores que emitem montagem x86, um if-else geralmente existe como uma única verificação com um salto condicional (por exemplo, jg, jl, jz, jnz, etc.), enquanto switch organiza os casos em ordem numérica e faz iterativas dec/ jzinstruções, o que é muito mais eficiente. Talvez uma otimização semelhante seja aplicada aqui.
Polinomial
@ Polinomial O comportamento de If-else e case é significativamente diferente nas linguagens de hardware em comparação com a programação linear típica. As otimizações do código operacional não são muito relevantes, pois a instrução HDL executa "instantaneamente".
W5VO

Respostas:

10

Alguém pode me dizer a diferença entre a construção If-Else e a construção Case de um processo em VHDL em termos de como o código é inferido no circuito RTL pela ferramenta de síntese?

A if-elsif-elseconstrução infere uma rede de roteamento prioritário:

esquemático

simular este circuito - esquemático criado usando o CircuitLab

Isso corresponde a

if bool_expr_1 then
    sig <= val_expr_1;
elsif bool_expr_2 then
    sig <= val_expr_2;
elsif bool_expr_3 then
    sig <= val_expr_3;
else
    sig <= val_expr_4;
end if;

A caseconstrução, por outro lado, infere um grande ol 'mux:

insira a descrição da imagem aqui

Isso corresponde a

case case_expr is
  when c0 =>
    sig <= val_expr_0;
  when c1 =>
    sig <= val_expr_1;
  when c2 =>
    sig <= val_expr_2;
      ...
  when others =>
    sig <= val_expr_N;
end case;

Obviamente, esses são designs muito simplificados, com apenas uma expressão de valor, resultando em uma saída.

Considere o caso de vários if-else aninhados e a mistura de instruções de caso com a construção if-else dentro de um processo.

De acordo com o acima, você pode ver como eles aninham / misturam.

Também quando usar qual construção?

Como if-elsededuz a prioridade, ele deve ser usado quando mais de uma condição de entrada puder ocorrer. O uso case, por outro lado, é apropriado quando as entradas são mutuamente exclusivas.

Angelo Stavrow
fonte
Entendo que a declaração de caso funciona apenas para uma condição de entrada única e se-mais pode funcionar para várias condições de entrada. Mas ambas as construções geram essencialmente muxes (na ausência de clk). Não é possível que a síntese lógica otimize a entrada única se-senão para um único grande mux em vez de uma cadeia de muxes? Além disso, o que é uma rede de roteamento prioritário ... não é simplesmente uma cadeia de muxes em vez de um grande mux?
nurabha
Além disso, quando temos um processo sensível a um relógio, o if-else pode gerar elementos seqüenciais, como registros, travas etc. Uma declaração de caso também pode gerar lógica seqüencial?
nurabha
Sim, uma rede de roteamento prioritário é exatamente isso - uma cadeia de muxes. A natureza da if-elseconstrução, no entanto, é onde essa cadeia surge. A primeira condição deve falhar para que a segunda condição seja testada. Esse não é o caso, er, da caseconstrução, e é por isso que uma if-elseinstrução não pode ser sintetizada como um único grande mux.
Angelo Stavrow
1
E sim, uma casedeclaração também pode gerar lógica sequencial. Encontrei "Real World VHDL" , uma série de slides de palestras da Universidade de Glasgow, que podem ser úteis para você.
Angelo Stavrow
Esta é uma boa referência.
nurabha
4

Em este velho post , o autor escreveu e sintetizadas duas versões funcionalmente equivalentes de código VHDL. Um usando if-else, o outro usando case. O resultado:

Eu sintetizei esse código e obtive os resultados exatos. Mesmo o esquema RTL era exatamente o mesmo para os dois programas.

E sua conclusão:

Isso mostra que as instruções 'case' e 'if ... elsif ... else' são igualmente eficientes. Mas, se você deseja escrever um código claro, é melhor usar 'case'. 'Case' é muito útil quando o a saída depende de um grande número de condições.Mas se o número de condições for muito pequeno (2 ou 3), você poderá usar 'if..elseif..else'.

Existem também dezenas de posts sobre esse assunto no Stack Overflow para todos os idiomas imagináveis. A conclusão é geralmente a mesma, que não há diferença em termos de desempenho. Ocasionalmente, se houver um grande número de casos, um compilador pode ser inteligente o suficiente para criar uma tabela de pesquisa que produziria um desempenho um pouco melhor.

Um sintetizador VHDL pode ser capaz de fazer algo semelhante. Mas você ainda precisaria de um grande número de casos. Nesse caso (trocadilhos), você provavelmente desejaria usar uma declaração de caso de qualquer maneira, pois ela fornece melhor legibilidade quando há um grande número de opções.

embedded.kyle
fonte