verilator/test_regress/t/t_constraint_struct_complex.v

183 lines
5.9 KiB
Systemverilog
Raw Normal View History

// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2025 by PlanV GmbH.
// SPDX-License-Identifier: CC0-1.0
class ArrayStruct;
/* verilator lint_off SIDEEFFECT */
// Struct with an unpacked array
typedef int arr_3_t[3];
typedef int arr_4_t[4];
typedef struct {
rand arr_3_t arr_3;
arr_4_t arr_4;
rand int arr[3];
} unpacked_struct_t;
// Struct with a dynamic array
typedef struct {
rand int arr[];
} dynamic_struct_t;
// Struct with a queue
typedef struct {
rand int arr[$];
} queue_struct_t;
// Struct with an associative array (string as index)
typedef struct {
rand int arr[string];
} associative_struct_t;
// Struct with a multi-dimensional array
typedef struct {
rand int arr[2][3];
} multi_dim_struct_t;
// Struct with a mix of dynamic and unpacked arrays
typedef struct {
rand int mix_arr[3][];
} mixed_struct_t;
rand unpacked_struct_t s1;
rand dynamic_struct_t s2;
rand queue_struct_t s3;
rand associative_struct_t s4;
rand multi_dim_struct_t s5;
rand mixed_struct_t s6;
constraint c_unpacked {
foreach (s1.arr[i]) s1.arr[i] inside {1, 2, 3, 4};
foreach (s1.arr_3[i]) s1.arr_3[i] inside {11, 22, 33, 44, 55};
}
constraint c_dynamic { foreach (s2.arr[i]) s2.arr[i] inside {[10:20]}; }
constraint c_queue { foreach (s3.arr[i]) s3.arr[i] inside {[100:200]}; }
constraint c_assoc {
s4.arr["one"] inside {[10:50]};
s4.arr["two"] inside {[51:100]};
s4.arr["three"] inside {[101:150]};
}
constraint c_multi_dim { foreach (s5.arr[i, j]) s5.arr[i][j] inside {[0:9]}; }
constraint c_mix {
foreach (s6.mix_arr[i, j]) s6.mix_arr[i][j] inside {[50:100]};
}
function new();
s1.arr = '{1, 2, 3};
s1.arr_3 = '{1, 2, 3};
s1.arr_4 = '{0, 2, 3, 4};
s2.arr = new[3];
foreach(s2.arr[i]) begin
s2.arr[i] = 'h0 + i;
end
s3.arr.push_back(100);
s3.arr.push_back(200);
s3.arr.push_back(300);
s4.arr["one"] = 1000;
s4.arr["two"] = 2000;
s4.arr["three"] = 3000;
s5.arr = '{ '{default:0}, '{default:0} };
foreach (s6.mix_arr[i]) begin
s6.mix_arr[i] = new[i + 1];
end
endfunction
function void print();
foreach (s1.arr[i]) $display("s1.arr[%0d] = %0d", i, s1.arr[i]);
foreach (s1.arr_3[i]) $display("s1.arr_3[%0d] = %0d", i, s1.arr_3[i]);
foreach (s1.arr_4[i]) $display("s1.arr_4[%0d] = %0d", i, s1.arr_4[i]);
foreach (s2.arr[i]) $display("s2.arr[%0d] = %0d", i, s2.arr[i]);
foreach (s3.arr[i]) $display("s3.arr[%0d] = %0d", i, s3.arr[i]);
foreach (s4.arr[i]) $display("s4.arr[\"%s\"] = %0d", i, s4.arr[i]);
foreach (s5.arr[i, j]) $display("s5.arr[%0d][%0d] = %0d", i, j, s5.arr[i][j]);
foreach (s6.mix_arr[i, j]) $display("s6.mix_arr[%0d][%0d] = %0d", i, j, s6.mix_arr[i][j]);
endfunction
// Self-test function to verify constraints
function void self_test();
foreach (s1.arr[i]) if (!(s1.arr[i] inside {1, 2, 3, 4})) $stop;
foreach (s1.arr_3[i]) if (!(s1.arr_3[i] inside {11, 22, 33, 44, 55})) $stop;
// Note: s1.arr_4[0] is not rand
if ((s1.arr_4[0] != 0) || (s1.arr_4[1] != 2) || (s1.arr_4[2] != 3) || (s1.arr_4[3] != 4)) $stop;
foreach (s2.arr[i]) if (!(s2.arr[i] inside {[10:20]})) $stop;
foreach (s3.arr[i]) if (!(s3.arr[i] inside {[100:200]})) $stop;
if (!(s4.arr["one"] inside {[10:50]})) $stop;
if (!(s4.arr["two"] inside {[51:100]})) $stop;
if (!(s4.arr["three"] inside {[101:150]})) $stop;
foreach (s5.arr[i, j]) if (!(s5.arr[i][j] inside {[0:9]})) $stop;
foreach (s6.mix_arr[i]) if (s6.mix_arr[i].size() == 0) $stop;
foreach (s6.mix_arr[i, j]) if (!(s6.mix_arr[i][j] inside {[50:100]})) $stop;
endfunction
/* verilator lint_off SIDEEFFECT */
endclass
class StructArray;
/* verilator lint_off WIDTHTRUNC */
typedef struct {
rand int arr[3];
rand int a;
rand bit [3:0] b;
bit c;
} struct_t;
rand struct_t s_arr[2];
constraint c_structArray_0 {
foreach (s_arr[i])
foreach (s_arr[i].arr[j])
s_arr[i].arr[j] inside {[0:9]};
}
constraint c_structArray_1 {
foreach (s_arr[i]) s_arr[i].a inside {[10:20]};
}
function new();
foreach (s_arr[i]) begin
foreach (s_arr[i].arr[j]) s_arr[i].arr[j] = 'h0 + j;
s_arr[i].a = 'h10 + i;
s_arr[i].b = 'h0 + i;
s_arr[i].c = i;
end
endfunction
function void print();
foreach (s_arr[i]) begin
foreach (s_arr[i].arr[j]) $display("s_arr[%0d].arr[%0d] = %0d", i, j, s_arr[i].arr[j]);
$display("s_arr[%0d].a = %0d", i, s_arr[i].a);
$display("s_arr[%0d].b = %0d", i, s_arr[i].b);
$display("s_arr[%0d].c = %0d", i, s_arr[i].c);
end
endfunction
function void self_test();
foreach (s_arr[i]) begin
foreach (s_arr[i].arr[j]) if (!(s_arr[i].arr[j] inside {[0:9]})) $stop;
if (!(s_arr[i].a inside {[10:20]})) $stop;
if (!(s_arr[0].c == 0)) $stop;
if (!(s_arr[1].c == 1)) $stop;
end
endfunction
/* verilator lint_off WIDTHTRUNC */
endclass
module t_constraint_struct_complex;
int success;
ArrayStruct as_c;
StructArray sa_c;
initial begin
as_c = new();
sa_c = new();
success = as_c.randomize();
if (success != 1) $stop;
as_c.self_test();
// as_c.print();
success = sa_c.randomize();
if (success != 1) $stop;
sa_c.self_test();
// sa_c.print();
$write("*-* All Finished *-*\n");
$finish;
end
endmodule