Delving into SystemVerilog's Built-In Coverage Functions

In this tutorial, we will discuss the various built-in coverage functions in SystemVerilog, which play a crucial role in obtaining and managing test coverage information. Understanding these functions will help you improve the test coverage of your designs and ultimately create more reliable and robust systems.

Obtaining Test Coverage Information

$coverage_control : Managing and Querying Test Coverage

The $coverage_control function is a key component in managing and querying coverage information in SystemVerilog. The function accepts four arguments: control_constant, coverage_type, scope_def, and modules_or_instance. The table below summarizes the pre-defined macros that can be used as arguments.

Coverage Control

MacroValueDescription
SV_COV_START0Start collecting coverage data
SV_COV_STOP1Stop collecting coverage data
SV_COV_RESET2Reset coverage data
SV_COV_CHECK3Check coverage against threshold

Scope Definition (Hierarchy Traversal/Accumulation Type)

MacroValueDescription
SV_COV_MODULE10Coverage for specific modules
SV_COV_HIER11Coverage for module hierarchies

Coverage Type Identification

MacroValueDescription
SV_COV_ASSERTION20Assertion coverage
SV_COV_FSM_STATE21Finite State Machine state coverage
SV_COV_STATEMENT22Statement coverage
SV_COV_TOGGLE23Toggle coverage

Status Results

MacroValueDescription
SV_COV_OVERFLOW-2Coverage overflow
SV_COV_ERROR-1Coverage error
SV_COV_NOCOV0No coverage
SV_COV_OK1Coverage is OK
SV_COV_PARTIAL2Partial coverage

Here's an example of using $coverage_control to start collecting statement coverage data for a specific module:

module TestBench;
  initial begin
    $coverage_control(`SV_COV_START, `SV_COV_STATEMENT, `SV_COV_MODULE, "MyModule");
  end
endmodule

In this example, the $coverage_control function is used with the SV_COV_START control constant to begin collecting statement coverage data for the module named "MyModule".

$coverage_get_max: Obtaining Maximum Coverage Value

The $coverage_get_max function is essential for acquiring the highest possible coverage value for a particular coverage type and hierarchy scope. The function takes three arguments: coverage_type, scope_def, and modules_or_instance.

The function returns an integer representing the maximum coverage number for the specified coverage type and hierarchy. The return values can have different meanings:

  • -2 (`SV_COV_OVERFLOW): The value is too large to be represented as an integer.
  • -1 (`SV_COV_ERROR): An error has occurred, usually due to incorrect arguments.
  • 0 (`SV_COV_NOCOV): There is no available coverage for the specified coverage type and hierarchy.
  • +pos_num: A number that can only be positive. It tells you the maximum number of things that can be covered for a specific type of coverage. This number is calculated by adding up all the things that can be covered within a certain group or hierarchy.

Below is an example demonstrating how to use the $coverage_get_max function to acquire the maximum statement coverage value for a specific module:

module TestBench;
  integer maxCoverageValue;
  initial begin
    maxCoverageValue = $coverage_get_max(`SV_COV_STATEMENT, `SV_COV_MODULE, "MyModule");
    $display("Maximum statement coverage value for MyModule: %0d", maxCoverageValue);
  end
endmodule

In this example, the $coverage_get_max function is used with the SV_COV_STATEMENT coverage type and SV_COV_MODULE scope definition to retrieve the maximum statement coverage value for the "MyModule" module. The obtained value is stored in the maxCoverageValue variable and displayed on the console.

$coverage_get: Retrieving Current Coverage Value

The $coverage_get function is used to obtain the current coverage value for a specific coverage type and hierarchy scope. This function takes the same arguments as the $coverage_get_max function: coverage_type, scope_def, and modules_or_instance.

