在约束块内使用函数
Using function inside constriant block
我正在尝试使用约束块内的函数。发生随机化,但未满足约束条件。我已经验证该函数在约束块之外按预期工作。该函数仅使用函数参数而不使用任何其他 class 成员。
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
我遇到了类似的问题post,但它没有解决我的问题。
代码有问题吗?如果不行,还有其他方法吗?
您引用的 post 解释了推理。在调用约束中的函数之前,函数的输入会选择随机值。因此,在评估等式约束之前,coeff_mult
实际上没有任何约束。
此外,从技术上讲,LRM 不允许在约束中表达非整数值,尽管某些工具允许在有限的情况下使用。
随机化实数的最佳策略是在 post_randomize()
.
中使用缩放整数值进行所有操作,然后将结果值转换为实数(或 sign/magnitude)
我有一个使用附加随机变量的函数使用示例。我已经用 ~10 个不同的种子进行了检查,我还发布了 1 个特定种子的约束结果。
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
我不太确定这个方法与您的方法有何不同。但是我在想,如果约束中没有任何随机变量,求解器可能会认为对任何变量都没有约束,因此它不会在求解之前尝试求解约束。
我试图插入临时变量,以强制求解器首先查看约束。
我不确定我的解释有多正确,但至少它对我有用了一段时间。您可以检查它并尝试 运行 它有更多的种子,然后再将其调整到您的解决方案中。
我正在尝试使用约束块内的函数。发生随机化,但未满足约束条件。我已经验证该函数在约束块之外按预期工作。该函数仅使用函数参数而不使用任何其他 class 成员。
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
我遇到了类似的问题post,但它没有解决我的问题。
代码有问题吗?如果不行,还有其他方法吗?
您引用的 post 解释了推理。在调用约束中的函数之前,函数的输入会选择随机值。因此,在评估等式约束之前,coeff_mult
实际上没有任何约束。
此外,从技术上讲,LRM 不允许在约束中表达非整数值,尽管某些工具允许在有限的情况下使用。
随机化实数的最佳策略是在 post_randomize()
.
我有一个使用附加随机变量的函数使用示例。我已经用 ~10 个不同的种子进行了检查,我还发布了 1 个特定种子的约束结果。
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
我不太确定这个方法与您的方法有何不同。但是我在想,如果约束中没有任何随机变量,求解器可能会认为对任何变量都没有约束,因此它不会在求解之前尝试求解约束。
我试图插入临时变量,以强制求解器首先查看约束。
我不确定我的解释有多正确,但至少它对我有用了一段时间。您可以检查它并尝试 运行 它有更多的种子,然后再将其调整到您的解决方案中。