Como sus nombres lo indican, las asignaciones sin bloqueo permiten la ejecución simultánea mientras que las asignaciones de bloqueo se ejecutan secuencialmente.
Tome la explicación de Nandland, por ejemplo:
En C, "Solo se permite ejecutar la segunda línea una vez que se completa la primera línea". Esto se usa como ejemplo o analogía con las sentencias de bloqueo en HDL.
Luego usa un ejemplo de 3 instrucciones que no bloquean frente a 3 que bloquean dentro de un bloque siempre, pero dice que tomará 3 ciclos de reloj para que el ejemplo sin bloqueo ejecute la tercera instrucción, mientras que las asignaciones de bloqueo "inmediatamente" confieren su valor al siguiente registro. .
always @(posedge i_clock)
begin
r_Test_1 <= 1'b1;
r_Test_2 <= r_Test_1;
r_Test_3 <= r_Test_2;
end
// versus:
always @(posedge i_clock)
begin
r_Test_1 = 1'b1;
r_Test_2 = r_Test_1;
r_Test_3 = r_Test_2;
end
Me parece que sus nombres deberían cambiarse. ¿Dónde está mi concepto erróneo? ¿Por qué nombrar las asignaciones sin bloqueo en la lógica secuencial cuando las declaraciones secuenciales bloquean evidentemente la ejecución de las declaraciones posteriores, ya que son declaraciones SECUENCIALES?
No es la asignación lo que se "bloquea", es la evaluación de las sentencias dentro del proceso.
En primer lugar, en ambos casos, todas las declaraciones se evalúan en cada ciclo de reloj. Pero como se señaló en un comentario, con la asignación sin bloqueo, se necesitan tres ciclos de reloj antes de que el valor se propague al último registro.
Con la asignación sin bloqueo, las tres sentencias se pueden ejecutar simultáneamente (por ejemplo, en hardware) o en cualquier orden arbitrario y siempre producen el mismo resultado. La evaluación de cualquier afirmación no "bloquea" la evaluación de las demás.
Con la asignación de bloqueo, las asignaciones deben completarse en el orden en que aparecen, al igual que en el código C. Cada sentencia "bloquea" la ejecución de las sentencias que le siguen.
¿Por qué la asignación "sin bloqueo" en Verilog parece un nombre inapropiado?
Porque es un nombre inapropiado.
El término no bloqueo se creó como un antónimo corolario del nombre inapropiado anterior bloqueo .
Mejores términos para bloquear y no bloquear serían evaluación ordenada y evaluación desordenada o evaluación en serie y evaluación paralela .
Pero luego hay un giro cruel: la evaluación ordenada se sintetiza como un circuito paralelo, mientras que la evaluación desordenada se sintetiza como un circuito en serie.
Nombre inapropiado de "bloqueo" | Nombre inapropiado del antónimo "sin bloqueo" |
---|---|
Evaluación ordenada (orden de código fuente) | Evaluación desordenada (orden determinado por el simulador) |
Evaluación de series (orden de código fuente) | Evaluación paralela (orden determinado por el simulador) |
Síntesis paralela | Síntesis en serie |
Aquí hay un ejemplo de Verilog que sinteticé con Quartus.
module BlockingNonBlocking
(
input wire clock,
input wire data,
output reg R1,
output reg R2,
output reg R3,
output reg R4,
output reg R5,
output reg R6
);
// "Blocking" misnomer
// Ordered evaluation (source-code order)
// Series evaluation (source-code order)
// Parallel synthesis
always @(posedge clock)
begin
R1 = data;
R2 = R1;
R3 = R2;
end
// "Non-Blocking" antonym misnomer
// Unordered evaluation (order determined by simulator)
// Parallel evaluation (order determined by simulator)
// Series synthesis
always @(posedge clock)
begin
R4 <= data;
R5 <= R4;
R6 <= R5;
end
endmodule
Figura 1 – Síntesis bloqueante versus no bloqueante.
Como puede ver, ambas variantes bloquean (en el verdadero sentido de la palabra) la data
señal hasta el borde positivo de lo clock
que significa que ambos son circuitos secuenciales, pero R1, R2 y R3 están en paralelo mientras que R4, R5 y R6 están en serie.
Los términos bloqueo y no bloqueo tienen más que ver con la semántica de ejecución del proceso de simulación que con la síntesis. Es lamentable que bloque sea también homónimo de agrupación o área contigua (a begin
/ end
bloque de sentencias).
Tanto las asignaciones de bloqueo como las de no bloqueo son declaraciones de procedimiento que se ejecutan secuencialmente dentro del alcance de un begin/end
proceso. Ambas declaraciones evalúan la expresión del lado derecho a medida que se encuentran, pero la diferencia entre ellas se muestra mejor con retrasos dentro de la asignación:
initial begin
#10
b = #5 a;
c = #5 b;
end
initial begin
#10
b <= #5 a;
c <= #5 b;
end
Ambos initial
procesos comienzan en el tiempo 0, luego se retrasan 10 unidades de tiempo. Ambas declaraciones de asignación evalúan el valor de a
en el tiempo 10. Pero la primera asignación de bloqueo suspende el proceso durante 5 unidades de tiempo, no se actualiza b
hasta el tiempo 15 y no comienza a ejecutar la segunda asignación de bloqueo hasta el tiempo 15. También suspende el initial
proceso y no se actualiza c
hasta el momento 20, que es cuando initial
finaliza el primer proceso.
La primera asignación sin bloqueo en el segundo initial
proceso programa y actualiza a b
la hora 15, pero no suspende el proceso. Entonces, la segunda asignación sin bloqueo se evalúa b
en el tiempo 10, que es su valor 'antiguo'. Programa una actualización c
con el valor anterior b
en el tiempo 15. El segundo initial
proceso finaliza en el tiempo 10.
Por cierto, rara vez ves tareas de bloqueo con retrasos dentro de la tarea. Es un remanente de Verilog muy temprano antes de que yo introdujera las asignaciones sin bloqueo en el lenguaje.
Estera
Andrés
DonFusili
usuario_1818839
mitu raj
tío dino