En realidad es bastante fácil. Primero, todos los bucles se desenrolla (el código no es synthesizable si no pueden ser desdobladas) y todas las funciones y tareas en línea. Después de que sólo está a la izquierda, si el caso y las declaraciones y asignaciones (si es caso y las declaraciones son esencialmente el mismo). las sentencias if se pueden transformar en multiplexores con las condiciones en la selección de entradas. Por ejemplo
if (cond1) begin
if (cond2)
foobar <= expr1;
end else
foobar <= expr2;
es el mismo
foobar <= cond1 ? (cond2 ? expr1 : foobar) : expr2;
(observe cómo el valor antiguo de foobar se utiliza en la cond1 && !cond2 caso). Por supuesto, hay un par de pasos adicionales para manejar el bloqueo de tareas asíncronas restablece, etc. Pero esta es la idea básica.
Recomiendo el uso de una herramienta de síntesis en simples fragmentos de código para aprender más acerca de la relación entre el código y el generado por el circuito. Usted puede utilizar de curso independientemente de la herramienta que está utilizando ya, pero yo no puedo escribir una respuesta a su pregunta sin mencionar Yosys, la Verilog herramienta de síntesis que he escrito. El comando yosys -p "proc;; show" test.v
va a traducir el módulo de prueba.v a a RTL netlist y mostrar el circuito (necesidades de graphviz y xdot instalado). Esto, por ejemplo, transformar esto en este.
Actualización: Farhad Yusufali frecuentes en los comentarios acerca del bloqueo de las asignaciones.
Considere el siguiente código:
always @(posedge clk) begin
a = x;
if (b) begin
c <= c + a;
a = y;
end
d <= a;
a = a + 1;
e <= a;
end
ahora podemos escribir esto como dos siempre se bloquea con sólo desbloqueo de asignación como este:
always @* begin
a_1 <= x;
if (b)
a_2 <= y;
else
a_2 <= a_1;
a_3 <= a_2 + 1;
end
always @(posedge clk) begin
if (b)
c <= c + a_1;
d <= a_2;
e <= a_3;
end
I. e. siempre a
se utiliza en el lado izquierdo de una asignación, nos movemos en la asignación para la asincrónico bloque y cambio a
a a_<index>
. Siempre a
se utiliza en el lado derecho de reemplazar con la última a_<index>
hemos creado. Cuando nos rama (como en if (b)
) y crear un nuevo a_<index>
en una de las ramas, entonces usted tiene que asegurarse de que la última asignación a una versión de a
en cada rama va para el mismo índice, la adición de asignaciones adicionales, según sea necesario (tales como la asignación de a_2
en la rama else).
Esta notación de la sustitución de una variable con múltiples variables con índices de esta manera es una variación de lo que se conoce como la SSA forma en que el compilador de diseño de la comunidad.