Ask a question about constraint with functions

I have below constraint in my test but it failed at sim_run when solving it… I know it’s not correct but have no idea how to implement it…


class my_item extends uvm_object;

        rand bit [17:0] my_addr;
        rand bit [3:0]  size[4];
        rand bit [17:0] base[4];
        rand bit [17:0] gen_addr;
        
        constraint my_cons {
        
            foreach (base[i])
                is_my_decode(base[i]) == 0;               // is_my_decode is a known function
            foreach (base[i])
                is_ip_domain(base[i]) == 1;               // is_ip_domain is a known function      

            gen_addr inside {my_gen_addr};                // my_gen_addr is a known array

            my_addr  dist { gen_addr :/ 1 , 
                            [base[0]:base[0]+size[0]] :/1 ,
                            [base[1]:base[1]+size[1]] :/1 ,
                            [base[2]:base[2]+size[2]] :/1 ,
                            [base[3]:base[3]+size[3]] :/1 };
        
          }

endclass : my_item

From my understanding, the reason of the failure is as described below (please correct me if I am wrong)

First, the base will be solved with below expression:


            my_addr  dist { gen_addr :/ 1 , 
                            [base[0]:base[0]+size[0]] :/1 ,
                            [base[1]:base[1]+size[1]] :/1 ,
                            [base[2]:base[2]+size[2]] :/1 ,
                            [base[3]:base[3]+size[3]] :/1 };

And then the results will be input to is_my_decode and is_ip_domain function. If any of the function call return false, my constraint is failed.

Thank you for any help !

In reply to zz8318:

You are correct. Random variables used as inputs to functions get solved first, then the outputs become non-random state values.

The only way around this is eliminating the function by re-writing it as an in-line expression, or creating a a lookup array with the values you are looking for:

bit [17:0] my_decode[$], ip_domain[$];
...
for(int i=0;i<=18'h3FFFF;i++) begin
    if (is_my_decode(i) == 0 ) my_decode.push_back(i);
    if (is_ip_domain(i) == 0 ) ip_domain.push_back(i);
end

constraint my_cons {
  foreach (base[i]) {
                base[i] inside { my_decode } ;
                base[i] inside { ip_decode } ;
...
  }

Unfortunately this might mean each array could wind up with 218 elements. If the functions do not need all 18-bits, you could reduce the size of the array.

In reply to dave_59:
Thanks Dave. I tried the similar way to solve it yesterday. Thank you