Hi, I run this code in QuestaSim but it has an error. Can anyone help me why this randomization failed?

class Packet;
rand bit p[2048];
int sum=0;
function int total(bit p[2048]);
for (int i=0;i<2048;i++)
sum = sum + p[i];
endfunction
constraint c_stim{
total(p)==256;
}
endclass:Packet

Calling user defined functions in a constraint break the solution space in that the random variables as inputs to the function must choose their values first. Then the return value of the function becomes a non-random state variable. The constraint solver is not required to keep trying different inputs to make sure its return value satisfies the remaining constraint (==256).

Also functions used in constraint must be “pure” they cannot reference or modify variables outside their scope. Imagine the behavior if there were multiple calls to your function total.

And finally, the LRM does not allow references to random variables that are aggregate arrays without using an iterative construct like foreach or sum reduction method that can be unrolled into a set of boolean equations.

Hi, Observed your code from top to bottom. There are loads of things to say and there are few speculations of mine.
1)You have called a user-defined method which will be acting after the randomization method and will return a value. That’s why you might get the right result but most of the time, you will get the wrong one.
2)It’s the dynamic array you are using. So in order to get the proper answer you have to use system defined method (array_manipulation). You gotta use p.sum().
3)Now return type of the sum will be depending upon the variable type you are dealing with. Here variable type is a bit. So you will get either 1 or 0.
4)Now finally, to get rid of all of these hindrances, you have to use the int variable. I tried to do so in the following code.

class Packet;
rand int p[20];
constraint values{
foreach(p[i])
p[i] inside {[0:1]};
}
constraint c_stim{
p.sum()==13;
}
endclass:Packet
module test;
Packet P=new;
initial begin
assert(P.randomize)
$display("%p",P.p);
end
endmodule
// Another way
class Packet;
rand bit[3:0][7:0] p[20];
rand bit[31:0]p1[20];
//rand int unsigned p1[20]; // by-defualt signed
constraint values{
foreach(p[i])
p[i] inside {[0:1024]};
}
constraint c_stim{
p.sum()>1352;
}
constraint eq{p[5] == p1[5];p[5]<=105 && p[5] >=99;} //extra ; some observation ;
endclass:Packet
module test;
Packet P=new;
initial begin
assert(P.randomize)
$display("%p",P.p);
$display("%0p",P.p1);
end
endmodule

Now go through it gingerly.
I have one tiny little problem here. During declaring the array, instead of using rand int along with constraint values, when I was using rand unsigned int along with no such values constraint, I was getting garbage value. WHY?

If you remove the constraint values, the constraint solver is giving you back values that satisfy the other active constraints. You need to plug in the “garbage values” into the constraint equation and see that it does in fact satisfy those constraints.

Hello sir, I have clarity of that. But that will happen in case of signed int (rand int p[20]) . In case of unsigned int declaration (rand int unsigned p[20]) , it’s giving garbage values which is not satisfying the constraint (2nd one) .
I should have got series of 0s and 1s.

Ok, Got it. Numbers are made of 32 bits, but the summation consists of more than 32 bits. As we are taking int variable that’s why we’ll be getting the sum result up to the 32nd bit. And the answer is 13. Hope I got it correct.

Ok, Got it. Numbers are made of 32 bits, but the summation consists of more than 32 bits. As we are taking int variable that’s why we’ll be getting the sum result up to the 32nd bit. And the answer is 13. Hope I got it correct.