2026-03-04 18:01:35 +01:00
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 by Wilson Snyder and Contributors
// SPDX-License-Identifier: CC0-1.0
// Test case for array reduction methods with 'with' clause in constraints (issue #6455)
2026-03-05 02:12:10 +01:00
// verilog_format: off
2026-03-04 18:01:35 +01:00
`define stop $stop
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
2026-03-05 02:12:10 +01:00
// verilog_format: on
2026-03-04 18:01:35 +01:00
class test_sum ;
rand byte array [ 5 ] ;
rand byte repeated_value ;
constraint c {
// Ensure exactly 3 occurrences of repeated_value using sum
2026-03-05 02:12:10 +01:00
array . sum ( ) with ( int ' ( item = = repeated_value ) ) = = 3 ;
2026-03-04 18:01:35 +01:00
// All other values should appear exactly once
2026-03-05 02:12:10 +01:00
foreach ( array [ i ] ) {
array [ i ] ! = repeated_value - > array . sum ( ) with ( int ' ( item = = array [ i ] ) ) = = 1 ;
2026-03-04 18:01:35 +01:00
}
}
function void verify ( ) ;
int count_map [ byte ] ;
int repeated_count = 0 ;
int i ;
i = randomize ( ) ;
`checkd ( i , 1 ) ;
// Count occurrences
foreach ( array [ idx ] ) begin
if ( ! count_map . exists ( array [ idx ] ) ) count_map [ array [ idx ] ] = 0 ;
count_map [ array [ idx ] ] + + ;
end
// Check repeated_value appears exactly 3 times
if ( count_map . exists ( repeated_value ) ) begin
repeated_count = count_map [ repeated_value ] ;
if ( repeated_count ! = 3 ) begin
$display ( " %%Error: sum test - repeated_value=%0d appears %0d times, expected 3 " ,
repeated_value , repeated_count ) ;
$stop ;
end
2026-03-05 02:12:10 +01:00
end
else begin
2026-03-04 18:01:35 +01:00
$display ( " %%Error: sum test - repeated_value=%0d doesn't appear in array " , repeated_value ) ;
$stop ;
end
// Check all other values appear exactly once
foreach ( count_map [ val ] ) begin
if ( val ! = repeated_value & & count_map [ val ] ! = 1 ) begin
2026-03-05 02:12:10 +01:00
$display ( " %%Error: sum test - value=%0d appears %0d times, expected 1 " , val ,
count_map [ val ] ) ;
2026-03-04 18:01:35 +01:00
$stop ;
end
end
endfunction
endclass
class test_product ;
rand bit [ 3 : 0 ] array [ 4 ] ;
constraint c {
// Product of non-zero elements should be <= 100
array . product ( ) with ( item ! = 0 ? int ' ( item ) : 1 ) < = 100 ;
// At least 2 non-zero elements
array . sum ( ) with ( int ' ( item ! = 0 ) ) > = 2 ;
}
function void verify ( ) ;
int prod = 1 ;
int nonzero_count = 0 ;
int i ;
i = randomize ( ) ;
`checkd ( i , 1 ) ;
foreach ( array [ idx ] ) begin
if ( array [ idx ] ! = 0 ) begin
prod * = array [ idx ] ;
nonzero_count + + ;
end
end
if ( prod > 100 ) begin
$display ( " %%Error: product test - product %0d > 100 " , prod ) ;
$stop ;
end
if ( nonzero_count < 2 ) begin
$display ( " %%Error: product test - only %0d non-zero elements " , nonzero_count ) ;
$stop ;
end
endfunction
endclass
class test_and ;
rand bit [ 7 : 0 ] array [ 3 ] ;
constraint c {
// AND of all elements with a mask should equal specific value
array . and ( ) with ( item & 8 'hF0 ) = = 8 'h50 ;
}
function void verify ( ) ;
bit [ 7 : 0 ] result = 8 'hFF ;
int i ;
i = randomize ( ) ;
`checkd ( i , 1 ) ;
foreach ( array [ idx ] ) begin
result & = ( array [ idx ] & 8 'hF0 ) ;
end
if ( result ! = 8 'h50 ) begin
$display ( " %%Error: and test - result 0x%0h != 0x50 " , result ) ;
$stop ;
end
endfunction
endclass
class test_or ;
rand bit [ 7 : 0 ] array [ 3 ] ;
constraint c {
// OR of specific bits should set bit 3
( array . or ( ) with ( item & 8 'h08 ) ) = = 8 'h08 ;
// At least one element has bit 3 set
array . sum ( ) with ( int ' ( ( item & 8 'h08 ) ! = 0 ) ) > = 1 ;
}
function void verify ( ) ;
bit [ 7 : 0 ] result = 8 'h00 ;
int i ;
i = randomize ( ) ;
`checkd ( i , 1 ) ;
foreach ( array [ idx ] ) begin
result | = ( array [ idx ] & 8 'h08 ) ;
end
if ( result ! = 8 'h08 ) begin
$display ( " %%Error: or test - result 0x%0h != 0x08 " , result ) ;
$stop ;
end
endfunction
endclass
class test_xor ;
rand bit [ 7 : 0 ] array [ 4 ] ;
constraint c {
// XOR of all elements should be non-zero (parity check)
array . xor ( ) with ( item ) ! = 0 ;
// Ensure some variation
array . sum ( ) with ( int ' ( item ! = 0 ) ) > = 2 ;
}
function void verify ( ) ;
bit [ 7 : 0 ] result = 8 'h00 ;
int i ;
i = randomize ( ) ;
`checkd ( i , 1 ) ;
foreach ( array [ idx ] ) begin
result ^ = array [ idx ] ;
end
if ( result = = 0 ) begin
$display ( " %%Error: xor test - result is 0 " ) ;
$stop ;
end
endfunction
endclass
module t ;
test_sum sum_inst ;
test_product product_inst ;
test_and and_inst ;
test_or or_inst ;
test_xor xor_inst ;
initial begin
// Test sum
sum_inst = new ( ) ;
repeat ( 20 ) sum_inst . verify ( ) ;
$display ( " sum test PASSED " ) ;
// Test product
product_inst = new ( ) ;
repeat ( 20 ) product_inst . verify ( ) ;
$display ( " product test PASSED " ) ;
// Test and
and_inst = new ( ) ;
repeat ( 20 ) and_inst . verify ( ) ;
$display ( " and test PASSED " ) ;
// Test or
or_inst = new ( ) ;
repeat ( 20 ) or_inst . verify ( ) ;
$display ( " or test PASSED " ) ;
// Test xor
xor_inst = new ( ) ;
repeat ( 20 ) xor_inst . verify ( ) ;
$display ( " xor test PASSED " ) ;
$write ( " *-* All Finished *-* \n " ) ;
$finish ;
end
endmodule