always thread observations

 

In the past we have noticed that students have had some issues with the always threads, specifically the handling of the events when a particular block of always code is executing. Consider the example code in test1.v.

module test1(i1,i2);

input i1, i2;
reg [31:0] a;

always @(i1) begin
    #1 a = 1;
    #5 a = a + 1;
    #5 a = a + 2;
end

always @(i2) begin
    #1 a = 10;
end

initial begin
    $monitor ($time, "\t a = %d", a);
    a = 2;
end

endmodule

module testtest1();

reg i1, i2;

test1 t1(i1,i2);

initial begin
    i1 = 1;
    #2 i1 = 0;
    #10 $finish;
end

endmodule

 

In the code above, when i1 is first assigned the 1 at time = 0, the always thread in module test1 begins to execute, at time = 2, when i1 changes to 0, what happens? In the Synopsys Verilog compiler VCS, the second event is completely lost if it arrives during the execution of an always thread. A digital circuit does not "execute" this way, but with VCS, the event is lost.

Chronologic VCS simulator copyright 1991-2004
Contains Synopsys proprietary information.
Compiler version 7.1.2; Runtime version 7.1.2; Mar 4 13:21 2005

            0     a = 2
            1     a = 1
            6     a = 2
            11    a = 4
$finish at simulation time 12
V C S S i m u l a t i o n R e p o r t
Time: 12
CPU Time: 0.280 seconds; Data structure size: 0.0Mb
Fri Mar 4 13:21:50 2005
 

This action is also observed with Icarus Verilog version 0.8 (an open source Verilog compiler - work in progress).


Now if the code is slightly modified:

module test1(i1,i2);

input i1, i2;
reg [31:0] a;
 

//thread 1
always @(i1) begin
    #1 a = 1;
    #5 a = a + 1;
    #5 a = a + 2;
end

//thread 2
always @(i2) begin
    #1 a = 10;
end

initial begin
    $monitor ($time, "\t a = %d", a);
    a = 2;
end

endmodule

module testtest1();

reg i1, i2;

test1 t1(i1,i2);

initial begin
    i1 = 1;
    #2 i2 = 1;
    #10 $finish;
end

endmodule

 

The modification has been shown in red above. In this example, the invocation of the second always thread while the first one is executing, modifies the value of register a in module test1. So the question that arises is, "Which value of a does the first thread of module test1 use?"

Here, the value of a changes to 10 at time = 3, and at time = 6, when thread 1 executes its next instruction, the value of a is 10. Here is the observed output:

Chronologic VCS simulator copyright 1991-2004
Contains Synopsys proprietary information.
Compiler version 7.1.2; Runtime version 7.1.2; Mar 4 13:23 2005

               0        a = 2
               1        a = 1
               3        a = 10
               6        a = 11
               11       a = 13
$finish at simulation time 12
V C S S i m u l a t i o n R e p o r t
Time: 12
CPU Time: 0.300 seconds; Data structure size: 0.0Mb
Fri Mar 4 13:23:27 2005
CPU time: .070 seconds to compile + 2.580 seconds to link + .350 seconds in simulation