Constraint problem

Hi all, here is my code. the simulator shows that Constraints are inconsistent and cannot be solved. What is the reason of that?
Thanks



class packet;
  randc bit [1:0] addr;
  randc bit [1:0] start_addr;
  randc bit [1:0] end_addr;
   
  constraint addr_1_range { addr inside {[start_addr:end_addr]}; }
endclass
 
module constr_inside;
  initial begin
    packet pkt;
    pkt = new();
    repeat(5) begin
      pkt.randomize();
      $display("\tstart_addr = %0d,end_addr = %0d",pkt.start_addr,pkt.end_addr);
      $display("\taddr = %0d",pkt.addr);

    end
  end
endmodule


In reply to peter:

I ran the same code on edaplayground (check the link for tool version), and there were no problems.

Output :
start_addr = 0,end_addr = 3
addr = 1
start_addr = 2,end_addr = 3
addr = 3
start_addr = 1,end_addr = 1
addr = 1
start_addr = 0,end_addr = 3
addr = 3
start_addr = 2,end_addr = 3
addr = 2

Could be a possible simulator issue and get in touch with your AE ?

In reply to KillSteal:

There is a problem when you have multiple randc variables with interconnected constraints. The solver has to order randc variable and that could cause randomize() to fail. Notice in the results you are getting for the values of
end_addr
are not cyclic. If the
repeat
loop gets extended, you notice that none of the variables have cyclic values. So it seems some tools are ignoring the randc modifier and just making the variables rand.

In reply to peter:

Please add beelow constraint to ur existing code to solve constraint solver issue.
constraint add_2_range{end_addr >= start_addr ;}

class packet;
randc bit [1:0] addr;
randc bit [1:0] start_addr;
randc bit [1:0] end_addr;

constraint addr_1_range { addr inside {[start_addr:end_addr]}; }
constraint add_2_range{end_addr >= start_addr ;}
endclass

module constr_inside;
initial begin
packet pkt;
pkt = new();
repeat(100) begin
pkt.randomize();
$display(“\tstart_addr = %0d,end_addr = %0d”,pkt.start_addr,pkt.end_addr);
$display(“\taddr = %0d”,pkt.addr);

end

en

In reply to KillSteal:

This code is failing for randomization issue only with Questa simulator in EDAPlayground and for all other simulators it’s passing.

Until end_addr>= start_addr ; constraint solver solves this constraint. When start_addr>=end_addr constraint will fail.

Just if we add below constraint , not seeing any constraint issue with Questasim also.
constraint add_2_range{end_addr >= start_addr ;}

But as Dave mentioned, it’s not generating cyclic values with randc variables. THis may be some tool specific.

In reply to happysri30:

I would not call that passing. It is failing to fail.

In reply to dave_59:

Eventhough simulator generate random_cyclic values, without add_2_range constraint, Constraint solver will fail if start_addr is greater than end_addr.

Would like to see any other appraoch to solve this issue.

In reply to happysri30:

You have to ask yourself what is the goal of making each variable cyclic? Normally without any randc modifiers, the goal of a constraint solver is to provide all possible solution sets with equal probability. This particular example has a solution set with 3 random variables with each variable have 4 possible values. But there are only 20 possible solutions. There are 10 solutions with start_addr==0 and only 1 solution with start_addr==3. end_addr has the reverse distribution. So there is no way to have both start_addr and end_addr have pure cyclic values.

What might make more sense is cycling though all all possible 20 solutions. You can do this by packing all the randc variables into one randc variable using packed array or struct.

typedef struct packed { bit [1:0] addr;
                        bit [1:0] start_addr;
                        bit [1:0] end_addr;
                      } st; 
randc st v;
constraint addr_1_range { v.addr inside {[v.start_addr:v.end_addr]}; }

In reply to dave_59:

Hi Dave, how to know there are 20 possible solution?
you mentioned that the solver has to order randc variable and that could cause randomize() to fail. what is the meaning of ordering randc variable? are there any examples about ordering randc variable

Thanks a lot!

In reply to peter:

For a simple example like that where there are only 6 random bits, you can exhaustively loop through all 64 possible values for v and count the number of values that satisfy the constraint

module top;
  struct packed { 
    bit [1:0] addr;
    bit [1:0] start_addr;
    bit [1:0] end_addr;
  } v;
  int count;
  initial do if (v.addr inside {[v.start_addr:v.end_addr]})
    $display("%p %0d",v,++count);
  while (++v != 0);
endmodule
# run -all
# '{addr:0, start_addr:0, end_addr:0} 1
# '{addr:0, start_addr:0, end_addr:1} 2
# '{addr:0, start_addr:0, end_addr:2} 3
# '{addr:0, start_addr:0, end_addr:3} 4
# '{addr:1, start_addr:0, end_addr:1} 5
# '{addr:1, start_addr:0, end_addr:2} 6
# '{addr:1, start_addr:0, end_addr:3} 7
# '{addr:1, start_addr:1, end_addr:1} 8
# '{addr:1, start_addr:1, end_addr:2} 9
# '{addr:1, start_addr:1, end_addr:3} 10
# '{addr:2, start_addr:0, end_addr:2} 11
# '{addr:2, start_addr:0, end_addr:3} 12
# '{addr:2, start_addr:1, end_addr:2} 13
# '{addr:2, start_addr:1, end_addr:3} 14
# '{addr:2, start_addr:2, end_addr:2} 15
# '{addr:2, start_addr:2, end_addr:3} 16
# '{addr:3, start_addr:0, end_addr:3} 17
# '{addr:3, start_addr:1, end_addr:3} 18
# '{addr:3, start_addr:2, end_addr:3} 19
# '{addr:3, start_addr:3, end_addr:3} 20

Ordering of random variables means choosing the value of a random variable before choosing the value of another random variable. Normally in the absence of randc or dist constraints, the cover chooses 1 of the 20 solutions with equal probability and the values of the random variables are chosen as a set; there is no order in picking values for each variable.

If you put the randc qualifier on the variable as a whole, the solver makes sure that every solution out of the 20 gets picked before repeating the same solution.But if you put the randc qualifier on the three individual variables, the solver has to choose value for a variable before picking the value of another variable.

Let’s say the cover picks values in this order addr:1, start_addr:0, end_addr:3 (which is solution #7) in the first call to randomize. But in the next call, it picks # '{addr:3, start_addr:1, but then the only value for end_addr is 3, which it already used in the first call.