Correct indent on coverage tests ; add required test drivers ; back out CMakeLists pch change and adjust test that required it to no longer need it
Signed-off-by: Matthew Ballance <matt.ballance@gmail.com>
This commit is contained in:
parent
e347943e3b
commit
80502fd9ee
|
|
@ -121,23 +121,6 @@ set(PACKAGE_VERSION ${PROJECT_VERSION})
|
|||
set(CXX ${CMAKE_CXX_COMPILER})
|
||||
set(AR ${CMAKE_AR})
|
||||
|
||||
# Detect precompiled header include flag (matches configure.ac logic)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_CXX_COMPILER} --help
|
||||
OUTPUT_VARIABLE _cxx_help
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
ERROR_QUIET
|
||||
)
|
||||
if(_cxx_help MATCHES "include-pch")
|
||||
# clang
|
||||
set(CFG_CXXFLAGS_PCH_I "-include-pch")
|
||||
set(CFG_GCH_IF_CLANG ".gch")
|
||||
else()
|
||||
# GCC
|
||||
set(CFG_CXXFLAGS_PCH_I "-include")
|
||||
set(CFG_GCH_IF_CLANG "")
|
||||
endif()
|
||||
|
||||
configure_file(include/verilated_config.h.in include/verilated_config.h @ONLY)
|
||||
configure_file(include/verilated.mk.in include/verilated.mk @ONLY)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of either the GNU Lesser General Public License Version 3
|
||||
# or the Perl Artistic License Version 2.0.
|
||||
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('vlt')
|
||||
|
||||
test.compile()
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -7,81 +7,81 @@
|
|||
// Test array bins - separate bin per value
|
||||
|
||||
module t;
|
||||
/* verilator lint_off UNSIGNED */
|
||||
bit [7:0] data;
|
||||
/* verilator lint_off UNSIGNED */
|
||||
bit [7:0] data;
|
||||
|
||||
covergroup cg;
|
||||
coverpoint data {
|
||||
// Array bins: creates 3 separate bins
|
||||
bins values[] = {1, 5, 9};
|
||||
covergroup cg;
|
||||
coverpoint data {
|
||||
// Array bins: creates 3 separate bins
|
||||
bins values[] = {1, 5, 9};
|
||||
|
||||
// Non-array bin: creates 1 bin covering all values
|
||||
bins grouped = {2, 6, 10};
|
||||
}
|
||||
endgroup
|
||||
// Non-array bin: creates 1 bin covering all values
|
||||
bins grouped = {2, 6, 10};
|
||||
}
|
||||
endgroup
|
||||
|
||||
initial begin
|
||||
cg cg_inst;
|
||||
real cov;
|
||||
initial begin
|
||||
cg cg_inst;
|
||||
real cov;
|
||||
|
||||
cg_inst = new();
|
||||
cg_inst = new();
|
||||
|
||||
// Initial coverage should be 0%
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
if (cov != 0.0) begin
|
||||
$error("Expected 0%% coverage, got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit first array bin value (1)
|
||||
data = 1;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("After hitting value 1: %0.2f%%", cov);
|
||||
// 1 bin out of 4 total bins (3 array bins + 1 grouped bin)
|
||||
if (cov < 23.0 || cov > 27.0) begin
|
||||
$error("Expected ~25%% (1/4 bins), got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit second array bin value (5)
|
||||
data = 5;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("After hitting value 5: %0.2f%%", cov);
|
||||
// 2 bins out of 4
|
||||
if (cov < 48.0 || cov > 52.0) begin
|
||||
$error("Expected ~50%% (2/4 bins), got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit the grouped bin (covers all of 2, 6, 10)
|
||||
data = 6;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("After hitting grouped bin: %0.2f%%", cov);
|
||||
// 3 bins out of 4
|
||||
if (cov < 73.0 || cov > 77.0) begin
|
||||
$error("Expected ~75%% (3/4 bins), got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit third array bin value (9)
|
||||
data = 9;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("After hitting value 9: %0.2f%%", cov);
|
||||
// All 4 bins covered
|
||||
if (cov != 100.0) begin
|
||||
$error("Expected 100%% (4/4 bins), got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Verify hitting other values in grouped bin doesn't increase coverage
|
||||
data = 2;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
if (cov != 100.0) begin
|
||||
$error("Coverage should stay 100%%, got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
$display("Array bins test PASSED");
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
// Initial coverage should be 0%
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
if (cov != 0.0) begin
|
||||
$error("Expected 0%% coverage, got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit first array bin value (1)
|
||||
data = 1;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("After hitting value 1: %0.2f%%", cov);
|
||||
// 1 bin out of 4 total bins (3 array bins + 1 grouped bin)
|
||||
if (cov < 23.0 || cov > 27.0) begin
|
||||
$error("Expected ~25%% (1/4 bins), got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit second array bin value (5)
|
||||
data = 5;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("After hitting value 5: %0.2f%%", cov);
|
||||
// 2 bins out of 4
|
||||
if (cov < 48.0 || cov > 52.0) begin
|
||||
$error("Expected ~50%% (2/4 bins), got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit the grouped bin (covers all of 2, 6, 10)
|
||||
data = 6;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("After hitting grouped bin: %0.2f%%", cov);
|
||||
// 3 bins out of 4
|
||||
if (cov < 73.0 || cov > 77.0) begin
|
||||
$error("Expected ~75%% (3/4 bins), got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit third array bin value (9)
|
||||
data = 9;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("After hitting value 9: %0.2f%%", cov);
|
||||
// All 4 bins covered
|
||||
if (cov != 100.0) begin
|
||||
$error("Expected 100%% (4/4 bins), got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Verify hitting other values in grouped bin doesn't increase coverage
|
||||
data = 2;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
if (cov != 100.0) begin
|
||||
$error("Coverage should stay 100%%, got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
$display("Array bins test PASSED");
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -5,44 +5,44 @@
|
|||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t;
|
||||
/* verilator lint_off UNSIGNED */
|
||||
/* verilator lint_off CMPCONST */
|
||||
logic [2:0] data; // 3-bit: 0-7
|
||||
/* verilator lint_off UNSIGNED */
|
||||
/* verilator lint_off CMPCONST */
|
||||
logic [2:0] data; // 3-bit: 0-7
|
||||
|
||||
covergroup cg;
|
||||
coverpoint data {
|
||||
bins auto[4]; // Should create 4 bins: [0:1], [2:3], [4:5], [6:7]
|
||||
}
|
||||
endgroup
|
||||
/* verilator lint_on CMPCONST */
|
||||
covergroup cg;
|
||||
coverpoint data {
|
||||
bins auto[4]; // Should create 4 bins: [0:1], [2:3], [4:5], [6:7]
|
||||
}
|
||||
endgroup
|
||||
/* verilator lint_on CMPCONST */
|
||||
|
||||
initial begin
|
||||
automatic cg cg_inst = new;
|
||||
initial begin
|
||||
automatic cg cg_inst = new;
|
||||
|
||||
// Initial coverage should be 0%
|
||||
$display("Coverage initial: %f%% (expected ~0.00%%)", cg_inst.get_inst_coverage());
|
||||
// Initial coverage should be 0%
|
||||
$display("Coverage initial: %f%% (expected ~0.00%%)", cg_inst.get_inst_coverage());
|
||||
|
||||
// Sample first bin: 0 or 1
|
||||
data = 0;
|
||||
cg_inst.sample();
|
||||
$display("Coverage after 0: %f%% (expected ~25.00%%)", cg_inst.get_inst_coverage());
|
||||
// Sample first bin: 0 or 1
|
||||
data = 0;
|
||||
cg_inst.sample();
|
||||
$display("Coverage after 0: %f%% (expected ~25.00%%)", cg_inst.get_inst_coverage());
|
||||
|
||||
// Sample second bin: 2 or 3
|
||||
data = 2;
|
||||
cg_inst.sample();
|
||||
$display("Coverage after 2: %f%% (expected ~50.00%%)", cg_inst.get_inst_coverage());
|
||||
// Sample second bin: 2 or 3
|
||||
data = 2;
|
||||
cg_inst.sample();
|
||||
$display("Coverage after 2: %f%% (expected ~50.00%%)", cg_inst.get_inst_coverage());
|
||||
|
||||
// Sample third bin: 4 or 5
|
||||
data = 5;
|
||||
cg_inst.sample();
|
||||
$display("Coverage after 5: %f%% (expected ~75.00%%)", cg_inst.get_inst_coverage());
|
||||
// Sample third bin: 4 or 5
|
||||
data = 5;
|
||||
cg_inst.sample();
|
||||
$display("Coverage after 5: %f%% (expected ~75.00%%)", cg_inst.get_inst_coverage());
|
||||
|
||||
// Sample fourth bin: 6 or 7
|
||||
data = 7;
|
||||
cg_inst.sample();
|
||||
$display("Coverage complete: %f%% (expected ~100.00%%)", cg_inst.get_inst_coverage());
|
||||
// Sample fourth bin: 6 or 7
|
||||
data = 7;
|
||||
cg_inst.sample();
|
||||
$display("Coverage complete: %f%% (expected ~100.00%%)", cg_inst.get_inst_coverage());
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -3,53 +3,53 @@
|
|||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
logic [1:0] data;
|
||||
logic [1:0] data;
|
||||
|
||||
// Covergroup with automatic sampling on posedge clk
|
||||
covergroup cg @(posedge clk);
|
||||
cp_data: coverpoint data {
|
||||
bins zero = {2'b00};
|
||||
bins one = {2'b01};
|
||||
bins two = {2'b10};
|
||||
bins three = {2'b11};
|
||||
}
|
||||
endgroup
|
||||
// Covergroup with automatic sampling on posedge clk
|
||||
covergroup cg @(posedge clk);
|
||||
cp_data: coverpoint data {
|
||||
bins zero = {2'b00};
|
||||
bins one = {2'b01};
|
||||
bins two = {2'b10};
|
||||
bins three = {2'b11};
|
||||
}
|
||||
endgroup
|
||||
|
||||
cg cg_inst = new;
|
||||
cg cg_inst = new;
|
||||
|
||||
int cyc = 0;
|
||||
int cyc = 0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
|
||||
case (cyc)
|
||||
0: data <= 2'b00; // Hit bin zero
|
||||
1: data <= 2'b01; // Hit bin one
|
||||
2: data <= 2'b10; // Hit bin two
|
||||
3: data <= 2'b11; // Hit bin three
|
||||
4: begin
|
||||
$display("Coverage: %f%%", cg_inst.get_inst_coverage());
|
||||
if (cg_inst.get_inst_coverage() >= 99.0) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end else begin
|
||||
$display("ERROR: Expected 100%% coverage, got %f%%", cg_inst.get_inst_coverage());
|
||||
$stop;
|
||||
end
|
||||
case (cyc)
|
||||
0: data <= 2'b00; // Hit bin zero
|
||||
1: data <= 2'b01; // Hit bin one
|
||||
2: data <= 2'b10; // Hit bin two
|
||||
3: data <= 2'b11; // Hit bin three
|
||||
4: begin
|
||||
$display("Coverage: %f%%", cg_inst.get_inst_coverage());
|
||||
if (cg_inst.get_inst_coverage() >= 99.0) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end else begin
|
||||
$display("ERROR: Expected 100%% coverage, got %f%%", cg_inst.get_inst_coverage());
|
||||
$stop;
|
||||
end
|
||||
endcase
|
||||
|
||||
// NOTE: NO manual .sample() call - relying on automatic sampling!
|
||||
|
||||
// Auto-stop after 10 cycles to prevent infinite loop
|
||||
if (cyc > 10) begin
|
||||
$display("ERROR: Test timed out");
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
|
||||
// NOTE: NO manual .sample() call - relying on automatic sampling!
|
||||
|
||||
// Auto-stop after 10 cycles to prevent infinite loop
|
||||
if (cyc > 10) begin
|
||||
$display("ERROR: Test timed out");
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -7,116 +7,116 @@
|
|||
// Test automatic bin creation when coverpoint has no explicit bins
|
||||
|
||||
module t(/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
logic [2:0] data3; // 3-bit: values 0-7
|
||||
logic [1:0] data2; // 2-bit: values 0-3
|
||||
logic [2:0] data3; // 3-bit: values 0-7
|
||||
logic [1:0] data2; // 2-bit: values 0-3
|
||||
|
||||
// Test 1: auto_bin_max default (64) - should create 8 bins for 3-bit signal
|
||||
// Each value should get its own bin since 2^3 = 8 < 64
|
||||
covergroup cg1;
|
||||
cp_data3: coverpoint data3; // No bins specified - autobins
|
||||
endgroup
|
||||
// Test 1: auto_bin_max default (64) - should create 8 bins for 3-bit signal
|
||||
// Each value should get its own bin since 2^3 = 8 < 64
|
||||
covergroup cg1;
|
||||
cp_data3: coverpoint data3; // No bins specified - autobins
|
||||
endgroup
|
||||
|
||||
// Test 2: With option.auto_bin_max = 4
|
||||
// Should create 4 bins: [0:1], [2:3], [4:5], [6:7]
|
||||
covergroup cg2;
|
||||
option.auto_bin_max = 4;
|
||||
cp_data3: coverpoint data3; // No bins specified - autobins
|
||||
endgroup
|
||||
// Test 2: With option.auto_bin_max = 4
|
||||
// Should create 4 bins: [0:1], [2:3], [4:5], [6:7]
|
||||
covergroup cg2;
|
||||
option.auto_bin_max = 4;
|
||||
cp_data3: coverpoint data3; // No bins specified - autobins
|
||||
endgroup
|
||||
|
||||
// Test 3: With ignore bins - should still auto-create for non-ignored values
|
||||
// Autobins created, but value 7 is ignored
|
||||
covergroup cg3;
|
||||
cp_data3: coverpoint data3 {
|
||||
ignore_bins reserved = {7};
|
||||
}
|
||||
endgroup
|
||||
// Test 3: With ignore bins - should still auto-create for non-ignored values
|
||||
// Autobins created, but value 7 is ignored
|
||||
covergroup cg3;
|
||||
cp_data3: coverpoint data3 {
|
||||
ignore_bins reserved = {7};
|
||||
}
|
||||
endgroup
|
||||
|
||||
// Test 4: Smaller signal - 2-bit
|
||||
// Should create 4 bins (one per value) since 2^2 = 4 < 64
|
||||
covergroup cg4;
|
||||
cp_data2: coverpoint data2; // No bins specified - autobins
|
||||
endgroup
|
||||
// Test 4: Smaller signal - 2-bit
|
||||
// Should create 4 bins (one per value) since 2^2 = 4 < 64
|
||||
covergroup cg4;
|
||||
cp_data2: coverpoint data2; // No bins specified - autobins
|
||||
endgroup
|
||||
|
||||
// Test 5: With auto_bin_max smaller than signal range
|
||||
// 2-bit signal (0-3) with auto_bin_max=2 should create 2 bins: [0:1], [2:3]
|
||||
covergroup cg5;
|
||||
option.auto_bin_max = 2;
|
||||
cp_data2: coverpoint data2; // No bins specified - autobins
|
||||
endgroup
|
||||
// Test 5: With auto_bin_max smaller than signal range
|
||||
// 2-bit signal (0-3) with auto_bin_max=2 should create 2 bins: [0:1], [2:3]
|
||||
covergroup cg5;
|
||||
option.auto_bin_max = 2;
|
||||
cp_data2: coverpoint data2; // No bins specified - autobins
|
||||
endgroup
|
||||
|
||||
initial begin
|
||||
cg1 cg1_inst;
|
||||
cg2 cg2_inst;
|
||||
cg3 cg3_inst;
|
||||
cg4 cg4_inst;
|
||||
cg5 cg5_inst;
|
||||
initial begin
|
||||
cg1 cg1_inst;
|
||||
cg2 cg2_inst;
|
||||
cg3 cg3_inst;
|
||||
cg4 cg4_inst;
|
||||
cg5 cg5_inst;
|
||||
|
||||
cg1_inst = new;
|
||||
cg2_inst = new;
|
||||
cg3_inst = new;
|
||||
cg4_inst = new;
|
||||
cg5_inst = new;
|
||||
cg1_inst = new;
|
||||
cg2_inst = new;
|
||||
cg3_inst = new;
|
||||
cg4_inst = new;
|
||||
cg5_inst = new;
|
||||
|
||||
// Test CG1: Hit values 0, 1, 2 (3 of 8 bins = 37.5%)
|
||||
data3 = 0; cg1_inst.sample();
|
||||
data3 = 1; cg1_inst.sample();
|
||||
data3 = 2; cg1_inst.sample();
|
||||
// Test CG1: Hit values 0, 1, 2 (3 of 8 bins = 37.5%)
|
||||
data3 = 0; cg1_inst.sample();
|
||||
data3 = 1; cg1_inst.sample();
|
||||
data3 = 2; cg1_inst.sample();
|
||||
|
||||
// Test CG2: Hit values 0, 1, 4 (bins [0:1] and [4:5], 2 of 4 bins = 50%)
|
||||
data3 = 0; cg2_inst.sample();
|
||||
data3 = 1; cg2_inst.sample();
|
||||
data3 = 4; cg2_inst.sample();
|
||||
// Test CG2: Hit values 0, 1, 4 (bins [0:1] and [4:5], 2 of 4 bins = 50%)
|
||||
data3 = 0; cg2_inst.sample();
|
||||
data3 = 1; cg2_inst.sample();
|
||||
data3 = 4; cg2_inst.sample();
|
||||
|
||||
// Test CG3: Hit values 0, 1, 7 (7 is ignored, so 2 of 7 valid bins = 28.6%)
|
||||
data3 = 0; cg3_inst.sample();
|
||||
data3 = 1; cg3_inst.sample();
|
||||
data3 = 7; cg3_inst.sample(); // Ignored
|
||||
// Test CG3: Hit values 0, 1, 7 (7 is ignored, so 2 of 7 valid bins = 28.6%)
|
||||
data3 = 0; cg3_inst.sample();
|
||||
data3 = 1; cg3_inst.sample();
|
||||
data3 = 7; cg3_inst.sample(); // Ignored
|
||||
|
||||
// Test CG4: Hit all values 0-3 (4 of 4 bins = 100%)
|
||||
data2 = 0; cg4_inst.sample();
|
||||
data2 = 1; cg4_inst.sample();
|
||||
data2 = 2; cg4_inst.sample();
|
||||
data2 = 3; cg4_inst.sample();
|
||||
// Test CG4: Hit all values 0-3 (4 of 4 bins = 100%)
|
||||
data2 = 0; cg4_inst.sample();
|
||||
data2 = 1; cg4_inst.sample();
|
||||
data2 = 2; cg4_inst.sample();
|
||||
data2 = 3; cg4_inst.sample();
|
||||
|
||||
// Test CG5: Hit values 0, 3 (bins [0:1] and [2:3], 2 of 2 bins = 100%)
|
||||
data2 = 0; cg5_inst.sample();
|
||||
data2 = 3; cg5_inst.sample();
|
||||
// Test CG5: Hit values 0, 3 (bins [0:1] and [2:3], 2 of 2 bins = 100%)
|
||||
data2 = 0; cg5_inst.sample();
|
||||
data2 = 3; cg5_inst.sample();
|
||||
|
||||
$display("CG1 (8 autobins): %0.1f%%", cg1_inst.get_inst_coverage());
|
||||
$display("CG2 (4 autobins w/ option): %0.1f%%", cg2_inst.get_inst_coverage());
|
||||
$display("CG3 (7 autobins w/ ignore): %0.1f%%", cg3_inst.get_inst_coverage());
|
||||
$display("CG4 (4 autobins): %0.1f%%", cg4_inst.get_inst_coverage());
|
||||
$display("CG5 (2 autobins w/ option): %0.1f%%", cg5_inst.get_inst_coverage());
|
||||
$display("CG1 (8 autobins): %0.1f%%", cg1_inst.get_inst_coverage());
|
||||
$display("CG2 (4 autobins w/ option): %0.1f%%", cg2_inst.get_inst_coverage());
|
||||
$display("CG3 (7 autobins w/ ignore): %0.1f%%", cg3_inst.get_inst_coverage());
|
||||
$display("CG4 (4 autobins): %0.1f%%", cg4_inst.get_inst_coverage());
|
||||
$display("CG5 (2 autobins w/ option): %0.1f%%", cg5_inst.get_inst_coverage());
|
||||
|
||||
// Validate coverage results
|
||||
if (cg1_inst.get_inst_coverage() < 30.0 || cg1_inst.get_inst_coverage() > 45.0) begin
|
||||
$display("FAIL: CG1 coverage out of range");
|
||||
$stop;
|
||||
end
|
||||
if (cg2_inst.get_inst_coverage() < 45.0 || cg2_inst.get_inst_coverage() > 55.0) begin
|
||||
$display("FAIL: CG2 coverage should be 50%% (2/4 bins with auto_bin_max=4)");
|
||||
$stop;
|
||||
end
|
||||
if (cg3_inst.get_inst_coverage() < 27.0 || cg3_inst.get_inst_coverage() > 30.0) begin
|
||||
$display("FAIL: CG3 coverage should be ~28.6%% (2/7 valid bins, value 7 ignored)");
|
||||
$stop;
|
||||
end
|
||||
if (cg4_inst.get_inst_coverage() < 95.0) begin
|
||||
$display("FAIL: CG4 coverage should be 100%%");
|
||||
$stop;
|
||||
end
|
||||
if (cg5_inst.get_inst_coverage() < 99.0) begin
|
||||
$display("FAIL: CG5 coverage should be 100%% (2/2 bins with auto_bin_max=2)");
|
||||
$stop;
|
||||
end
|
||||
// Validate coverage results
|
||||
if (cg1_inst.get_inst_coverage() < 30.0 || cg1_inst.get_inst_coverage() > 45.0) begin
|
||||
$display("FAIL: CG1 coverage out of range");
|
||||
$stop;
|
||||
end
|
||||
if (cg2_inst.get_inst_coverage() < 45.0 || cg2_inst.get_inst_coverage() > 55.0) begin
|
||||
$display("FAIL: CG2 coverage should be 50%% (2/4 bins with auto_bin_max=4)");
|
||||
$stop;
|
||||
end
|
||||
if (cg3_inst.get_inst_coverage() < 27.0 || cg3_inst.get_inst_coverage() > 30.0) begin
|
||||
$display("FAIL: CG3 coverage should be ~28.6%% (2/7 valid bins, value 7 ignored)");
|
||||
$stop;
|
||||
end
|
||||
if (cg4_inst.get_inst_coverage() < 95.0) begin
|
||||
$display("FAIL: CG4 coverage should be 100%%");
|
||||
$stop;
|
||||
end
|
||||
if (cg5_inst.get_inst_coverage() < 99.0) begin
|
||||
$display("FAIL: CG5 coverage should be 100%% (2/2 bins with auto_bin_max=2)");
|
||||
$stop;
|
||||
end
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
%Error: t/t_covergroup_autobins_bad.v:17:18: Automatic bins array size must be a constant
|
||||
%Error: t/t_covergroup_autobins_bad.v:17:12: Automatic bins array size must be a constant
|
||||
: ... note: In instance 't'
|
||||
17 | bins auto[size_var];
|
||||
| ^~~~
|
||||
17 | bins auto[size_var];
|
||||
| ^~~~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: t/t_covergroup_autobins_bad.v:24:18: Automatic bins array size must be 1-10000, got 0
|
||||
%Error: t/t_covergroup_autobins_bad.v:24:12: Automatic bins array size must be 1-10000, got 0
|
||||
: ... note: In instance 't'
|
||||
24 | bins auto[0];
|
||||
| ^~~~
|
||||
%Error: t/t_covergroup_autobins_bad.v:31:18: Automatic bins array size must be 1-10000, got 10001
|
||||
24 | bins auto[0];
|
||||
| ^~~~
|
||||
%Error: t/t_covergroup_autobins_bad.v:31:12: Automatic bins array size must be 1-10000, got 10001
|
||||
: ... note: In instance 't'
|
||||
31 | bins auto[10001];
|
||||
| ^~~~
|
||||
31 | bins auto[10001];
|
||||
| ^~~~
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -8,33 +8,33 @@
|
|||
// Tests for automatic bins error conditions
|
||||
|
||||
module t;
|
||||
int size_var;
|
||||
logic [3:0] cp_expr;
|
||||
int size_var;
|
||||
logic [3:0] cp_expr;
|
||||
|
||||
// Error: array size must be a constant
|
||||
covergroup cg1;
|
||||
cp1: coverpoint cp_expr {
|
||||
bins auto[size_var];
|
||||
}
|
||||
endgroup
|
||||
// Error: array size must be a constant
|
||||
covergroup cg1;
|
||||
cp1: coverpoint cp_expr {
|
||||
bins auto[size_var];
|
||||
}
|
||||
endgroup
|
||||
|
||||
// Error: array size must be 1-10000 (zero)
|
||||
covergroup cg2;
|
||||
cp1: coverpoint cp_expr {
|
||||
bins auto[0];
|
||||
}
|
||||
endgroup
|
||||
// Error: array size must be 1-10000 (zero)
|
||||
covergroup cg2;
|
||||
cp1: coverpoint cp_expr {
|
||||
bins auto[0];
|
||||
}
|
||||
endgroup
|
||||
|
||||
// Error: array size must be 1-10000 (too large)
|
||||
covergroup cg3;
|
||||
cp1: coverpoint cp_expr {
|
||||
bins auto[10001];
|
||||
}
|
||||
endgroup
|
||||
// Error: array size must be 1-10000 (too large)
|
||||
covergroup cg3;
|
||||
cp1: coverpoint cp_expr {
|
||||
bins auto[10001];
|
||||
}
|
||||
endgroup
|
||||
|
||||
cg1 cg1_inst = new;
|
||||
cg2 cg2_inst = new;
|
||||
cg3 cg3_inst = new;
|
||||
cg1 cg1_inst = new;
|
||||
cg2 cg2_inst = new;
|
||||
cg3 cg3_inst = new;
|
||||
|
||||
initial $finish;
|
||||
initial $finish;
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -7,45 +7,45 @@
|
|||
// Test viewing individual bin hit counts
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
/* verilator lint_off UNSIGNED */
|
||||
logic [3:0] data;
|
||||
/* verilator lint_off UNSIGNED */
|
||||
logic [3:0] data;
|
||||
|
||||
covergroup cg;
|
||||
coverpoint data {
|
||||
bins zero = {0};
|
||||
bins low = {[1:3]};
|
||||
bins mid = {[4:7]};
|
||||
bins high = {[8:15]};
|
||||
}
|
||||
endgroup
|
||||
covergroup cg;
|
||||
coverpoint data {
|
||||
bins zero = {0};
|
||||
bins low = {[1:3]};
|
||||
bins mid = {[4:7]};
|
||||
bins high = {[8:15]};
|
||||
}
|
||||
endgroup
|
||||
|
||||
cg cg_inst;
|
||||
cg cg_inst;
|
||||
|
||||
initial begin
|
||||
cg_inst = new;
|
||||
initial begin
|
||||
cg_inst = new;
|
||||
|
||||
// Sample various values with different frequencies
|
||||
data = 0; cg_inst.sample(); // zero: 1
|
||||
data = 1; cg_inst.sample(); // low: 1
|
||||
data = 2; cg_inst.sample(); // low: 2
|
||||
data = 2; cg_inst.sample(); // low: 3
|
||||
data = 5; cg_inst.sample(); // mid: 1
|
||||
data = 10; cg_inst.sample(); // high: 1
|
||||
// Sample various values with different frequencies
|
||||
data = 0; cg_inst.sample(); // zero: 1
|
||||
data = 1; cg_inst.sample(); // low: 1
|
||||
data = 2; cg_inst.sample(); // low: 2
|
||||
data = 2; cg_inst.sample(); // low: 3
|
||||
data = 5; cg_inst.sample(); // mid: 1
|
||||
data = 10; cg_inst.sample(); // high: 1
|
||||
|
||||
// Verify coverage is 100% (all 4 bins hit)
|
||||
check_coverage(100.0, "final");
|
||||
// Verify coverage is 100% (all 4 bins hit)
|
||||
check_coverage(100.0, "final");
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
task check_coverage(real expected, string label);
|
||||
real cov;
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("Coverage %s: %0.2f%% (expected ~%0.2f%%)", label, cov, expected);
|
||||
if (cov < expected - 0.5 || cov > expected + 0.5) begin
|
||||
$error("Coverage mismatch: got %0.2f%%, expected ~%0.2f%%", cov, expected);
|
||||
$stop;
|
||||
end
|
||||
|
||||
task check_coverage(real expected, string label);
|
||||
real cov;
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("Coverage %s: %0.2f%% (expected ~%0.2f%%)", label, cov, expected);
|
||||
if (cov < expected - 0.5 || cov > expected + 0.5) begin
|
||||
$error("Coverage mismatch: got %0.2f%%, expected ~%0.2f%%", cov, expected);
|
||||
$stop;
|
||||
end
|
||||
endtask
|
||||
endtask
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,73 +0,0 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain
|
||||
// SPDX-FileCopyrightText: 2026 Matthew Ballance
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// Test bin options: at_least, weight, goal
|
||||
|
||||
module t;
|
||||
/* verilator lint_off UNSIGNED */
|
||||
bit [7:0] addr;
|
||||
|
||||
covergroup cg;
|
||||
option.per_instance = 1;
|
||||
option.comment = "Test covergroup with options";
|
||||
|
||||
coverpoint addr {
|
||||
option.at_least = 2; // Each bin needs at least 2 hits
|
||||
option.weight = 10; // This coverpoint has weight 10
|
||||
|
||||
bins low = {[0:3]};
|
||||
bins mid = {[4:7]};
|
||||
bins high = {[8:15]};
|
||||
}
|
||||
endgroup
|
||||
|
||||
initial begin
|
||||
cg cg_inst;
|
||||
real cov;
|
||||
|
||||
cg_inst = new();
|
||||
|
||||
// Hit low once - should be 0% because at_least = 2
|
||||
addr = 2;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("After 1 hit: %0.2f%%", cov);
|
||||
if (cov != 0.0) begin
|
||||
$error("Expected 0%% (bin needs 2 hits), got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit low again - should be 33.33% (1/3 bins)
|
||||
addr = 1;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("After 2 hits to low: %0.2f%%", cov);
|
||||
if (cov < 30.0 || cov > 35.0) begin
|
||||
$error("Expected ~33.33%%, got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit mid twice - should be 66.67% (2/3 bins)
|
||||
addr = 5; cg_inst.sample();
|
||||
addr = 6; cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("After mid hits: %0.2f%%", cov);
|
||||
if (cov < 63.0 || cov > 70.0) begin
|
||||
$error("Expected ~66.67%%, got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit high twice - should be 100%
|
||||
addr = 10; cg_inst.sample();
|
||||
addr = 12; cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("After all bins hit: %0.2f%%", cov);
|
||||
if (cov != 100.0) begin
|
||||
$error("Expected 100%%, got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
$display("Bin options test PASSED");
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2024 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// Test advanced bin types that ARE supported:
|
||||
// - ignore_bins
|
||||
// - wildcard bins
|
||||
// - array bins (explicit values only, not ranges yet)
|
||||
|
||||
module t;
|
||||
|
||||
logic [3:0] data;
|
||||
int error_count = 0;
|
||||
|
||||
// Test 1: ignore_bins
|
||||
covergroup cg_ignore;
|
||||
coverpoint data {
|
||||
bins low = {[0:3]};
|
||||
bins mid = {[4:7]};
|
||||
bins high = {[8:11]};
|
||||
ignore_bins reserved = {[12:15]}; // Should not count toward coverage
|
||||
}
|
||||
endgroup
|
||||
|
||||
// Test 2: Array bins (with ranges - now working!)
|
||||
covergroup cg_array;
|
||||
coverpoint data {
|
||||
bins values[] = {[0:3]}; // Creates 4 bins: values[0], values[1], values[2], values[3]
|
||||
}
|
||||
endgroup
|
||||
|
||||
// Test 3: wildcard bins (with don't-care bits)
|
||||
covergroup cg_wildcard;
|
||||
coverpoint data {
|
||||
wildcard bins pattern0 = {4'b00??}; // Matches 0,1,2,3
|
||||
wildcard bins pattern1 = {4'b01??}; // Matches 4,5,6,7
|
||||
wildcard bins pattern2 = {4'b10??}; // Matches 8,9,10,11
|
||||
wildcard bins pattern3 = {4'b11??}; // Matches 12,13,14,15
|
||||
}
|
||||
endgroup
|
||||
|
||||
initial begin
|
||||
cg_ignore cg1;
|
||||
cg_array cg2;
|
||||
cg_wildcard cg3;
|
||||
real cov;
|
||||
|
||||
cg1 = new;
|
||||
cg2 = new;
|
||||
cg3 = new;
|
||||
|
||||
// Test 1: ignore_bins
|
||||
$display("Test 1: ignore_bins");
|
||||
data = 0; cg1.sample(); // low
|
||||
data = 5; cg1.sample(); // mid
|
||||
data = 9; cg1.sample(); // high
|
||||
data = 12; cg1.sample(); // ignored - should not affect coverage
|
||||
data = 13; cg1.sample(); // ignored
|
||||
|
||||
cov = cg1.get_inst_coverage();
|
||||
$display(" Coverage with ignore_bins: %0.1f%% (expect 100%%)", cov);
|
||||
// 3 out of 3 non-ignored bins = 100%
|
||||
if (cov < 99.0 || cov > 101.0) begin
|
||||
$display("%%Error: Expected 100%%, got %0.1f%%", cov);
|
||||
error_count++;
|
||||
end
|
||||
|
||||
// Test 2: Array bins
|
||||
$display("Test 2: Array bins (with ranges)");
|
||||
data = 0; cg2.sample(); // values[0]
|
||||
data = 1; cg2.sample(); // values[1]
|
||||
data = 2; cg2.sample(); // values[2]
|
||||
// Note: values[3] not sampled, so 75% coverage expected
|
||||
|
||||
cov = cg2.get_inst_coverage();
|
||||
$display(" Coverage with array bins: %0.1f%% (expect 75%%)", cov);
|
||||
// 3 out of 4 bins = 75%
|
||||
if (cov < 74.0 || cov > 76.0) begin
|
||||
$display("%%Error: Expected 75%%, got %0.1f%%", cov);
|
||||
error_count++;
|
||||
end
|
||||
|
||||
// Test 3: Wildcard bins
|
||||
$display("Test 3: Wildcard bins");
|
||||
data = 2; cg3.sample(); // pattern0 (00??)
|
||||
data = 5; cg3.sample(); // pattern1 (01??)
|
||||
data = 10; cg3.sample(); // pattern2 (10??)
|
||||
// pattern3 not sampled, so 75% coverage
|
||||
|
||||
cov = cg3.get_inst_coverage();
|
||||
$display(" Coverage with wildcard bins: %0.1f%% (expect 75%%)", cov);
|
||||
// 3 out of 4 bins = 75%
|
||||
if (cov < 74.0 || cov > 76.0) begin
|
||||
$display("%%Error: Expected 75%%, got %0.1f%%", cov);
|
||||
error_count++;
|
||||
end
|
||||
|
||||
if (error_count == 0) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
end else begin
|
||||
$display("%%Error: %0d test(s) failed", error_count);
|
||||
$stop;
|
||||
end
|
||||
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2024 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// Test default bins and illegal_bins
|
||||
|
||||
module t;
|
||||
|
||||
logic [3:0] data;
|
||||
int error_count = 0;
|
||||
|
||||
// Test 1: default bins
|
||||
covergroup cg_default;
|
||||
coverpoint data {
|
||||
bins special = {0, 5, 10};
|
||||
bins others = default; // Catch-all for uncovered values
|
||||
}
|
||||
endgroup
|
||||
|
||||
// Test 2: illegal_bins (we'll test it doesn't crash on valid values)
|
||||
covergroup cg_valid;
|
||||
coverpoint data {
|
||||
bins valid = {[0:10]};
|
||||
illegal_bins reserved = {[11:15]};
|
||||
}
|
||||
endgroup
|
||||
|
||||
initial begin
|
||||
cg_default cg1;
|
||||
cg_valid cg2;
|
||||
real cov;
|
||||
|
||||
cg1 = new;
|
||||
cg2 = new;
|
||||
|
||||
// Test 1: default bins
|
||||
$display("Test 1: default bins");
|
||||
data = 0; cg1.sample(); // special bin
|
||||
data = 1; cg1.sample(); // default/others bin
|
||||
data = 5; cg1.sample(); // special bin
|
||||
data = 7; cg1.sample(); // default/others bin
|
||||
data = 10; cg1.sample(); // special bin
|
||||
|
||||
cov = cg1.get_inst_coverage();
|
||||
$display(" Coverage with default bins: %0.1f%%", cov);
|
||||
// Both bins hit: special (3 values: 0,5,10) and default (2 values: 1,7)
|
||||
// Expected: 2/2 = 100%
|
||||
if (cov < 99.0 || cov > 101.0) begin
|
||||
$display("%%Error: Expected 100%%, got %0.1f%%", cov);
|
||||
error_count++;
|
||||
end
|
||||
|
||||
// Test 2: illegal_bins (test with valid values only)
|
||||
$display("Test 2: illegal_bins (sampling valid values)");
|
||||
data = 0; cg2.sample(); // valid
|
||||
data = 5; cg2.sample(); // valid
|
||||
data = 10; cg2.sample(); // valid
|
||||
|
||||
cov = cg2.get_inst_coverage();
|
||||
$display(" Coverage with illegal_bins: %0.1f%%", cov);
|
||||
// Only the valid bin counts, illegal bins don't count toward coverage
|
||||
// 1 bin out of 1 = 100%
|
||||
if (cov < 99.0 || cov > 101.0) begin
|
||||
$display("%%Error: Expected 100%%, got %0.1f%%", cov);
|
||||
error_count++;
|
||||
end
|
||||
|
||||
if (error_count == 0) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
end else begin
|
||||
$display("%%Error: %0d test(s) failed", error_count);
|
||||
$stop;
|
||||
end
|
||||
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -14,63 +14,63 @@
|
|||
// Solution: Call .sample() explicitly in an always block.
|
||||
|
||||
module t;
|
||||
logic clk = 0;
|
||||
always #5 clk = ~clk;
|
||||
logic clk = 0;
|
||||
always #5 clk = ~clk;
|
||||
|
||||
logic [1:0] data;
|
||||
logic [1:0] data;
|
||||
|
||||
/* verilator lint_off UNSIGNED */
|
||||
covergroup cg; // NOTE: No clocking event - we'll sample explicitly
|
||||
cp: coverpoint data {
|
||||
bins val0 = {2'b00};
|
||||
bins val1 = {2'b01};
|
||||
bins val2 = {2'b10};
|
||||
bins val3 = {2'b11};
|
||||
}
|
||||
endgroup
|
||||
/* verilator lint_on UNSIGNED */
|
||||
/* verilator lint_off UNSIGNED */
|
||||
covergroup cg; // NOTE: No clocking event - we'll sample explicitly
|
||||
cp: coverpoint data {
|
||||
bins val0 = {2'b00};
|
||||
bins val1 = {2'b01};
|
||||
bins val2 = {2'b10};
|
||||
bins val3 = {2'b11};
|
||||
}
|
||||
endgroup
|
||||
/* verilator lint_on UNSIGNED */
|
||||
|
||||
cg cg_inst = new;
|
||||
cg cg_inst = new;
|
||||
|
||||
// Explicit sampling workaround for internal clocks
|
||||
always @(posedge clk) begin
|
||||
cg_inst.sample();
|
||||
end
|
||||
// Explicit sampling workaround for internal clocks
|
||||
always @(posedge clk) begin
|
||||
cg_inst.sample();
|
||||
end
|
||||
|
||||
initial begin
|
||||
// Cycle 0
|
||||
data = 2'b00;
|
||||
@(posedge clk);
|
||||
initial begin
|
||||
// Cycle 0
|
||||
data = 2'b00;
|
||||
@(posedge clk);
|
||||
|
||||
// Cycle 1
|
||||
data = 2'b01;
|
||||
@(posedge clk);
|
||||
// Cycle 1
|
||||
data = 2'b01;
|
||||
@(posedge clk);
|
||||
|
||||
// Cycle 2
|
||||
data = 2'b10;
|
||||
@(posedge clk);
|
||||
// Cycle 2
|
||||
data = 2'b10;
|
||||
@(posedge clk);
|
||||
|
||||
// Cycle 3
|
||||
data = 2'b11;
|
||||
@(posedge clk);
|
||||
// Cycle 3
|
||||
data = 2'b11;
|
||||
@(posedge clk);
|
||||
|
||||
// Check coverage
|
||||
#1; // Small delay to ensure last sample completes
|
||||
// Check coverage
|
||||
#1; // Small delay to ensure last sample completes
|
||||
|
||||
begin
|
||||
automatic real cov = cg_inst.get_inst_coverage();
|
||||
$display("Coverage: %0.1f%%", cov);
|
||||
begin
|
||||
automatic real cov = cg_inst.get_inst_coverage();
|
||||
$display("Coverage: %0.1f%%", cov);
|
||||
|
||||
// Should have hit all 4 bins = 100%
|
||||
if (cov >= 99.0) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end else begin
|
||||
$display("ERROR: Expected 100%% coverage, got %f%%", cov);
|
||||
$display("ERROR: This is a known limitation - auto-sampling doesn't work with internal clocks");
|
||||
$stop;
|
||||
end
|
||||
// Should have hit all 4 bins = 100%
|
||||
if (cov >= 99.0) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end else begin
|
||||
$display("ERROR: Expected 100%% coverage, got %f%%", cov);
|
||||
$display("ERROR: This is a known limitation - auto-sampling doesn't work with internal clocks");
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -8,54 +8,54 @@
|
|||
// Status: WORKS - Verilator correctly auto-samples when clk is a module port
|
||||
|
||||
module t(/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
logic [1:0] data;
|
||||
logic [1:0] data;
|
||||
|
||||
/* verilator lint_off UNSIGNED */
|
||||
covergroup cg @(posedge clk);
|
||||
cp: coverpoint data {
|
||||
bins val0 = {2'b00};
|
||||
bins val1 = {2'b01};
|
||||
bins val2 = {2'b10};
|
||||
bins val3 = {2'b11};
|
||||
}
|
||||
endgroup
|
||||
/* verilator lint_on UNSIGNED */
|
||||
/* verilator lint_off UNSIGNED */
|
||||
covergroup cg @(posedge clk);
|
||||
cp: coverpoint data {
|
||||
bins val0 = {2'b00};
|
||||
bins val1 = {2'b01};
|
||||
bins val2 = {2'b10};
|
||||
bins val3 = {2'b11};
|
||||
}
|
||||
endgroup
|
||||
/* verilator lint_on UNSIGNED */
|
||||
|
||||
cg cg_inst = new;
|
||||
cg cg_inst = new;
|
||||
|
||||
int cyc = 0;
|
||||
int cyc = 0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
|
||||
// Change data each cycle
|
||||
data <= cyc[1:0];
|
||||
// Change data each cycle
|
||||
data <= cyc[1:0];
|
||||
|
||||
if (cyc == 5) begin
|
||||
/* verilator lint_off IMPLICITSTATIC */
|
||||
real cov = cg_inst.get_inst_coverage();
|
||||
/* verilator lint_on IMPLICITSTATIC */
|
||||
$display("Coverage: %0.1f%%", cov);
|
||||
if (cyc == 5) begin
|
||||
/* verilator lint_off IMPLICITSTATIC */
|
||||
real cov = cg_inst.get_inst_coverage();
|
||||
/* verilator lint_on IMPLICITSTATIC */
|
||||
$display("Coverage: %0.1f%%", cov);
|
||||
|
||||
// Should have hit all 4 bins (cycles 0-3) = 100%
|
||||
if (cov >= 99.0) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end else begin
|
||||
$display("ERROR: Expected 100%% coverage, got %f%%", cov);
|
||||
$stop;
|
||||
end
|
||||
// Should have hit all 4 bins (cycles 0-3) = 100%
|
||||
if (cov >= 99.0) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end else begin
|
||||
$display("ERROR: Expected 100%% coverage, got %f%%", cov);
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
|
||||
if (cyc > 10) begin
|
||||
$display("ERROR: Test timeout");
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
if (cyc > 10) begin
|
||||
$display("ERROR: Test timeout");
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -5,78 +5,78 @@
|
|||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
logic [1:0] data;
|
||||
logic [1:0] data;
|
||||
|
||||
// Covergroup with 4 bins
|
||||
covergroup cg @(posedge clk);
|
||||
cp: coverpoint data {
|
||||
bins low = {2'b00};
|
||||
bins mid1 = {2'b01};
|
||||
bins mid2 = {2'b10};
|
||||
bins high = {2'b11};
|
||||
}
|
||||
endgroup
|
||||
// Covergroup with 4 bins
|
||||
covergroup cg @(posedge clk);
|
||||
cp: coverpoint data {
|
||||
bins low = {2'b00};
|
||||
bins mid1 = {2'b01};
|
||||
bins mid2 = {2'b10};
|
||||
bins high = {2'b11};
|
||||
}
|
||||
endgroup
|
||||
|
||||
cg cg_inst = new;
|
||||
cg cg_inst = new;
|
||||
|
||||
initial begin
|
||||
// Initially no bins covered - should be 0%
|
||||
real cov;
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("Coverage after 0 samples: %f", cov);
|
||||
if (cov != 0.0) $stop;
|
||||
initial begin
|
||||
// Initially no bins covered - should be 0%
|
||||
real cov;
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("Coverage after 0 samples: %f", cov);
|
||||
if (cov != 0.0) $stop;
|
||||
|
||||
// Cover 1 bin (low) - should be 25%
|
||||
@(posedge clk);
|
||||
data = 2'b00;
|
||||
@(posedge clk);
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("Coverage after 1/4 bins: %f", cov);
|
||||
if (cov < 24.9 || cov > 25.1) begin
|
||||
$display("%%Error: Expected 25%%, got %f", cov);
|
||||
$stop;
|
||||
end
|
||||
// Cover 1 bin (low) - should be 25%
|
||||
@(posedge clk);
|
||||
data = 2'b00;
|
||||
@(posedge clk);
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("Coverage after 1/4 bins: %f", cov);
|
||||
if (cov < 24.9 || cov > 25.1) begin
|
||||
$display("%%Error: Expected 25%%, got %f", cov);
|
||||
$stop;
|
||||
end
|
||||
|
||||
// Cover 2nd bin (mid1) - should be 50%
|
||||
@(posedge clk);
|
||||
data = 2'b01;
|
||||
@(posedge clk);
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("Coverage after 2/4 bins: %f", cov);
|
||||
if (cov < 49.9 || cov > 50.1) begin
|
||||
$display("%%Error: Expected 50%%, got %f", cov);
|
||||
$stop;
|
||||
end
|
||||
// Cover 2nd bin (mid1) - should be 50%
|
||||
@(posedge clk);
|
||||
data = 2'b01;
|
||||
@(posedge clk);
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("Coverage after 2/4 bins: %f", cov);
|
||||
if (cov < 49.9 || cov > 50.1) begin
|
||||
$display("%%Error: Expected 50%%, got %f", cov);
|
||||
$stop;
|
||||
end
|
||||
|
||||
// Cover 3rd bin (mid2) - should be 75%
|
||||
@(posedge clk);
|
||||
data = 2'b10;
|
||||
@(posedge clk);
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("Coverage after 3/4 bins: %f", cov);
|
||||
if (cov < 74.9 || cov > 75.1) begin
|
||||
$display("%%Error: Expected 75%%, got %f", cov);
|
||||
$stop;
|
||||
end
|
||||
// Cover 3rd bin (mid2) - should be 75%
|
||||
@(posedge clk);
|
||||
data = 2'b10;
|
||||
@(posedge clk);
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("Coverage after 3/4 bins: %f", cov);
|
||||
if (cov < 74.9 || cov > 75.1) begin
|
||||
$display("%%Error: Expected 75%%, got %f", cov);
|
||||
$stop;
|
||||
end
|
||||
|
||||
// Cover 4th bin (high) - should be 100%
|
||||
@(posedge clk);
|
||||
data = 2'b11;
|
||||
@(posedge clk);
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("Coverage after 4/4 bins: %f", cov);
|
||||
if (cov < 99.9 || cov > 100.1) begin
|
||||
$display("%%Error: Expected 100%%, got %f", cov);
|
||||
$stop;
|
||||
end
|
||||
// Cover 4th bin (high) - should be 100%
|
||||
@(posedge clk);
|
||||
data = 2'b11;
|
||||
@(posedge clk);
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("Coverage after 4/4 bins: %f", cov);
|
||||
if (cov < 99.9 || cov > 100.1) begin
|
||||
$display("%%Error: Expected 100%%, got %f", cov);
|
||||
$stop;
|
||||
end
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -7,57 +7,57 @@
|
|||
// Test querying coverage values via get_inst_coverage
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
/* verilator lint_off UNSIGNED */
|
||||
logic [3:0] data;
|
||||
/* verilator lint_off UNSIGNED */
|
||||
logic [3:0] data;
|
||||
|
||||
covergroup cg;
|
||||
coverpoint data {
|
||||
bins low = {[0:3]};
|
||||
bins mid = {[4:7]};
|
||||
bins high = {[8:15]};
|
||||
}
|
||||
endgroup
|
||||
covergroup cg;
|
||||
coverpoint data {
|
||||
bins low = {[0:3]};
|
||||
bins mid = {[4:7]};
|
||||
bins high = {[8:15]};
|
||||
}
|
||||
endgroup
|
||||
|
||||
cg cg_inst;
|
||||
cg cg_inst;
|
||||
|
||||
initial begin
|
||||
cg_inst = new;
|
||||
initial begin
|
||||
cg_inst = new;
|
||||
|
||||
// Initially no coverage
|
||||
check_coverage(0.0, "initial");
|
||||
// Initially no coverage
|
||||
check_coverage(0.0, "initial");
|
||||
|
||||
// Sample low bin - should be 33.33% (1 of 3 bins)
|
||||
data = 1;
|
||||
cg_inst.sample();
|
||||
check_coverage(33.33, "after low");
|
||||
// Sample low bin - should be 33.33% (1 of 3 bins)
|
||||
data = 1;
|
||||
cg_inst.sample();
|
||||
check_coverage(33.33, "after low");
|
||||
|
||||
// Sample mid bin - should be 66.67% (2 of 3 bins)
|
||||
data = 5;
|
||||
cg_inst.sample();
|
||||
check_coverage(66.67, "after mid");
|
||||
// Sample mid bin - should be 66.67% (2 of 3 bins)
|
||||
data = 5;
|
||||
cg_inst.sample();
|
||||
check_coverage(66.67, "after mid");
|
||||
|
||||
// Sample high bin - should be 100% (3 of 3 bins)
|
||||
data = 10;
|
||||
cg_inst.sample();
|
||||
check_coverage(100.0, "after high");
|
||||
// Sample high bin - should be 100% (3 of 3 bins)
|
||||
data = 10;
|
||||
cg_inst.sample();
|
||||
check_coverage(100.0, "after high");
|
||||
|
||||
// Sample again - coverage should still be 100%
|
||||
data = 2;
|
||||
cg_inst.sample();
|
||||
check_coverage(100.0, "after resample");
|
||||
// Sample again - coverage should still be 100%
|
||||
data = 2;
|
||||
cg_inst.sample();
|
||||
check_coverage(100.0, "after resample");
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
task check_coverage(real expected, string label);
|
||||
real cov;
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("Coverage %s: %0.2f%% (expected ~%0.2f%%)", label, cov, expected);
|
||||
// Allow 0.5% tolerance for floating point
|
||||
if (cov < expected - 0.5 || cov > expected + 0.5) begin
|
||||
$error("Coverage mismatch: got %0.2f%%, expected ~%0.2f%%", cov, expected);
|
||||
$stop;
|
||||
end
|
||||
|
||||
task check_coverage(real expected, string label);
|
||||
real cov;
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("Coverage %s: %0.2f%% (expected ~%0.2f%%)", label, cov, expected);
|
||||
// Allow 0.5% tolerance for floating point
|
||||
if (cov < expected - 0.5 || cov > expected + 0.5) begin
|
||||
$error("Coverage mismatch: got %0.2f%%, expected ~%0.2f%%", cov, expected);
|
||||
$stop;
|
||||
end
|
||||
endtask
|
||||
endtask
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -7,67 +7,67 @@
|
|||
// Test 3-way cross coverage
|
||||
|
||||
module t;
|
||||
logic [1:0] addr;
|
||||
logic cmd;
|
||||
logic mode;
|
||||
logic [1:0] addr;
|
||||
logic cmd;
|
||||
logic mode;
|
||||
|
||||
// Covergroup with 3-way cross coverage
|
||||
covergroup cg;
|
||||
cp_addr: coverpoint addr {
|
||||
bins addr0 = {0};
|
||||
bins addr1 = {1};
|
||||
bins addr2 = {2};
|
||||
}
|
||||
cp_cmd: coverpoint cmd {
|
||||
bins read = {0};
|
||||
bins write = {1};
|
||||
}
|
||||
cp_mode: coverpoint mode {
|
||||
bins normal = {0};
|
||||
bins debug = {1};
|
||||
}
|
||||
// 3-way cross: addr x cmd x mode = 3 x 2 x 2 = 12 cross bins
|
||||
addr_cmd_mode: cross cp_addr, cp_cmd, cp_mode;
|
||||
endgroup
|
||||
// Covergroup with 3-way cross coverage
|
||||
covergroup cg;
|
||||
cp_addr: coverpoint addr {
|
||||
bins addr0 = {0};
|
||||
bins addr1 = {1};
|
||||
bins addr2 = {2};
|
||||
}
|
||||
cp_cmd: coverpoint cmd {
|
||||
bins read = {0};
|
||||
bins write = {1};
|
||||
}
|
||||
cp_mode: coverpoint mode {
|
||||
bins normal = {0};
|
||||
bins debug = {1};
|
||||
}
|
||||
// 3-way cross: addr x cmd x mode = 3 x 2 x 2 = 12 cross bins
|
||||
addr_cmd_mode: cross cp_addr, cp_cmd, cp_mode;
|
||||
endgroup
|
||||
|
||||
cg cg_inst = new;
|
||||
cg cg_inst = new;
|
||||
|
||||
initial begin
|
||||
// Hit different 3-way cross bins
|
||||
addr = 0; cmd = 0; mode = 0; cg_inst.sample(); // addr0 x read x normal
|
||||
$display("Sample 1: addr=%0d, cmd=%0d, mode=%0d", addr, cmd, mode);
|
||||
initial begin
|
||||
// Hit different 3-way cross bins
|
||||
addr = 0; cmd = 0; mode = 0; cg_inst.sample(); // addr0 x read x normal
|
||||
$display("Sample 1: addr=%0d, cmd=%0d, mode=%0d", addr, cmd, mode);
|
||||
|
||||
addr = 1; cmd = 1; mode = 0; cg_inst.sample(); // addr1 x write x normal
|
||||
$display("Sample 2: addr=%0d, cmd=%0d, mode=%0d", addr, cmd, mode);
|
||||
addr = 1; cmd = 1; mode = 0; cg_inst.sample(); // addr1 x write x normal
|
||||
$display("Sample 2: addr=%0d, cmd=%0d, mode=%0d", addr, cmd, mode);
|
||||
|
||||
addr = 2; cmd = 0; mode = 1; cg_inst.sample(); // addr2 x read x debug
|
||||
$display("Sample 3: addr=%0d, cmd=%0d, mode=%0d", addr, cmd, mode);
|
||||
addr = 2; cmd = 0; mode = 1; cg_inst.sample(); // addr2 x read x debug
|
||||
$display("Sample 3: addr=%0d, cmd=%0d, mode=%0d", addr, cmd, mode);
|
||||
|
||||
addr = 0; cmd = 1; mode = 1; cg_inst.sample(); // addr0 x write x debug
|
||||
$display("Sample 4: addr=%0d, cmd=%0d, mode=%0d", addr, cmd, mode);
|
||||
addr = 0; cmd = 1; mode = 1; cg_inst.sample(); // addr0 x write x debug
|
||||
$display("Sample 4: addr=%0d, cmd=%0d, mode=%0d", addr, cmd, mode);
|
||||
|
||||
addr = 1; cmd = 0; mode = 1; cg_inst.sample(); // addr1 x read x debug
|
||||
$display("Sample 5: addr=%0d, cmd=%0d, mode=%0d", addr, cmd, mode);
|
||||
addr = 1; cmd = 0; mode = 1; cg_inst.sample(); // addr1 x read x debug
|
||||
$display("Sample 5: addr=%0d, cmd=%0d, mode=%0d", addr, cmd, mode);
|
||||
|
||||
// Check coverage
|
||||
// Total bins:
|
||||
// - 3 bins in cp_addr (addr0, addr1, addr2)
|
||||
// - 2 bins in cp_cmd (read, write)
|
||||
// - 2 bins in cp_mode (normal, debug)
|
||||
// - 12 bins in 3-way cross (3 x 2 x 2)
|
||||
// Total = 19 bins
|
||||
// Hit: addr0, addr1, addr2 (3), read, write (2), normal, debug (2), 5 cross bins
|
||||
// Total = 12 out of 19 = 63.2%
|
||||
$display("Coverage: %0.1f%%", cg_inst.get_inst_coverage());
|
||||
// Check coverage
|
||||
// Total bins:
|
||||
// - 3 bins in cp_addr (addr0, addr1, addr2)
|
||||
// - 2 bins in cp_cmd (read, write)
|
||||
// - 2 bins in cp_mode (normal, debug)
|
||||
// - 12 bins in 3-way cross (3 x 2 x 2)
|
||||
// Total = 19 bins
|
||||
// Hit: addr0, addr1, addr2 (3), read, write (2), normal, debug (2), 5 cross bins
|
||||
// Total = 12 out of 19 = 63.2%
|
||||
$display("Coverage: %0.1f%%", cg_inst.get_inst_coverage());
|
||||
|
||||
if (cg_inst.get_inst_coverage() < 62.0 || cg_inst.get_inst_coverage() > 64.0) begin
|
||||
$display("%%Error: Expected coverage around 63%%, got %0.1f%%",
|
||||
cg_inst.get_inst_coverage());
|
||||
$stop;
|
||||
end
|
||||
if (cg_inst.get_inst_coverage() < 62.0 || cg_inst.get_inst_coverage() > 64.0) begin
|
||||
$display("%%Error: Expected coverage around 63%%, got %0.1f%%",
|
||||
cg_inst.get_inst_coverage());
|
||||
$stop;
|
||||
end
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -7,68 +7,68 @@
|
|||
// Test 4-way cross coverage
|
||||
|
||||
module t;
|
||||
logic [1:0] addr;
|
||||
logic cmd;
|
||||
logic mode;
|
||||
logic parity;
|
||||
logic [1:0] addr;
|
||||
logic cmd;
|
||||
logic mode;
|
||||
logic parity;
|
||||
|
||||
// Covergroup with 4-way cross coverage
|
||||
covergroup cg;
|
||||
cp_addr: coverpoint addr {
|
||||
bins addr0 = {0};
|
||||
bins addr1 = {1};
|
||||
}
|
||||
cp_cmd: coverpoint cmd {
|
||||
bins read = {0};
|
||||
bins write = {1};
|
||||
}
|
||||
cp_mode: coverpoint mode {
|
||||
bins normal = {0};
|
||||
bins debug = {1};
|
||||
}
|
||||
cp_parity: coverpoint parity {
|
||||
bins even = {0};
|
||||
bins odd = {1};
|
||||
}
|
||||
// 4-way cross: addr x cmd x mode x parity = 2 x 2 x 2 x 2 = 16 cross bins
|
||||
addr_cmd_mode_parity: cross cp_addr, cp_cmd, cp_mode, cp_parity;
|
||||
endgroup
|
||||
// Covergroup with 4-way cross coverage
|
||||
covergroup cg;
|
||||
cp_addr: coverpoint addr {
|
||||
bins addr0 = {0};
|
||||
bins addr1 = {1};
|
||||
}
|
||||
cp_cmd: coverpoint cmd {
|
||||
bins read = {0};
|
||||
bins write = {1};
|
||||
}
|
||||
cp_mode: coverpoint mode {
|
||||
bins normal = {0};
|
||||
bins debug = {1};
|
||||
}
|
||||
cp_parity: coverpoint parity {
|
||||
bins even = {0};
|
||||
bins odd = {1};
|
||||
}
|
||||
// 4-way cross: addr x cmd x mode x parity = 2 x 2 x 2 x 2 = 16 cross bins
|
||||
addr_cmd_mode_parity: cross cp_addr, cp_cmd, cp_mode, cp_parity;
|
||||
endgroup
|
||||
|
||||
cg cg_inst = new;
|
||||
cg cg_inst = new;
|
||||
|
||||
initial begin
|
||||
// Hit different 4-way cross bins
|
||||
addr = 0; cmd = 0; mode = 0; parity = 0; cg_inst.sample();
|
||||
$display("Sample 1: addr=%0d, cmd=%0d, mode=%0d, parity=%0d", addr, cmd, mode, parity);
|
||||
initial begin
|
||||
// Hit different 4-way cross bins
|
||||
addr = 0; cmd = 0; mode = 0; parity = 0; cg_inst.sample();
|
||||
$display("Sample 1: addr=%0d, cmd=%0d, mode=%0d, parity=%0d", addr, cmd, mode, parity);
|
||||
|
||||
addr = 1; cmd = 1; mode = 0; parity = 1; cg_inst.sample();
|
||||
$display("Sample 2: addr=%0d, cmd=%0d, mode=%0d, parity=%0d", addr, cmd, mode, parity);
|
||||
addr = 1; cmd = 1; mode = 0; parity = 1; cg_inst.sample();
|
||||
$display("Sample 2: addr=%0d, cmd=%0d, mode=%0d, parity=%0d", addr, cmd, mode, parity);
|
||||
|
||||
addr = 0; cmd = 1; mode = 1; parity = 0; cg_inst.sample();
|
||||
$display("Sample 3: addr=%0d, cmd=%0d, mode=%0d, parity=%0d", addr, cmd, mode, parity);
|
||||
addr = 0; cmd = 1; mode = 1; parity = 0; cg_inst.sample();
|
||||
$display("Sample 3: addr=%0d, cmd=%0d, mode=%0d, parity=%0d", addr, cmd, mode, parity);
|
||||
|
||||
addr = 1; cmd = 0; mode = 1; parity = 1; cg_inst.sample();
|
||||
$display("Sample 4: addr=%0d, cmd=%0d, mode=%0d, parity=%0d", addr, cmd, mode, parity);
|
||||
addr = 1; cmd = 0; mode = 1; parity = 1; cg_inst.sample();
|
||||
$display("Sample 4: addr=%0d, cmd=%0d, mode=%0d, parity=%0d", addr, cmd, mode, parity);
|
||||
|
||||
// Check coverage
|
||||
// Total bins:
|
||||
// - 2 bins in cp_addr
|
||||
// - 2 bins in cp_cmd
|
||||
// - 2 bins in cp_mode
|
||||
// - 2 bins in cp_parity
|
||||
// - 16 bins in 4-way cross (2 x 2 x 2 x 2)
|
||||
// Total = 24 bins
|
||||
// Hit: 2+2+2+2+4 = 12 out of 24 = 50%
|
||||
$display("Coverage: %0.1f%%", cg_inst.get_inst_coverage());
|
||||
// Check coverage
|
||||
// Total bins:
|
||||
// - 2 bins in cp_addr
|
||||
// - 2 bins in cp_cmd
|
||||
// - 2 bins in cp_mode
|
||||
// - 2 bins in cp_parity
|
||||
// - 16 bins in 4-way cross (2 x 2 x 2 x 2)
|
||||
// Total = 24 bins
|
||||
// Hit: 2+2+2+2+4 = 12 out of 24 = 50%
|
||||
$display("Coverage: %0.1f%%", cg_inst.get_inst_coverage());
|
||||
|
||||
if (cg_inst.get_inst_coverage() < 49.0 || cg_inst.get_inst_coverage() > 51.0) begin
|
||||
$display("%%Error: Expected coverage around 50%%, got %0.1f%%",
|
||||
cg_inst.get_inst_coverage());
|
||||
$stop;
|
||||
end
|
||||
if (cg_inst.get_inst_coverage() < 49.0 || cg_inst.get_inst_coverage() > 51.0) begin
|
||||
$display("%%Error: Expected coverage around 50%%, got %0.1f%%",
|
||||
cg_inst.get_inst_coverage());
|
||||
$stop;
|
||||
end
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of either the GNU Lesser General Public License Version 3
|
||||
# or the Perl Artistic License Version 2.0.
|
||||
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('vlt')
|
||||
|
||||
test.compile()
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -7,77 +7,77 @@
|
|||
// Test basic cross coverage functionality
|
||||
|
||||
module t;
|
||||
/* verilator lint_off UNSIGNED */
|
||||
bit [7:0] addr;
|
||||
bit [7:0] cmd;
|
||||
/* verilator lint_off UNSIGNED */
|
||||
bit [7:0] addr;
|
||||
bit [7:0] cmd;
|
||||
|
||||
covergroup cg;
|
||||
// Two coverpoints with 2 bins each
|
||||
a: coverpoint addr {
|
||||
bins low = {[0:3]};
|
||||
bins high = {[4:7]};
|
||||
}
|
||||
covergroup cg;
|
||||
// Two coverpoints with 2 bins each
|
||||
a: coverpoint addr {
|
||||
bins low = {[0:3]};
|
||||
bins high = {[4:7]};
|
||||
}
|
||||
|
||||
b: coverpoint cmd {
|
||||
bins read = {0};
|
||||
bins write = {1};
|
||||
}
|
||||
b: coverpoint cmd {
|
||||
bins read = {0};
|
||||
bins write = {1};
|
||||
}
|
||||
|
||||
// 2-way cross creates 4 bins: lowread, lowwrite, highread, highwrite
|
||||
c: cross a, b;
|
||||
endgroup
|
||||
// 2-way cross creates 4 bins: lowread, lowwrite, highread, highwrite
|
||||
c: cross a, b;
|
||||
endgroup
|
||||
|
||||
initial begin
|
||||
cg cg_inst;
|
||||
real cov;
|
||||
initial begin
|
||||
cg cg_inst;
|
||||
real cov;
|
||||
|
||||
cg_inst = new();
|
||||
cg_inst = new();
|
||||
|
||||
// Initially coverage should be 0%
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
if (cov != 0.0) begin
|
||||
$error("Initial coverage should be 0%%, got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit lowread
|
||||
addr = 2; cmd = 0;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
// Should have: a.low(1), b.read(1), c.low_x__read(1) = 3/8 = 37.5%
|
||||
if (cov < 35.0 || cov > 40.0) begin
|
||||
$error("After 1 sample, expected ~37.5%%, got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit highwrite
|
||||
addr = 5; cmd = 1;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
// Should have: a.low(1), a.high(1), b.read(1), b.write(1),
|
||||
// c.low_x__read(1), c.high_x__write(1) = 6/8 = 75%
|
||||
if (cov < 70.0 || cov > 80.0) begin
|
||||
$error("After 2 samples, expected ~75%%, got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit lowwrite
|
||||
addr = 1; cmd = 1;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
// Should have 7/8 = 87.5%
|
||||
if (cov < 85.0 || cov > 90.0) begin
|
||||
$error("After 3 samples, expected ~87.5%%, got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit highread for 100% coverage
|
||||
addr = 7; cmd = 0;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
// Should have 8/8 = 100%
|
||||
if (cov != 100.0) begin
|
||||
$error("After all bins hit, expected 100%%, got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
$display("Cross coverage test PASSED - final coverage: %0.2f%%", cov);
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
// Initially coverage should be 0%
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
if (cov != 0.0) begin
|
||||
$error("Initial coverage should be 0%%, got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit lowread
|
||||
addr = 2; cmd = 0;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
// Should have: a.low(1), b.read(1), c.low_x__read(1) = 3/8 = 37.5%
|
||||
if (cov < 35.0 || cov > 40.0) begin
|
||||
$error("After 1 sample, expected ~37.5%%, got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit highwrite
|
||||
addr = 5; cmd = 1;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
// Should have: a.low(1), a.high(1), b.read(1), b.write(1),
|
||||
// c.low_x__read(1), c.high_x__write(1) = 6/8 = 75%
|
||||
if (cov < 70.0 || cov > 80.0) begin
|
||||
$error("After 2 samples, expected ~75%%, got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit lowwrite
|
||||
addr = 1; cmd = 1;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
// Should have 7/8 = 87.5%
|
||||
if (cov < 85.0 || cov > 90.0) begin
|
||||
$error("After 3 samples, expected ~87.5%%, got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit highread for 100% coverage
|
||||
addr = 7; cmd = 0;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
// Should have 8/8 = 100%
|
||||
if (cov != 100.0) begin
|
||||
$error("After all bins hit, expected 100%%, got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
$display("Cross coverage test PASSED - final coverage: %0.2f%%", cov);
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -7,80 +7,76 @@
|
|||
// Test large cross coverage with sparse map implementation
|
||||
|
||||
module t(/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
int cyc = 0;
|
||||
int cyc = 0;
|
||||
|
||||
logic [3:0] a;
|
||||
logic [3:0] b;
|
||||
logic [3:0] c;
|
||||
logic [3:0] d;
|
||||
logic [3:0] a;
|
||||
logic [3:0] b;
|
||||
logic [3:0] c;
|
||||
logic [3:0] d;
|
||||
|
||||
covergroup cg @(posedge clk);
|
||||
option.per_instance = 1;
|
||||
covergroup cg @(posedge clk);
|
||||
option.per_instance = 1;
|
||||
|
||||
// Each coverpoint has 4 bins, total cross: 4444 = 256 bins
|
||||
// This exceeds threshold of 64, so should use sparse map
|
||||
cp_a: coverpoint a {
|
||||
bins a0 = {0,1,2,3};
|
||||
bins a1 = {4,5,6,7};
|
||||
bins a2 = {8,9,10,11};
|
||||
bins a3 = {12,13,14,15};
|
||||
}
|
||||
// Each coverpoint has 3 bins, total cross: 3*3*3*3 = 81 bins
|
||||
// This exceeds threshold of 64, so should use sparse map
|
||||
cp_a: coverpoint a {
|
||||
bins a0 = {0,1,2,3,4};
|
||||
bins a1 = {5,6,7,8,9};
|
||||
bins a2 = {10,11,12,13,14,15};
|
||||
}
|
||||
|
||||
cp_b: coverpoint b {
|
||||
bins b0 = {0,1,2,3};
|
||||
bins b1 = {4,5,6,7};
|
||||
bins b2 = {8,9,10,11};
|
||||
bins b3 = {12,13,14,15};
|
||||
}
|
||||
cp_b: coverpoint b {
|
||||
bins b0 = {0,1,2,3,4};
|
||||
bins b1 = {5,6,7,8,9};
|
||||
bins b2 = {10,11,12,13,14,15};
|
||||
}
|
||||
|
||||
cp_c: coverpoint c {
|
||||
bins c0 = {0,1,2,3};
|
||||
bins c1 = {4,5,6,7};
|
||||
bins c2 = {8,9,10,11};
|
||||
bins c3 = {12,13,14,15};
|
||||
}
|
||||
cp_c: coverpoint c {
|
||||
bins c0 = {0,1,2,3,4};
|
||||
bins c1 = {5,6,7,8,9};
|
||||
bins c2 = {10,11,12,13,14,15};
|
||||
}
|
||||
|
||||
cp_d: coverpoint d {
|
||||
bins d0 = {0,1,2,3};
|
||||
bins d1 = {4,5,6,7};
|
||||
bins d2 = {8,9,10,11};
|
||||
bins d3 = {12,13,14,15};
|
||||
}
|
||||
cp_d: coverpoint d {
|
||||
bins d0 = {0,1,2,3,4};
|
||||
bins d1 = {5,6,7,8,9};
|
||||
bins d2 = {10,11,12,13,14,15};
|
||||
}
|
||||
|
||||
// 4-way cross: 4444 = 256 bins (> 64 threshold)
|
||||
cross_abcd: cross cp_a, cp_b, cp_c, cp_d;
|
||||
endgroup
|
||||
// 4-way cross: 3*3*3*3 = 81 bins (> 64 threshold, uses sparse map)
|
||||
cross_abcd: cross cp_a, cp_b, cp_c, cp_d;
|
||||
endgroup
|
||||
|
||||
cg cg_inst = new;
|
||||
cg cg_inst = new;
|
||||
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
|
||||
// Generate some cross coverage
|
||||
a <= cyc[3:0];
|
||||
b <= cyc[7:4];
|
||||
c <= cyc[3:0]; // Intentionally correlate some
|
||||
d <= cyc[7:4];
|
||||
// Generate some cross coverage
|
||||
a <= cyc[3:0];
|
||||
b <= cyc[7:4];
|
||||
c <= cyc[3:0]; // Intentionally correlate some
|
||||
d <= cyc[7:4];
|
||||
|
||||
if (cyc == 20) begin
|
||||
/* verilator lint_off IMPLICITSTATIC */
|
||||
real inst_cov = cg_inst.get_inst_coverage();
|
||||
/* verilator lint_on IMPLICITSTATIC */
|
||||
$display("Coverage: %0.1f%%", inst_cov);
|
||||
if (cyc == 20) begin
|
||||
/* verilator lint_off IMPLICITSTATIC */
|
||||
real inst_cov = cg_inst.get_inst_coverage();
|
||||
/* verilator lint_on IMPLICITSTATIC */
|
||||
$display("Coverage: %0.1f%%", inst_cov);
|
||||
|
||||
if (inst_cov < 1.0 || inst_cov > 100.0) begin
|
||||
$display("%%Error: Invalid coverage value");
|
||||
$stop;
|
||||
end
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
if (inst_cov < 1.0 || inst_cov > 100.0) begin
|
||||
$display("%%Error: Invalid coverage value");
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -7,59 +7,59 @@
|
|||
// Test basic cross coverage with 2-way cross
|
||||
|
||||
module t;
|
||||
logic [1:0] addr;
|
||||
logic cmd;
|
||||
logic clk;
|
||||
logic [1:0] addr;
|
||||
logic cmd;
|
||||
logic clk;
|
||||
|
||||
// Covergroup with cross coverage
|
||||
covergroup cg;
|
||||
cp_addr: coverpoint addr {
|
||||
bins addr0 = {0};
|
||||
bins addr1 = {1};
|
||||
bins addr2 = {2};
|
||||
bins addr3 = {3};
|
||||
}
|
||||
cp_cmd: coverpoint cmd {
|
||||
bins read = {0};
|
||||
bins write = {1};
|
||||
}
|
||||
// Cross coverage: addr x cmd = 4 x 2 = 8 bins
|
||||
addr_cmd: cross cp_addr, cp_cmd;
|
||||
endgroup
|
||||
// Covergroup with cross coverage
|
||||
covergroup cg;
|
||||
cp_addr: coverpoint addr {
|
||||
bins addr0 = {0};
|
||||
bins addr1 = {1};
|
||||
bins addr2 = {2};
|
||||
bins addr3 = {3};
|
||||
}
|
||||
cp_cmd: coverpoint cmd {
|
||||
bins read = {0};
|
||||
bins write = {1};
|
||||
}
|
||||
// Cross coverage: addr x cmd = 4 x 2 = 8 bins
|
||||
addr_cmd: cross cp_addr, cp_cmd;
|
||||
endgroup
|
||||
|
||||
cg cg_inst = new;
|
||||
cg cg_inst = new;
|
||||
|
||||
initial begin
|
||||
// Hit different cross bins
|
||||
addr = 0; cmd = 0; cg_inst.sample(); // addr0 x read
|
||||
$display("After sample 1: addr=%0d, cmd=%0d", addr, cmd);
|
||||
initial begin
|
||||
// Hit different cross bins
|
||||
addr = 0; cmd = 0; cg_inst.sample(); // addr0 x read
|
||||
$display("After sample 1: addr=%0d, cmd=%0d", addr, cmd);
|
||||
|
||||
addr = 1; cmd = 1; cg_inst.sample(); // addr1 x write
|
||||
$display("After sample 2: addr=%0d, cmd=%0d", addr, cmd);
|
||||
addr = 1; cmd = 1; cg_inst.sample(); // addr1 x write
|
||||
$display("After sample 2: addr=%0d, cmd=%0d", addr, cmd);
|
||||
|
||||
addr = 2; cmd = 0; cg_inst.sample(); // addr2 x read
|
||||
$display("After sample 3: addr=%0d, cmd=%0d", addr, cmd);
|
||||
addr = 2; cmd = 0; cg_inst.sample(); // addr2 x read
|
||||
$display("After sample 3: addr=%0d, cmd=%0d", addr, cmd);
|
||||
|
||||
addr = 0; cmd = 1; cg_inst.sample(); // addr0 x write
|
||||
$display("After sample 4: addr=%0d, cmd=%0d", addr, cmd);
|
||||
addr = 0; cmd = 1; cg_inst.sample(); // addr0 x write
|
||||
$display("After sample 4: addr=%0d, cmd=%0d", addr, cmd);
|
||||
|
||||
// Check coverage - should be 50% (4 out of 8 bins hit)
|
||||
// Actually, with cross bins, we have:
|
||||
// - 4 bins in cp_addr: addr0, addr1, addr2, addr3
|
||||
// - 2 bins in cp_cmd: read, write
|
||||
// - 8 bins in cross (4 x 2)
|
||||
// Hit: addr0, addr1, addr2 (3 bins), read, write (2 bins), 4 cross bins
|
||||
// Total = 9 out of 14 = 64.3%
|
||||
$display("Coverage: %0.1f%%", cg_inst.get_inst_coverage());
|
||||
// Check coverage - should be 50% (4 out of 8 bins hit)
|
||||
// Actually, with cross bins, we have:
|
||||
// - 4 bins in cp_addr: addr0, addr1, addr2, addr3
|
||||
// - 2 bins in cp_cmd: read, write
|
||||
// - 8 bins in cross (4 x 2)
|
||||
// Hit: addr0, addr1, addr2 (3 bins), read, write (2 bins), 4 cross bins
|
||||
// Total = 9 out of 14 = 64.3%
|
||||
$display("Coverage: %0.1f%%", cg_inst.get_inst_coverage());
|
||||
|
||||
if (cg_inst.get_inst_coverage() < 63.0 || cg_inst.get_inst_coverage() > 65.0) begin
|
||||
$display("%%Error: Expected coverage around 64%%, got %0.1f%%",
|
||||
cg_inst.get_inst_coverage());
|
||||
$stop;
|
||||
end
|
||||
if (cg_inst.get_inst_coverage() < 63.0 || cg_inst.get_inst_coverage() > 65.0) begin
|
||||
$display("%%Error: Expected coverage around 64%%, got %0.1f%%",
|
||||
cg_inst.get_inst_coverage());
|
||||
$stop;
|
||||
end
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of either the GNU Lesser General Public License Version 3
|
||||
# or the Perl Artistic License Version 2.0.
|
||||
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('simulator')
|
||||
|
||||
test.compile()
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -7,54 +7,54 @@
|
|||
// Test small cross coverage with inline implementation
|
||||
|
||||
module t(/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
int cyc = 0;
|
||||
int cyc = 0;
|
||||
|
||||
logic [3:0] a;
|
||||
logic [3:0] b;
|
||||
logic [3:0] a;
|
||||
logic [3:0] b;
|
||||
|
||||
covergroup cg @(posedge clk);
|
||||
option.per_instance = 1;
|
||||
covergroup cg @(posedge clk);
|
||||
option.per_instance = 1;
|
||||
|
||||
// 2-way cross: 44 = 16 bins (< 64 threshold, should use inline)
|
||||
cp_a: coverpoint a {
|
||||
bins a0 = {0,1,2,3};
|
||||
bins a1 = {4,5,6,7};
|
||||
bins a2 = {8,9,10,11};
|
||||
bins a3 = {12,13,14,15};
|
||||
}
|
||||
// 2-way cross: 44 = 16 bins (< 64 threshold, should use inline)
|
||||
cp_a: coverpoint a {
|
||||
bins a0 = {0,1,2,3};
|
||||
bins a1 = {4,5,6,7};
|
||||
bins a2 = {8,9,10,11};
|
||||
bins a3 = {12,13,14,15};
|
||||
}
|
||||
|
||||
cp_b: coverpoint b {
|
||||
bins b0 = {0,1,2,3};
|
||||
bins b1 = {4,5,6,7};
|
||||
bins b2 = {8,9,10,11};
|
||||
bins b3 = {12,13,14,15};
|
||||
}
|
||||
cp_b: coverpoint b {
|
||||
bins b0 = {0,1,2,3};
|
||||
bins b1 = {4,5,6,7};
|
||||
bins b2 = {8,9,10,11};
|
||||
bins b3 = {12,13,14,15};
|
||||
}
|
||||
|
||||
cross_ab: cross cp_a, cp_b;
|
||||
endgroup
|
||||
cross_ab: cross cp_a, cp_b;
|
||||
endgroup
|
||||
|
||||
cg cg_inst = new;
|
||||
cg cg_inst = new;
|
||||
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
|
||||
a <= cyc[3:0];
|
||||
b <= cyc[7:4];
|
||||
a <= cyc[3:0];
|
||||
b <= cyc[7:4];
|
||||
|
||||
if (cyc == 20) begin
|
||||
/* verilator lint_off IMPLICITSTATIC */
|
||||
real inst_cov = cg_inst.get_inst_coverage();
|
||||
/* verilator lint_on IMPLICITSTATIC */
|
||||
$display("Coverage: %0.1f%%", inst_cov);
|
||||
if (cyc == 20) begin
|
||||
/* verilator lint_off IMPLICITSTATIC */
|
||||
real inst_cov = cg_inst.get_inst_coverage();
|
||||
/* verilator lint_on IMPLICITSTATIC */
|
||||
$display("Coverage: %0.1f%%", inst_cov);
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -13,26 +13,26 @@
|
|||
// - Hierarchy ("cg.cp.low", "cg.cp.high")
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
logic [1:0] data;
|
||||
logic [1:0] data;
|
||||
|
||||
covergroup cg;
|
||||
cp: coverpoint data {
|
||||
bins low = {2'b00};
|
||||
bins high = {2'b11};
|
||||
}
|
||||
endgroup
|
||||
covergroup cg;
|
||||
cp: coverpoint data {
|
||||
bins low = {2'b00};
|
||||
bins high = {2'b11};
|
||||
}
|
||||
endgroup
|
||||
|
||||
cg cg_inst = new;
|
||||
cg cg_inst = new;
|
||||
|
||||
initial begin
|
||||
// Sample both bins
|
||||
data = 2'b00;
|
||||
cg_inst.sample();
|
||||
initial begin
|
||||
// Sample both bins
|
||||
data = 2'b00;
|
||||
cg_inst.sample();
|
||||
|
||||
data = 2'b11;
|
||||
cg_inst.sample();
|
||||
data = 2'b11;
|
||||
cg_inst.sample();
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of either the GNU Lesser General Public License Version 3
|
||||
# or the Perl Artistic License Version 2.0.
|
||||
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('vlt')
|
||||
|
||||
test.compile()
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -7,60 +7,60 @@
|
|||
// Test default bins - catch-all for values not in other bins
|
||||
|
||||
module t;
|
||||
/* verilator lint_off UNSIGNED */
|
||||
bit [7:0] data;
|
||||
/* verilator lint_off UNSIGNED */
|
||||
bit [7:0] data;
|
||||
|
||||
covergroup cg;
|
||||
coverpoint data {
|
||||
bins low = {[0:3]};
|
||||
bins high = {[12:15]};
|
||||
bins other = default; // Catches everything else (4-11, 16+)
|
||||
}
|
||||
endgroup
|
||||
covergroup cg;
|
||||
coverpoint data {
|
||||
bins low = {[0:3]};
|
||||
bins high = {[12:15]};
|
||||
bins other = default; // Catches everything else (4-11, 16+)
|
||||
}
|
||||
endgroup
|
||||
|
||||
initial begin
|
||||
cg cg_inst;
|
||||
real cov;
|
||||
initial begin
|
||||
cg cg_inst;
|
||||
real cov;
|
||||
|
||||
cg_inst = new();
|
||||
cg_inst = new();
|
||||
|
||||
// Hit low bin
|
||||
data = 2;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("After low: %0.2f%%", cov);
|
||||
if (cov < 30.0 || cov > 35.0) begin
|
||||
$error("Expected ~33.33%% (1/3 bins), got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit high bin
|
||||
data = 14;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("After high: %0.2f%%", cov);
|
||||
if (cov < 63.0 || cov > 70.0) begin
|
||||
$error("Expected ~66.67%% (2/3 bins), got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit default bin with value 7 (not in low or high)
|
||||
data = 7;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("After default (7): %0.2f%%", cov);
|
||||
if (cov != 100.0) begin
|
||||
$error("Expected 100%% (3/3 bins), got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit another default value (should not increase coverage)
|
||||
data = 20;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
if (cov != 100.0) begin
|
||||
$error("Coverage should stay 100%%, got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
$display("Default bins test PASSED");
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
// Hit low bin
|
||||
data = 2;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("After low: %0.2f%%", cov);
|
||||
if (cov < 30.0 || cov > 35.0) begin
|
||||
$error("Expected ~33.33%% (1/3 bins), got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit high bin
|
||||
data = 14;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("After high: %0.2f%%", cov);
|
||||
if (cov < 63.0 || cov > 70.0) begin
|
||||
$error("Expected ~66.67%% (2/3 bins), got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit default bin with value 7 (not in low or high)
|
||||
data = 7;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("After default (7): %0.2f%%", cov);
|
||||
if (cov != 100.0) begin
|
||||
$error("Expected 100%% (3/3 bins), got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Hit another default value (should not increase coverage)
|
||||
data = 20;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
if (cov != 100.0) begin
|
||||
$error("Coverage should stay 100%%, got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
$display("Default bins test PASSED");
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of either the GNU Lesser General Public License Version 3
|
||||
# or the Perl Artistic License Version 2.0.
|
||||
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('vlt')
|
||||
|
||||
test.compile()
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -8,86 +8,86 @@
|
|||
|
||||
module t;
|
||||
|
||||
covergroup cg;
|
||||
coverpoint data {
|
||||
bins low = {[0:1]};
|
||||
bins high = {[2:3]};
|
||||
}
|
||||
endgroup
|
||||
covergroup cg;
|
||||
coverpoint data {
|
||||
bins low = {[0:1]};
|
||||
bins high = {[2:3]};
|
||||
}
|
||||
endgroup
|
||||
|
||||
int data;
|
||||
int data;
|
||||
|
||||
initial begin
|
||||
cg cg_inst;
|
||||
real cov;
|
||||
initial begin
|
||||
cg cg_inst;
|
||||
real cov;
|
||||
|
||||
// Test 1: Create single dynamic instance
|
||||
$display("Test 1: Single dynamic instance");
|
||||
cg_inst = new;
|
||||
// Test 1: Create single dynamic instance
|
||||
$display("Test 1: Single dynamic instance");
|
||||
cg_inst = new;
|
||||
|
||||
// Initially no coverage
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display(" Initial coverage: %f", cov);
|
||||
if (cov != 0.0) $stop;
|
||||
// Initially no coverage
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display(" Initial coverage: %f", cov);
|
||||
if (cov != 0.0) $stop;
|
||||
|
||||
// Sample low bin
|
||||
// Sample low bin
|
||||
data = 0;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display(" After sampling low: %f", cov);
|
||||
if (cov < 49.0 || cov > 51.0) $stop; // ~50%
|
||||
|
||||
// Sample high bin
|
||||
data = 2;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display(" After sampling high: %f", cov);
|
||||
if (cov < 99.0 || cov > 101.0) $stop; // ~100%
|
||||
|
||||
// Test 2: Multiple dynamic instances
|
||||
$display("Test 2: Multiple dynamic instances");
|
||||
begin
|
||||
cg cg1, cg2, cg3;
|
||||
|
||||
cg1 = new;
|
||||
cg2 = new;
|
||||
cg3 = new;
|
||||
|
||||
// Sample different bins in each
|
||||
data = 0;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display(" After sampling low: %f", cov);
|
||||
if (cov < 49.0 || cov > 51.0) $stop; // ~50%
|
||||
cg1.sample();
|
||||
|
||||
// Sample high bin
|
||||
data = 2;
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display(" After sampling high: %f", cov);
|
||||
if (cov < 99.0 || cov > 101.0) $stop; // ~100%
|
||||
cg2.sample();
|
||||
|
||||
// Test 2: Multiple dynamic instances
|
||||
$display("Test 2: Multiple dynamic instances");
|
||||
begin
|
||||
cg cg1, cg2, cg3;
|
||||
data = 1;
|
||||
cg3.sample();
|
||||
|
||||
cg1 = new;
|
||||
cg2 = new;
|
||||
cg3 = new;
|
||||
// Check individual coverage
|
||||
cov = cg1.get_inst_coverage();
|
||||
$display(" cg1 coverage: %f", cov);
|
||||
if (cov < 49.0 || cov > 51.0) $stop; // 50%
|
||||
|
||||
// Sample different bins in each
|
||||
data = 0;
|
||||
cg1.sample();
|
||||
cov = cg2.get_inst_coverage();
|
||||
$display(" cg2 coverage: %f", cov);
|
||||
if (cov < 49.0 || cov > 51.0) $stop; // 50%
|
||||
|
||||
data = 2;
|
||||
cg2.sample();
|
||||
cov = cg3.get_inst_coverage();
|
||||
$display(" cg3 coverage: %f", cov);
|
||||
if (cov < 49.0 || cov > 51.0) $stop; // 50%
|
||||
end
|
||||
|
||||
data = 1;
|
||||
cg3.sample();
|
||||
// Test 3: Reassignment (old instance should be cleaned up)
|
||||
$display("Test 3: Instance reassignment");
|
||||
cg_inst = new; // Create new, old should be freed
|
||||
|
||||
// Check individual coverage
|
||||
cov = cg1.get_inst_coverage();
|
||||
$display(" cg1 coverage: %f", cov);
|
||||
if (cov < 49.0 || cov > 51.0) $stop; // 50%
|
||||
// New instance starts with 0% coverage
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display(" New instance coverage: %f", cov);
|
||||
if (cov != 0.0) $stop;
|
||||
|
||||
cov = cg2.get_inst_coverage();
|
||||
$display(" cg2 coverage: %f", cov);
|
||||
if (cov < 49.0 || cov > 51.0) $stop; // 50%
|
||||
|
||||
cov = cg3.get_inst_coverage();
|
||||
$display(" cg3 coverage: %f", cov);
|
||||
if (cov < 49.0 || cov > 51.0) $stop; // 50%
|
||||
end
|
||||
|
||||
// Test 3: Reassignment (old instance should be cleaned up)
|
||||
$display("Test 3: Instance reassignment");
|
||||
cg_inst = new; // Create new, old should be freed
|
||||
|
||||
// New instance starts with 0% coverage
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display(" New instance coverage: %f", cov);
|
||||
if (cov != 0.0) $stop;
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -6,49 +6,49 @@
|
|||
// Expected: Should compile, coverage should be 100% (nothing to cover)
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
logic [7:0] value;
|
||||
logic [7:0] value;
|
||||
|
||||
// Empty covergroup - no coverpoints defined
|
||||
covergroup cg_empty;
|
||||
// Intentionally empty
|
||||
endgroup
|
||||
// Empty covergroup - no coverpoints defined
|
||||
covergroup cg_empty;
|
||||
// Intentionally empty
|
||||
endgroup
|
||||
|
||||
cg_empty cg_inst = new;
|
||||
cg_empty cg_inst = new;
|
||||
|
||||
int cyc = 0;
|
||||
int cyc = 0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
value <= value + 1;
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
value <= value + 1;
|
||||
|
||||
cg_inst.sample();
|
||||
cg_inst.sample();
|
||||
|
||||
if (cyc == 5) begin
|
||||
// Get coverage - should be 100% (nothing to fail)
|
||||
begin
|
||||
real cov;
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("Empty covergroup coverage: %f%%", cov);
|
||||
if (cyc == 5) begin
|
||||
// Get coverage - should be 100% (nothing to fail)
|
||||
begin
|
||||
real cov;
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("Empty covergroup coverage: %f%%", cov);
|
||||
|
||||
// Empty covergroup should report 100% coverage
|
||||
if (cov >= 99.9) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end else begin
|
||||
$display("ERROR: Expected 100%% coverage for empty covergroup, got %f%%", cov);
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
// Empty covergroup should report 100% coverage
|
||||
if (cov >= 99.9) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end else begin
|
||||
$display("ERROR: Expected 100%% coverage for empty covergroup, got %f%%", cov);
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (cyc > 10) begin
|
||||
$display("ERROR: Test timed out");
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
if (cyc > 10) begin
|
||||
$display("ERROR: Test timed out");
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -5,19 +5,19 @@
|
|||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t (input clk);
|
||||
int value = 0;
|
||||
int value = 0;
|
||||
|
||||
covergroup cg;
|
||||
cp: coverpoint value {
|
||||
bins low = {[0:5]};
|
||||
}
|
||||
endgroup
|
||||
covergroup cg;
|
||||
cp: coverpoint value {
|
||||
bins low = {[0:5]};
|
||||
}
|
||||
endgroup
|
||||
|
||||
cg my_cg = new;
|
||||
cg my_cg = new;
|
||||
|
||||
always @(posedge clk) begin
|
||||
real cov;
|
||||
cov = my_cg.get_inst_coverage();
|
||||
my_cg.sample();
|
||||
end
|
||||
always @(posedge clk) begin
|
||||
real cov;
|
||||
cov = my_cg.get_inst_coverage();
|
||||
my_cg.sample();
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -5,19 +5,19 @@
|
|||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t (input clk);
|
||||
logic enable = 0;
|
||||
int value = 0;
|
||||
logic enable = 0;
|
||||
int value = 0;
|
||||
|
||||
covergroup cg_iff;
|
||||
cp_value: coverpoint value iff (enable) {
|
||||
bins low = {[0:5]};
|
||||
bins mid = {[6:10]};
|
||||
}
|
||||
endgroup
|
||||
covergroup cg_iff;
|
||||
cp_value: coverpoint value iff (enable) {
|
||||
bins low = {[0:5]};
|
||||
bins mid = {[6:10]};
|
||||
}
|
||||
endgroup
|
||||
|
||||
cg_iff cg = new;
|
||||
cg_iff cg = new;
|
||||
|
||||
always @(posedge clk) begin
|
||||
cg.sample();
|
||||
end
|
||||
always @(posedge clk) begin
|
||||
cg.sample();
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -7,57 +7,57 @@
|
|||
// Test ignore_bins - excluded from coverage
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
/* verilator lint_off UNSIGNED */
|
||||
logic [3:0] data;
|
||||
/* verilator lint_off UNSIGNED */
|
||||
logic [3:0] data;
|
||||
|
||||
covergroup cg;
|
||||
coverpoint data {
|
||||
bins low = {[0:3]};
|
||||
bins mid = {[4:7]};
|
||||
bins high = {[8:11]};
|
||||
ignore_bins reserved = {[12:15]}; // Should not count toward coverage
|
||||
}
|
||||
endgroup
|
||||
covergroup cg;
|
||||
coverpoint data {
|
||||
bins low = {[0:3]};
|
||||
bins mid = {[4:7]};
|
||||
bins high = {[8:11]};
|
||||
ignore_bins reserved = {[12:15]}; // Should not count toward coverage
|
||||
}
|
||||
endgroup
|
||||
|
||||
cg cg_inst;
|
||||
cg cg_inst;
|
||||
|
||||
initial begin
|
||||
cg_inst = new;
|
||||
initial begin
|
||||
cg_inst = new;
|
||||
|
||||
// Initially 0% (0 of 3 regular bins)
|
||||
check_coverage(0.0, "initial");
|
||||
// Initially 0% (0 of 3 regular bins)
|
||||
check_coverage(0.0, "initial");
|
||||
|
||||
// Hit reserved bin - should still be 0%
|
||||
data = 13;
|
||||
cg_inst.sample();
|
||||
check_coverage(0.0, "after reserved");
|
||||
// Hit reserved bin - should still be 0%
|
||||
data = 13;
|
||||
cg_inst.sample();
|
||||
check_coverage(0.0, "after reserved");
|
||||
|
||||
// Hit low bin - now 33.33% (1 of 3)
|
||||
data = 1;
|
||||
cg_inst.sample();
|
||||
check_coverage(33.33, "after low");
|
||||
// Hit low bin - now 33.33% (1 of 3)
|
||||
data = 1;
|
||||
cg_inst.sample();
|
||||
check_coverage(33.33, "after low");
|
||||
|
||||
// Hit another reserved value - still 33.33%
|
||||
data = 15;
|
||||
cg_inst.sample();
|
||||
check_coverage(33.33, "after another reserved");
|
||||
// Hit another reserved value - still 33.33%
|
||||
data = 15;
|
||||
cg_inst.sample();
|
||||
check_coverage(33.33, "after another reserved");
|
||||
|
||||
// Complete regular bins
|
||||
data = 5; cg_inst.sample(); // mid
|
||||
data = 10; cg_inst.sample(); // high
|
||||
check_coverage(100.0, "complete");
|
||||
// Complete regular bins
|
||||
data = 5; cg_inst.sample(); // mid
|
||||
data = 10; cg_inst.sample(); // high
|
||||
check_coverage(100.0, "complete");
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
task check_coverage(real expected, string label);
|
||||
real cov;
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("Coverage %s: %0.2f%% (expected ~%0.2f%%)", label, cov, expected);
|
||||
if (cov < expected - 0.5 || cov > expected + 0.5) begin
|
||||
$error("Coverage mismatch: got %0.2f%%, expected ~%0.2f%%", cov, expected);
|
||||
$stop;
|
||||
end
|
||||
|
||||
task check_coverage(real expected, string label);
|
||||
real cov;
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("Coverage %s: %0.2f%% (expected ~%0.2f%%)", label, cov, expected);
|
||||
if (cov < expected - 0.5 || cov > expected + 0.5) begin
|
||||
$error("Coverage mismatch: got %0.2f%%, expected ~%0.2f%%", cov, expected);
|
||||
$stop;
|
||||
end
|
||||
endtask
|
||||
endtask
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -5,35 +5,35 @@
|
|||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t;
|
||||
/* verilator lint_off UNSIGNED */
|
||||
logic [1:0] data;
|
||||
/* verilator lint_off UNSIGNED */
|
||||
logic [1:0] data;
|
||||
|
||||
covergroup cg;
|
||||
coverpoint data {
|
||||
bins low = {0};
|
||||
bins mid = {1};
|
||||
bins high = {2};
|
||||
illegal_bins forbidden = {3};
|
||||
}
|
||||
endgroup
|
||||
covergroup cg;
|
||||
coverpoint data {
|
||||
bins low = {0};
|
||||
bins mid = {1};
|
||||
bins high = {2};
|
||||
illegal_bins forbidden = {3};
|
||||
}
|
||||
endgroup
|
||||
|
||||
initial begin
|
||||
automatic cg cg_inst = new;
|
||||
initial begin
|
||||
automatic cg cg_inst = new;
|
||||
|
||||
// Sample legal values only
|
||||
data = 0;
|
||||
cg_inst.sample();
|
||||
$display("Coverage after low: %f%% (expected ~33.33%%)", cg_inst.get_inst_coverage());
|
||||
// Sample legal values only
|
||||
data = 0;
|
||||
cg_inst.sample();
|
||||
$display("Coverage after low: %f%% (expected ~33.33%%)", cg_inst.get_inst_coverage());
|
||||
|
||||
data = 1;
|
||||
cg_inst.sample();
|
||||
$display("Coverage after mid: %f%% (expected ~66.67%%)", cg_inst.get_inst_coverage());
|
||||
data = 1;
|
||||
cg_inst.sample();
|
||||
$display("Coverage after mid: %f%% (expected ~66.67%%)", cg_inst.get_inst_coverage());
|
||||
|
||||
data = 2;
|
||||
cg_inst.sample();
|
||||
$display("Coverage complete: %f%% (expected ~100.00%%)", cg_inst.get_inst_coverage());
|
||||
data = 2;
|
||||
cg_inst.sample();
|
||||
$display("Coverage complete: %f%% (expected ~100.00%%)", cg_inst.get_inst_coverage());
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -7,28 +7,28 @@
|
|||
// Minimal test for covergroup parsing and code generation
|
||||
|
||||
module t;
|
||||
int unsigned addr; // Use unsigned to avoid comparison warnings
|
||||
int unsigned addr; // Use unsigned to avoid comparison warnings
|
||||
|
||||
covergroup cg;
|
||||
cp_addr: coverpoint addr {
|
||||
bins low = {[0:127]};
|
||||
bins high = {[128:255]};
|
||||
}
|
||||
endgroup
|
||||
covergroup cg;
|
||||
cp_addr: coverpoint addr {
|
||||
bins low = {[0:127]};
|
||||
bins high = {[128:255]};
|
||||
}
|
||||
endgroup
|
||||
|
||||
initial begin
|
||||
cg cg_inst;
|
||||
cg_inst = new;
|
||||
initial begin
|
||||
cg cg_inst;
|
||||
cg_inst = new;
|
||||
|
||||
// Sample some values
|
||||
addr = 10;
|
||||
cg_inst.sample();
|
||||
// Sample some values
|
||||
addr = 10;
|
||||
cg_inst.sample();
|
||||
|
||||
addr = 200;
|
||||
cg_inst.sample();
|
||||
addr = 200;
|
||||
cg_inst.sample();
|
||||
|
||||
$display("Coverage: %0.1f%%", cg_inst.get_coverage());
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
$display("Coverage: %0.1f%%", cg_inst.get_coverage());
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -7,53 +7,53 @@
|
|||
// Test mixed bin types: single values and ranges
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
/* verilator lint_off UNSIGNED */
|
||||
logic [7:0] opcode;
|
||||
/* verilator lint_off UNSIGNED */
|
||||
logic [7:0] opcode;
|
||||
|
||||
covergroup cg;
|
||||
coverpoint opcode {
|
||||
bins nop = {8'h00};
|
||||
bins load = {8'h01, 8'h02, 8'h03};
|
||||
bins store = {8'h04, 8'h05};
|
||||
bins arith = {[8'h10:8'h1F]};
|
||||
bins others = {[8'h20:8'hFE]}; // Avoid 0xFF to prevent CMPCONST warning
|
||||
}
|
||||
endgroup
|
||||
covergroup cg;
|
||||
coverpoint opcode {
|
||||
bins nop = {8'h00};
|
||||
bins load = {8'h01, 8'h02, 8'h03};
|
||||
bins store = {8'h04, 8'h05};
|
||||
bins arith = {[8'h10:8'h1F]};
|
||||
bins others = {[8'h20:8'hFE]}; // Avoid 0xFF to prevent CMPCONST warning
|
||||
}
|
||||
endgroup
|
||||
|
||||
cg cg_inst;
|
||||
cg cg_inst;
|
||||
|
||||
initial begin
|
||||
cg_inst = new;
|
||||
initial begin
|
||||
cg_inst = new;
|
||||
|
||||
// Test single value bins
|
||||
opcode = 8'h00; cg_inst.sample(); // nop
|
||||
check_coverage(20.0, "after nop");
|
||||
// Test single value bins
|
||||
opcode = 8'h00; cg_inst.sample(); // nop
|
||||
check_coverage(20.0, "after nop");
|
||||
|
||||
// Test multi-value list bin
|
||||
opcode = 8'h02; cg_inst.sample(); // load
|
||||
check_coverage(40.0, "after load");
|
||||
// Test multi-value list bin
|
||||
opcode = 8'h02; cg_inst.sample(); // load
|
||||
check_coverage(40.0, "after load");
|
||||
|
||||
opcode = 8'h05; cg_inst.sample(); // store
|
||||
check_coverage(60.0, "after store");
|
||||
opcode = 8'h05; cg_inst.sample(); // store
|
||||
check_coverage(60.0, "after store");
|
||||
|
||||
// Test range bin
|
||||
opcode = 8'h15; cg_inst.sample(); // arith
|
||||
check_coverage(80.0, "after arith");
|
||||
// Test range bin
|
||||
opcode = 8'h15; cg_inst.sample(); // arith
|
||||
check_coverage(80.0, "after arith");
|
||||
|
||||
opcode = 8'h80; cg_inst.sample(); // others
|
||||
check_coverage(100.0, "after others");
|
||||
opcode = 8'h80; cg_inst.sample(); // others
|
||||
check_coverage(100.0, "after others");
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
task check_coverage(real expected, string label);
|
||||
real cov;
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("Coverage %s: %0.2f%% (expected ~%0.2f%%)", label, cov, expected);
|
||||
if (cov < expected - 0.5 || cov > expected + 0.5) begin
|
||||
$error("Coverage mismatch: got %0.2f%%, expected ~%0.2f%%", cov, expected);
|
||||
$stop;
|
||||
end
|
||||
|
||||
task check_coverage(real expected, string label);
|
||||
real cov;
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("Coverage %s: %0.2f%% (expected ~%0.2f%%)", label, cov, expected);
|
||||
if (cov < expected - 0.5 || cov > expected + 0.5) begin
|
||||
$error("Coverage mismatch: got %0.2f%%, expected ~%0.2f%%", cov, expected);
|
||||
$stop;
|
||||
end
|
||||
endtask
|
||||
endtask
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -7,54 +7,54 @@
|
|||
// Test multiple covergroup instances with separate tracking
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
/* verilator lint_off UNSIGNED */
|
||||
logic [3:0] data1, data2;
|
||||
/* verilator lint_off UNSIGNED */
|
||||
logic [3:0] data1, data2;
|
||||
|
||||
covergroup cg;
|
||||
coverpoint data1 {
|
||||
bins low = {[0:3]};
|
||||
bins high = {[4:15]};
|
||||
}
|
||||
endgroup
|
||||
covergroup cg;
|
||||
coverpoint data1 {
|
||||
bins low = {[0:3]};
|
||||
bins high = {[4:15]};
|
||||
}
|
||||
endgroup
|
||||
|
||||
cg cg_inst1, cg_inst2;
|
||||
cg cg_inst1, cg_inst2;
|
||||
|
||||
initial begin
|
||||
cg_inst1 = new;
|
||||
cg_inst2 = new;
|
||||
initial begin
|
||||
cg_inst1 = new;
|
||||
cg_inst2 = new;
|
||||
|
||||
// Initially both have 0% coverage
|
||||
check_coverage(cg_inst1, 0.0, "inst1 initial");
|
||||
check_coverage(cg_inst2, 0.0, "inst2 initial");
|
||||
// Initially both have 0% coverage
|
||||
check_coverage(cg_inst1, 0.0, "inst1 initial");
|
||||
check_coverage(cg_inst2, 0.0, "inst2 initial");
|
||||
|
||||
// Sample different values in each instance
|
||||
data1 = 1;
|
||||
cg_inst1.sample(); // inst1: low covered (50%)
|
||||
check_coverage(cg_inst1, 50.0, "inst1 after low");
|
||||
check_coverage(cg_inst2, 0.0, "inst2 still empty");
|
||||
// Sample different values in each instance
|
||||
data1 = 1;
|
||||
cg_inst1.sample(); // inst1: low covered (50%)
|
||||
check_coverage(cg_inst1, 50.0, "inst1 after low");
|
||||
check_coverage(cg_inst2, 0.0, "inst2 still empty");
|
||||
|
||||
data1 = 10;
|
||||
cg_inst2.sample(); // inst2: high covered (50%)
|
||||
check_coverage(cg_inst1, 50.0, "inst1 still 50%");
|
||||
check_coverage(cg_inst2, 50.0, "inst2 after high");
|
||||
data1 = 10;
|
||||
cg_inst2.sample(); // inst2: high covered (50%)
|
||||
check_coverage(cg_inst1, 50.0, "inst1 still 50%");
|
||||
check_coverage(cg_inst2, 50.0, "inst2 after high");
|
||||
|
||||
// Complete coverage in inst1
|
||||
data1 = 8;
|
||||
cg_inst1.sample(); // inst1: both covered (100%)
|
||||
check_coverage(cg_inst1, 100.0, "inst1 complete");
|
||||
check_coverage(cg_inst2, 50.0, "inst2 still 50%");
|
||||
// Complete coverage in inst1
|
||||
data1 = 8;
|
||||
cg_inst1.sample(); // inst1: both covered (100%)
|
||||
check_coverage(cg_inst1, 100.0, "inst1 complete");
|
||||
check_coverage(cg_inst2, 50.0, "inst2 still 50%");
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
task check_coverage(cg inst, real expected, string label);
|
||||
real cov;
|
||||
cov = inst.get_inst_coverage();
|
||||
$display("Coverage %s: %0.2f%% (expected ~%0.2f%%)", label, cov, expected);
|
||||
if (cov < expected - 0.5 || cov > expected + 0.5) begin
|
||||
$error("Coverage mismatch: got %0.2f%%, expected ~%0.2f%%", cov, expected);
|
||||
$stop;
|
||||
end
|
||||
|
||||
task check_coverage(cg inst, real expected, string label);
|
||||
real cov;
|
||||
cov = inst.get_inst_coverage();
|
||||
$display("Coverage %s: %0.2f%% (expected ~%0.2f%%)", label, cov, expected);
|
||||
if (cov < expected - 0.5 || cov > expected + 0.5) begin
|
||||
$error("Coverage mismatch: got %0.2f%%, expected ~%0.2f%%", cov, expected);
|
||||
$stop;
|
||||
end
|
||||
endtask
|
||||
endtask
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -7,73 +7,73 @@
|
|||
// since they all sample the same expression (value1)
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
logic [2:0] value1;
|
||||
logic [2:0] value1;
|
||||
|
||||
covergroup cg;
|
||||
cp: coverpoint value1 {
|
||||
bins low = {[0:3]};
|
||||
bins high = {[4:7]};
|
||||
}
|
||||
endgroup
|
||||
covergroup cg;
|
||||
cp: coverpoint value1 {
|
||||
bins low = {[0:3]};
|
||||
bins high = {[4:7]};
|
||||
}
|
||||
endgroup
|
||||
|
||||
// Create three independent instances
|
||||
cg cg_inst1 = new;
|
||||
cg cg_inst2 = new;
|
||||
cg cg_inst3 = new;
|
||||
// Create three independent instances
|
||||
cg cg_inst1 = new;
|
||||
cg cg_inst2 = new;
|
||||
cg cg_inst3 = new;
|
||||
|
||||
int cyc = 0;
|
||||
int cyc = 0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
|
||||
case (cyc)
|
||||
0: begin
|
||||
value1 <= 1; // low bin for all instances
|
||||
end
|
||||
1: begin
|
||||
value1 <= 6; // high bin for all instances -> 100%
|
||||
end
|
||||
2: begin
|
||||
begin
|
||||
real cov1, cov2, cov3;
|
||||
cov1 = cg_inst1.get_inst_coverage();
|
||||
cov2 = cg_inst2.get_inst_coverage();
|
||||
cov3 = cg_inst3.get_inst_coverage();
|
||||
|
||||
$display("Instance 1 coverage: %f%%", cov1);
|
||||
$display("Instance 2 coverage: %f%%", cov2);
|
||||
$display("Instance 3 coverage: %f%%", cov3);
|
||||
|
||||
// All instances sample the same coverpoint (value1), so they should all be 100%
|
||||
// This tests that multiple instances track coverage independently,
|
||||
// even when sampling the same expression
|
||||
if (cov1 >= 99.0 && cov2 >= 99.0 && cov3 >= 99.0) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end else begin
|
||||
$display("ERROR: Coverage mismatch");
|
||||
$display(" Expected: inst1=100%%, inst2=100%%, inst3=100%%");
|
||||
$display(" Got: inst1=%f%%, inst2=%f%%, inst3=%f%%", cov1, cov2, cov3);
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
end
|
||||
endcase
|
||||
|
||||
// Each instance samples the same value (value1)
|
||||
// But tracks coverage independently
|
||||
cg_inst1.sample();
|
||||
cg_inst2.sample();
|
||||
cg_inst3.sample();
|
||||
|
||||
if (cyc > 10) begin
|
||||
$display("ERROR: Test timed out");
|
||||
$stop;
|
||||
case (cyc)
|
||||
0: begin
|
||||
value1 <= 1; // low bin for all instances
|
||||
end
|
||||
end
|
||||
1: begin
|
||||
value1 <= 6; // high bin for all instances -> 100%
|
||||
end
|
||||
2: begin
|
||||
begin
|
||||
real cov1, cov2, cov3;
|
||||
cov1 = cg_inst1.get_inst_coverage();
|
||||
cov2 = cg_inst2.get_inst_coverage();
|
||||
cov3 = cg_inst3.get_inst_coverage();
|
||||
|
||||
$display("Instance 1 coverage: %f%%", cov1);
|
||||
$display("Instance 2 coverage: %f%%", cov2);
|
||||
$display("Instance 3 coverage: %f%%", cov3);
|
||||
|
||||
// All instances sample the same coverpoint (value1), so they should all be 100%
|
||||
// This tests that multiple instances track coverage independently,
|
||||
// even when sampling the same expression
|
||||
if (cov1 >= 99.0 && cov2 >= 99.0 && cov3 >= 99.0) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end else begin
|
||||
$display("ERROR: Coverage mismatch");
|
||||
$display(" Expected: inst1=100%%, inst2=100%%, inst3=100%%");
|
||||
$display(" Got: inst1=%f%%, inst2=%f%%, inst3=%f%%", cov1, cov2, cov3);
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
end
|
||||
endcase
|
||||
|
||||
// Each instance samples the same value (value1)
|
||||
// But tracks coverage independently
|
||||
cg_inst1.sample();
|
||||
cg_inst2.sample();
|
||||
cg_inst3.sample();
|
||||
|
||||
if (cyc > 10) begin
|
||||
$display("ERROR: Test timed out");
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -6,60 +6,60 @@
|
|||
// Expected: Should handle negative numbers correctly
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
int signed value;
|
||||
int signed value;
|
||||
|
||||
/* verilator lint_off CMPCONST */
|
||||
covergroup cg;
|
||||
cp_neg: coverpoint value {
|
||||
bins negative = {[-100:-1]};
|
||||
bins zero = {0};
|
||||
bins positive = {[1:100]};
|
||||
bins mixed = {[-10:10]};
|
||||
}
|
||||
endgroup
|
||||
/* verilator lint_on CMPCONST */
|
||||
/* verilator lint_off CMPCONST */
|
||||
covergroup cg;
|
||||
cp_neg: coverpoint value {
|
||||
bins negative = {[-100:-1]};
|
||||
bins zero = {0};
|
||||
bins positive = {[1:100]};
|
||||
bins mixed = {[-10:10]};
|
||||
}
|
||||
endgroup
|
||||
/* verilator lint_on CMPCONST */
|
||||
|
||||
cg cg_inst = new;
|
||||
cg cg_inst = new;
|
||||
|
||||
int cyc = 0;
|
||||
int cyc = 0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
|
||||
case (cyc)
|
||||
0: value <= -50; // Hit negative bin
|
||||
1: value <= 0; // Hit zero bin
|
||||
2: value <= 50; // Hit positive bin
|
||||
3: value <= -5; // Hit mixed bin (also negative)
|
||||
4: value <= 5; // Hit mixed bin (also positive)
|
||||
5: begin
|
||||
begin
|
||||
real cov;
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("Coverage with negative ranges: %f%%", cov);
|
||||
case (cyc)
|
||||
0: value <= -50; // Hit negative bin
|
||||
1: value <= 0; // Hit zero bin
|
||||
2: value <= 50; // Hit positive bin
|
||||
3: value <= -5; // Hit mixed bin (also negative)
|
||||
4: value <= 5; // Hit mixed bin (also positive)
|
||||
5: begin
|
||||
begin
|
||||
real cov;
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("Coverage with negative ranges: %f%%", cov);
|
||||
|
||||
// All 4 bins should be hit = 100%
|
||||
if (cov >= 99.0) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end else begin
|
||||
$display("ERROR: Expected 100%% coverage, got %f%%", cov);
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
// All 4 bins should be hit = 100%
|
||||
if (cov >= 99.0) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end else begin
|
||||
$display("ERROR: Expected 100%% coverage, got %f%%", cov);
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
|
||||
cg_inst.sample();
|
||||
|
||||
if (cyc > 10) begin
|
||||
$display("ERROR: Test timed out");
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
|
||||
cg_inst.sample();
|
||||
|
||||
if (cyc > 10) begin
|
||||
$display("ERROR: Test timed out");
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
%Warning-COVERIGN: t/t_covergroup_option_unsup.v:15:13: Ignoring unsupported coverage option: foobar
|
||||
15 | option.foobar = 1;
|
||||
| ^~~~~~
|
||||
%Warning-COVERIGN: t/t_covergroup_option_unsup.v:15:7: Ignoring unsupported coverage option: foobar
|
||||
15 | option.foobar = 1;
|
||||
| ^~~~~~
|
||||
... For warning description see https://verilator.org/warn/COVERIGN?v=latest
|
||||
... Use "/* verilator lint_off COVERIGN */" and lint_on around source to disable this message.
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -8,14 +8,14 @@
|
|||
// Test: unsupported coverage option name in a coverpoint
|
||||
|
||||
module t;
|
||||
logic [3:0] cp_expr;
|
||||
logic [3:0] cp_expr;
|
||||
|
||||
covergroup cg;
|
||||
cp1: coverpoint cp_expr {
|
||||
option.foobar = 1;
|
||||
}
|
||||
endgroup
|
||||
covergroup cg;
|
||||
cp1: coverpoint cp_expr {
|
||||
option.foobar = 1;
|
||||
}
|
||||
endgroup
|
||||
|
||||
cg cg_inst = new;
|
||||
initial $finish;
|
||||
cg cg_inst = new;
|
||||
initial $finish;
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -7,107 +7,107 @@
|
|||
// Performance test for functional coverage - measures sample() overhead
|
||||
|
||||
module t;
|
||||
logic [7:0] data;
|
||||
logic [3:0] state;
|
||||
logic [15:0] addr;
|
||||
logic [7:0] data;
|
||||
logic [3:0] state;
|
||||
logic [15:0] addr;
|
||||
|
||||
// Large covergroup with multiple coverpoints and many bins
|
||||
covergroup cg_perf;
|
||||
// Coverpoint with many bins
|
||||
cp_data: coverpoint data {
|
||||
bins d0 = {0};
|
||||
bins d1 = {1};
|
||||
bins d2 = {2};
|
||||
bins d3 = {3};
|
||||
bins d4 = {4};
|
||||
bins d5 = {5};
|
||||
bins d6 = {6};
|
||||
bins d7 = {7};
|
||||
bins d8 = {8};
|
||||
bins d9 = {9};
|
||||
bins d10 = {[10:19]};
|
||||
bins d20 = {[20:29]};
|
||||
bins d30 = {[30:39]};
|
||||
bins d40 = {[40:49]};
|
||||
bins d50 = {[50:59]};
|
||||
bins rest = {[60:255]};
|
||||
}
|
||||
// Large covergroup with multiple coverpoints and many bins
|
||||
covergroup cg_perf;
|
||||
// Coverpoint with many bins
|
||||
cp_data: coverpoint data {
|
||||
bins d0 = {0};
|
||||
bins d1 = {1};
|
||||
bins d2 = {2};
|
||||
bins d3 = {3};
|
||||
bins d4 = {4};
|
||||
bins d5 = {5};
|
||||
bins d6 = {6};
|
||||
bins d7 = {7};
|
||||
bins d8 = {8};
|
||||
bins d9 = {9};
|
||||
bins d10 = {[10:19]};
|
||||
bins d20 = {[20:29]};
|
||||
bins d30 = {[30:39]};
|
||||
bins d40 = {[40:49]};
|
||||
bins d50 = {[50:59]};
|
||||
bins rest = {[60:255]};
|
||||
}
|
||||
|
||||
cp_state: coverpoint state {
|
||||
bins s0 = {0};
|
||||
bins s1 = {1};
|
||||
bins s2 = {2};
|
||||
bins s3 = {3};
|
||||
bins s4 = {4};
|
||||
bins s5 = {5};
|
||||
bins s6 = {6};
|
||||
bins s7 = {7};
|
||||
bins s8 = {8};
|
||||
bins s9 = {9};
|
||||
bins s10 = {10};
|
||||
bins s11 = {11};
|
||||
bins s12 = {12};
|
||||
bins s13 = {13};
|
||||
bins s14 = {14};
|
||||
bins s15 = {15};
|
||||
}
|
||||
cp_state: coverpoint state {
|
||||
bins s0 = {0};
|
||||
bins s1 = {1};
|
||||
bins s2 = {2};
|
||||
bins s3 = {3};
|
||||
bins s4 = {4};
|
||||
bins s5 = {5};
|
||||
bins s6 = {6};
|
||||
bins s7 = {7};
|
||||
bins s8 = {8};
|
||||
bins s9 = {9};
|
||||
bins s10 = {10};
|
||||
bins s11 = {11};
|
||||
bins s12 = {12};
|
||||
bins s13 = {13};
|
||||
bins s14 = {14};
|
||||
bins s15 = {15};
|
||||
}
|
||||
|
||||
// verilator lint_off UNSIGNED
|
||||
// verilator lint_off CMPCONST
|
||||
cp_addr: coverpoint addr {
|
||||
bins low = {[16'h0000:16'h03FF]}; // [0:1023]
|
||||
bins mid = {[16'h0400:16'h07FF]}; // [1024:2047]
|
||||
bins high = {[16'h0800:16'hFFFF]}; // [2048:65535]
|
||||
}
|
||||
// verilator lint_on CMPCONST
|
||||
// verilator lint_on UNSIGNED
|
||||
// verilator lint_off UNSIGNED
|
||||
// verilator lint_off CMPCONST
|
||||
cp_addr: coverpoint addr {
|
||||
bins low = {[16'h0000:16'h03FF]}; // [0:1023]
|
||||
bins mid = {[16'h0400:16'h07FF]}; // [1024:2047]
|
||||
bins high = {[16'h0800:16'hFFFF]}; // [2048:65535]
|
||||
}
|
||||
// verilator lint_on CMPCONST
|
||||
// verilator lint_on UNSIGNED
|
||||
|
||||
// Cross coverage adds more bins
|
||||
cross_data_state: cross cp_data, cp_state;
|
||||
endgroup
|
||||
// Cross coverage adds more bins
|
||||
cross_data_state: cross cp_data, cp_state;
|
||||
endgroup
|
||||
|
||||
cg_perf cg_inst = new;
|
||||
cg_perf cg_inst = new;
|
||||
|
||||
initial begin
|
||||
automatic longint start_time, end_time, elapsed;
|
||||
automatic int iterations = 100000;
|
||||
automatic real avg_time_ns;
|
||||
initial begin
|
||||
automatic longint start_time, end_time, elapsed;
|
||||
automatic int iterations = 100000;
|
||||
automatic real avg_time_ns;
|
||||
|
||||
$display("=== Functional Coverage Performance Test ===");
|
||||
$display("Iterations: %0d", iterations);
|
||||
$display("=== Functional Coverage Performance Test ===");
|
||||
$display("Iterations: %0d", iterations);
|
||||
|
||||
// Measure sample() overhead
|
||||
start_time = $time;
|
||||
// Measure sample() overhead
|
||||
start_time = $time;
|
||||
|
||||
for (int i = 0; i < iterations; i++) begin
|
||||
// Vary the data to hit different bins
|
||||
data = i[7:0];
|
||||
state = i[3:0];
|
||||
addr = i[15:0];
|
||||
for (int i = 0; i < iterations; i++) begin
|
||||
// Vary the data to hit different bins
|
||||
data = i[7:0];
|
||||
state = i[3:0];
|
||||
addr = i[15:0];
|
||||
|
||||
cg_inst.sample();
|
||||
end
|
||||
cg_inst.sample();
|
||||
end
|
||||
|
||||
end_time = $time;
|
||||
elapsed = end_time - start_time;
|
||||
end_time = $time;
|
||||
elapsed = end_time - start_time;
|
||||
|
||||
avg_time_ns = real'(elapsed) / real'(iterations);
|
||||
avg_time_ns = real'(elapsed) / real'(iterations);
|
||||
|
||||
$display("Total time: %0d time units", elapsed);
|
||||
$display("Average time per sample(): %0.2f time units", avg_time_ns);
|
||||
$display("Coverage: %0.1f%%", cg_inst.get_inst_coverage());
|
||||
$display("Total time: %0d time units", elapsed);
|
||||
$display("Average time per sample(): %0.2f time units", avg_time_ns);
|
||||
$display("Coverage: %0.1f%%", cg_inst.get_inst_coverage());
|
||||
|
||||
// Performance target: < 100 cycles per sample()
|
||||
// Assuming 1 time unit = 1 ns, typical CPU @ 3 GHz = 0.33 ns/cycle
|
||||
// 100 cycles = 33 ns
|
||||
if (avg_time_ns < 33.0) begin
|
||||
$display("PASS: Performance within target (< 100 cycles)");
|
||||
end else begin
|
||||
$display("WARNING: Performance may need optimization (> 100 cycles)");
|
||||
end
|
||||
// Performance target: < 100 cycles per sample()
|
||||
// Assuming 1 time unit = 1 ns, typical CPU @ 3 GHz = 0.33 ns/cycle
|
||||
// 100 cycles = 33 ns
|
||||
if (avg_time_ns < 33.0) begin
|
||||
$display("PASS: Performance within target (< 100 cycles)");
|
||||
end else begin
|
||||
$display("WARNING: Performance may need optimization (> 100 cycles)");
|
||||
end
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -7,64 +7,64 @@
|
|||
// Realistic example: Bus transaction coverage
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
/* verilator lint_off UNSIGNED */
|
||||
logic [31:0] addr;
|
||||
logic [1:0] burst_type;
|
||||
logic valid;
|
||||
/* verilator lint_off UNSIGNED */
|
||||
logic [31:0] addr;
|
||||
logic [1:0] burst_type;
|
||||
logic valid;
|
||||
|
||||
// Coverage for a memory bus interface
|
||||
covergroup bus_cg;
|
||||
// Address coverage with interesting regions
|
||||
coverpoint addr {
|
||||
bins zero_page = {[32'h0000_0000:32'h0000_00FF]};
|
||||
bins boot_rom = {[32'h0000_1000:32'h0000_1FFF]};
|
||||
bins dram = {[32'h4000_0000:32'h7FFF_FFFF]};
|
||||
bins peripherals = {[32'h8000_0000:32'h9FFF_FFFF]};
|
||||
}
|
||||
// Coverage for a memory bus interface
|
||||
covergroup bus_cg;
|
||||
// Address coverage with interesting regions
|
||||
coverpoint addr {
|
||||
bins zero_page = {[32'h0000_0000:32'h0000_00FF]};
|
||||
bins boot_rom = {[32'h0000_1000:32'h0000_1FFF]};
|
||||
bins dram = {[32'h4000_0000:32'h7FFF_FFFF]};
|
||||
bins peripherals = {[32'h8000_0000:32'h9FFF_FFFF]};
|
||||
}
|
||||
|
||||
// Burst type coverage (only when valid)
|
||||
coverpoint burst_type iff (valid) {
|
||||
bins single = {2'b00};
|
||||
bins incr = {2'b01};
|
||||
bins wrap = {2'b10};
|
||||
bins reserved = {2'b11};
|
||||
}
|
||||
endgroup
|
||||
// Burst type coverage (only when valid)
|
||||
coverpoint burst_type iff (valid) {
|
||||
bins single = {2'b00};
|
||||
bins incr = {2'b01};
|
||||
bins wrap = {2'b10};
|
||||
bins reserved = {2'b11};
|
||||
}
|
||||
endgroup
|
||||
|
||||
bus_cg cg_inst;
|
||||
bus_cg cg_inst;
|
||||
|
||||
initial begin
|
||||
cg_inst = new;
|
||||
initial begin
|
||||
cg_inst = new;
|
||||
|
||||
// Test various transactions
|
||||
// Test various transactions
|
||||
|
||||
// Boot sequence - should hit zero_page and boot_rom
|
||||
valid = 1;
|
||||
addr = 32'h0000_0010; burst_type = 2'b00; cg_inst.sample();
|
||||
addr = 32'h0000_1100; burst_type = 2'b01; cg_inst.sample();
|
||||
// Boot sequence - should hit zero_page and boot_rom
|
||||
valid = 1;
|
||||
addr = 32'h0000_0010; burst_type = 2'b00; cg_inst.sample();
|
||||
addr = 32'h0000_1100; burst_type = 2'b01; cg_inst.sample();
|
||||
|
||||
// After boot
|
||||
check_coverage(50.0, "after boot");
|
||||
// After boot
|
||||
check_coverage(50.0, "after boot");
|
||||
|
||||
// DRAM access with wrap burst
|
||||
addr = 32'h4000_0000; burst_type = 2'b10; cg_inst.sample();
|
||||
check_coverage(75.0, "after dram access");
|
||||
// DRAM access with wrap burst
|
||||
addr = 32'h4000_0000; burst_type = 2'b10; cg_inst.sample();
|
||||
check_coverage(75.0, "after dram access");
|
||||
|
||||
// Peripheral access completes all addr bins
|
||||
addr = 32'h8000_0100; burst_type = 2'b11; cg_inst.sample();
|
||||
check_coverage(100.0, "complete");
|
||||
// Peripheral access completes all addr bins
|
||||
addr = 32'h8000_0100; burst_type = 2'b11; cg_inst.sample();
|
||||
check_coverage(100.0, "complete");
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
task check_coverage(real expected, string label);
|
||||
real cov;
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("Bus Coverage %s: %0.2f%% (expected ~%0.2f%%)", label, cov, expected);
|
||||
if (cov < expected - 1.0 || cov > expected + 1.0) begin
|
||||
$error("Coverage mismatch: got %0.2f%%, expected ~%0.2f%%", cov, expected);
|
||||
$stop;
|
||||
end
|
||||
|
||||
task check_coverage(real expected, string label);
|
||||
real cov;
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("Bus Coverage %s: %0.2f%% (expected ~%0.2f%%)", label, cov, expected);
|
||||
if (cov < expected - 1.0 || cov > expected + 1.0) begin
|
||||
$error("Coverage mismatch: got %0.2f%%, expected ~%0.2f%%", cov, expected);
|
||||
$stop;
|
||||
end
|
||||
endtask
|
||||
endtask
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -7,30 +7,30 @@
|
|||
// Test basic functional coverage sampling
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
/* verilator lint_off UNSIGNED */
|
||||
logic [3:0] data;
|
||||
int cyc = 0;
|
||||
/* verilator lint_off UNSIGNED */
|
||||
logic [3:0] data;
|
||||
int cyc = 0;
|
||||
|
||||
covergroup cg;
|
||||
coverpoint data {
|
||||
bins low = {[0:3]};
|
||||
bins mid = {[4:7]};
|
||||
bins high = {[8:15]};
|
||||
}
|
||||
endgroup
|
||||
covergroup cg;
|
||||
coverpoint data {
|
||||
bins low = {[0:3]};
|
||||
bins mid = {[4:7]};
|
||||
bins high = {[8:15]};
|
||||
}
|
||||
endgroup
|
||||
|
||||
cg cg_inst;
|
||||
cg cg_inst;
|
||||
|
||||
initial begin
|
||||
cg_inst = new;
|
||||
initial begin
|
||||
cg_inst = new;
|
||||
|
||||
// Sample different values
|
||||
data = 1; cg_inst.sample();
|
||||
data = 5; cg_inst.sample();
|
||||
data = 10; cg_inst.sample();
|
||||
data = 2; cg_inst.sample(); // low hit twice
|
||||
// Sample different values
|
||||
data = 1; cg_inst.sample();
|
||||
data = 5; cg_inst.sample();
|
||||
data = 10; cg_inst.sample();
|
||||
data = 2; cg_inst.sample(); // low hit twice
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -7,43 +7,43 @@
|
|||
// Test basic covergroup with simple coverpoint
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
logic [7:0] addr;
|
||||
logic cmd;
|
||||
logic [7:0] addr;
|
||||
logic cmd;
|
||||
|
||||
// Simple covergroup with two coverpoints
|
||||
covergroup cg @(posedge clk);
|
||||
cp_addr: coverpoint addr {
|
||||
bins low = {[0:127]};
|
||||
bins high = {[128:255]};
|
||||
}
|
||||
cp_cmd: coverpoint cmd {
|
||||
bins read = {0};
|
||||
bins write = {1};
|
||||
}
|
||||
endgroup
|
||||
// Simple covergroup with two coverpoints
|
||||
covergroup cg @(posedge clk);
|
||||
cp_addr: coverpoint addr {
|
||||
bins low = {[0:127]};
|
||||
bins high = {[128:255]};
|
||||
}
|
||||
cp_cmd: coverpoint cmd {
|
||||
bins read = {0};
|
||||
bins write = {1};
|
||||
}
|
||||
endgroup
|
||||
|
||||
cg cg_inst = new;
|
||||
cg cg_inst = new;
|
||||
|
||||
initial begin
|
||||
// Sample some values
|
||||
addr = 10; cmd = 0;
|
||||
@(posedge clk);
|
||||
initial begin
|
||||
// Sample some values
|
||||
addr = 10; cmd = 0;
|
||||
@(posedge clk);
|
||||
|
||||
addr = 200; cmd = 1;
|
||||
@(posedge clk);
|
||||
addr = 200; cmd = 1;
|
||||
@(posedge clk);
|
||||
|
||||
addr = 50; cmd = 0;
|
||||
@(posedge clk);
|
||||
addr = 50; cmd = 0;
|
||||
@(posedge clk);
|
||||
|
||||
$display("Coverage: %0.1f%%", cg_inst.get_coverage());
|
||||
$display("Coverage: %0.1f%%", cg_inst.get_coverage());
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -8,62 +8,62 @@
|
|||
|
||||
module t;
|
||||
|
||||
covergroup cg;
|
||||
coverpoint data {
|
||||
bins low = {[0:1]};
|
||||
bins mid = {[2:3]};
|
||||
bins high = {[4:5]};
|
||||
}
|
||||
endgroup
|
||||
covergroup cg;
|
||||
coverpoint data {
|
||||
bins low = {[0:1]};
|
||||
bins mid = {[2:3]};
|
||||
bins high = {[4:5]};
|
||||
}
|
||||
endgroup
|
||||
|
||||
int data;
|
||||
int data;
|
||||
|
||||
initial begin
|
||||
cg cg1, cg2, cg3;
|
||||
real type_cov;
|
||||
initial begin
|
||||
cg cg1, cg2, cg3;
|
||||
real type_cov;
|
||||
|
||||
cg1 = new;
|
||||
cg2 = new;
|
||||
cg3 = new;
|
||||
cg1 = new;
|
||||
cg2 = new;
|
||||
cg3 = new;
|
||||
|
||||
// Initially, no bins covered - should be 0%
|
||||
type_cov = cg::get_coverage();
|
||||
$display("Initial type coverage: %f", type_cov);
|
||||
if (type_cov != 0.0) $stop;
|
||||
// Initially, no bins covered - should be 0%
|
||||
type_cov = cg::get_coverage();
|
||||
$display("Initial type coverage: %f", type_cov);
|
||||
if (type_cov != 0.0) $stop;
|
||||
|
||||
// Sample cg1 with low bin
|
||||
data = 0;
|
||||
cg1.sample();
|
||||
type_cov = cg::get_coverage();
|
||||
$display("After cg1.sample(low): %f", type_cov);
|
||||
// 1 bin covered out of 3 = 33.33%
|
||||
if (type_cov < 33.0 || type_cov > 34.0) $stop;
|
||||
// Sample cg1 with low bin
|
||||
data = 0;
|
||||
cg1.sample();
|
||||
type_cov = cg::get_coverage();
|
||||
$display("After cg1.sample(low): %f", type_cov);
|
||||
// 1 bin covered out of 3 = 33.33%
|
||||
if (type_cov < 33.0 || type_cov > 34.0) $stop;
|
||||
|
||||
// Sample cg2 with mid bin
|
||||
data = 2;
|
||||
cg2.sample();
|
||||
type_cov = cg::get_coverage();
|
||||
$display("After cg2.sample(mid): %f", type_cov);
|
||||
// 2 bins covered out of 3 = 66.67%
|
||||
if (type_cov < 66.0 || type_cov > 67.0) $stop;
|
||||
// Sample cg2 with mid bin
|
||||
data = 2;
|
||||
cg2.sample();
|
||||
type_cov = cg::get_coverage();
|
||||
$display("After cg2.sample(mid): %f", type_cov);
|
||||
// 2 bins covered out of 3 = 66.67%
|
||||
if (type_cov < 66.0 || type_cov > 67.0) $stop;
|
||||
|
||||
// Sample cg3 with high bin
|
||||
data = 4;
|
||||
cg3.sample();
|
||||
type_cov = cg::get_coverage();
|
||||
$display("After cg3.sample(high): %f", type_cov);
|
||||
// 3 bins covered out of 3 = 100%
|
||||
if (type_cov < 99.9 || type_cov > 100.1) $stop;
|
||||
// Sample cg3 with high bin
|
||||
data = 4;
|
||||
cg3.sample();
|
||||
type_cov = cg::get_coverage();
|
||||
$display("After cg3.sample(high): %f", type_cov);
|
||||
// 3 bins covered out of 3 = 100%
|
||||
if (type_cov < 99.9 || type_cov > 100.1) $stop;
|
||||
|
||||
// Sample cg1 again with same bin - should not change coverage
|
||||
data = 1;
|
||||
cg1.sample();
|
||||
type_cov = cg::get_coverage();
|
||||
$display("After cg1.sample(low again): %f", type_cov);
|
||||
if (type_cov < 99.9 || type_cov > 100.1) $stop;
|
||||
// Sample cg1 again with same bin - should not change coverage
|
||||
data = 1;
|
||||
cg1.sample();
|
||||
type_cov = cg::get_coverage();
|
||||
$display("After cg1.sample(low again): %f", type_cov);
|
||||
if (type_cov < 99.9 || type_cov > 100.1) $stop;
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -3,49 +3,49 @@
|
|||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t;
|
||||
logic [2:0] state;
|
||||
int errors = 0;
|
||||
logic [2:0] state;
|
||||
int errors = 0;
|
||||
|
||||
covergroup cg;
|
||||
cp_state: coverpoint state {
|
||||
bins trans_3val = (0 => 1 => 2); // 3-value sequence
|
||||
bins trans_3val_2 = (2 => 3 => 4); // Another 3-value sequence
|
||||
}
|
||||
endgroup
|
||||
covergroup cg;
|
||||
cp_state: coverpoint state {
|
||||
bins trans_3val = (0 => 1 => 2); // 3-value sequence
|
||||
bins trans_3val_2 = (2 => 3 => 4); // Another 3-value sequence
|
||||
}
|
||||
endgroup
|
||||
|
||||
cg cg_inst = new;
|
||||
cg cg_inst = new;
|
||||
|
||||
initial begin
|
||||
// Test sequence 1: 0 => 1 => 2 (should complete trans_3val)
|
||||
state = 0;
|
||||
cg_inst.sample();
|
||||
initial begin
|
||||
// Test sequence 1: 0 => 1 => 2 (should complete trans_3val)
|
||||
state = 0;
|
||||
cg_inst.sample();
|
||||
|
||||
state = 1; // 0 => 1 (state machine now at position 1)
|
||||
cg_inst.sample();
|
||||
state = 1; // 0 => 1 (state machine now at position 1)
|
||||
cg_inst.sample();
|
||||
|
||||
state = 2; // 1 => 2 (completes trans_3val: 0=>1=>2)
|
||||
cg_inst.sample();
|
||||
state = 2; // 1 => 2 (completes trans_3val: 0=>1=>2)
|
||||
cg_inst.sample();
|
||||
|
||||
// Test sequence 2: 2 => 3 => 4 (should complete trans_3val_2)
|
||||
state = 3; // 2 => 3 (state machine now at position 1 for trans_3val_2)
|
||||
cg_inst.sample();
|
||||
// Test sequence 2: 2 => 3 => 4 (should complete trans_3val_2)
|
||||
state = 3; // 2 => 3 (state machine now at position 1 for trans_3val_2)
|
||||
cg_inst.sample();
|
||||
|
||||
state = 4; // 3 => 4 (completes trans_3val_2: 2=>3=>4)
|
||||
cg_inst.sample();
|
||||
state = 4; // 3 => 4 (completes trans_3val_2: 2=>3=>4)
|
||||
cg_inst.sample();
|
||||
|
||||
// Check coverage
|
||||
$display("Coverage: %f%%", cg_inst.get_inst_coverage());
|
||||
if (cg_inst.get_inst_coverage() < 99.0) begin
|
||||
$display("ERROR: Expected 100%% coverage, got %f%%", cg_inst.get_inst_coverage());
|
||||
errors++;
|
||||
end
|
||||
// Check coverage
|
||||
$display("Coverage: %f%%", cg_inst.get_inst_coverage());
|
||||
if (cg_inst.get_inst_coverage() < 99.0) begin
|
||||
$display("ERROR: Expected 100%% coverage, got %f%%", cg_inst.get_inst_coverage());
|
||||
errors++;
|
||||
end
|
||||
|
||||
if (errors == 0) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
end else begin
|
||||
$display("*-* FAILED with %0d errors *-*", errors);
|
||||
end
|
||||
$finish;
|
||||
end
|
||||
if (errors == 0) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
end else begin
|
||||
$display("*-* FAILED with %0d errors *-*", errors);
|
||||
end
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
%Warning-COVERIGN: t/t_covergroup_trans_empty_bad.v:15:26: Ignoring unsupported: cover '[*'
|
||||
15 | bins t1 = (1 [*2]);
|
||||
| ^~
|
||||
%Warning-COVERIGN: t/t_covergroup_trans_empty_bad.v:15:20: Ignoring unsupported: cover '[*'
|
||||
15 | bins t1 = (1 [*2]);
|
||||
| ^~
|
||||
... For warning description see https://verilator.org/warn/COVERIGN?v=latest
|
||||
... Use "/* verilator lint_off COVERIGN */" and lint_on around source to disable this message.
|
||||
%Error: t/t_covergroup_trans_empty_bad.v:15:18: Transition set without items
|
||||
%Error: t/t_covergroup_trans_empty_bad.v:15:12: Transition set without items
|
||||
: ... note: In instance 't'
|
||||
15 | bins t1 = (1 [*2]);
|
||||
| ^~
|
||||
15 | bins t1 = (1 [*2]);
|
||||
| ^~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -8,14 +8,14 @@
|
|||
// Test: transition bin with unsupported repetition operator causes empty transition set
|
||||
|
||||
module t;
|
||||
logic [3:0] cp_expr;
|
||||
logic [3:0] cp_expr;
|
||||
|
||||
covergroup cg;
|
||||
cp1: coverpoint cp_expr {
|
||||
bins t1 = (1 [*2]);
|
||||
}
|
||||
endgroup
|
||||
covergroup cg;
|
||||
cp1: coverpoint cp_expr {
|
||||
bins t1 = (1 [*2]);
|
||||
}
|
||||
endgroup
|
||||
|
||||
cg cg_inst = new;
|
||||
initial $finish;
|
||||
cg cg_inst = new;
|
||||
initial $finish;
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -3,51 +3,51 @@
|
|||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
logic [2:0] state;
|
||||
logic [2:0] state;
|
||||
|
||||
covergroup cg;
|
||||
// Test array bins: creates separate bin for each transition
|
||||
cp_array: coverpoint state {
|
||||
bins trans_array[] = (0 => 1), (1 => 2), (2 => 3);
|
||||
}
|
||||
endgroup
|
||||
covergroup cg;
|
||||
// Test array bins: creates separate bin for each transition
|
||||
cp_array: coverpoint state {
|
||||
bins trans_array[] = (0 => 1), (1 => 2), (2 => 3);
|
||||
}
|
||||
endgroup
|
||||
|
||||
cg cg_inst = new;
|
||||
cg cg_inst = new;
|
||||
|
||||
int cyc = 0;
|
||||
int cyc = 0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
|
||||
case (cyc)
|
||||
0: state <= 0;
|
||||
1: state <= 1; // 0 => 1 (hits trans_array[0=>1])
|
||||
2: state <= 2; // 1 => 2 (hits trans_array[1=>2])
|
||||
3: state <= 3; // 2 => 3 (hits trans_array[2=>3])
|
||||
4: begin
|
||||
real cov = cg_inst.get_inst_coverage();
|
||||
$display("Coverage: %f%%", cov);
|
||||
// We should have hit all 3 array bins = 100%
|
||||
if (cov >= 99.0) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end else begin
|
||||
$display("ERROR: Expected 100%% coverage, got %f%%", cov);
|
||||
$stop;
|
||||
end
|
||||
case (cyc)
|
||||
0: state <= 0;
|
||||
1: state <= 1; // 0 => 1 (hits trans_array[0=>1])
|
||||
2: state <= 2; // 1 => 2 (hits trans_array[1=>2])
|
||||
3: state <= 3; // 2 => 3 (hits trans_array[2=>3])
|
||||
4: begin
|
||||
real cov = cg_inst.get_inst_coverage();
|
||||
$display("Coverage: %f%%", cov);
|
||||
// We should have hit all 3 array bins = 100%
|
||||
if (cov >= 99.0) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end else begin
|
||||
$display("ERROR: Expected 100%% coverage, got %f%%", cov);
|
||||
$stop;
|
||||
end
|
||||
endcase
|
||||
|
||||
cg_inst.sample();
|
||||
|
||||
if (cyc > 10) begin
|
||||
$display("ERROR: Test timed out");
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
|
||||
cg_inst.sample();
|
||||
|
||||
if (cyc > 10) begin
|
||||
$display("ERROR: Test timed out");
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -3,55 +3,55 @@
|
|||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t;
|
||||
logic [2:0] state;
|
||||
int errors = 0;
|
||||
logic [2:0] state;
|
||||
int errors = 0;
|
||||
|
||||
covergroup cg;
|
||||
cp_state: coverpoint state {
|
||||
bins trans_restart = (1 => 2 => 3); // Should handle restart correctly
|
||||
}
|
||||
endgroup
|
||||
covergroup cg;
|
||||
cp_state: coverpoint state {
|
||||
bins trans_restart = (1 => 2 => 3); // Should handle restart correctly
|
||||
}
|
||||
endgroup
|
||||
|
||||
cg cg_inst = new;
|
||||
cg cg_inst = new;
|
||||
|
||||
initial begin
|
||||
// Sequence: 1, 2, 1, 2, 3
|
||||
// This tests restart logic: when we see 1 again while in middle of sequence,
|
||||
// we should restart from position 1 (not reset to 0)
|
||||
initial begin
|
||||
// Sequence: 1, 2, 1, 2, 3
|
||||
// This tests restart logic: when we see 1 again while in middle of sequence,
|
||||
// we should restart from position 1 (not reset to 0)
|
||||
|
||||
state = 1; // Start: position = 1
|
||||
cg_inst.sample();
|
||||
$display("After state=1: seqpos should be 1");
|
||||
state = 1; // Start: position = 1
|
||||
cg_inst.sample();
|
||||
$display("After state=1: seqpos should be 1");
|
||||
|
||||
state = 2; // Advance: position = 2
|
||||
cg_inst.sample();
|
||||
$display("After state=2: seqpos should be 2");
|
||||
state = 2; // Advance: position = 2
|
||||
cg_inst.sample();
|
||||
$display("After state=2: seqpos should be 2");
|
||||
|
||||
state = 1; // Restart! Should go to position 1 (not 0)
|
||||
cg_inst.sample();
|
||||
$display("After state=1 (restart): seqpos should be 1");
|
||||
state = 1; // Restart! Should go to position 1 (not 0)
|
||||
cg_inst.sample();
|
||||
$display("After state=1 (restart): seqpos should be 1");
|
||||
|
||||
state = 2; // Advance: position = 2
|
||||
cg_inst.sample();
|
||||
$display("After state=2: seqpos should be 2");
|
||||
state = 2; // Advance: position = 2
|
||||
cg_inst.sample();
|
||||
$display("After state=2: seqpos should be 2");
|
||||
|
||||
state = 3; // Complete! Bin should increment
|
||||
cg_inst.sample();
|
||||
$display("After state=3: bin should have incremented, seqpos reset to 0");
|
||||
state = 3; // Complete! Bin should increment
|
||||
cg_inst.sample();
|
||||
$display("After state=3: bin should have incremented, seqpos reset to 0");
|
||||
|
||||
// Check coverage
|
||||
$display("Coverage: %f%%", cg_inst.get_inst_coverage());
|
||||
if (cg_inst.get_inst_coverage() < 99.0) begin
|
||||
$display("ERROR: Expected 100%% coverage, got %f%%", cg_inst.get_inst_coverage());
|
||||
errors++;
|
||||
end
|
||||
// Check coverage
|
||||
$display("Coverage: %f%%", cg_inst.get_inst_coverage());
|
||||
if (cg_inst.get_inst_coverage() < 99.0) begin
|
||||
$display("ERROR: Expected 100%% coverage, got %f%%", cg_inst.get_inst_coverage());
|
||||
errors++;
|
||||
end
|
||||
|
||||
if (errors == 0) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
end else begin
|
||||
$display("*-* FAILED with %0d errors *-*", errors);
|
||||
end
|
||||
$finish;
|
||||
end
|
||||
if (errors == 0) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
end else begin
|
||||
$display("*-* FAILED with %0d errors *-*", errors);
|
||||
end
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of either the GNU Lesser General Public License Version 3
|
||||
# or the Perl Artistic License Version 2.0.
|
||||
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('simulator')
|
||||
|
||||
test.compile()
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -3,52 +3,52 @@
|
|||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
logic [2:0] state;
|
||||
logic [2:0] state;
|
||||
|
||||
covergroup cg;
|
||||
cp_state: coverpoint state {
|
||||
bins trans1 = (0 => 1);
|
||||
bins trans2 = (1 => 2);
|
||||
bins trans3 = (2 => 3);
|
||||
}
|
||||
endgroup
|
||||
covergroup cg;
|
||||
cp_state: coverpoint state {
|
||||
bins trans1 = (0 => 1);
|
||||
bins trans2 = (1 => 2);
|
||||
bins trans3 = (2 => 3);
|
||||
}
|
||||
endgroup
|
||||
|
||||
cg cg_inst = new;
|
||||
cg cg_inst = new;
|
||||
|
||||
int cyc = 0;
|
||||
int cyc = 0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
|
||||
case (cyc)
|
||||
0: state <= 0;
|
||||
1: state <= 1; // 0 => 1 (trans1 should hit)
|
||||
2: state <= 2; // 1 => 2 (trans2 should hit)
|
||||
3: state <= 3; // 2 => 3 (trans3 should hit)
|
||||
4: begin
|
||||
$display("Coverage: %f%%", cg_inst.get_inst_coverage());
|
||||
if (cg_inst.get_inst_coverage() >= 99.0) begin // Allow for rounding
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end else begin
|
||||
$display("ERROR: Expected 100%% coverage, got %f%%", cg_inst.get_inst_coverage());
|
||||
$stop;
|
||||
end
|
||||
case (cyc)
|
||||
0: state <= 0;
|
||||
1: state <= 1; // 0 => 1 (trans1 should hit)
|
||||
2: state <= 2; // 1 => 2 (trans2 should hit)
|
||||
3: state <= 3; // 2 => 3 (trans3 should hit)
|
||||
4: begin
|
||||
$display("Coverage: %f%%", cg_inst.get_inst_coverage());
|
||||
if (cg_inst.get_inst_coverage() >= 99.0) begin // Allow for rounding
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end else begin
|
||||
$display("ERROR: Expected 100%% coverage, got %f%%", cg_inst.get_inst_coverage());
|
||||
$stop;
|
||||
end
|
||||
endcase
|
||||
|
||||
// Sample the covergroup manually each clock
|
||||
cg_inst.sample();
|
||||
|
||||
// Auto-stop after 10 cycles to prevent infinite loop
|
||||
if (cyc > 10) begin
|
||||
$display("ERROR: Test timed out");
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
|
||||
// Sample the covergroup manually each clock
|
||||
cg_inst.sample();
|
||||
|
||||
// Auto-stop after 10 cycles to prevent infinite loop
|
||||
if (cyc > 10) begin
|
||||
$display("ERROR: Test timed out");
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
%Error: t/t_covergroup_trans_single_bad.v:15:18: Transition requires at least two values
|
||||
%Error: t/t_covergroup_trans_single_bad.v:15:12: Transition requires at least two values
|
||||
: ... note: In instance 't'
|
||||
15 | bins t1 = (1);
|
||||
| ^~
|
||||
15 | bins t1 = (1);
|
||||
| ^~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -8,14 +8,14 @@
|
|||
// Test: transition bin requires at least two values
|
||||
|
||||
module t;
|
||||
logic [3:0] cp_expr;
|
||||
logic [3:0] cp_expr;
|
||||
|
||||
covergroup cg;
|
||||
cp1: coverpoint cp_expr {
|
||||
bins t1 = (1);
|
||||
}
|
||||
endgroup
|
||||
covergroup cg;
|
||||
cp1: coverpoint cp_expr {
|
||||
bins t1 = (1);
|
||||
}
|
||||
endgroup
|
||||
|
||||
cg cg_inst = new;
|
||||
initial $finish;
|
||||
cg cg_inst = new;
|
||||
initial $finish;
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of either the GNU Lesser General Public License Version 3
|
||||
# or the Perl Artistic License Version 2.0.
|
||||
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('vlt')
|
||||
|
||||
test.compile()
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -7,73 +7,73 @@
|
|||
// Test wildcard bins with don't care matching
|
||||
|
||||
module t;
|
||||
/* verilator lint_off UNSIGNED */
|
||||
bit [7:0] data;
|
||||
/* verilator lint_off UNSIGNED */
|
||||
bit [7:0] data;
|
||||
|
||||
covergroup cg;
|
||||
coverpoint data {
|
||||
// Match any value with upper nibble = 4'b0000
|
||||
wildcard bins low = {8'b0000_????};
|
||||
covergroup cg;
|
||||
coverpoint data {
|
||||
// Match any value with upper nibble = 4'b0000
|
||||
wildcard bins low = {8'b0000_????};
|
||||
|
||||
// Match any value with upper nibble = 4'b1111
|
||||
wildcard bins high = {8'b1111_????};
|
||||
// Match any value with upper nibble = 4'b1111
|
||||
wildcard bins high = {8'b1111_????};
|
||||
|
||||
// Match specific pattern with don't cares
|
||||
wildcard bins pattern = {8'b10?0_11??};
|
||||
}
|
||||
endgroup
|
||||
// Match specific pattern with don't cares
|
||||
wildcard bins pattern = {8'b10?0_11??};
|
||||
}
|
||||
endgroup
|
||||
|
||||
initial begin
|
||||
cg cg_inst;
|
||||
real cov;
|
||||
initial begin
|
||||
cg cg_inst;
|
||||
real cov;
|
||||
|
||||
cg_inst = new();
|
||||
cg_inst = new();
|
||||
|
||||
// Test low bin (upper nibble = 0000)
|
||||
data = 8'b0000_0101; // Should match 'low'
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("After sample 1 (low): %0.2f%%", cov);
|
||||
if (cov < 30.0 || cov > 35.0) begin
|
||||
$error("Expected ~33.33%% (1/3 bins), got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Test high bin (upper nibble = 1111)
|
||||
data = 8'b1111_1010; // Should match 'high'
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("After sample 2 (high): %0.2f%%", cov);
|
||||
if (cov < 63.0 || cov > 70.0) begin
|
||||
$error("Expected ~66.67%% (2/3 bins), got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Test pattern bin (10?0_11??)
|
||||
data = 8'b1000_1101; // Should match 'pattern' (10[0]0_11[0]1)
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("After sample 3 (pattern): %0.2f%%", cov);
|
||||
if (cov != 100.0) begin
|
||||
$error("Expected 100%% (3/3 bins), got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Verify another pattern match
|
||||
data = 8'b1010_1111; // Should also match 'pattern' (10[1]0_11[1]1)
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
if (cov != 100.0) begin
|
||||
$error("Pattern should still be 100%%, got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Verify non-matching value doesn't change coverage
|
||||
data = 8'b0101_0101; // Shouldn't match any bin
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
if (cov != 100.0) begin
|
||||
$error("Non-matching value shouldn't change coverage, got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
$display("Wildcard bins test PASSED - final coverage: %0.2f%%", cov);
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
// Test low bin (upper nibble = 0000)
|
||||
data = 8'b0000_0101; // Should match 'low'
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("After sample 1 (low): %0.2f%%", cov);
|
||||
if (cov < 30.0 || cov > 35.0) begin
|
||||
$error("Expected ~33.33%% (1/3 bins), got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Test high bin (upper nibble = 1111)
|
||||
data = 8'b1111_1010; // Should match 'high'
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("After sample 2 (high): %0.2f%%", cov);
|
||||
if (cov < 63.0 || cov > 70.0) begin
|
||||
$error("Expected ~66.67%% (2/3 bins), got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Test pattern bin (10?0_11??)
|
||||
data = 8'b1000_1101; // Should match 'pattern' (10[0]0_11[0]1)
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
$display("After sample 3 (pattern): %0.2f%%", cov);
|
||||
if (cov != 100.0) begin
|
||||
$error("Expected 100%% (3/3 bins), got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Verify another pattern match
|
||||
data = 8'b1010_1111; // Should also match 'pattern' (10[1]0_11[1]1)
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
if (cov != 100.0) begin
|
||||
$error("Pattern should still be 100%%, got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
// Verify non-matching value doesn't change coverage
|
||||
data = 8'b0101_0101; // Shouldn't match any bin
|
||||
cg_inst.sample();
|
||||
cov = cg_inst.get_inst_coverage();
|
||||
if (cov != 100.0) begin
|
||||
$error("Non-matching value shouldn't change coverage, got %0.2f%%", cov);
|
||||
end
|
||||
|
||||
$display("Wildcard bins test PASSED - final coverage: %0.2f%%", cov);
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
Loading…
Reference in New Issue