Question:
Array 1, Array 2, randomize them make sure all entries within array are unique. generate array1 and array2 such that at-least one element is common between two arrays.
variable 1 should take random value which is part of both arrays
For example
If array1 randomized to : '{12, 2, -2, 4, 6, 10, 1, 0}
If array2 randomized to : '{1, 5, 7, 12, 0, 20}
Then value1 should take random value inside {1, 12, 0} all with equal weight 33.33%
for simplicity you can take assumptions, for example array length will be random but max 10 elements etc etc
Solution:
class Card;
rand int array1 [];
rand int array2 [];
rand int var1;
int q [$];
// To keep track of common entires across arrays
rand int dummy[];
// Unique
constraint c_array1 {
array1.size() inside {[1:10]};
unique{array1};
foreach(array1[i])
array1[i] inside {[-10:10]};
};
constraint c_array2 {
array2.size() inside {[1:10]};
unique{array2};
foreach(array2[i])
array2[i] inside {[-10:10]};
};
// At-least one element is common between two arrays
constraint c_common {
foreach(array1[i]) {
foreach(array2[ii]){
if (array1.size()>=array2.size()){
dummy[i]==(array1[i]==array2[ii]);
} else {
dummy[ii]==(array1[i]==array2[ii]);
}
}
}
dummy.size() == ((array1.size() >= array2.size()) ? array1.size() : array2.size());
dummy.sum() > 0;
};
function void post_randomize ();
foreach(array1[i])
foreach(array2[ii])
if (array1[i]==array2[ii])
q.push_back(array1[i]);
std::randomize(var1) with {var1 inside {q};};
endfunction
endclass
module tb;
Card card;
initial begin
repeat(5) begin
card = new();
card.randomize();
$display("###############");
$display ("# ARRAY1 is");
foreach(card.array1[i])
$display("%0d",card.array1[i]);
$display("###############");
$display ("# ARRAY2 is");
foreach(card.array2[i])
$display("%0d",card.array2[i]);
$display("###############");
$display ("# DUMMY is");
foreach(card.dummy[i])
$display("%0d",card.dummy[i]);
$display("###############");
$display ("# Q is");
foreach(card.q[i])
$display("%0d",card.q[i]);
$display("###############");
$display("# VAR1 is %0d #",card.var1);
$display("###############\n\n\n");
end
end
endmodule
Issue:
Sometimes it solves the constraint and sometimes it does not (gives constraint solver errors).
1. When constraint solves, it generates valid output, for example:
###############
ARRAY1 is
2
###############
ARRAY2 is
2
-8
4
###############
DUMMY is
1
0
0
###############
Q is
2
###############
VAR1 is 2
###############
2. When constraint does not resolve, Full error is shown below:
=======================================================
Solver failed when solving following set of constraints
rand integer array1[0]; // rand_mode = ON
rand integer array1[1]; // rand_mode = ON
rand integer array1[2]; // rand_mode = ON
rand integer array1[3]; // rand_mode = ON
rand integer array1[4]; // rand_mode = ON
rand integer array1[5]; // rand_mode = ON
rand integer array1[6]; // rand_mode = ON
rand integer array1[7]; // rand_mode = ON
rand integer array1[8]; // rand_mode = ON
rand integer array1[9]; // rand_mode = ON
rand integer array2[0]; // rand_mode = ON
rand integer array2[1]; // rand_mode = ON
rand integer array2[2]; // rand_mode = ON
rand integer array2[3]; // rand_mode = ON
rand integer array2[4]; // rand_mode = ON
rand integer dummy[0]; // rand_mode = ON
rand integer dummy[1]; // rand_mode = ON
rand integer dummy[2]; // rand_mode = ON
rand integer dummy[3]; // rand_mode = ON
rand integer dummy[4]; // rand_mode = ON
rand integer dummy[5]; // rand_mode = ON
rand integer dummy[6]; // rand_mode = ON
rand integer dummy[7]; // rand_mode = ON
rand integer dummy[8]; // rand_mode = ON
rand integer dummy[9]; // rand_mode = ON
constraint c_array2 // (from this) (constraint_mode = ON) (testbench.sv:31)
{
unique {array2[0], array2[1], array2[2], array2[3], array2[4]};
}
constraint c_common // (from this) (constraint_mode = ON) (testbench.sv:39)
{
((32’((((((((((dummy[0] + dummy[1]) + dummy[2]) + dummy[3]) + dummy[4]) + dummy[5]) + dummy[6]) + dummy[7]) + dummy[8]) + dummy[9]))) > 0);
(dummy[0] == (array1[0] == array2[0]));
(dummy[0] == (array1[0] == array2[1]));
(dummy[1] == (array1[1] == array2[3]));
(dummy[1] == (array1[1] == array2[4]));
(dummy[2] == (array1[2] == array2[0]));
(dummy[2] == (array1[2] == array2[4]));
(dummy[3] == (array1[3] == array2[0]));
(dummy[3] == (array1[3] == array2[1]));
(dummy[4] == (array1[4] == array2[3]));
(dummy[4] == (array1[4] == array2[4]));
(dummy[5] == (array1[5] == array2[0]));
(dummy[5] == (array1[5] == array2[4]));
(dummy[6] == (array1[6] == array2[0]));
(dummy[6] == (array1[6] == array2[1]));
(dummy[7] == (array1[7] == array2[3]));
(dummy[7] == (array1[7] == array2[4]));
(dummy[8] == (array1[8] == array2[0]));
(dummy[8] == (array1[8] == array2[4]));
(dummy[9] == (array1[9] == array2[0]));
(dummy[9] == (array1[9] == array2[1]));
}
=======================================================
Info-[CNST-SATE] A standalone test-case for this failure has automatically been extracted
from randomize serial 1 partition 2.
To reproduce the error using the extracted testcase, please use the
following command:
cd /home/runner/./simv.cst/testcases;
vcs -sverilog extracted_r_1_p_2_inconsistent_constraints.sv -R
To reproduce the error using the original design and verbose logging, re-run
simulation using:
simv +ntb_solver_debug=trace +ntb_solver_debug_filter=1
To reproduce the error using the original design and debug the error with
Verdi/DVE:
- re-compile the original design with -debug_access+all, if not already
done so
% vcs -debug_access+all - re-run the simulation interactively with -gui/-verdi
% simv -gui/-verdi - enter the following commands to begin interactive constraint
inconsistency debug within Verdi/DVE
I. set the breakpoint: verdi/dve> stop -solver -serial 1
II. run the simulation till it stops: verdi/dve> run
III. step in the constraint solver: verdi/dve> step -solver
Error-[CNST-CIF] Constraints inconsistency failure
testbench.sv, 69
Constraints are inconsistent and cannot be solved.
Please check the inconsistent constraints being printed above and rewrite
them.
Tool:
Additional question:
Funny thing is if I replace c_array# constraint code:
foreach(array#[i])
array#[i] inside {[-10:10]};
with
foreach(array#[i])
array#[i] inside {[0:10]};
Then simulator just hangs forever, no errors no displays.
NOTE:
I am more interested on why this logic does not work, rather than alternative solutions. Thank you.