Diferencia entre la instrucción If-else y Case en VHDL

Quiero entender cómo se sintetizan diferentes construcciones en código VHDL en RTL.

  • ¿Alguien puede decirme la diferencia entre la construcción If-Else y las construcciones de declaraciones Case de un proceso en VHDL en términos de cómo la herramienta de síntesis infiere el código en el circuito RTL?
  • Considere el caso de múltiples if-else anidados y la combinación de sentencias de caso con la construcción if-else dentro de un proceso.
  • ¿También cuándo usar qué construcción?

PD: He visto una pregunta relacionada "Múltiples sentencias if en proceso en vhdl", pero eso no responde a mi pregunta de todos modos.

No puedo comentar cómo se configurarían las puertas físicas, pero en la mayoría de los compiladores que emiten un ensamblaje x86, un if-else generalmente existe como una verificación única con un salto condicional (por ejemplo, jg, jl, jz, jnz, etc.), mientras que switch organiza los casos en orden numérico y realiza iteraciones dec/ jzinstrucciones, lo cual es mucho más eficiente. Quizás se aplique aquí una optimización similar.
@Polynomial El comportamiento de If-else y el caso son significativamente diferentes en los lenguajes de hardware en comparación con su programación lineal típica. Las optimizaciones del código de operación no son muy relevantes ya que la instrucción HDL se ejecuta "instantáneamente".

Respuestas (2)

¿Alguien puede decirme la diferencia entre la construcción If-Else y las construcciones de declaraciones Case de un proceso en VHDL en términos de cómo la herramienta de síntesis infiere el código en el circuito RTL?

La if-elsif-elseconstrucción infiere una red de enrutamiento de prioridad:

esquemático

simular este circuito : esquema creado con CircuitLab

esto 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;

La caseconstrucción, por otro lado, infiere un gran ol 'mux:

ingrese la descripción de la imagen aquí

esto 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, estos son diseños muy simplificados con una sola expresión de valor, lo que da como resultado una salida.

Considere el caso de múltiples if-else anidados y la combinación de sentencias de caso con la construcción if-else dentro de un proceso.

Según lo anterior, puede ver cómo anidarían/mezclarían.

¿También cuándo usar qué construcción?

Dado que if-elseinfiere prioridad, debe usarse cuando pueda ocurrir más de una condición de entrada. Usar case, por otro lado, es apropiado cuando las entradas son mutuamente excluyentes.

Entiendo que la declaración de caso funciona solo para una condición de entrada única y if-else puede funcionar para múltiples condiciones de entrada. Pero ambas construcciones esencialmente generan muxes (en ausencia de clk). ¿No es posible que la síntesis lógica pueda optimizar if-else de una sola entrada a un solo mux grande en lugar de una cadena de muxes? Además, ¿qué es una red de enrutamiento de prioridad... no es simplemente una cadena de muxes en lugar de 1 gran mux?
Además, cuando tenemos un proceso sensible a un reloj, if-else puede generar elementos secuenciales como registros, pestillos, etc. ¿Puede una declaración de caso generar también lógica secuencial?
Sí, una red de enrutamiento prioritario es exactamente eso: una cadena de muxes. La naturaleza de la if-elseconstrucción, sin embargo, es donde surge esa cadena. La primera condición debe fallar para que se pruebe la segunda condición. Este no es el caso para, er, la caseconstrucción, y es por eso que una if-elsedeclaración no se pudo sintetizar como un mux grande único.
Y sí, una casedeclaración también puede generar lógica secuencial. Encontré "Real World VHDL" , una serie de diapositivas de conferencias de la Universidad de Glasgow, que pueden serle útiles.
Esta es una buena referencia.
Angelo Stavrow: ¿Significa esto que el caso-ejemplo tiene menos demora de entrada a salida que el caso si/si no?

En esta antigua publicación de blog , el autor escribió y sintetizó dos versiones funcionalmente equivalentes del código VHDL. Uno usando if-else, el otro usando case. El resultado:

Sinteticé este código y obtuve los resultados exactos. Incluso el esquema RTL era exactamente el mismo para ambos programas.

Y su conclusión:

Esto muestra que las sentencias 'case' y 'if...elsif...else' son igualmente eficientes. Pero si quiere escribir un código claro, entonces mejor use 'case'. 'case' es muy útil cuando el la salida depende de una gran cantidad de condiciones. Pero si la cantidad de condiciones es muy pequeña (2 o 3), entonces puede usar 'if..elseif..else'.

También hay docenas de publicaciones sobre este tema en Stack Overflow para todos los idiomas imaginables. La conclusión es generalmente la misma, que no hay diferencia en cuanto al rendimiento. Ocasionalmente, si hay una gran cantidad de casos, un compilador puede ser lo suficientemente inteligente como para crear una tabla de búsqueda que produzca un rendimiento ligeramente mejor.

Un sintetizador VHDL puede ser capaz de hacer algo similar. Pero aún necesitaría una gran cantidad de casos, en cuyo caso (juego de palabras) probablemente querrá usar una declaración de caso de todos modos, ya que proporciona una mejor legibilidad donde hay una gran cantidad de opciones.