2026-06-05 15:35:01 +02:00
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2026 by Wilson Snyder.
// SPDX-FileCopyrightText: 2026 Wilson Snyder
// SPDX-License-Identifier: CC0-1.0
// Test iff (enable) guard: sampling is gated by the enable condition.
// Covers iff on explicit value bins, default bin, array bins,
// simple 2-step transition, and 3-step transition.
//
// Also covers compound iff expressions (&&, ||, unary !, bit/part-select,
// relational compare, parenthesized bitwise, and a concatenation-valued
// coverpoint with a compound iff). Previously any iff that was not a bare
// reference or a unary ! tripped an internal error ("Unexpected '...'
// expression under 'COVERPOINT'") because the iff child was widthed with no
// context.
// 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 ;
logic enable ;
int value ;
// Signals for the compound-iff covergroups below
logic m_is_read ;
logic [ 3 : 0 ] m_be ;
logic [ 1 : 0 ] m_a ;
logic [ 1 : 0 ] m_b ;
int count ;
// iff on explicit value bins
covergroup cg_iff ;
cp_value: coverpoint value iff ( enable ) {
2026-06-06 00:36:55 +02:00
bins disabled_lo = { 1 } ; bins disabled_hi = { 2 } ; bins enabled_lo = { 3 } ; bins enabled_hi = { 4 } ;
2026-06-05 15:35:01 +02:00
}
endgroup
// iff on default bin
covergroup cg_default_iff ;
cp: coverpoint value iff ( enable ) {
bins known = { 10 } ;
bins def = default ; // default bin with coverpoint-level iff
}
endgroup
// iff on array bins
covergroup cg_array_iff ;
cp: coverpoint value iff ( enable ) {
bins arr [ ] = { 5 , 6 , 7 } ; // array bins, all gated by iff
}
endgroup
// iff on 2-step transition
covergroup cg_trans2_iff ;
2026-06-06 00:36:55 +02:00
cp: coverpoint value iff ( enable ) { bins t2 = ( 1 = > 2 ) ; }
2026-06-05 15:35:01 +02:00
endgroup
// iff on 3-step transition
covergroup cg_trans3_iff ;
2026-06-06 00:36:55 +02:00
cp: coverpoint value iff ( enable ) { bins t3 = ( 1 = > 2 = > 3 ) ; }
2026-06-05 15:35:01 +02:00
endgroup
// --- compound iff expressions ---
// unary ! combined with && and a bit-select, on a concatenation-valued
// coverpoint expression -- the exact reported shape.
covergroup cg_and ;
2026-06-06 00:36:55 +02:00
cp_concat: coverpoint {
m_a [ 0 ] , m_b [ 0 ]
} iff ( ! m_is_read & & m_be [ 0 ] ) {
bins b00 = { 2 'b00 } ; bins b01 = { 2 'b01 } ; bins b10 = { 2 'b10 } ; bins b11 = { 2 'b11 } ;
2026-06-05 15:35:01 +02:00
}
endgroup
// logical || guard
covergroup cg_or ;
2026-06-06 00:36:55 +02:00
cp: coverpoint count iff ( m_be [ 0 ] | | m_be [ 1 ] ) { bins lo = { 1 } ; bins hi = { 2 } ; }
2026-06-05 15:35:01 +02:00
endgroup
// part-select compare guard
covergroup cg_part ;
2026-06-06 00:36:55 +02:00
cp: coverpoint count iff ( m_be [ 3 : 0 ] ! = 0 ) { bins one = { 1 } ; }
2026-06-05 15:35:01 +02:00
endgroup
// relational compare guard
covergroup cg_rel ;
2026-06-06 00:36:55 +02:00
cp: coverpoint count iff ( count > 3 ) { bins five = { 5 } ; bins two = { 2 } ; }
2026-06-05 15:35:01 +02:00
endgroup
// parenthesized bitwise guard
covergroup cg_bitw ;
2026-06-06 00:36:55 +02:00
cp: coverpoint count iff ( ( m_a & m_b ) = = 2 'b10 ) { bins seven = { 7 } ; }
2026-06-05 15:35:01 +02:00
endgroup
2026-06-06 00:36:55 +02:00
cg_iff cg1 = new ;
cg_default_iff cg2 = new ;
cg_array_iff cg3 = new ;
cg_trans2_iff cg4 = new ;
cg_trans3_iff cg5 = new ;
cg_and ca = new ;
cg_or co = new ;
cg_part cpp = new ;
cg_rel cr = new ;
cg_bitw cb = new ;
2026-06-05 15:35:01 +02:00
initial begin
// Sample disabled_lo and disabled_hi with enable=0 -- must not be recorded
enable = 0 ;
2026-06-06 00:36:55 +02:00
value = 1 ;
cg1 . sample ( ) ;
value = 2 ;
cg1 . sample ( ) ;
2026-06-05 15:35:01 +02:00
`checkr ( cg1 . get_inst_coverage ( ) , 0.0 ) ;
// Sample enabled_lo and enabled_hi with enable=1 -- must be recorded
enable = 1 ;
2026-06-06 00:36:55 +02:00
value = 3 ;
cg1 . sample ( ) ;
2026-06-05 15:35:01 +02:00
`checkr ( cg1 . get_inst_coverage ( ) , 25.0 ) ;
2026-06-06 00:36:55 +02:00
value = 4 ;
cg1 . sample ( ) ;
2026-06-05 15:35:01 +02:00
`checkr ( cg1 . get_inst_coverage ( ) , 50.0 ) ;
// cg2: default bin -- enable=1 lets known and default through
enable = 1 ;
2026-06-06 00:36:55 +02:00
value = 10 ;
cg2 . sample ( ) ; // hits 'known'
2026-06-12 17:40:48 +02:00
`checkr ( cg2 . get_inst_coverage ( ) , 100.0 ) ; // 1/1: only 'known' counts (default excluded, LRM 19.5)
2026-06-06 00:36:55 +02:00
value = 99 ;
cg2 . sample ( ) ; // hits 'def' (default)
2026-06-05 15:35:01 +02:00
`checkr ( cg2 . get_inst_coverage ( ) , 100.0 ) ;
enable = 0 ;
2026-06-06 00:36:55 +02:00
value = 99 ;
cg2 . sample ( ) ; // gated by iff -- must NOT hit 'def'
2026-06-05 15:35:01 +02:00
`checkr ( cg2 . get_inst_coverage ( ) , 100.0 ) ;
// cg3: array bins with iff (3 bins: arr[5], arr[6], arr[7])
// 1/3 hit -> 33.3% (not a clean binary fraction; no checkr)
enable = 1 ;
2026-06-06 00:36:55 +02:00
value = 5 ;
cg3 . sample ( ) ; // arr[5] hit
2026-06-05 15:35:01 +02:00
enable = 0 ;
2026-06-06 00:36:55 +02:00
value = 6 ;
cg3 . sample ( ) ; // gated
2026-06-05 15:35:01 +02:00
// cg4: 2-step transition with iff
enable = 1 ;
2026-06-06 00:36:55 +02:00
value = 1 ;
cg4 . sample ( ) ;
2026-06-05 15:35:01 +02:00
`checkr ( cg4 . get_inst_coverage ( ) , 0.0 ) ;
2026-06-06 00:36:55 +02:00
value = 2 ;
cg4 . sample ( ) ; // (1=>2) hit with enable=1
2026-06-05 15:35:01 +02:00
`checkr ( cg4 . get_inst_coverage ( ) , 100.0 ) ;
enable = 0 ;
2026-06-06 00:36:55 +02:00
value = 1 ;
cg4 . sample ( ) ;
value = 2 ;
cg4 . sample ( ) ; // (1=>2) gated by iff
2026-06-05 15:35:01 +02:00
`checkr ( cg4 . get_inst_coverage ( ) , 100.0 ) ;
// cg5: 3-step transition with iff
enable = 1 ;
2026-06-06 00:36:55 +02:00
value = 1 ;
cg5 . sample ( ) ;
value = 2 ;
cg5 . sample ( ) ; // mid-sequence, enable=1
2026-06-05 15:35:01 +02:00
enable = 0 ;
2026-06-06 00:36:55 +02:00
value = 3 ;
cg5 . sample ( ) ; // iff is disabled at step 3 - incomplete sequence is discarded
2026-06-05 15:35:01 +02:00
`checkr ( cg5 . get_inst_coverage ( ) , 0.0 ) ;
enable = 1 ;
2026-06-06 00:36:55 +02:00
value = 1 ;
cg5 . sample ( ) ;
value = 2 ;
cg5 . sample ( ) ;
value = 3 ;
cg5 . sample ( ) ; // (1=>2=>3) fully hit with enable=1
2026-06-05 15:35:01 +02:00
`checkr ( cg5 . get_inst_coverage ( ) , 100.0 ) ;
// --- compound iff expressions ---
// cg_and: guard true -> {0,1}=2'b01 sampled into b01
2026-06-06 00:36:55 +02:00
m_is_read = 0 ;
m_be = 4 'b0001 ;
m_a = 2 'b10 ;
m_b = 2 'b11 ; // m_a[0]=0,m_b[0]=1 -> 2'b01
2026-06-05 15:35:01 +02:00
ca . sample ( ) ; // b01 hit
`checkr ( ca . get_inst_coverage ( ) , 25.0 ) ;
2026-06-06 00:36:55 +02:00
m_is_read = 1 ;
m_a = 2 'b11 ;
m_b = 2 'b11 ; // guard false -> gated
2026-06-05 15:35:01 +02:00
ca . sample ( ) ;
`checkr ( ca . get_inst_coverage ( ) , 25.0 ) ;
// cg_or: guard true via bit1
2026-06-06 00:36:55 +02:00
m_be = 4 'b0010 ;
count = 1 ;
co . sample ( ) ; // lo hit
2026-06-05 15:35:01 +02:00
`checkr ( co . get_inst_coverage ( ) , 50.0 ) ;
2026-06-06 00:36:55 +02:00
m_be = 4 'b0000 ;
count = 2 ;
co . sample ( ) ; // gated
2026-06-05 15:35:01 +02:00
`checkr ( co . get_inst_coverage ( ) , 50.0 ) ;
// cg_part: part-select != 0
2026-06-06 00:36:55 +02:00
m_be = 4 'b1000 ;
count = 1 ;
cpp . sample ( ) ; // one hit
2026-06-05 15:35:01 +02:00
`checkr ( cpp . get_inst_coverage ( ) , 100.0 ) ;
2026-06-06 00:36:55 +02:00
m_be = 4 'b0000 ;
count = 1 ;
cpp . sample ( ) ; // gated
2026-06-05 15:35:01 +02:00
`checkr ( cpp . get_inst_coverage ( ) , 100.0 ) ;
// cg_rel: count > 3
2026-06-06 00:36:55 +02:00
count = 5 ;
cr . sample ( ) ; // five hit (5>3)
2026-06-05 15:35:01 +02:00
`checkr ( cr . get_inst_coverage ( ) , 50.0 ) ;
2026-06-06 00:36:55 +02:00
count = 2 ;
cr . sample ( ) ; // two gated (2>3 false)
2026-06-05 15:35:01 +02:00
`checkr ( cr . get_inst_coverage ( ) , 50.0 ) ;
// cg_bitw: (m_a & m_b) == 2'b10
2026-06-06 00:36:55 +02:00
m_a = 2 'b10 ;
m_b = 2 'b11 ;
count = 7 ;
cb . sample ( ) ; // seven hit
2026-06-05 15:35:01 +02:00
`checkr ( cb . get_inst_coverage ( ) , 100.0 ) ;
2026-06-06 00:36:55 +02:00
m_a = 2 'b00 ;
m_b = 2 'b11 ;
count = 7 ;
cb . sample ( ) ; // gated
2026-06-05 15:35:01 +02:00
`checkr ( cb . get_inst_coverage ( ) , 100.0 ) ;
$write ( " *-* All Finished *-* \n " ) ;
$finish ;
end
endmodule