Atraso de Atribuição Inter e Intra Verilog
As instruções de atraso Verilog podem ter atrasos especificados no lado esquerdo ou no lado direito do operador de atribuição.
Atrasos entre tarefas
// Delay is specified on the left side
#<delay> <LHS> = <RHS>
Uma atribuição entre tarefas A instrução de atraso tem valor de atraso no LHS do operador de atribuição. Isso indica que a instrução em si é executada depois o atraso expira e é a forma mais comum de controle de atraso.
module tb;
reg a, b, c, q;
initial begin
$monitor("[%0t] a=%0b b=%0b c=%0b q=%0b", $time, a, b, c, q);
// Initialize all signals to 0 at time 0
a <= 0;
b <= 0;
c <= 0;
q <= 0;
// Inter-assignment delay: Wait for #5 time units
// and then assign a and c to 1. Note that 'a' and 'c'
// gets updated at the end of current timestep
#5 a <= 1;
c <= 1;
// Inter-assignment delay: Wait for #5 time units
// and then assign 'q' with whatever value RHS gets
// evaluated to
#5 q <= a & b | c;
#20;
end
endmodule
Observe que q se torna 1 em 10 unidades de tempo porque a instrução é avaliada em 10 unidades de tempo e RHS, que é uma combinação de a, b e c, é avaliada como 1.
Registro de simulação
xcelium> run [0] a=0 b=0 c=0 q=0 [5] a=1 b=0 c=1 q=0 [10] a=1 b=0 c=1 q=1 xmsim: *W,RNQUIE: Simulation is complete.
Atrasos entre tarefas
// Delay is specified on the right side
<LHS> = #<delay> <RHS>
Uma tarefa interna atraso é aquele em que há um atraso no RHS do operador de atribuição. Isso indica que a instrução é avaliada e os valores de todos os sinais no RHS são capturados primeiro. Então ele é atribuído ao sinal resultante somente depois o atraso expira.
module tb;
reg a, b, c, q;
initial begin
$monitor("[%0t] a=%0b b=%0b c=%0b q=%0b", $time, a, b, c, q);
// Initialize all signals to 0 at time 0
a <= 0;
b <= 0;
c <= 0;
q <= 0;
// Inter-assignment delay: Wait for #5 time units
// and then assign a and c to 1. Note that 'a' and 'c'
// gets updated at the end of current timestep
#5 a <= 1;
c <= 1;
// Intra-assignment delay: First execute the statement
// then wait for 5 time units and then assign the evaluated
// value to q
q <= #5 a & b | c;
#20;
end
endmodule
Observe que a atribuição para q está faltando no log!
Registro de simulação
xcelium> run [0] a=0 b=0 c=0 q=0 [5] a=1 b=0 c=1 q=0 xmsim: *W,RNQUIE: Simulation is complete.
Isso ocorre porque em 5 unidades de tempo, a e c são atribuídos usando instruções sem bloqueio. E o comportamento de não-bloqueio instruções é tal que RHS é avaliado, mas é atribuído à variável somente no final desse passo de tempo.
Portanto, o valor de a e c é avaliado como 1, mas ainda não atribuído quando a próxima instrução não bloqueante, que é a de q, é executada. Então, quando RHS de q é avaliado, a e c ainda tem o valor antigo de 0 e, portanto,
$monitor
não detecta uma alteração para exibir a instrução. Para observar a mudança, vamos alterar as instruções de atribuição para a e c de não bloqueante para bloqueante.
...
// Non-blocking changed to blocking and rest of the
// code remains the same
#5 a = 1;
c = 1;
q <= #5 a & b | c;
...
Registro de simulação xcelium> run [0] a=0 b=0 c=0 q=0 [5] a=1 b=0 c=1 q=0 [10] a=1 b=0 c=1 q=1 xmsim: *W,RNQUIE: Simulation is complete.
Verilog