What is the exact difference between static tasks/functions and automatic tasks/functions ? please explain with a clear example

I executes a sample code to analyze the difference between static and automatic task/function but it gives me the same output ?
so please explain me the exact difference between them with clear example.
Thank you

The lifetime of a function or task is a concept that I’ve only seen in Verilog. Verilog started out with having only static lifetimes of functions or tasks, meaning that there was no call stack for arguments or variables local to the routines. This meant you could not have recursive or re-entrant routines, unlike most other modern programming languages. The thinking was synthesis could not create stacks of memory dynamically when called. Verilog 2001 added the ‘automatic’ lifetime qualifier to give routines the normal behavior of most programming languages. SystemVerilog added a lifetime qualifier for modules and interfaces so that all routines defined in that module would be considered automatic by default so you didn’t have to add the automatic keyword after each function or task declaration. SV also added the ‘static’ lifetime qualifier so that if for some stupid reason you declared a module as ‘automatic’ but still needed a particular function inside that module to have the original Verilog behavior. The
static
or
automatic
lifetime qualifier appears to the right of the
function
or
task
keyword.

Note that the lifetime of class methods are always automatic, you cannot even declare them with a static lifetime. This is not to be confused with a static class qualifier, where the static keyword appears to the left of the function or task. This means it is a method of the class type, not of a class instance or object.

Look at the tryfact example in 13.4.2 Static and automatic functions and see what happens if you don’t make the factorial function automatic.

In reply to dave_59:

Thank you for your kind reply Dave. but I executed that code with the following outputs.

1)I got the following results with using automatic keyword
0 factorial=1
1 factorial=1
2 factorial=2
3 factorial=6
4 factorial=24
5 factorial=120
6 factorial=720
7 factorial=5040

2)Output without automatic keyword I got
0 factorial=1
1 factorial=1
2 factorial=1
3 factorial=1
4 factorial=1
5 factorial=1
6 factorial=1
7 factorial=1

according to me this is static behavior and not automatic. Please rectify me in case my understanding is incorrect.

In reply to Hardik Trivedi:

Hi Hardik,

Where is the code for Factorial Example. I am not able to figure out the link for the example.

Thanks .

In reply to abhishekmj:

Hi Abhishek,

module tryfact;
// define the function
  function automatic integer factorial (input [31:0] operand);
    if (operand >= 2)
      factorial = factorial (operand - 1) * operand;
    else
      factorial = 1;
   endfunction: factorial
// test the function
  integer result;
  initial begin
    for (int n = 0; n <= 7; n++) begin
      result = factorial(n);
      $display("%0d factorial=%0d", n, result);
    end
  end
endmodule: tryfact

In reply to Hardik Trivedi:

Hi Hardik,

  Dave's explanation should clear your confusion between automatic and static.

For calculating the factorial, the function should be automatic so that there will be multiple memory allocations for the variable “factorial” which is a property of recursive function. If the function is static, then memory for the variable ‘factorial’ will be only once and finally factorial value is becoming ‘1’ in the recursive calls.

Consider the following example also for understanding the difference between static and automatic.


module test();

task add(int a, int b);
	#2;
	$display("the sum is %0d", a+b);
endtask

initial
	fork
		begin
			add(2,3);
		end
		begin
			#1;
			add(3,4);
		end
	join
endmodule

In the above example, the task add is static. So, memory for the variables a & b will be allocated only once. Hence, output for the program will be as follows (which will be definitely different from your prediction).

the sum is 7
the sum is 7.

make the task as automatic and see the difference.

1 Like

In reply to Hardik Trivedi:

Thanks Dave for the detailed explanation

Hi Dave Could u explain why methods with static lifetime are not allowed within a class?

In reply to Have_A_Doubt:
Declaring any function or task with an explicit static lifetime is something you should never need to do in either Verilog or SystemVerilog. If it were not for the mandate to be 100% backward compatibility with Verilog-2001, it could have been eliminated from SystemVerilog.

Because the
class
is a new construct in SystemVerilog, we had the opportunity to change the default lifetime and eliminate the confusion between ‘static function’ and ‘function static’. Anyone declaring a function with a static lifetime in a class would most likely be making a mistake thinking they were declaring a static method. By making it illegal, their mistake is caught much earlier.

In reply to puttasatish:

Hi puttasatish,
If I give the same code with no delay. I’m getting below results
the sum is 5
the sum is 7.
Do you know what could be the reason?

module test();
 
task add(int a, int b);
	//#2;
	$display("the sum is %0d", a+b);
endtask
 
initial
	fork
		begin
			add(2,3);
		end
		begin
			//#1;
			add(3,4);
		end
	join
endmodule

In reply to srikanthen:

With no delays, you have a race condition. There are many possible outcomes, although you are only likely to see 5,7, or 7,5. That is because most event driven simulators only exec one thread at a time and do not switch to another thread until there is a potential blocking event.

In reply to dave_59:

Thanks a lot Dave for clarification

what is potentail blocking event? can you please explain

In reply to lalithjithan:

what is potentail blocking event? can you please explain

That is any kind of construct that will block, like Delay or @signal_change, or has a chance of blocking, like wait(true_condition), mailbox.get(Item).

In reply to puttasatish:

Can anyone please explain me

module test();
 
task add(int a, int b);
	#2;
	$display("the sum is %0d", a+b);
endtask
 
initial
	fork
		begin
			add(2,3);
		end
		begin
			#1;
			add(3,4);
		end
	join
endmodule

How do we get sum is 7
Sum is 7
According to me, it should be 5 and 7, but for what reason the sum 7 and 7

In reply to tejal vernekar:

The a and b arguments are static variables. Please re-read the entire thread.

In reply to dave_59:

But for static lifetime, we need to use task static add(int a,int b)
By default it will have automatic lifetime

In reply to tejal vernekar:

Please re-read the entire thread. The default lifetime for the code you post is static.

In reply to tejal vernekar:

In reply to dave_59:
But for static lifetime, we need to use task static add(int a,int b)
By default it will have automatic lifetime

Keep in mind, task/function in module is always static at the fault. task/function in class is always automatic at default.

1 Like

In reply to cuonghl:

Thank you