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

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

In reply to dave_59:

Thank you

In reply to dave_59:

I too had the same doubt that answer should be 5 & 7. But is it that since add is a static task, so when fork-join will end, latest value will overlap(/erase any previous value) & hence 7 is displayed twice.
Please correct me if I’m wrong.
Thanks

In reply to GoAyushi:

Hope this makes things clearer

Since the add is a static task by default, the local variables are allotted only one memory location for all calls to that task.

@t=0 → a=3 , b=2
@t=1 → a=3 , b=4; (second call overwrites the first call values, as no separate memory is allocated for local variables in different calls to the task); The first call hasn’t reached the display statement because of #2 delay.
@t=2 → The first call display statement is executed and the sum is a(3)+b(4)=7
@t=3 → The second call’s display statement is executed and the sum is again a(3)+b(4)=7.

In reply to dave_59:

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.

Hi Dave,
From the quotes is it implied that all the functions in my scoreboard class are automatic by default? And during run_phase all calls made to any task or functions will have an automatic behavior?
Thanks,
DJ

In reply to tejal vernekar:

please give example with using automatic keyword,i am getting error…

In reply to danajewely:
First question, yes. See the second paragraph of my previous reply.

Second question, not exactly. The calling of a task or function does not determine its lifetime, only its declaration. All of the tasks/function in your UVM code will be automatic, but let’s say your driver calls a task/function via a virtual interface, the lifetime of those are static by default unless you declare them otherwise.

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.

Does that mean, by Default all functions and tasks are Automatic ?

I tried the example

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

whose o/p is 7 ,7 which means by default lifetime is static …

In reply to abajaj:

The default lifetime for everything is static, except for class methods, which can only have automatic lifetimes.

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.

what does this mean ?

In reply to abajaj:

module automatic test();
 
task add(int a, int b); // the lifetime of this task is now implicitly automatic
	#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 dave_59:

Hi Dave, thank you for your explanation. I am wondering more about the synthesis consequences of automatic vs static and what later enabled automatic? Specifically, it is my understanding that each call of a module, task, or function in a verilog program will synth into a hardware element or collection of for each.

Let’s say I have a fibonacci program with 20 rounds. For example, let’s say each round synthesizes to a single CLB such that I now have 20 CLBs utilized on the fpga to execute the entirety of the program. this would mean that each round is static in terms of it’s hardware implementation right? Automatic would be if I only had 1 or a few CLBs that could be reused over and over as many rounds as it takes to execute a program? I hope you can see my confusion. It hovers around how static and automatic are thought about in terms of synthesis, not programming.

Thanks Again!

In reply to dave_59:

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.

I still don’t get how the static task produces the correct result without the #2 delay and otherwise with the #2 delay.