verilator/test_regress/t/t_constraint_array_reductio...

76 lines
2.3 KiB
Systemverilog

// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 PlanV GmbH
// SPDX-License-Identifier: CC0-1.0
// Test array reduction methods in constraints with class inheritance (issue #7226)
// The bug was that .sum() in a constraint crashed with "Can't locate varref scope"
// when the class extends another class.
// verilog_format: off
`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);
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
// verilog_format: on
class Base;
rand int base_val;
constraint c_base {base_val inside {[1:100]};}
endclass
// Derived class with dynamic array and .sum() constraint -- the crash scenario
class Derived extends Base;
rand int arr[];
constraint c_size {arr.size() == 4;}
constraint c_sum {arr.sum() == 200;}
function new();
arr = new[4];
endfunction
endclass
// Multi-level inheritance: ensure deeper hierarchies also work
class GrandChild extends Derived;
rand bit [7:0] extra[3];
constraint c_extra_or {extra.or() != 0;}
endclass
module t;
initial begin
static Derived d = new();
static GrandChild g = new();
int sum_check;
// Test single-level inheritance with .sum()
repeat (5) begin
`checkd(d.randomize(), 1)
`checkd(d.arr.size(), 4)
sum_check = 0;
foreach (d.arr[i]) sum_check += d.arr[i];
`checkd(sum_check, 200)
`checkd(d.base_val inside {[1:100]}, 1)
end
// Test multi-level inheritance with reduction on fixed array
repeat (5) begin
bit [7:0] or_check;
`checkd(g.randomize(), 1)
`checkd(g.arr.size(), 4)
sum_check = 0;
foreach (g.arr[i]) sum_check += g.arr[i];
`checkd(sum_check, 200)
or_check = 0;
foreach (g.extra[i]) or_check |= g.extra[i];
if (or_check == 0) begin
$write("%%Error: %s:%0d: extra.or() should be nonzero\n", `__FILE__, `__LINE__);
`stop;
end
`checkd(g.base_val inside {[1:100]}, 1)
end
$write("*-* All Finished *-*\n");
$finish;
end
endmodule