Automatic variable

module test;
    initial begin
        for(int i = 0; i < 5; i++)begin
            fork
                begin
                    automatic int l = i;             
                    $display(i,l);
                end
            join_none
        end
    end
endmodule

What are the rules for automatic variable declaration? Why in the above code “l” is not behaving like a automatic variable?

In reply to yourcheers:

module test;
initial begin
for(int i = 0; i < 5; i++)begin
fork
begin
automatic int l = i;             
$display(i,l);
end
join_none
end
end
endmodule

What are the rules for automatic variable declaration? Why in the above code “l” is not behaving like a automatic variable?

In your example i,l display the same value 5 as execution of all threads happen after all of them forked off by that time i is 5.

Each instance of automatic variable mapped to separate memory location in stack.


        for(int i = 0; i < 5; i++)begin
            automatic int l = i;  // will be executed 5 time and mapped to 5 memory location in stack 
        end

Static variables are mapped to fixed memory location.


        for(int i = 0; i < 5; i++)begin
            //int l = i;  // illegal decalration
            int l;  // will be executed only once, mapped to one fixed memory location
            l = i; 
        end

you should use automatic variable when you want map the each instance of variable to separate memory space.
Note : Variable declared in the class is by default automatic.


module test;
    initial begin
        for(int i = 0; i < 5; i++)begin
            automatic int l = i;  
            fork
                begin           
                    $display(i,l);
                end
            join_none
        end
    end
endmodule

//output:
5  0
5  1
5  2
5  3
5  4

In reply to Rahulkumar:

I think the point you missed is the timing of when variable initialization happens in a declaration. A static variable gets initialized once before time 0. An automatic variable gets initialized each time the scope where variable where the variable is declared in gets activated. For both fork and begin blocks, this happens as soon as the parent process hits the fork or begin keywords (also the same for tasks or functions).

In the original example, there are no variables declared in the fork/join_none block. However, the variable
l
is declared inside the nested begin/end block process. The five sub-processes spawned by fork/join_none do not start executing until the parent process suspends or, as in this case, reaches the end. At that point the value of
i
is 5 for all the sub-processes. So all 5 copies of
l
get initialized to the value 5.

You can fix this by moving the declaration of
l
one scope level up

initial begin
        for(int i = 0; i < 5; i++)begin         
            fork
                automatic int l = i;  
                begin           
                    $display(i,l);
                end
            join_none
        end
    end

Or two levels as Rahulkumar suggested.

Thanks Rahul & Dave. Helpful information.

In reply to dave_59:

Hi Dave,
I have some questions.
Q1:You mention that a static variable gets initialized once before time 0. In the 1800-2017 page 128, the example shows executes once at time zero. So, the static var in sv should be initialized at time 0 or before time 0 ?

Q2:
In the following code, int x should be declared and initialized as 2 at time 0? Or int x should be declared at time 0, and get initialized as 2 at time 5?

initial begin
   #5;
   for(int i = 0; i < 5; i++)begin
      static int x = 2; 
   end
 end

Thank a lot!

In reply to peter:

By “before time 0” I meant during the Initial Singularity before the Big Bang when time and space did not exist. :smiling_face:

Sorry, my definition of “before time 0” is just a shortcut for saying "at time 0, but before any other processes spawned at time 0 by initial/always, or other continuous assignment constructs have begun.

In your example, x gets initialized as 2 at time 0.

1 Like