How to understand the automatic key word?

Recently I ran into a problem brought by automatic key work. Basically I understand the key work static/automatic determined the memory accolcate and variable lifetime or scope. But I don’t know what is default way for a variable/function/task in UVM testbench ? Please refer to following example .



always (event1) begin
  check;
end

always (event2) begin
  check;
end

always (event3) begin
  check;
end

task check;
  int i;
  int j;
  i++;
  j++;
endtask


Please image that what happened if even1 & event2 & event3 happened simultaneously ?

Another question is how to understand the always block, does it mean the separated threads when we have multiple always blocks ?

Thank

tasks and functions that are not declared as a class method default to a static lifetime, and all variables declared inside will be static as well. So i and j initialize to the value 0 at time 0. Each call to check() increments i and j by 1. If the tasks were declared with an automatic lifetime, then i and j would have an automatic lifetime. That means each time there is a call to check, i and j are allocated, initialized to 0, incremented by 1, and de-allocated upon return of the task.

Class methods can only be declared with an automatic lifetime and the variables inside the method will default to an automatic lifetime. Note that within either method or non-method tasks/functions, you have the option to explicitly declare individual variables with automatic or static lifetimes. You may want to read this post for more details.

Yes, each always block represents a separate thread. And the LRM does not guarantee atomic execution of the ++ operator, so it is possible to clobber a static variable when multiple threads are writing to it simultaneously. However in practice, I don’t think you could ever write a piece of code that shows this behavior.

In reply to dave_59:

Hi, Dave, thanks so much for your anwser, the only thing confused me is that you said “Class methods can only be declared with an automatic lifetime” ? It appears to me that we could use “static” in left to declare a function/task, which means we create a static function/task for this class, is that right ? So why “Class methods can only be declared with an automatic lifetime” ? Is that because " In later revision of SV, you are no longer even allowed to specify a ‘static’ lifetime for a class method." ?

Thanks

In reply to caowangyang:

Hi, Dave, please ignore my previous notes, I understand the difference between “lifetime qualifier” and “class (method) qualifier”, thanks.