Square number using Constraint Randomization

I want to make the constraint such that it will give me only the square of that number.
Here is the constraint what I have written.

rand byte unsigned a;
constraint c1{foreach(a[i]) a[i]==a[i]*a[i];}

Is this the correct way to write because I am not getting the expected output.

I think a[i] in both, LHS and RHS of constraint might cause an issue.

There can be multiple ways to address this. One way which strikes me first (might not be the most optimized one), is using a temporary array and substituting squared values in the main array.

class A;
rand byte unsigned a[];
rand byte unsigned temp[]; // temporary array
rand int unsigned a_size; // determines size of array
constraint c1{  foreach(a*) 
                {
                  a[i]==temp[i]*temp[i];
                  // temp[i] inside {[1:5]}; // use some range for which squares are required
                  unique {temp};             // use unique, for each unique entry in array 
                }
                a.size == a_size;
                temp.size == a_size;  // size of temp must be same as main array size
                a_size inside {[1:5]};
                solve temp, a_size before a;
             }
endclass

Or you can generate any random values in the main array and use [i]post-randomize* function to square each entry. This method won’t require any temporary array substitution:

class A;
rand byte unsigned a[];
rand int unsigned a_size;
constraint c1{  foreach(a[i]) 
                {
                  a[i] inside {[1:5]}; // generate any values
                }
                a.size == a_size;
                a_size inside {[1:5]};
                solve a_size before a;
             }

function void post_randomize(); 
foreach(a[i])
  a[i] = a[i]*a[i]; // squaring here
endfunction

In reply to Huzefa Halolwala:

You can even try this out.



module top;

    class base;
      
      rand bit[7:0] a[];
      constraint a_cn
      {
        a.size == 10;
        foreach(a[i])
        {
          a[i] == (i+1) ** 2;
         
        }
      }
          
       function void post_randomize();
         a.shuffle(); 
       endfunction
    endclass
            
    initial begin
      base b;
      b = new();
      b.randomize();
      foreach(b.a[i])
        $display("%0d",b.a[i]);
    end
endmodule

In reply to Alay Patel:

What is the use of a.shuffle ?

In reply to Huzefa Halolwala:

In reply to Alay Patel:
What is the use of a.shuffle ?

If you look at the constraint, it will generate the squared number in ascending order like 1,4,9 etc… So shuffle method will change the order of each and every element of the dynamic array as if they are generated randomly.

Please run the above code with and without the post_randomize method. You will get to know about it.