How to use soft constraint?

Hi,
in my testbench, code as follows, sometimes data_len is constrainted, max value more than 512 ,which isn’t expected!!,but simulator not report randomize failed!!, how to use soft in order to generate the designed packet payload length

class    x_item extends  uvm_sequence_item;
       ....
       rand  bit[15:0]  data_len;
       rand  bit[31:0]  x_data[];
       ....
endclass
 
calss  my_seq extends  uvm_sequence #(x_item);

    rand  my_pkt_enum  my_pkt;

    rand  bit[15:0]  data_len;
    constraint C_data_len
    {
       (my_pkt==ether_pkt ) ->  soft  data_len >=0; soft data_len<= 512;
        
    }
    rand  bit[31:0]  x_data[];
    constraint  C_xdata
    {
       x_data.size==data_len;
       solve data_len before x_data;
    ]
 
    virtual  task body();
         .....
        start_item(req)
        if(!req.randomize with {
                  ...
               req.data_len==local::data_len;
         
        })
            `uvm_fatal("","" )
        req.x_data=new[data_len];
        foreach(x_data[i])
          req.x_data[i]=x_data[i];

        ....
endtask

In my test ,sequence is randomized,when data_len is constrainted as specific value , Random results is right ,but use default constraint ,Uncertainly Random results occurs(may be more than 512),who can help me ? The simualtor is questasim10.2c.

  class my_test0 extends uvm_test;

      .....
     virtual task  main_phase(uvm_phase phase );

      my_seq  my_seq_u=my_seq::type_id::create("my_seq_u");
      // raise phase
                    .....
          if(! my_seq_u.randomize () with
             {
                
                 my_pkt   == ether_pkt;
                 data_len == 1230;  // randomize result is right
             ....
             })
             `uvm_fatal("","")

........................................
 endclass

  class my_test1 extends uvm_test;

      .....
     virtual task  main_phase(uvm_phase phase );

      my_seq  my_seq_u=my_seq::type_id::create("my_seq_u");
      // raise phase
                    .....
          if(! my_seq_u.randomize () with
             {
                 my_pkt  == ether_pkt;
                 //data_len == 1230; default randomize result is uncertained.
             ....
             })
             `uvm_fatal("","")

............................
 endclass

thank u
./wszhong

It would help if you could cut and paste your code rather than re-enter it because you have many typos that make it difficult to understand where your problem is. When you wrote

constraint C_data_len {
       (my_pkt==ether_pkt ) ->  soft  data_len >=0; soft data_len<= 512;
   }

I think you really had

constraint C_data_len {
       (my_pkt==ether_pkt ) ->  { soft  data_len >=0; soft data_len<= 512; }
   }

Without the extra set of {}'s you are only constraining data_len >=0, which is redundant because data_len in an unsigned integral value. And data_len will be unconditionally less than 512 because it would not be part of the implication.

With the extra set of {}'s, there is no constraint on data_len when my_pkt != ether_pkt. The probability of my_pkt == ether_pkt is extremely low. See 18.5.10 Variable ordering in the 1800-2012 LRM. What you might want to do is change your C_xdata constraint to


constraint  C_xdata
    {
       x_data.size==data_len;
       solve my_pkt before data_len;
    }

In reply to wszhong631:

Yes, you can do

solve A,B,C, my_pkt before data_len

or create a temp rand variable


rand bit data_len_constraint;

  constraint C_data_len {
      ( A & ( B || C) & (my_pkt==ether_pkt )) == data_len_constraint; data_len_constraint ->  {soft  data_len >=0; soft data_len<= 512;
      solve data_len_constraint before data_len;
    }

In reply to dave_59:

Hi,dave
thank you for quick reply. the question confused me for two weeks. I have another question

calss  my_seq extends  uvm_sequence #(x_item);
 
    rand  my_pkt_enum  my_pkt;
    rand   bit         A;
    rand   bit         B;
    rand   bit         C;
    rand  bit[15:0]  data_len;   
    constraint C_data_len {
      ( A & ( B || C) & (my_pkt==ether_pkt )) ->  {soft  data_len >=0; soft data_len<= 512;}
    }      

    then, whether xdata should constraint to 

    constraint  C_xdata
    {
       x_data.size==data_len;
       solve my_pkt before data_len;
       solve A before data_len;
       solve B before data_len;
       solve C before data_len;
    }

[/i]

or not ?


the sceniro exists my testbench,I will debug it.