Number of set bits ('b1) in 8 bit random variable should be grater than 3 is failed with the following error

Wrote the following code to generate the 8 bit random variable which should have more than 3 bits set as 'b1.
It is working when I set the count to be less than any value between 0-8.
But when I set the constraint to count >3, the simulator reports the following error:

module array_methods();
class stbits;
rand bit [7:0] arr;
int i;
int count='d0;

constraint set_bit_cnt {(count > 'd3 );}

function void bitcnt();
foreach(this.arr[i]) begin
 if(this.arr[i] == 'b1)
  this.count = this.count+'d1; end
endfunction

function void post_randomize();
  this.bitcnt();
endfunction 
endclass

initial begin
stbits sb;
sb = new();
if(sb.randomize())
$display("randomization successful");
foreach(sb.arr[i])
$display("The generated arr values are %b",sb.arr[i]);
end
endmodule

SIMULATION RESULT:
ncsim> run
if(sb.randomize())
|
ncsim: *W,SVRNDF (./set_bits.sv,24|14): The randomize method call failed.
Observed simulation time : 0 FS + 0
ncsim: *W,RNDOCS: These constraints contribute to the set of conflicting constraints:

constraint set_bit_cnt {(count > 'd3 );} (./set_bits.sv,8)
ncsim: *W,RNDOCS: These variables contribute to the set of conflicting constraints:

int count='d0; (./set_bits.sv,6)
(The current value of the state variable ‘count’ is 0)
THe generated arr values are 0
THe generated arr values are 0
THe generated arr values are 0
THe generated arr values are 0
THe generated arr values are 0
THe generated arr values are 0
THe generated arr values are 0
THe generated arr values are 0

Take a look at this post and see if it answers your question.

In reply to cgales:

Thank u for the answer.I tried the referred post/link way, a compilation error is generated
ERROR: As a temporary implementation restriction, the source data type in a static cast must be an integral, real or class data type.

I suppose this is a tool issue.

But is there anything wrong in the above code(first post) or is it again a tool issue?.

In reply to nagar975:

count is not a rand variable, but all constraints must be met before calling post_randomize(). Since count is initially 0, it cannot meet the constraint that its value must be greater than 3.

You can write

constraint set_bit_cnt {(('d0 + arr[0] + arr[1] + arr[2] + arr[3] + arr[4] + arr[5] + arr[6] + arr[7] ) > 'd3 );}

The 'd0 + is make the addition result a 32-bit value. Other wise the sum is a 1 bit result.

In reply to dave_59:

Thanks dave, with the suggested solution it is working fine.
I figured out the following things from the above solution,

1)There is no need/use of writing the function(function void bitcnt();) to find out no of 'b1’s and call it in post_randomization.
2)The randomization solver works like, pre_randomize()->randomize()-> solve the constraints ->post_randomize()
my earlier assumption was {pre_randomize()->randomize()-> post_randomize()->solve the constraints} repeat this till the constraints are satisfied.
which is the reason I called bit counter function in post randomize, which also a reason it was not working earlier.

are my assumptions valid?.

In reply to nagar975:

Yes. More accurately, calling randomize() first calls pre_randomize, then solves the constraints, then call post_randomize().

In reply to nagar975:

Hi,
Here my two cents.
I find the solution provided in other thread important to be mentioned. That solution is in my opinion longer but quite more efficient than leaving the count function in the constraint solver.

That solution is about creating a vector of indices that you can shuffle, and then randomize the number of index you want to take from that vector to insert the ones. Take in mind that this doesn´t require any constraint and it doesn´t force the solver with try and error but just plain loops.

Here i present an example function where you can configure the max number of ones inside 3 vectors of 32,32 and 128bits respectively and that will be concatenated in one single vector.


    function logic[BLK_AIRQC_NUM_IRQS-1:0] randomize_irq(int max_int_ones=15,int max_ext_ones=15,int max_sgi_ones=20);
        automatic logic [BLK_AIRQC_NUM_IRQS-1:0] all_irqs_after_randomization=0;
        automatic int  irqs_128index_arr[BLK_AIRQC_NUM_IRQ_INT_G];
        automatic int  irqs_32index_arr[BLK_AIRQC_NUM_IRQ_EXT_G];
        automatic logic [BLK_AIRQC_NUM_IRQ_INT_G-1:0] int_irqs=0;        
        automatic logic [BLK_AIRQC_NUM_IRQ_EXT_G-1:0] ext_irqs=0;        
        automatic logic [BLK_AIRQC_NUM_IRQ_SGI_G-1:0] sgi_irqs=0;
        automatic int random_number_of_ones;
        //allirqs= (MSB) sgi , ext , int (LSB)
        //Initialization of indices
        foreach(irqs_32index_arr[i]) begin
            irqs_32index_arr[i]=i;//put indices on each element value
        end
        foreach(irqs_128index_arr[i]) begin
            irqs_128index_arr[i]=i;//put indices on each element value
        end
        //end of initialization
        //////////////////////
        
        irqs_32index_arr.shuffle;//randomize the order of the array or indices        
        assert(std::randomize() with {random_number_of_ones dist  {['h1:max_ext_ones]:=100, 0:=0,['h0:32]:=50};});            
        for (int unsigned i=0; i<random_number_of_ones; i++) begin//now use the n first indices to put ones
            ext_irqs[irqs_32index_arr[i]]=1;//put ones for IRQs using the index from the shuffled vector            
        end
        irqs_32index_arr.shuffle;//randomize the order of the array or indices
        assert(std::randomize(random_number_of_ones) with {random_number_of_ones dist  {['h1:max_sgi_ones]:=100, 0:=0,['h0:32]:=50};});
        for (int unsigned i=0; i<random_number_of_ones; i++) begin
            sgi_irqs[irqs_32index_arr[i]]=1;//put ones for IRQs using the index from the shuffled vector            
        end
        irqs_128index_arr.shuffle;//randomize the order of the array or indices
        assert(std::randomize(random_number_of_ones) with {random_number_of_ones dist  {['h1:max_int_ones]:=100, 0:=0,['h0:128]:=30};});
        for (int unsigned i=0; i<random_number_of_ones; i++) begin
            int_irqs[irqs_128index_arr[i]]=1;//put ones for IRQs using the index from the shuffled vector            
        end
        all_irqs_after_randomization = {sgi_irqs, ext_irqs, int_irqs};
        return all_irqs_after_randomization;        
    endfunction


I hope it helps
Jonathan