¿Cómo se sintetizan las instrucciones de bloqueo? - Verilog

2

Entiendo que con el siguiente código de Verilog

always @(posedge i_clock)
begin
    r_Test_1 <= 1'b1;
    r_Test_2 <= r_Test_1;
    r_Test_3 <= r_Test_2;
end

Utiliza declaraciones no bloqueantes, todas en paralelo y entiendo que cuando se sintetiza, es básicamente 3 registros en serie y se necesitan 3 ciclos de reloj para que 1'b1 alcance r_Test_3.

Pero que hay de esto,

always @(posedge i_clock)
begin
    r_Test_1 = 1'b1;
    r_Test_2 = r_Test_1;
    r_Test_3 = r_Test_2;
end

Esto usa instrucciones de bloqueo y, por lo tanto, todo este código se debe realizar en serie. ¿Cómo exactamente se sintetizará esto? Quiero decir, ¿será exactamente igual? Estoy confundido.

    
pregunta AlfroJang80

3 respuestas

5

Lo que hace que VHDL y verilog sean algo confusos es que fueron diseñados originalmente para describir hardware para simulación y luego reutilizados para describir hardware para síntesis.

  

Entiendo que con el siguiente código de Verilog

     

(Ejemplo de código snip usando asignaciones de bloqueo)

     

Utiliza declaraciones no bloqueantes, todas en paralelo y entiendo que cuando se sintetiza, es básicamente 3 registros en serie y se necesitan 3 ciclos de reloj para que 1'b1 alcance r_Test_3.

Cuidado.

Recuerde que el estado inicial de los registros no está definido. Como resultado, a menos que haya especificado el estado inicial de los registros *, es muy probable que su sintetizador optimice esto para que todas sus señales tengan un valor constante de 1.

Por ahora, simulamos que estableciste el estado inicial de los registros en cero y simplemente no lo has incluido en tu ejemplo. En ese caso, como usted dice, habrá tres registros establecidos uno tras otro en los tres primeros bordes del reloj.

  

Pero que hay de esto,

     

(Ejemplo de código snip usando asignaciones de bloqueo)

     

Esto usa instrucciones de bloqueo y, por lo tanto, todo este código se debe realizar en serie. ¿Cómo exactamente se sintetizará esto? Quiero decir, ¿será exactamente igual? Estoy confundido.

Como dice el fotón, ese código es equivalente a.

always @(posedge i_clock)
begin
    r_Test_1 = 1'b1;
    r_Test_2 = 1'b1;
    r_Test_3 = 1'b1;
end

Pero nada de eso realmente responde a tu pregunta real que se reduce a.

  

¿Cómo se sintetizan los bloqueos en los bloques secuenciales siempre sintetizados?

Cómo se comporta una instrucción de bloqueo en un bloque secuencial y, por lo tanto, cómo se sintetiza depende de dónde la lea. Hay tres casos.

  • El mismo bloque siempre, leer después de escribir.
  • El mismo bloque siempre, leer antes de escribir (o sin escribir en esta invocación del bloque).
  • Bloque siempre diferente.

En el primer caso, no hay necesidad de un registro (aunque uno puede generarse inicialmente y luego eliminarse por tener un fanout cero). La señal solo se alimenta de manera combinatoria.

En el segundo caso, el valor debe almacenarse de un ciclo de reloj al siguiente, por lo que es necesario un registro.

Tenga en cuenta que en algunos casos el control de flujo puede significar que una lectura es a veces después de una escritura y otras no, en ese caso la herramienta de síntesis deberá generar un mux para leer desde el registro o directamente desde la lógica, según corresponda. al igual que necesita generar muxes cuando se escribe un valor en varias rutas diferentes.

En el tercer caso, el comportamiento no está bien definido. En la simulación, los resultados dependerán del orden en que se evalúen los bloques siempre. En síntesis, la herramienta probablemente emitirá una advertencia y hará algo, pero lo que haga puede que no sea lo que quería.

Por lo tanto, debe evitar el tercer caso. Si usa las asignaciones de bloqueo en bloques siempre secuenciales, debería solo leer los resultados de esas asignaciones desde el mismo bloque siempre. Las señales que pasan entre diferentes bloques siempre (o que salen al mundo exterior) siempre deben usar asignaciones sin bloqueo.

* Desafortunadamente, la capacidad de especificar el estado inicial de los registros es algo que varía entre las herramientas (y las versiones de las herramientas), algunos permiten el uso de bloques "iniciales" para este propósito, algunos requieren técnicas específicas de las herramientas, otros no Apóyalo en todo.

    
respondido por el Peter Green
2

Tu segundo bloque de código es equivalente a

always @(posedge i_clock)
begin
    r_Test_1 = 1'b1;
    r_Test_2 = 1'b1;
    r_Test_3 = 1'b1;
end

Puede sintetizarse como 3 flip-flops, todos con entradas ligadas a la lógica alta.

O simplemente se puede sintetizar como un solo flip-flop, con toda la otra lógica que está conectada a r_Test_1 , r_Test_2 o r_Test_3 realmente se conecta a la misma red física del circuito (asumiendo que es fan-out Los requisitos todavía se pueden cumplir de esta manera).

Dicho esto, estoy de acuerdo con el comentario de Oldfart. Se adhieren a la asignación no bloqueante para la lógica secuencial sintetizable.

    
respondido por el The Photon
0

Tu primer bloque es equivalente a bloques paralelos

always @(posedge i_clock)  r_Test_1 <= 1'b1;
always @(posedge i_clock)  r_Test_2 <= r_Test_1;
always @(posedge i_clock)  r_Test_3 <= r_Test_2;

Que se sintetiza en una cadena de fracasos

El segundo se ajusta a

always @(posedge i_clock)  r_Test_3 <= 1'b1;

Que es un flop. Esto supone que no hay otras referencias a las otras variables fuera del bloque.

    
respondido por el dave_59

Lea otras preguntas en las etiquetas