SystemVerilog covergroup
is a user-defined type that encapsulates the specification of a coverage model. They can be defined once and instantiated muliple times at different places via the new
function.
covergroup
can be defined in either a package, module, program, interface, or class and usually encapsulates the following information:
- A set of coverage points
- Cross coverage between coverage points
- An event that defines when the covergroup is sampled
- Other options to configure coverage object
covergroup
module tb;
// Declare some variables that can be "sampled" in the covergroup
bit [1:0] mode;
bit [2:0] cfg;
// Declare a clock to act as an event that can be used to sample
// coverage points within the covergroup
bit clk;
always #20 clk = ~clk;
// "cg" is a covergroup that is sampled at every posedge clk
covergroup cg @ (posedge clk);
coverpoint mode;
endgroup
// Create an instance of the covergroup
cg cg_inst;
initial begin
// Instantiate the covergroup object similar to a class object
cg_inst= new();
// Stimulus : Simply assign random values to the coverage variables
// so that different values can be sampled by the covergroup object
for (int i = 0; i < 5; i++) begin
@(negedge clk);
mode = $random;
cfg = $random;
$display ("[%0t] mode=0x%0h cfg=0x%0h", $time, mode, cfg);
end
end
// At the end of 500ns, terminate test and print collected coverage
initial begin
#500 $display ("Coverage = %0.2f %%", cg_inst.get_inst_coverage());
$finish;
end
endmodule
ncsim> run [40] mode=0x0 cfg=0x1 [80] mode=0x1 cfg=0x3 [120] mode=0x1 cfg=0x5 [160] mode=0x1 cfg=0x2 [200] mode=0x1 cfg=0x5 Coverage = 50.00 % Simulation complete via $finish(1) at time 500 NS + 0
coverpoint
A covergroup
can contain one or more coverage points. A coverpoint
specifies an integral expression that is required to be covered. Evaluation of the coverpoint
expression happens when the covergroup
is sampled. The SystemVerilog coverage point can be optionally labeled with a colon :
.
The example shown below randomizes the two variables mode and cfg multiple times and is assigned a value on every negative edge of the clock. The covergroup
is specified to be sampled at every occurence of a positive edge of the clock. So the two variables are randomized 5 times at the negative edge of the clock and sampled at the positive edge of the clock.
mode can have values from 0 to 3 and cfg can have values from 0 to 7. The question of coverage is this: How much of the total values each variable can have has actually happened ?
module tb;
bit [1:0] mode;
bit [2:0] cfg;
bit clk;
always #20 clk = ~clk;
// "cg" is a covergroup that is sampled at every posedge clk
// This covergroup has two coverage points, one to cover "mode"
// and the other to cover "cfg". Mode can take any value from
// 0 -> 3 and cfg can take any value from 0 -> 7
covergroup cg @ (posedge clk);
// Coverpoints can optionally have a name before a colon ":"
cp_mode : coverpoint mode;
cp_cfg_10 : coverpoint cfg[1:0];
cp_cfg_lsb : coverpoint cfg[0];
cp_sum : coverpoint (mode + cfg);
endgroup
cg cg_inst;
initial begin
cg_inst= new();
for (int i = 0; i < 5; i++) begin
@(negedge clk);
mode = $random;
cfg = $random;
$display ("[%0t] mode=0x%0h cfg=0x%0h", $time, mode, cfg);
end
end
initial begin
#500 $display ("Coverage = %0.2f %%", cg_inst.get_inst_coverage());
$finish;
end
endmodule
ncsim> run
[40] mode=0x0 cfg=0x1
[80] mode=0x1 cfg=0x3
[120] mode=0x1 cfg=0x5
[160] mode=0x1 cfg=0x2
[200] mode=0x1 cfg=0x5
Coverage = 78.12 %
Simulation complete via $finish(1) at time 500 NS + 0