Constraint for selecting multiple byte lanes

Hello.

I’m describing constraints for selecting multiple byte lanes.
For expandability and maintenance, I want to modify my code. My code is not clear.

The code below is simplified. Please correct it if it has errors.


class my_class;
  rand logic [2:0] size;
  rand logic [31:0] array[];
endclass

...

my_class my_obj;
my_obj = new;

my_obj.randomize() with {
  array.size() = size;
  foreach(array[i]) {
    if (size == 1) {
      array[i] == 'h0 || array[i] == 'hf;
    } else if (size == 2) {
      array[i] == 'h0  || array[i] == 'hf  ||
      array[i] == 'hf0 || array[i] == 'hff;
    } else if (size == 3) {
      array[i] == 'h0     || array[i] == 'hf     ||
      array[i] == 'hf0    || array[i] == 'hff    ||
      array[i] == 'hf00   || array[i] == 'hf0f   ||
      array[i] == 'hff0   || array[i] == 'hfff   ||
      array[i] == 'hf000  || array[i] == 'hf00f  ||
      array[i] == 'hf0f0  || array[i] == 'hf0ff  ||
      array[i] == 'hff00  || array[i] == 'hff0f  ||
      array[i] == 'hfff0  || array[i] == 'hffff;
    } else if (size == 4) {
      array[i] == 'h0     || array[i] == 'hf     ||
      array[i] == 'hf0    || array[i] == 'hff    ||
      array[i] == 'hf00   || array[i] == 'hf0f   ||
      array[i] == 'hff0   || array[i] == 'hfff   ||
      array[i] == 'hf000  || array[i] == 'hf00f  ||
      array[i] == 'hf0f0  || array[i] == 'hf0ff  ||
      array[i] == 'hff00  || array[i] == 'hff0f  ||
      array[i] == 'hfff0  || array[i] == 'hffff  ||
      ...
    } ...
  }
}

Please, comment

In reply to jh_veryveri:

This can be done using a helper array (an array used to make constraints easier to write). In this case, the helper lets you iterate over each byte lane.

module top;
  class my_class;
    rand logic [2:0] size;
    rand logic [31:0] array[];
    rand bit helper[8];
    constraint c {
      array.size() == size;
      foreach(helper[lane]) {
        helper[lane] == lane < size;
        foreach(array[i])
          if (helper[lane])
            array[i][lane*4+:4] inside {'0,'1};
          else
            array[i][lane*4+:4] == '0;
      }
    }
  endclass
        
  my_class c = new;
      initial repeat(5) begin
        assert(c.randomize() );
    $displayh("%p %p",c.array,c.helper);
  end
endmodule

In reply to dave_59:

Thanks for your comment and code.

Please refer my code…

In my case, I describe constraints to `uvm_rand_send_with.
I try to refer your code. The ‘size’ and ‘array’ are declare in the ‘tr’ class. But ‘helper’ isn’t declare in the class.
I want to use ‘helper’ as local rand variable in the ‘seq’ class even though I can declare a variable like ‘helper’ in the ‘tr’ class.
Can I use a ‘helper’ variable in the ‘seq’ class?

My code is below.


class seq;

  tr tr_obj;

  task body ();
    `uvm_create(tr_obj);
    
    ...
    
    `uvm_rand_send_width(tr_obj, {
      // constraint for selecting byte lane
    }
  endtask

endclass

class tr;
  rand logic [2:0] size;
  rand logic [31:0] array[];
endclass

I trying like below. This code doesn’t work. I trying to fix it.


class seq;

  tr tr_obj;

  rand helper[];

  task body ();
    `uvm_create(tr_obj);
    
    ...
    
    `uvm_rand_send_width(tr_obj, {
      local::helper.size() inside {1,2,3,4,5,6,7,8};

      tr_obj.array.size() == tr_obj.size;
      foreach ( local::helper[select_lane] ) {
        foreach ( tr_obj.array[i] ) {
          tr_obj[i][(select_lane)*4+;4] inside {'0, '1};
        }
      }
    }
  endtask

endclass

class tr;
  rand logic [2:0] size;
  rand logic [31:0] array[];
endclass

In reply to jh_veryveri:

A couple of problems with your code.

helper has to be a fixed sized array of 8 1-bit elements. Based on your original example, this assumes each array element is a fixed 32-bits wide, and each byte lane is 4-bits wide.

Even though you declared helper as rand in your seq class, it is not part of the tr object that is being randomized. Unfortunately the call to tr_obj.rnadomize() is buried inside the `uvm_rand_send_with macro. So the helper array gets treated as a non-random state variable.

If you can’t modify the tr class directly, you should extend it adding the helper array. Then use the UVM factory to override the tr class.