2026-06-05 15:35:01 +02:00
// 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 array bins - separate bin per value, including range expressions
// verilog_format: off
`define stop $stop
`define checkr(gotv,expv) do if ((gotv) != (expv)) begin $write("%%Error: %s:%0d: got=%f exp=%f\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
// verilog_format: on
module t ;
bit [ 7 : 0 ] data ;
2026-06-23 04:14:43 +02:00
bit [ 1 : 0 ] sel ;
bit [ 63 : 0 ] wide ;
2026-06-05 15:35:01 +02:00
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
// cg2: array bins using a range expression - one bin per value in the range
covergroup cg2 ;
cp: coverpoint data {
2026-06-06 00:36:55 +02:00
bins range_arr [ ] = { [ 0 : 3 ] } ; // range expression: creates 4 separate bins
2026-06-05 15:35:01 +02:00
}
endgroup
// cg3: sized array bins - bins r[N] = {[lo:hi]} distributes range into N bins
covergroup cg3 ;
cp: coverpoint data {
2026-06-06 00:36:55 +02:00
bins range_sized [ 4 ] = { [ 4 : 7 ] } ; // explicit count: 4 bins covering [4:7]
2026-06-05 15:35:01 +02:00
}
endgroup
2026-06-23 04:14:43 +02:00
// cg4: array bins with '$' (open range) - '$' resolves to the coverpoint domain max.
// For 2-bit sel, {[0:$]} == {[0:3]}: one bin per value -> 4 bins (issue #7750).
covergroup cg4 ;
cp: coverpoint sel {
bins all_vals [ ] = { [ 0 : $ ] } ;
}
endgroup
// cg5: lower-open range {[lo:$]} == {[lo:maxVal]} -> bins for 2 and 3
covergroup cg5 ;
cp: coverpoint sel {
bins hi_vals [ ] = { [ 2 : $ ] } ;
}
endgroup
// cg6: upper-open range {[$:hi]} == {[0:hi]} -> bins for 0 and 1
covergroup cg6 ;
cp: coverpoint sel {
bins lo_open [ ] = { [ $ : 1 ] } ;
}
endgroup
// cg7: a reversed range {[hi:lo]} (hi<lo) contributes no bins; the plain
// values 5 and 7 each create one bin -> 2 bins total.
covergroup cg7 ;
cp: coverpoint data {
bins rev [ ] = { [ 3 : 1 ] , 5 , 7 } ;
}
endgroup
// cg8: wide (>= 64-bit) coverpoint, exercising the 64-bit domain-max path
covergroup cg8 ;
cp: coverpoint wide {
bins w [ ] = { [ 0 : 1 ] } ;
}
endgroup
// cg9: two ranges that are each under COVER_BINS_LIMIT (1000) but whose
// cumulative size exceeds it. The first range populates the value list, the
// second trips the running-total guard -> COVERIGN, the whole bin is ignored.
// cpA is crossed, so it is non-convertible and routes through the legacy
// per-bin generateArrayBins() path (exercising its unsupported-bin guard).
covergroup cg9 ;
cpA: coverpoint wide {
bins cumulative [ ] = { [ 0 : 500 ] , [ 0 : 500 ] } ;
bins ok = { 5 } ;
}
cpB: coverpoint sel {
bins lo = { 1 } ;
}
cross cpA , cpB ;
endgroup
2026-06-05 15:35:01 +02:00
initial begin
2026-06-06 00:36:55 +02:00
cg cg_inst ;
2026-06-05 15:35:01 +02:00
cg2 cg2_inst ;
cg3 cg3_inst ;
2026-06-23 04:14:43 +02:00
cg4 cg4_inst ;
cg5 cg5_inst ;
cg6 cg6_inst ;
cg7 cg7_inst ;
cg8 cg8_inst ;
cg9 cg9_inst ;
2026-06-05 15:35:01 +02:00
2026-06-06 00:36:55 +02:00
cg_inst = new ( ) ;
2026-06-05 15:35:01 +02:00
cg2_inst = new ( ) ;
cg3_inst = new ( ) ;
2026-06-23 04:14:43 +02:00
cg4_inst = new ( ) ;
cg5_inst = new ( ) ;
cg6_inst = new ( ) ;
cg7_inst = new ( ) ;
cg8_inst = new ( ) ;
cg9_inst = new ( ) ;
2026-06-05 15:35:01 +02:00
// Hit first array bin value (1)
data = 1 ;
cg_inst . sample ( ) ;
`checkr ( cg_inst . get_inst_coverage ( ) , 25.0 ) ;
// Hit second array bin value (5)
data = 5 ;
cg_inst . sample ( ) ;
`checkr ( cg_inst . get_inst_coverage ( ) , 50.0 ) ;
// Hit the grouped bin (covers all of 2, 6, 10)
data = 6 ;
cg_inst . sample ( ) ;
`checkr ( cg_inst . get_inst_coverage ( ) , 75.0 ) ;
// Hit third array bin value (9)
data = 9 ;
cg_inst . sample ( ) ;
`checkr ( cg_inst . get_inst_coverage ( ) , 100.0 ) ;
// Verify hitting other values in grouped bin doesn't increase coverage
data = 2 ;
cg_inst . sample ( ) ;
`checkr ( cg_inst . get_inst_coverage ( ) , 100.0 ) ;
// Hit range_arr bins ([0:3])
2026-06-06 00:36:55 +02:00
data = 0 ;
cg2_inst . sample ( ) ;
2026-06-05 15:35:01 +02:00
`checkr ( cg2_inst . get_inst_coverage ( ) , 25.0 ) ;
2026-06-06 00:36:55 +02:00
data = 1 ;
cg2_inst . sample ( ) ;
2026-06-05 15:35:01 +02:00
`checkr ( cg2_inst . get_inst_coverage ( ) , 50.0 ) ;
2026-06-06 00:36:55 +02:00
data = 2 ;
cg2_inst . sample ( ) ;
2026-06-05 15:35:01 +02:00
`checkr ( cg2_inst . get_inst_coverage ( ) , 75.0 ) ;
// Hit range_sized bins ([4:7])
2026-06-06 00:36:55 +02:00
data = 4 ;
cg3_inst . sample ( ) ;
2026-06-05 15:35:01 +02:00
`checkr ( cg3_inst . get_inst_coverage ( ) , 25.0 ) ;
2026-06-06 00:36:55 +02:00
data = 5 ;
cg3_inst . sample ( ) ;
2026-06-05 15:35:01 +02:00
`checkr ( cg3_inst . get_inst_coverage ( ) , 50.0 ) ;
2026-06-06 00:36:55 +02:00
data = 6 ;
cg3_inst . sample ( ) ;
2026-06-05 15:35:01 +02:00
`checkr ( cg3_inst . get_inst_coverage ( ) , 75.0 ) ;
2026-06-23 04:14:43 +02:00
// Hit cg4 '$' bins ([0:$] == [0:3], 4 bins): cover 3 of 4
sel = 0 ;
cg4_inst . sample ( ) ;
`checkr ( cg4_inst . get_inst_coverage ( ) , 25.0 ) ;
sel = 1 ;
cg4_inst . sample ( ) ;
`checkr ( cg4_inst . get_inst_coverage ( ) , 50.0 ) ;
sel = 2 ;
cg4_inst . sample ( ) ;
`checkr ( cg4_inst . get_inst_coverage ( ) , 75.0 ) ;
// Hit cg5 lower-open bins ([2:$] == [2:3], 2 bins): cover 1 of 2
sel = 2 ;
cg5_inst . sample ( ) ;
`checkr ( cg5_inst . get_inst_coverage ( ) , 50.0 ) ;
// Hit cg6 upper-open bins ([$:1] == [0:1], 2 bins): cover 1 of 2
sel = 0 ;
cg6_inst . sample ( ) ;
`checkr ( cg6_inst . get_inst_coverage ( ) , 50.0 ) ;
// Hit cg7 bins (reversed [3:1] -> no bins; 5 and 7 -> 2 bins): cover 1 of 2
data = 5 ;
cg7_inst . sample ( ) ;
`checkr ( cg7_inst . get_inst_coverage ( ) , 50.0 ) ;
// Hit cg8 wide bins ([0:1], 2 bins): cover 1 of 2
wide = 1 ;
cg8_inst . sample ( ) ;
`checkr ( cg8_inst . get_inst_coverage ( ) , 50.0 ) ;
// Exercise cg9 (crossed cpA with an ignored cumulative array bin, legacy path)
wide = 5 ;
sel = 1 ;
cg9_inst . sample ( ) ;
2026-06-05 15:35:01 +02:00
$write ( " *-* All Finished *-* \n " ) ;
$finish ;
end
endmodule