“static task” vs. “task static”

I have this code in Systemverilog, when I write “task static”, the result for variable “j” is incremented sequentially.

However, when I write “static task”, the result for variable “j” is unchanged, meaning “j” stays at value “1”.

Could someone please explain what are the differences between “task static” and “static task”? I am so confused.


class A;
  task static incr();     //    <-----------------------------------------
    int unsigned j;
    j++;
    $display("j is %d",j);
  endtask
endclass

module top;
  A obj_1;
  A obj_2;

  initial begin
    $display("Display variable j");
    obj_1 = new();
    obj_2 = new();
    obj_1.incr();
    obj_2.incr();
    obj_1.incr();
    obj_2.incr();
    obj_1.incr();
    $display("Finished printing");
  end
endmodule : top


In reply to zero_h:
task static:
Variables declared inside a static task, function, or block are local in scope and default to a static lifetime.

static task:
A static method is different from a task with static lifetime. The former refers to the lifetime of the method within the class, while the latter refers to the lifetime of the arguments and variables within the task.

Keyword Static has different meaning when used to left and to the right of the task keyword. When used on the left side, i.e. static task incr();, task declared is static and associated with the particular class and not with the instance of the class. Static methods (task and functions) can operate only on static properties (data members) since they have no “this” pointer.
when used on right hand side, i.e. task static incr(), static refers to lifetime of local variables, parameters of the task. In this case, local variable and parameters are static, not passed on stack and initilized before start of simulation. Corresponding qualifier is “automatic” where local variables and parameters are passed on the stack and are initilized every time you enter the scope in which they are declared. In your case, lifetime of j is static, it is initialzed only once, each task instance shares the same copy, so it is incremented sequentially
rgs,
-sunil

In reply to zero_h:

As a class method,
task static
is illegal.

See if these posts help you

https://verificationacademy.com/forums/systemverilog/automatic-variables-inside-static-method#reply-42858

https://verificationacademy.com/forums/systemverilog/what-exact-difference-between-static-tasks/functions-and-automatic-tasks/functions-please-explain-clear-example#reply-44935

In reply to dave_59:

As a class method, task static is illegal.

Thanks Dave, I am new to Systemverilog so I might not fully understand what “illegal” means. Please bear with me. However, I can compile the code with “task static” and rum simulation without any error. It’s just that “task static” and “static task” will give me different results…

In reply to puranik.sunil@tcs.com:

When used on the left side, i.e. static task incr();, task declared is static and associated with the particular class and not with the instance of the class.

Hi puranik.sunil, can you please give me some examples of the benefits of using a “static task” vs. just a regular “task”? Is it the only purpose to be able to call a task in a class without instantiating an object?

In reply to zero_h:[/[i]In reply to zero_h:

Illegal means you should have gotten an error before simulation starts. You either have a tool bug or an older version of software.

In reply to dave_59:

The tool I’m using is:
Questa Sim -64 10.4c
Revision: 2015.07
Date: Jul 20 2015

In reply to zero_h:

This is a public methodology forum not for tool specific support. Contact your tool vendor directly for support.

In reply to dave_59:

I didn’t mean to ask for tool support. I was trying to point out that the tool I used is a common/popular legit tool and the version should be new enough (just in case some readers of this forum want to test run my code).

And as a followup, I looked up “SystemVerilog 3.1a Language Reference Manual” page 116,


//A static method is different from a method with static lifetime. The former refers to the lifetime of the method within the class, while the latter refers to the lifetime of the arguments and variables within the task.

class TwoTasks;
static task foo(); ... endtask // static class method with
                               // automatic variable lifetime
task static bar(); ... endtask // non-static class method with
                               // static variable lifetime
endclass

I guess “task static” is legal.

In reply to zero_h:

It was made illegal in the IEEE LRM. You should not be using the Accellera LRM, which is over 12 years old.

In reply to dave_59:

This is something good to know about.
It’s surprising that 2015.07 version of QuestaSim doesn’t reflect such changes. I wish those major parties/organizations will have better rules communication.
Do you know which tool does reflect such errors so we can avoid future effort on similar issues?

examples of the benefits of using a “static task” vs. just a regular “task”? - the static methods are used to manipulate the static properties - static data members of the class. Static data members are shared by all the instances of class unlike ordinary data members, which have one copy per instance. You can use static data members (and static methods) if, for example you would like to keep a running count of number of objects of particular class which are created. Example is given below :

 
class Transaction;
  static int count = 0; // Number of objects created
  int id; // Unique instance ID
  function new();
    id = count++; // Set ID, bump count
  endfunction
endclass

Transaction t1, t2;
initial begin
  t1 = new(); // 1st instance, id=0, count=1
  t2 = new(); // 2nd instance, id=1, count=2
  $display("Second id=%d, count=%d", t2.id, t2.count);
end 

Another use for a static variable is when every instance of a class needs information
from a single object. For example, a transaction class may refer to a configuration
object for a mode bit. If you have a nonstatic handle in the Transaction class, every
object will have its own copy, wasting space. Example below  shows how to use a static
variable instead:

``` verilog

class Transaction;
  static Config cfg; // A handle with static storage
  MODE_E mode;
  function new();
    mode = cfg.mode;
  endfunction
endclass

Config cfg;
initial begin
  cfg = new(MODE_ON);
  Transaction::cfg = cfg;
...
end

In reply to puranik.sunil@tcs.com:

Thank you Sunil. I really appreciate your explanation. You would make a great teacher.

You can refer to book “System verilog for verification” by Chris Spear. It is good for beginners.