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.
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
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 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?