done
probablemente se esté actualizando antes de que se ejecute siempre el bloque en el mismo paso de tiempo (es decir, tiempo cero).
A wire
solo se puede asignar con una asignación de bloqueo continuo. Las asignaciones no bloqueantes ( <=
) solo se pueden hacer a reg
. Si las asignaciones de reg
s que la unidad done
cambian de bloqueo ( =
) a no bloqueo ( <=
), debería ser el resultado deseado.
Una asignación sin bloqueo hace una evaluación inmediata con una actualización retrasada. Esto permite evaluar los valores correctos sin afectar la evaluación de una expresión dependiente. Nota: la actualización retrasada está en el programador de pasos de tiempo verilog; no tendrá un retraso visible en la forma de onda.
Use las asignaciones no bloqueantes en reg
que desea tratar como un flop. Cualquier reg
usado para la lógica combinacional o la generación de reloj debe usar el bloqueo. Habrá condiciones de carrera si el bloqueo no se utiliza para la lógica combinacional o el reloj.
...
reg clk;
reg a,b,c;
always #10 clk = !clk;
assign done = func(a,b,c);
initial begin
clk=0;
a <= 1'b0;
b <= 1'b0;
c <= 1'b0;
#10;
a <= 1'b1;
#20;
b <= 1'b1;
a <= 1'b0;
#20;
a <= 1'b1;
c <= 1'b1;
#20;
a <= 1'b0;
b <= 1'b0;
end