What is the use of SystemVerilog extern?

I see the UVM makes heavy use of the SystemVerilog extern keyword. Classes are defined with their methods declared as extern, and those methods defined underneath the class within the same file. Similarly, I have also seen classes defined in a header (.svh) file, which is included in a .sv file containing the definitions of the extern methods. Example:

my_class.svh


class my_class
  extern function new();
  extern function void build_phase(uvm_phase phase);
  extern function int something()
endclass : my_class

my_class.sv:


`include 'my_class.svh'

function my_class::new() { ... }
function void my_class::build_phase(uvm_phase phase) { ... }
function int my_class::something() { ... }

From what I understand, this is to eliminate compile-time dependencies, if say, class A depends on class B and class B depends on class A then in what order should we include them in the package? However, I presumed that was the reason for forward type definitions i.e.


package my_package;
  typedef class class_a class_a
  typedef class class_b class_b
  
  // include order doesn't matter.
  `include 'class_b.sv'
  `include 'class_a.sv'
endpackage : my_package

Am I misunderstanding the use of the extern keyword? If so, can you provide an example of where extern is required over forward typedef?

Thanks,
Thomas

In reply to Emphacy:

Then main use of the extern keyword is for readability. By declaring all the prototypes together without seeing their implementations, you can quickly see the API that a class provides. This makes documentation easier as well as making it easier for IP providers to encrypt their implementation leaving the prototypes visible.

In other languages like C++, declaring the class prototypes in a different file is a requirement for separate compilation. It’s not required by SystemVerilog; it uses packages instead.

I don’t think extern was ever intended to remove compile order dependencies. typedef should not be used for that either—only for rare cases of cyclic class dependencies.

In reply to dave_59:

Thanks Dave, that’s very helpful.