Blocking, delayed assignment vs Non-blocking, delayed assignment on a buffer

I am posting this question after going through a famous presentation on “understanding verilog blocking and non-blocking assignments by stuart sutherland” which literally discusses every possible variant.

Input
0-10 LOW
10-20 HIGH
20-30 LOW
30-33- HIGH
33-36-LOW
36-45 HIGH
45-end of simulation LOW

For the 2 cases below my analysis is output follows input with the mentioned delay. so the glitch propagates in both cases (transport delay). But in the presentation the one with blocking assignment stays HIGH from 38-50 which is incorrect.

Can anyone confirm the same? The output would be the same for both cases below is my analysis.


always@(in)
output <= #5 in;


always@(in)
output = #5 in;

*In reply to hsam:*For simulation, it helps to unroll these procedural looping statements.

initial begin
        @(in)
        output <= #5 in;
        @(in)
        output <= #5 in;
        @(in)
        output <= #5 in;
        ...

Using non-blocking assignments, there is no delay between the successive
@(in)
constructs, so every change on
in
gets caught. The change to
out
gets scheduled for 5 time units later for every change of
in
. That is the definition of transport delay.

initial begin
        @(in)
        output = #5 in;
        @(in)
        output = #5 in;
        @(in)
        output = #5 in;
        ...

Using blocking assignments, there is a 5 time unit delay between the successive
@(in)
constructs, so every change on
in
that happens during that delay is lost.
in
cannot change faster the the propagation delay to
out
. That is the definition of inertial delay.

In reply to hsam:

I don’t think glitch propagates in both cases…
Non-blocking: glitch propagates
blocking: glitch won’t propagate

are you seeing the same output in both cases? which simulation tool used for this?

In reply to dave_59:

I thought that the effect of blocking statements is only on the next statements within a procedural block. Based on the explanation it sounds like even the always block once triggered is paused if the always block has blocking statements and is paused till the blocking statements complete their evaluation and assignment and only then it gets unblocked and start responding again to any triggers on it’s sensitivity list.

whereas in the non-blocking case we evaluate continuously as the always block is never paused by the transport delays in the non-blocking statements. And I guess the same holds even if we had an inertial delay using non-blocking statements.

Please confirm. Thanks a lot Dave for your earlier explanation.

In reply to Desam:

I was just white boarding, No simulations.

In reply to dave_59:

what happens here if the clk period is 4ns?

Does that mean that at the 2nd posedge of the clk this always block is not triggered as the assignment to B is blocking?


always@(posedge clk)
begin
 A = 1;
 B = #5 A+1;
end


How about this always block at the 2nd posedge of the clock?


always@(posedge clk)
begin
 A = 1;
 #5 B = A+1;
end

In reply to hsam:

In both always blocks, the 2nd posedge gets missed because of the procedural delay. Each always block creates only a single process.