https://www.chipverify.com/systemverilog/systemverilog-solve-before
可以参考这个链接,英文版,讲解了很多SV的用法
可以类比概率论中的条件概率:条件概率是指事件A在另外一个事件B已经发生条件下的发生概率。条件概率表示为:P(A|B),读作“在B的条件下A的概率”。
solve-before的用法
solve A before B
简单点说,就是在解决B之前先解决A,可以改变概率的分布,使得某些特定的情况比其他情况更容易被选择。
随机分布实例
其中3位随机变量b可以具有8个合法值(2^3个组合)。 b被随机赋值所有可能值(0~7)的概率相同,都等于1/8。每次都是从0 ~ 7中随机选择,不管前一个数选择的是啥值,下一个数照样随机选择0 ~ 7中的任意一个值。
class ABC;
rand bit [2:0] b;
endclass
module tb;
initial begin
ABC abc = new;
for (int i = 0; i < 10; i++) begin
abc.randomize();
$display ("b=%0d", abc.b);
end
end
endmodule
运行结果:
不使用solve - before
a和b是一起确定的,不是一个接一个确定的
其中声明了两个随机变量。这个约束确保了当a = 1时,b = 0x3。当a为0时,b可以采用4个值中的任何一个。 因此,这里有4种组合。 接下来,当a为1时,b只能取1个值,因此只能有1个组合。因此,有5种可能的组合,并且如果约束求解器必须为每个分配均等的概率,则选择任何组合的概率为1/5。
class ABC;
rand bit a;
rand bit [1:0] b;
constraint c_ab { a -> b == 3'h3; }
endclass
module tb;
initial begin
ABC abc = new;
for (int i = 0; i < 8; i++) begin
abc.randomize();
$display ("a=%0d b=%0d", abc.a, abc.b);
end
end
endmodule
仿真结果:
统计表:
使用solve - before
SystemVerilog允许一种机制来对变量排序,以便a可以独立于b进行选择。这是通过使用solve关键字来完成的。
class ABC;
rand bit a;
rand bit [1:0] b;
constraint c_ab { a -> b == 3'h3;
//告诉求解者在尝试b之前必须先解出a,因此a的值决定了b的值
//
solve a before b;
}
endclass
module tb;
initial begin
ABC abc = new;
for (int i = 0; i < 8; i++) begin
abc.randomize();
$display ("a=%0d b=%0d", abc.a, abc.b);
end
end
endmodule
仿真结果:
统计表:
在这里,首先解决a,然后根据得到的b解决。因为a首先被求解,所以选择0或1的概率为50%。接下来,为b选择一个值的概率取决于为a选择的值。从表中可以看出,当a=0是,b无论选择啥值,Probability都非常的小,但是当a=1时,b=3的概率等于1/2。所以总体来说b=3的概率要大于1/2这么一丢丢。
限制
在使用Solve之前有一些限制,下面列出了这些限制:
- 不允许使用randc变量,因为它们总是先被解决;
- 变量应该是整数值;
- 在这样的排序中不应该存在循环依赖,solve a before b combined with solve b before a。