Randomize int with implication constraint

Hi SV forum.
the following code is inside a class.
if I randomize the class, width get a value between 1 to 20 as expected;


  rand int width;
  constraint width_c {width inside {[1:20]};}

but if I use the following code width gets unexpected values.


  typedef enum bit [3:0] {OPTION_A, OPTION_B} opt_sets;
  rand opt_sets opt;
  rand int width;
  constraint width_c 
    {
      (opt==OPTION_A) -> width inside {[1:10]};
      (opt==OPTION_B) -> width inside {[11:20]};
    }

If I change int to bit vector every thing works fine


  typedef enum bit [3:0] {OPTION_A, OPTION_B} opt_sets;
  rand opt_sets opt;
  rand bit [5:0] width;
  constraint width_c 
    {
      (opt==OPTION_A) -> width inside {[1:10]};
      (opt==OPTION_B) -> width inside {[11:20]};
    }

Why is that?
Why int randomization works as expected in code listing 1 and not in 2?

In reply to shimonc:

The original code, with

rand int width;

works fine for me. Looks like your simulator has an issue.

In reply to shimonc:

It would really help to show a complete executable example and explain what you mean by unexpected results. Does that mean you’re getting values you don’t think meet the constraints or you’re not getting values you think you should be getting?

Hi what I am seeing it really strange.
Following is the class I am randomizing.
If I am randomizing this class without opt_c I get the following results.


Values of class members are: width = -298377340 opt = OPTION_D
Values of class members are: width = -218128014 opt = OPTION_D
Values of class members are: width = -1743494760 opt = OPTION_D
Values of class members are: width = 176629997 opt = OPTION_D


I can except that if OPTION_D is chosen, width can be negative number or not following the width_c constraint.
But why OPTION_D is always chosen?
If I include opt_c constraint OPTION_D is never chosen.
and the results are as expected


Values of class members are: width = 30 opt = OPTION_C
Values of class members are: width = 26 opt = OPTION_C
Values of class members are: width = 4 opt = OPTION_A
Values of class members are: width = 16 opt = OPTION_B
Values of class members are: width = 10 opt = OPTION_A
Values of class members are: width = 23 opt = OPTION_C
Values of class members are: width = 25 opt = OPTION_C


I run 200 randomizations


class sets extends uvm_object;
    typedef enum bit [1:0] {OPTION_A, OPTION_B, OPTION_C, OPTION_D} opt_sets ;
    rand opt_sets opt;
    rand int width;
    //constraint opt_c {opt inside {OPTION_A, OPTION_B, OPTION_C};}
    constraint width_c 
    {
      (opt == OPTION_A) -> width inside {[1:10]};
      (opt == OPTION_B) -> width inside {[11:20]};
      (opt == OPTION_C) -> width inside {[21:30]};
    }
    `uvm_object_utils_begin(sets)
    `uvm_field_int(width, UVM_ALL_ON)
    `uvm_field_enum(opt_sets, opt, UVM_ALL_ON)
    `uvm_object_utils_end
    function new (string name = "sets");
      super.new(name);
    endfunction
    function string convert2string();
      string s ="";
      $sformat(s, "%s Values of class members are:", s);
      $sformat(s, "%s width = %0d", s, width);
      $sformat(s, "%s opt = %s", s, opt.name());
      return s;
    endfunction
  endclass

I knowת, I know, I know


constraint order {solve opt before width;}
****************************************************************
 Values of class members are: width = 23 opt = OPTION_C
 Values of class members are: width = 14 opt = OPTION_B
 Values of class members are: width = -1804317302 opt = OPTION_D
 Values of class members are: width = 7 opt = OPTION_A
 Values of class members are: width = 1381317998 opt = OPTION_D
******************************************************************

In reply to shimonc:

With


constraint width_c 
    {
      (opt == OPTION_A) -> width inside {[1:10]};
      (opt == OPTION_B) -> width inside {[11:20]};
      (opt == OPTION_C) -> width inside {[21:30]};
    }

if opt == OPTION_D then there is no constraint on width and it can take any value from -2,147,483,648 to +2,147,483,647.