Blocking/Nonblocking with Delay

delayverilog

I am now confused by one piece of Verilog Codee, its kind of testing the blocking or non-blocking assignment features that combination with Delay model.

 module cl_tb;

  reg x,y,z;


initial begin
    x = 2;
    #4;
    y <= #9 x;
    x = 1;
    #50 $stop;
end

initial begin
  $monitor("%0t,%d,%d,%d",$time,x,y,z);
end

always @(x,y)
begin
   z = # 2 x+y;
end

endmodule 

By hand-calculation, I could get the result
[ Time: X value, Y value, Z value] below:
[0: 2,x,x]
[2: 2,0,2]
[4: 1,0,2]
[6: 1,0,1]
[13: 1,2,1]
[15: 1,2,3]

However, the simulation result is
[0,0,x,x];
[4,1,x,x];
[13,1,0,x];
[15,1,0,1];

Which you can see from the link http://www.edaplayground.com/x/Was

I am wondering why the always@(x,y) was not triggered at timeslot 2 and 4.

Best

Best Answer

Register variables in Verilog represent flip-flops in hardware.

The declaration:

reg x;

creates a single-bit register that can only hold the values:
x (unknown), 0 or 1.

The cl_tb.v code is attempting to assign values to register x that are too large to fit in a single bit value. Verilog converts the integers to binary representation and fills in the register starting at the LSB until it runs out of bits in the register and it stops. It issues no warnings for this (perhaps because it's expected that sometimes you might want to use the LSBs of a value).

Change your declaration for the x, y and z registers to make them wide enough to handle your largest anticipated value.

reg [2:0] x, y, z;

Then the output is:

0,2,x,x
4,1,x,x
13,1,2,x
15,1,2,3

The 'hand calculation' you show is incorrect. For example, the always block triggers when x is updated at time zero, but y is not assigned until #9 later. Hence register z is also still unknown and the monitor is not triggered.