Reputation: 25
I am trying to use a function inside constraint block. Randomization happens but the constraints are not being met. I have verified that the function works as expected outside the constraint block. The function uses only function arguments and not any other class members.
local rand logic [6:0] [3:0] [9:0] coeff_mult;
constraint prods_are_multiples {
foreach(coeff_mult[i]) {
get_real(coeff_mult[i][3]) == (-1 * get_real(coeff_mult[i][0]));
get_real(coeff_mult[i][2]) == (-1 * get_real(coeff_mult[i][1]));
get_real(coeff_mult[i][0]) == (3 * get_real(coeff_mult[i][1]));
}
}
function automatic shortreal get_real(input [9:0] val);
shortreal sign;
bit [9:0] magnitude;
sign = -1**(val[9]);
magnitude = ({10{val[9]}} ^ val[9:0]) + val[9];
get_real = sign * (magnitude[9:3] + magnitude[2] * 0.5 + magnitude[1] * 0.25 + magnitude[0] * 0.125);
endfunction
I came across a similar post, but it didnt solve my problem.
Is there anything wrong with the code? If not, is there any other way of doing this?
Upvotes: 0
Views: 703
Reputation: 42698
The post you reference explains the reasoning. The inputs to your function get their random values chosen before calling the function in the constraint. So there are effectively no constraints on coeff_mult
before evaluating the equality constraints.
Also, the LRM does not allow expressions of non-integral values in constraints, technically, although some tools allow limited cases.
The best strategy for randomizing real numbers is doing everything with scaled integral values, then converting the resulting values to real (or sign/magnitude) in post_randomize()
.
Upvotes: 4
Reputation: 1992
I have a working example of your kind of function usage with use of additional random variable. I have checked this with ~10 different seeds and I have also posted constraint results with 1 particular seed.
typedef bit [7:0] tabc;
class t;
rand bit [3:0] a, b;
rand tabc ca;
// Original Constraint : get_b(b) == get_a(a) + 1;
constraint c {
ca == get_b(b);
get_a(a) == ca - 1;
}
function tabc get_a (input bit[3:0] a);
return (tabc'(a + 15));
endfunction
function tabc get_b (input bit[3:0] b);
return (tabc'(b + 10));
endfunction
endclass
program temp();
t t1 = new();
initial
begin
repeat (10) begin
t1.randomize();
$display("t1.a - %0d", t1.a);
$display("t1.b - %0d", t1.b);
end
end
endprogram
// Results -
t1.a - 7
t1.b - 13
t1.a - 2
t1.b - 8
t1.a - 5
t1.b - 11
t1.a - 4
t1.b - 10
t1.a - 0
t1.b - 6
t1.a - 8
t1.b - 14
t1.a - 9
t1.b - 15
t1.a - 6
t1.b - 12
t1.a - 0
t1.b - 6
t1.a - 5
t1.b - 11
I am not quite sure of how this one is different than your method. However I am thinking that without having any random variable in constraints, the solver might have considered as no constraint for any variable and hence it didn't try to solve constraint before the solution.
I tried to insert temporary variable, in order to force solver to look at constraints first.
I am not sure how much correct my explanation is, but atleast it worked for me for some time. You can check it and try to run it with more seeds, before adapting it into your solution.
Upvotes: 1