Tutorials

Learn More

The SystemVerilog packages provide a systematic mechanism for sharing parameters, data, function, tasks, types, property to other interfaces, programs, or modules that can be declared within a package.

  1. The package can be made accessible within the interface, programs, modules, and other packages using an import keyword followed by scope resolution operator :: and what has to import. An import mechanism provides controlled access based on what is imported
  2. Items in the package cannot have hierarchical references. 
  3. They are explicitly named scopes appearing at the same level as top-level modules or primitives.

Syntax:

package <package_name>;
  ...
endpackage

// To import package
import <package_name> :: *;  // All package items are imported
import <package_name> :: <method_name>;  // Only <method_name> is imported

Package Examples

A Basic example

In the below example, a transaction class and pkg_funct() function is defined inside the package and it is instantiated in the module.

package pkg;
  class transaction;
    int data = 5;
    
    function void display();
      $display("data = %0d", data);
    endfunction
  endclass

  function pkg_funct();
    $display("Inside pkg_funct");
  endfunction
endpackage

//-------------------------------

import pkg::*;
module package_example;
  initial begin
    transaction tr = new();
    tr.display();
    pkg_funct();
  end
endmodule

Output:

data = 5
Inside pkg_funct

Explicit import example

Out of transaction class and pkg_funct(), only the transaction class is imported. Thus, pkg_funct() is not accessible.

package pkg;
  class transaction;
    int data = 5;
    
    function void display();
      $display("data = %0d", data);
    endfunction
  endclass

  function pkg_funct();
    $display("Inside pkg_funct");
  endfunction
endpackage

//-------------------------------

import pkg::transaction;
module package_example;
  initial begin
    transaction tr = new();
    tr.display();
    //pkg_funct(); // Not accessible
  end
endmodule

Output:

data = 5

Package items are accessed using scope resolution operator example

Package items are accessed using scope resolution operator

package pkg_A;
  int data = 5;
  function pkg_funct();
    $display("pkg_A: Inside pkg_funct, data = %0d", data);
  endfunction
endpackage

package pkg_B;
  int data = 10;
  function pkg_funct();
    $display("pkg_B: Inside pkg_funct, data = %0d", data);
  endfunction
endpackage

//-------------------------------

import pkg_A::*;
import pkg_B::*;

module package_example;
  initial begin
    pkg_A::pkg_funct();
    pkg_B::pkg_funct();
  end
endmodule

Output:

pkg_A: Inside pkg_funct, data = 5
pkg_B: Inside pkg_funct, data = 10

Nested package example

The pkg_A is imported in the pkg_B and pkg_B is imported in the pkg_C.

package pkg_A;
  int data = 5;
  int id_A = 1;

  function pkg_funct();
    $display("pkg_A: Inside pkg_funct, data = %0d, id_A = %0d", data, id_A);
  endfunction
endpackage

package pkg_B;
  import pkg_A::*;
  int data = 10;
  int id_B = 2;

  function pkg_funct();
    $display("pkg_B: Inside pkg_funct, data = %0d, id_B = %0d", data, id_B);
  endfunction
endpackage

package pkg_C;
  import pkg_B::*;
  int data = 15;
  int id_C = 3;

  function pkg_funct();
    $display("pkg_C: Inside pkg_funct, data = %0d, id_C = %0d", data, id_C);
  endfunction
endpackage

//-------------------------------

import pkg_C::*;

module package_example;
  initial begin
    pkg_A::pkg_funct();
    pkg_B::pkg_funct();
    pkg_C::pkg_funct();
  end
endmodule

Output:

pkg_A: Inside pkg_funct, data = 5, id_A = 1
pkg_B: Inside pkg_funct, data = 10, id_B = 2
pkg_C: Inside pkg_funct, data = 15, id_C = 3

System Verilog Tutorials