Values injection into randomize variable

Is there a way to inject values to randomized variables from command line and still comply with the constraints?

Let’s say I have the following class:

class my_class;

    rand int a;
    rand int b;

    constraint a_b_c{
        a > b;
    }
 
endclass

now I want to get values from command line

$value$plusargs("VALUE_A=%0d", a);
$value$plusargs("VALUE_B=%0d", b);

if I use the code above in post_randomize function, I might inject values that won’t meet the constraints, and if I use it in pre_randomize function, the values will be overridden in randomization.

You can read the command line values in the parent class which will be randomizing the child class. You can then use ‘with’ clause when randomizing:

class my_class;

  rand int a;
  rand int b;

  constraint a_b_c{
    a > b;
  }
  
  function new();
  endfunction
  
  function void display();
    $display("a is: %0d  b is %0d", a, b);
  endfunction
 
endclass

class top;
  my_class m1;
  
  function new();
    m1 = new();
  endfunction
  
  function void run();
    int a,b;
    bit a_is_set, b_is_set;
    a_is_set = $value$plusargs("VALUE_A=%0d", a);
    b_is_set = $value$plusargs("VALUE_B=%0d", b);
    
    case ({a_is_set, b_is_set})
      2'b00: begin
        $display("Neither a or b is passed from command line");
        if (!m1.randomize()) begin
          $display("Randomization failed!");
        end
        else begin
          m1.display();
        end
      end
      2'b01: begin
        $display("b is passed from command line");
        if (!m1.randomize() with {b == local::b;}) begin
          $display("Randomization failed!");
        end
        else begin
          m1.display();
        end
      end
      2'b10: begin
        $display("a is passed from command line");
        if (!m1.randomize() with {a == local::a;}) begin
          $display("Randomization failed!");
        end
        else begin
          m1.display();
        end
      end
      2'b11: begin
        $display("a and b are passed from command line");
        if (!m1.randomize() with {a == local::a; b == local::b;}) begin
          $display("Randomization failed!");
        end
        else begin
          m1.display();
        end
      end
    endcase
    
  endfunction
  
endclass

module testbench;
  top t1;
  
  initial begin
    t1 = new();
    t1.run();
  end
endmodule

A simpler solution is turning off the rand_mode of variables that have been set from the command line.

if ($value$plusargs("VALUE_A=%0d", a)) a.rand_mode(0);
if ($value$plusargs("VALUE_B=%0d", b)) b.rand_mode(0);

Remember that turning off rand_mode does not turn off any constraints associated with that variable. If a>b is not true, you will get a randomization error.

Much better solution. Thanks Dave!

class my_class;

  rand int a;
  rand int b;

  constraint a_b_c{
    a > b;
  }
  
  function new();
  endfunction
  
  function void pre_randomize();
    if ($value$plusargs("VALUE_A=%0d", a)) a.rand_mode(0);
    if ($value$plusargs("VALUE_B=%0d", b)) b.rand_mode(0);
  endfunction
  
  function void display();
    $display("a is: %0d  b is %0d", a, b);
  endfunction
 
endclass

class top;
  my_class m1;
  
  function new();
    m1 = new();
  endfunction
  
  function void run();
    if (!m1.randomize()) begin
      $display("Randomization failed!");
    end
    else begin
      m1.display();
    end
  endfunction
  
endclass

module testbench;
  top t1;
  
  initial begin
    t1 = new();
    t1.run();
  end
endmodule

Thanks!

Is the constraint still applicable if I override both a and b variables in that example?

You should never override variables. Only constraints and methods. If you were to extend the class and declare variables a & b, the constraint in the base class would not apply to the variables in the extended class.

I’m sorry, my terminology was wrong.

I meant, if I set a & b values with plusargs, your solution turn the random mode for both of them. In that case, if I set illegal values, will the constraint fail or it will be ignored as both variables are set to non-random?

Constraint will fail. constraint_mode() is independent of rand_mode().

Thanks!