Bloqueo y no bloqueo de Verilog
Bloqueo
Bloqueo las sentencias de asignación se asignan usando =
y se ejecutan uno tras otro en un bloque procesal. Sin embargo, esto no evitará la ejecución de declaraciones que se ejecutan en un bloque paralelo.
module tb;
reg [7:0] a, b, c, d, e;
initial begin
a = 8'hDA;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
b = 8'hF1;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
c = 8'h30;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
end
initial begin
d = 8'hAA;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
e = 8'h55;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
end
endmodule
Tenga en cuenta que hay dos initial
bloques que se ejecutan en paralelo cuando comienza la simulación. Las declaraciones se ejecutan secuencialmente en cada bloque y ambos bloques finalizan en el tiempo 0ns. Para ser más específicos, la variable a se asigna primero, seguido de la declaración de visualización que luego es seguida por todas las demás declaraciones. Esto es visible en la salida donde la variable b y c son 8'hxx en la primera instrucción de visualización. Esto se debe a que la variable b y c las asignaciones aún no se han ejecutado cuando el primer $display
se llama.
ncsim> run [0] a=0xda b=0xx c=0xx [0] a=0xda b=0xf1 c=0xx [0] a=0xda b=0xf1 c=0x30 [0] d=0xaa e=0xx [0] d=0xaa e=0x55 ncsim: *W,RNQUIE: Simulation is complete.
En el siguiente ejemplo, agregaremos algunas demoras en el mismo conjunto de declaraciones para ver cómo se comporta.
module tb;
reg [7:0] a, b, c, d, e;
initial begin
a = 8'hDA;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
#10 b = 8'hF1;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
c = 8'h30;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
end
initial begin
#5 d = 8'hAA;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
#5 e = 8'h55;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
end
endmodule
Registro de simulación ncsim> run [0] a=0xda b=0xx c=0xx [5] d=0xaa e=0xx [10] a=0xda b=0xf1 c=0xx [10] a=0xda b=0xf1 c=0x30 [10] d=0xaa e=0x55 ncsim: *W,RNQUIE: Simulation is complete.
Sin bloqueo
Sin bloqueo La asignación permite programar asignaciones sin bloquear la ejecución de las siguientes declaraciones y se especifica mediante un <=
símbolo. Es interesante notar que el mismo símbolo se usa como operador relacional en expresiones y como operador de asignación en el contexto de una asignación sin bloqueo. Si tomamos el primer ejemplo de arriba, reemplace todo =
symobls con un operador de asignación sin bloqueo <=
, veremos alguna diferencia en la salida.
module tb;
reg [7:0] a, b, c, d, e;
initial begin
a <= 8'hDA;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
b <= 8'hF1;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
c <= 8'h30;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
end
initial begin
d <= 8'hAA;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
e <= 8'h55;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
end
endmodule
Mira que todos los $display
declaraciones impresas 'h'x
. La razón de este comportamiento radica en la forma en que se ejecutan las asignaciones sin bloqueo. Se captura el RHS de cada declaración sin bloqueo de un paso de tiempo particular y se pasa a la siguiente declaración. El valor RHS capturado se asigna a la variable LHS solo al final del paso de tiempo.
ncsim> run [0] a=0xx b=0xx c=0xx [0] a=0xx b=0xx c=0xx [0] a=0xx b=0xx c=0xx [0] d=0xx e=0xx [0] d=0xx e=0xx ncsim: *W,RNQUIE: Simulation is complete.
Entonces, si desglosamos el flujo de ejecución del ejemplo anterior, obtendremos algo como lo que se muestra a continuación.
|__ Spawn Block1: initial | |___ Time #0ns : a <= 8'DA, is non-blocking so note value of RHS (8'hDA) and execute next step | |___ Time #0ns : $display() is blocking, so execute this statement: But a hasn't received new values so a=8'hx | |___ Time #0ns : b <= 8'F1, is non-blocking so note value of RHS (8'hF1) and execute next step | |___ Time #0ns : $display() is blocking, so execute this statement. But b hasn't received new values so b=8'hx | |___ Time #0ns : c <= 8'30, is non-blocking so note value of RHS (8'h30) and execute next step | |___ Time #0ns : $display() is blocking, so execute this statement. But c hasn't received new values so c=8'hx | |___ End of time-step and initial block, assign captured values into variables a, b, c | |__ Spawn Block2: initial | |___ Time #0ns : d <= 8'AA, is non-blocking so note value of RHS (8'hAA) and execute next step | |___ Time #0ns : $display() is blocking, so execute this statement: But d hasn't received new values so d=8'hx | |___ Time #0ns : e <= 8'55, is non-blocking so note value of RHS (8'h55) and execute next step | |___ Time #0ns : $display() is blocking, so execute this statement. But e hasn't received new values so e=8'hx | |___ End of time-step and initial block, assign captured values into variables d and e | |__ End of simulation at #0ns
A continuación, usemos el segundo ejemplo y reemplacemos todas las declaraciones de bloqueo por no bloqueo.
module tb;
reg [7:0] a, b, c, d, e;
initial begin
a <= 8'hDA;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
#10 b <= 8'hF1;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
c <= 8'h30;
$display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
end
initial begin
#5 d <= 8'hAA;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
#5 e <= 8'h55;
$display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
end
endmodule
Una vez más, podemos ver que el resultado es diferente al que obtuvimos antes.
Registro de simulaciónncsim> run [0] a=0xx b=0xx c=0xx [5] d=0xx e=0xx [10] a=0xda b=0xx c=0xx [10] a=0xda b=0xx c=0xx [10] d=0xaa e=0xx ncsim: *W,RNQUIE: Simulation is complete.
Si desglosamos el flujo de ejecución, obtendremos algo como lo que se muestra a continuación.
|__ Spawn Block1 at #0ns: initial | |___ Time #0ns : a <= 8'DA, is non-blocking so note value of RHS (8'hDA) and execute next step | |___ Time #0ns : $display() is blocking, so execute this statement: But a hasn't received new values so a=8'hx | |___ End of time-step : Assign captured value to variable a, and a is now 8'hDA | |___ Wait until time advances by 10 time-units to #10ns | | |___ Time #10ns : b <= 8'F1, is non-blocking so note value of RHS (8'hF1) and execute next step | |___ Time #10ns : $display() is blocking, so execute this statement. But b hasn't received new values so b=8'hx | |___ Time #10ns : c <= 8'30, is non-blocking so note value of RHS (8'h30) and execute next step | |___ Time #10ns : $display() is blocking, so execute this statement. But c hasn't received new values so c=8'hx | |___ End of time-step and initial block, assign captured values into variables b, c | |__ Spawn Block2 at #0ns: initial | |___ Wait until time advances by 5 time-units to #5ns | | |___ Time #5ns : d <= 8'AA, is non-blocking so note value of RHS (8'hAA) and execute next step | |___ Time #5ns : $display() is blocking, so execute this statement: But d hasn't received new values so d=8'hx | |___ End of time-step : Assign captured value to variable d, and d is now 8'hAA | |___ Wait until time advances by 5 time-units to #5ns | | |___ Time #10ns : e <= 8'55, is non-blocking so note value of RHS (8'h55) and execute next step | |___ Time #10ns : $display() is blocking, so execute this statement. But e hasn't received new values so e=8'hx | |___ End of time-step and initial block, assign captured values to variable e, and e is now 8'h55 | |__ End of simulation at #10ns
Verilog