Similar to the $coverage_get_max function, $coverage_get returns an integer value, with the following meanings:

  • -2 (`SV_COV_OVERFLOW): The value is too large to be represented as an integer.
  • -1 (`SV_COV_ERROR): An error has occurred, usually due to incorrect arguments.
  • 0 (`SV_COV_NOCOV): There is no available coverage for the specified coverage type and hierarchy.
  • +pos_num: This is a positive number that shows the current value of coverage. It tells you the sum of all the things that have been covered for a specific type of coverage within a certain group or hierarchy.

You can calculate the coverage rate (in percentage) by dividing the current coverage value returned by $coverage_get by the maximum coverage value returned by $coverage_get_max, and then multiplying by 100.

Here's an example that demonstrates how to use the $coverage_get function to calculate the statement coverage rate for a specific module:

module TestBench;
  integer currentCoverageValue, maxCoverageValue;
  real coverageRate;
  initial begin
    maxCoverageValue = $coverage_get_max(`SV_COV_STATEMENT, `SV_COV_MODULE, "MyModule");
    currentCoverageValue = $coverage_get(`SV_COV_STATEMENT, `SV_COV_MODULE, "MyModule");
    coverageRate = (currentCoverageValue * 100.0) / maxCoverageValue;
    $display("Statement coverage rate for MyModule: %.2f%%", coverageRate);
  end
endmodule

In this example, the $coverage_get function retrieves the current statement coverage value for the "MyModule" module, while the $coverage_get_max function obtains the maximum statement coverage value. The coverage rate is calculated and displayed on the console.

$coverage_merge: Merging Coverage Data

The $coverage_merge function helps you load and combine coverage data from a saved coverage database for a specific coverage type. It takes two arguments: coverage_type and name. The name is a string that the tool uses to find the coverage database in a unique way based on the implementation.

module TestModule;
  initial begin
    // Load and merge coverage data from a saved coverage database
    int mergeResult;
    mergeResult = $coverage_merge(`SV_COV_ASSERTION, "coverageDatabase");
    if (mergeResult == `SV_COV_OK) begin
      $display("Coverage data has been found and merged.");
    end
  end
endmodule

The function returns the following values:

  • `SV_COV_OK: The coverage data was found and merged successfully.
  • `SV_COV_NOCOV: The coverage data was found but didn't contain the requested coverage type.
  • `SV_COV_ERROR: The coverage data couldn't be found, didn't match this design, or another issue occurred.

$coverage_save: Saving Coverage Data

The $coverage_save function allows you to save the current coverage state to the tool's coverage database, linking it with the given name. It also takes two arguments: coverage_type and name. The name maps to the coverage database based on the implementation.

module TestModule;
  initial begin
    // Save the current state of coverage to the tool's coverage database
    int saveResult;
    saveResult = $coverage_save(`SV_COV_ASSERTION, "coverageDatabase");
    if (saveResult == `SV_COV_OK) begin
      $display("Coverage data was successfully saved.");
    end
  end
endmodule

This function returns:

  • `SV_COV_OK: The coverage data was saved successfully.
  • `SV_COV_NOCOV: There's no available coverage data for this design (nothing was saved).
  • `SV_COV_ERROR: An error occurred during the save process. The tool will automatically remove the coverage database entry for the name to maintain the database's integrity. Overwriting an existing name is not considered an error.

Managing Coverage Data with System Tasks and Functions

$set_coverage_db_name: Setting Coverage Database Name

The $set_coverage_db_name system task enables you to define the name for your coverage database. You can set the database name using the following example:

module TestBench;
  initial begin
    $set_coverage_db_name("MyCoverageDatabase");
  end
endmodule

$load_coverage_db: Loading Coverage Data

The $load_coverage_db system function allows you to import coverage data from a coverage database file into the simulator. Here's an example demonstrating how to use $load_coverage_db to load the coverage data:

module TestBench;
  bit loadSuccess;
  
  initial begin
    $load_coverage_db("MyCoverageDatabase");
  end
endmodule

$get_coverage: Retrieving Overall Coverage

The $get_coverage system function returns a real number between 0 and 100, representing the overall coverage across all coverage group types. This value is calculated as previously described. Here's an example of how to use $get_coverage to retrieve the overall coverage:

module TestBench;
  real overallCoverage;

  initial begin
    overallCoverage = $get_coverage();
    $display("Overall coverage: %.2f%%", overallCoverage);
  end
endmodule

SystemVerilog offers various built-in functions for obtaining and managing test coverage information. Mastering these functions allows you to create more robust and reliable systems by identifying and improving test coverage gaps. By using these functions, you can control and query coverage, obtain maximum and current coverage values, merge and save coverage data, and check coverage against a threshold. Make sure to explore and understand these functions to enhance your testing strategies and ensure your designs meet the desired level of quality.