The super keyword is used from within a sub-class to refer to properties and methods of the base class. It's mandatory to use super to reach a base class's own version of a property or method, once the sub-class has overridden it with its own version of the same name.

7 min read | Intermediate Level

What You'll Learn

  • What super refers to, and exactly when you're required to use it
  • Why super only works inside a class that actually extends another
  • How super.method_name() reaches the base class's own version of an overridden method
  • How this ties into the constructor-chaining pattern from SystemVerilog Class Constructor

super Requires an Actual Inheritance Relationship

super can only be used within a class scope that actually derives from a base class. The code below has a compile error, because extPacket is missing the extends keyword — it isn't really a child of Packet at all, despite the name:


class Packet;
	int addr;
	function display ();
		$display ("[Base] addr=0x%0h", addr);
	endfunction
endclass

class extPacket;                       // "extends" keyword missing -> not a child class
	function new ();
		super.new ();
	endfunction
endclass

module tb;
	Packet p;
  	extPacket ep;
  
  	initial begin
      ep = new();
      p = new();
      p.display();
    end
endmodule

Output

Output
super.new ();
        |
ncvlog: *E,CLSSPX (testbench.sv,12|8): 'super' can only be used within a class scope that derives from a base class.

Adding extends Packet fixes this:


class extPacket extends Packet;                       // extPacket is a child class of Packet
	function new ();
		super.new ();
	endfunction
endclass

Output

Output
ncsim> run
[Base] addr=0x0
ncsim: *W,RNQUIE: Simulation is complete.

The output here comes from p.display() — a plain Packet object, unrelated to extPacket. This example only demonstrates that the compile error is gone; extPacket itself isn't actually exercised yet. The next section puts it to real use.

Quick Check

Q: If extPacket kept super.new() inside its constructor but the extends Packet clause were removed again, would that be a compile-time or a run-time error?

Show Answer

Compile-time — exactly like the first example. super requires an actual inheritance relationship to exist at all, and that's checked when the code is compiled, not when it runs.

Accessing an Overridden Base Method With super

Here, extPacket's own display() calls Packet's version explicitly with super.display(), before adding its own line:


class Packet;
  int addr;
  
  function display ();
    $display ("[Base] addr=0x%0h", addr);
  endfunction
endclass

class extPacket extends Packet;
  function display();
    super.display();                          // Call base class display method
    $display ("[Child] addr=0x%0h", addr);
  endfunction
  
  function new ();
    super.new ();
  endfunction
endclass

module tb;
 	Packet p;
  	extPacket ep;
  
  	initial begin
      ep = new();
      p = new();
      ep.display();
    end
endmodule

Output

Output
ncsim> run
[Base] addr=0x0
[Child] addr=0x0
ncsim: *W,RNQUIE: Simulation is complete.
extPacket display() calls super.display() before printing its own line

ep.display() now runs both lines — the base class's own output first (via super.display()), followed by the child's own line. Without super, extPacket's override would have completely replaced Packet's behavior instead of building on it.

Quick Check

Q: If extPacket's display() didn't call super.display() at all, what would ep.display() print?

Show Answer

Just [Child] addr=0x0 — only the child's own line. super.display() is what explicitly pulls in the base class's output; without it, an override runs only its own statements.

Where Is This Used?

UVM component phase methods follow exactly this pattern — an overridden run_phase(phase) or build_phase(phase) commonly calls super.run_phase(phase) or super.build_phase(phase) at the very start, ensuring the base class's own setup still happens before the derived class's additional logic runs, rather than silently skipping it.

Common Beginner Mistakes

Mistake #1: Using super in a class that doesn't actually extend anything

As the first example shows, this is a compile-time error, not a warning. Why? super only has meaning relative to an actual base class — a missing extends clause (even with a name that looks like it implies inheritance, like extPacket) means there's simply nothing for super to refer to.

Mistake #2: Using super for a method the child never actually overrides

If a child class doesn't redefine a method at all, calling it unqualified already reaches the base class's version — no super needed. Why? super is specifically for reaching the base class's version of something the child has overridden with its own version of the same name; using it elsewhere is unnecessary, though not harmful.

Mistake #3: Assuming super automatically chains through every ancestor

super.method_name() only calls exactly what's written at that one level — it isn't an automatic "run everything from every ancestor" mechanism. Why? If a three-level inheritance chain needs every level's behavior to run, each level's own override has to explicitly call super.method_name() itself; skip one level's call, and the chain stops there.

Practice Exercise

Challenge: Extend the Chain One More Level

Add a third class, extPacket2, extending extPacket, with its own display() that calls super.display() first, then prints its own line. What does calling display() on an extPacket2 object print?

Hint

Each level's super.display() call reaches exactly one level up — work out what each level in the chain actually calls before combining them.

Solution

class extPacket2 extends extPacket;
  function new ();
    super.new ();
  endfunction

  function display ();
    super.display ();
    $display ("[Grandchild] addr=0x%0h", addr);
  endfunction
endclass

module tb;
  extPacket2 gc;

  initial begin
    gc = new ();
    gc.display ();
  end
endmodule

This prints three lines: [Base] addr=0x0, then [Child] addr=0x0, then [Grandchild] addr=0x0 — extPacket2's super.display() reaches extPacket's override, which itself calls super.display() to reach Packet's original version, chaining all the way back.

Summary

In this tutorial, you learned:

  • super refers to the base class from within a sub-class, and is required to reach a base class's version of a property or method the sub-class has overridden
  • super only works inside a class that genuinely extends another — using it anywhere else is a compile-time error
  • super.method_name() calls exactly the base class's own version of that method, letting an override extend behavior instead of fully replacing it
  • super doesn't automatically chain through every level of a multi-level inheritance hierarchy — each level needs its own explicit call for the chain to continue
Did you find what you were looking for?

Quiz

Test Your Knowledge

1 of 5 Score: 0 / 5