11. Packages

11.1. Introduction

In this chapter, we will see various features of SystemVerilog which is available for packages. We will see following synthesizable-features of SystemVerilog,

  • Packages : similar to packages in VHDL
  • typedef : it is used to create the user-defined types
  • struct : similar to ‘structure’ in C/C++

Also, following are the synthesizable constructs which can be used in Packages,

  • typedef
  • struct
  • import
  • task
  • functions
  • const
  • parameter, localparameter

11.2. Creating packages

In Listing 11.1, a package ‘my_package’ is created in the file ‘my_package.sv’.

Listing 11.1 package ‘my_package’
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// my_package.sv

package my_package; // package name
    parameter initial_value = 1; // initial value
    typedef enum {ADD, SUB} op_list; // list of operatios

    typedef struct{
        logic [4:0] a, b; // for input
        logic [9:0] m; // for output : store multiplication result
    } port_t;

endpackage

11.3. Import package

Package can be imported in following ways. The first three methods of import are shown in Listing 11.2 and the simulation results are shown in Fig. 11.1.

  • Wild card import using * (Line 4)
  • Import specific item using ‘import’ and ‘scope-resolution-operator ::’ (Line 7)
  • Direct import using :: (Line 11)
  • Inport using `include (discussed in Section 11.4)

Note

  • Wildcard import does not import items but adds the package into the path.
  • Importing the ‘enum-definition’ will not import it’s labels e.g. ‘import op_list’ will not import ‘ADD’ and ‘SUB’.
Listing 11.2 import package ‘my_package’
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
// use_package.sv

// // import method 1 : import everything from my_package
// import my_package::*;

// // import method 2 : import individual value from package
import my_package::initial_value; // import 'initial_value' from my_package

module use_package(
    input logic clk,
    input my_package::port_t D, // import port_t from my_package
    output logic[5:0] s
);

always_ff @(posedge clk) begin
    s = D.a + D.b + initial_value;
    D.m = D.a * D.b;
end

endmodule
../_images/pack1.png

Fig. 11.1 Simulation results of Listing 11.2

11.4. Package with conditional compilation

In this section, we will create a testbench for ‘my_package.sv’ file; and use the keyword ‘include’ to use the package in it.

11.4.1. Modify my_package.sv

  • In Listing 11.3, the wildcard import statement is added at the Line 17, which is not the part of the package ‘my_package’.
  • To import the Line 17, we need to use ‘include’ directive in the code as shown in Line 3 of Listing 11.4.
  • Lines 3-4 and 19 are the statement for conditional compilation. In the other words, if the ‘my_package.sv’ is not compiled/imported, then it will be complied/imported.

Note

Since, directive ‘include’ is not used in Listing 11.2 therefore Line 17 of Listing 11.3 will not be executed in Listing 11.2, therefore we need to use the package-name to import items e.g. my_package::port_t etc.

Listing 11.3 Contditional compilation using ‘ifndef’
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// my_package.sv

`ifndef MYPACKAGE_DONE
    `define MYPACKAGE_DONE
    package my_package; // package name
        parameter initial_value = 1; // initial value
        typedef enum {ADD, SUB} op_list; // list of operatios

        typedef struct{
            logic [4:0] a, b; // for input
            logic [9:0] m; // for output : store multiplication result
        } port_t;

    endpackage

    // import package in the design
    import my_package::*;

`endif

11.4.2. Testbench

Listing 11.4 is the testbench for Listing 11.2. The results are shown in Fig. 11.2.

Note

  • `timescale 1ns/10ps directive can be used in SystemVerilog.
  • Also, we can further split `timescale directive in SystemVerilog as below,
timeunit 1ns;
timeprecision 10ps;
  • Lastly, if we defined the time-parameters in ‘package’ and ‘design-file’, then ‘design-file parameters’ will override the ‘package-parameters’.
Listing 11.4 Testbench
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// use_package_tb.sv

`include "my_package.sv"

module use_package_tb;

logic clk = 0; // initialize clock with 0
port_t D; // import port_t from my_package
logic[5:0] sum;

use_package uut (
    .clk(clk),
    .D(D),
    .s(sum)
);

always #10
    clk = ~clk;

initial begin
    @(negedge clk)
    D.a = 6;
    D.b = 5;
end
endmodule
../_images/pack2.png

Fig. 11.2 Simulation results of Listing 11.4