Static Properties & Methods in SystemVerilog: A Comprehensive Guide

In short: A static class property is shared by every object of the class: there is one copy, not one per instance. A static method belongs to the class rather than to any object, so you call it with the class scope operator (ClassName::method()) without creating an instance, and it can only touch static members. Use static members for things common to all objects, such as a shared counter, and avoid them for anything that should be unique per object.

Most class members belong to each object: every instance gets its own copy. Sometimes, though, you want one value shared by the whole class, or a helper you can call without making an object at all. That is what static properties and methods are for. This guide explains when to use them, shows working examples including a shared counter and a UVM case, points out the traps, and answers common questions.

When to use static properties and methods

A static property is useful when data must be shared across all instances of a class. A common example is counting how many objects have been created: every constructor bumps the same shared counter. A static method is useful for a helper related to the class that does not need any per-object data. Because it is not tied to an instance, you can call it through the class name without creating an object, and it may access only static members.

class MyClass;
  static int instanceCount;
  function new();
    instanceCount++;
  endfunction
endclass
class MyUtil;
  static function void printMessage();
    $display("Hello, World!");
  endfunction
endclass

A simple way to picture it

Think of a shop with a people-counter above the door and a printed price list on the wall. The people-counter is a static property: there is one counter for the whole shop, and every customer who walks in adds one to the same number. The price list is a static method: it belongs to the shop, not to any single customer, and anyone can read it without becoming a customer first.

A normal member is like something each customer carries in their own bag: private to them, one per person. Static members are the shared fixtures everyone sees the same way. That is the difference between one copy for the class and one copy per object.

A worked example: counting instances

Here a Car class keeps a shared count of how many cars have been created. The constructor calls a static method that increments the shared property, and another static method returns the total.

class Car;
  static int totalCars;

  function new();
    incrementTotalCars();
  endfunction

  static function void incrementTotalCars();
    totalCars++;
  endfunction

  static function int getTotalCars();
    return totalCars;
  endfunction
endclass

module test;
  initial begin
    Car c1 = new();
    Car c2 = new();
    Car c3 = new();
    $display("Total Cars: %0d", Car::getTotalCars());
  end
endmodule

Three cars are created, so each constructor bumps the same shared totalCars. The expected output is shown below.

Simulation output showing Total Cars: 3, because the static property is shared across all three Car instances.
Total Cars: 3

This shows the key point: totalCars is one shared value across every Car object, which lets us count instances from a single place.

Static members in a UVM context

In a UVM testbench, a static property can track something across all objects of a type, for example the total number of transactions across every instance of a sequence.

class MySequence extends uvm_sequence #(MyTransaction);
  `uvm_object_utils(MySequence)
  static int totalTransactions;

  function new(string name = "MySequence");
    super.new(name);
  endfunction

  task body();
    MyTransaction trans = MyTransaction::type_id::create("trans");
    start_item(trans);
    finish_item(trans);
    totalTransactions++;
  endtask
endclass

Because totalTransactions is static, every sequence object adds to the same total, so you get a running count without passing a handle around.

Potential pitfalls

Sharing is what makes static members handy, and also what makes them risky. If a value should be unique to each object, a static property is the wrong choice, because every object would see and change the same copy.

  • Storing per-object data in a static property, so objects overwrite each other’s values.
  • Assuming a static method can read normal members. It cannot; it may access only static members.

Common mistakes

  • Calling a static method on an object instead of using ClassName::method().
  • Putting instance-specific state in a static property and being surprised it is shared.
  • Accessing non-static properties from a static method, which the compiler rejects.
  • Forgetting a static property keeps its value for the whole simulation.
  • Overusing static members, which makes code harder to reason about.

Key takeaways

  • A static property is one shared copy for the whole class, not one per object.
  • A static method is called with ClassName::method() and may access only static members.
  • They are ideal for shared counters and class-level helpers.
  • Never use a static property for data that must be unique per object.
  • Static members live for the whole simulation, so watch for stale values.

Honesty note: the code follows a plain reading of the SystemVerilog and UVM LRM (IEEE 1800 and 1800.2) and is written to show the idea. Exact output depends on your simulator, so confirm on your own tool or on EDA Playground before relying on it.

Related reading

What is a static property in SystemVerilog?

A static property is a class member shared by all objects of the class. There is a single copy rather than one per instance, so every object reads and writes the same value.

What is a static method in SystemVerilog?

A static method belongs to the class rather than to any object. You call it with the class scope operator, ClassName::method(), without creating an instance, and it can access only static members.

How do I call a static method?

Use the class scope operator, for example Car::getTotalCars(). You do not need to create an object of the class first.

Can a static method access non-static properties?

No. A static method is not tied to any object, so it can access only static properties and other static methods, not per-instance members.

When should I use a static property?

When data must be shared across all instances of a class, such as a counter of how many objects have been created or a running total across a testbench.

When should I avoid a static property?

When the value should be unique to each object. A static property is shared, so per-object data stored in it would be overwritten by every instance.

How are static members useful in UVM?

They can track values across all objects of a type, for example a shared count of transactions across every instance of a sequence, without passing a handle around.

How long does a static property keep its value?

For the whole simulation. Because it is shared and long-lived, be careful that a stale value from earlier does not carry over unexpectedly.

Similar Posts

2 Comments

  1. static function int PKT_ID;
    pkt_id++;
    return pkt_id ;
    endfunction: PKT_ID
    endclass

    There is a small mistake. The output of static function will be 1,2,3,4,5

  2. Hi Hardik,
    Firstly, Thank you for the blogs. Really nice.

    I tried to run the 2nd chunk of code (static method). Saw the below output.
    # dynapkt[0].id = 0
    # dynapkt[1].id = 0
    # dynapkt[2].id = 0
    # dynapkt[3].id = 0
    # dynapkt[4].id = 0
    (Tool: Questa)

    I am not able to ascertain the reason. Can you please explain that?

Comments are closed.