SystemVerilog约束求解器默认情况下尝试给出随机值的均匀分布。因此,作为给定约束的解的任何合法值的概率是相同的。但是使用solve - before可以改变概率的分布,使得某些特定的情况比其他情况更容易被选择。我们将通过比较一个有和没有使用这个结构的例子来看到solve - before的效果。
随机分布示例
例如,考虑下面的示例,其中3位随机变量b可以具有8个合法值(2^3个组合)。 b获得值0的概率与所有获得其他可能值的概率相同。
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
Simulation Log
ncsim> run
b=7
b=7
b=2
b=1
b=6
b=4
b=2
b=4
b=0
b=1
ncsim: *W,RNQUIE: Simulation is complete.
请注意,即使在如下所示的模拟输出中有重复的值,这也仅仅意味着先前的随机化对当前迭代没有影响。因此,随机化器可以自由选择这8个值中的任何一个,而不管之前的值是什么。
Without solve - before
在没有求解之前,考虑下面的示例,其中声明了两个随机变量。这个约束确保了当a = 1时,b = 0x3。
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
Simulation Log
ncsim> run
a=0 b=0
a=0 b=1
a=0 b=0
a=0 b=1
a=0 b=2
a=1 b=3
a=0 b=3
a=0 b=3
ncsim: *W,RNQUIE: Simulation is complete.
当a为0时,b可以采用4个值中的任何一个。 因此,这里有4种组合。 接下来,当a为1时,b只能取1个值,因此只能有1个组合。
因此,有5种可能的组合,并且如果约束求解器必须为每个分配均等的概率,则选择任何组合的概率为1/5。
下表列出了a和b每种组合的概率:
With 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
Simulation Log
ncsim> run
a=1 b=3
a=1 b=3
a=0 b=1
a=0 b=0
a=0 b=0
a=0 b=1
a=1 b=3
a=0 b=2
ncsim: *W,RNQUIE: Simulation is complete.
将此输出与上一个输出进行比较,以了解区别。在这里,首先解决a,然后根据得到的b解决。
因为a首先被求解,所以选择0或1的概率为50%。接下来,为b选择一个值的概率取决于为a选择的值。
Restrictions
在使用Solve之前有一些限制,下面列出了这些限制:
【1】不允许使用randc变量,因为它们总是先被解决;
【2】变量应该是整数值;
【3】在这样的排序中不应该存在循环依赖,solve a before b combined with solve b before a。
参考文献 :
【1】https://www.chipverify.com/systemverilog/systemverilog-solve-before