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
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
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
By “before time 0” I meant during the Initial Singularity before the Big Bang when time and space did not exist.
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.