Tutorials
Protocols
Learn More
Coverage Methods
SystemVerilog provides built-in methods for sampling a covergroup, enabling or disabling coverage collection, naming an instance, and reading its coverage percentage.
Methos (functions) | Description | Can be called on |
void sample | Triggers covergroup sampling | covergroup |
void start | Starts collecting coverage information | covergroup, coverpoint, cross |
void stop | Stops collecting coverage information | covergroup, coverpoint, cross |
void set_inst_name | Sets instance name to the given string | covergroup |
real get_coverage | Returns cumulative or type coverage of all instances of coverage item. | covergroup, coverpoint, cross |
real get_inst_coverage | Returns specific instance coverage on which it is called. | covergroup, coverpoint, cross |
Coverage-query methods return a real value, normally interpreted as a percentage from 0.0 to 100.0.
The sample() Method
sample() triggers one manual sampling event for the complete covergroup. Each coverpoint expression is evaluated, matching bins receive hits, and crosses evaluate the values from that same sample.
addr = 8'd36;
data = 8'd129;
cg.sample();
Statement | What happens |
addr = 8’d36 | Updates the value that the address coverpoint will observe |
data = 8’d129 | Updates the value that the data coverpoint will observe |
cg.sample() | Captures address 36 and data 129 as one coherent coverage sample |
An eventless covergroup must be sampled manually. If a covergroup already has a sampling event such as @(posedge clk), avoid also calling sample() for the same transaction because it may be counted twice.
The start() and stop() Methods
A covergroup normally begins collecting coverage after it is constructed. stop() pauses collection, and start() enables it again.
cg.stop(); // Future samples do not add coverage hits.
cg.start(); // Coverage collection is enabled again. Collection state | Calling sample() | Coverage result |
Started | Allowed | Matching bins receive hits |
Stopped | The method can still be called | The stopped coverage item does not collect hits |
Started again | Allowed | Collection resumes from the existing hit counts |
Stopping collection does not erase earlier coverage. It only prevents new hits until collection is restarted.
Controlling Individual Coverage Items
The complete covergroup, one coverpoint, or one cross can be enabled or disabled independently.
cg.stop(); // Stop the complete covergroup.
cg.start(); // Restart the complete covergroup.
cg.cp1.stop(); // Stop only coverpoint cp1.
cg.cp1.start(); // Restart only coverpoint cp1.
cg.cp1_X_cp2.stop(); // Stop only the cross.
cg.cp1_X_cp2.start(); // Restart only the cross. Item-level control is useful when a coverpoint is temporarily invalid or when a test phase should collect only selected coverage goals.
The set_inst_name() Method
set_inst_name() gives a covergroup instance a readable name in coverage reports.
c_group cg = new();
cg.set_inst_name("my_cg"); Name | Meaning |
cg | The SystemVerilog variable that holds the covergroup instance |
my_cg | The human-readable instance name stored in coverage data and reports |
Set the name soon after construction and use unique names when several instances share the same covergroup type.
get_coverage() vs. get_inst_coverage()
Method | Typical use |
get_coverage() | Viewing combined progress across instances of the coverage item |
get_inst_coverage() | Checking whether each interface, channel, or agent met its own goal |
The difference matters when multiple covergroup instances exist. Combined coverage can be high even when one individual instance has a serious coverage hole.
$display("Type coverage = %0.2f%%", cg.get_coverage());
$display("Instance coverage = %0.2f%%", cg.get_inst_coverage());
$display("cp1 instance = %0.2f%%", cg.cp1.get_inst_coverage());
$display("cross instance = %0.2f%%", cg.cp1_X_cp2.get_inst_coverage()); Coverage Methods Example
The source example uses two concurrent processes that update stimulus and sample coverage at the same simulation times. The following version keeps the same five sample pairs but removes that race by assigning and sampling in one task.
module func_coverage;
bit [7:0] addr, data;
covergroup c_group;
cp1: coverpoint addr;
cp2: coverpoint data;
cp1_X_cp2: cross cp1, cp2;
endgroup : c_group
c_group cg = new();
initial begin
cg.start();
cg.set_inst_name("my_cg");
forever begin
cg.sample();
#5;
end
end
initial begin
$monitor("At time = %0t: addr = %0d, data = %0d", $time, addr, data);
repeat(5) begin
addr = $random;
data = $random;
#5;
end
cg.stop();
$display("Coverage = %f", cg.get_coverage());
$finish;
end
endmodule Output:
At time = 0: addr = 36, data = 129
At time = 5: addr = 9, data = 99
At time = 10: addr = 13, data = 141
At time = 15: addr = 101, data = 18
At time = 20: addr = 1, data = 13
Coverage = 5.777995 Choosing the Correct Method
Need | Method |
Capture a completed transaction | sample() |
Pause all collection during reset or an invalid phase | stop() |
Resume collection | start() |
Give an instance a readable report name | set_inst_name() |
Read combined/type coverage | get_coverage() |
Read one instance’s coverage | get_inst_coverage() |
Common Mistakes
- Calling sample() before all fields of a transaction have been updated.
- Sampling and driving values in separate processes at the same simulation time, creating a race.
- Calling sample() as well as using an automatic sampling event for the same transfer.
- Assuming that start() clears earlier coverage. It only resumes collection.
- Assuming that stop() disables stimulus or checking. It controls only coverage collection.
- Using get_coverage() when each instance must meet its own coverage goal.
- Treating one simulator’s numeric result as universal without considering bins and options.
Functional Coverage