SystemVerilog中的solve - before的用法详解

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之前有一些限制,下面列出了这些限制:

  1. 不允许使用randc变量,因为它们总是先被解决;
  2. 变量应该是整数值;
  3. 在这样的排序中不应该存在循环依赖,solve a before b combined with solve b before a。
### SystemVerilog 中 `solve before` 的用法 #### 基本概念 `solve before` 是一种用于指定变量求解顺序的关键字。尽管它不会直接影响随机化结果的约束范围,但它会改变随机值的选择方式以及它们之间的依赖关系[^2]。 当多个变量之间存在相互依赖的关系时,通过定义 `solve before` 关系可以控制这些变量在随机化过程中的计算次序。这有助于实现更加精确的行为建模和测试场景生成[^1]。 --- #### 随机分布的影响 通常情况下,在没有显式的 `solve before` 定义时,SystemVerilog 默认按照声明顺序来解决变量间的依赖关系。然而,这种默认行为可能无法满足复杂的测试需求。因此,引入 `solve before` 可以让开发者明确指定哪些变量应该优先于其他变量被求解[^3]。 需要注意的是,虽然 `solve before` 不会影响最终随机化的合法解集,但它确实能够调整某些特定组合出现的可能性概率。 --- #### 示例代码说明 以下是两个对比示例,分别展示了未使用与已使用 `solve before` 的情况: ##### Without Solve-Before (无 solve-before) ```systemverilog class NoSolveBefore; rand bit [7:0] a, b; constraint c { a + b == 10; // 简单加法规则 } endclass : NoSolveBefore ``` 在这个例子中,`a` 和 `b` 被视为同等重要,系统会在两者间自由分配权重并尝试找到符合条件的一组解。由于缺乏明确指示哪个变量应先决定,实际运行过程中可能会表现出不可预测的结果倾向。 ##### With Solve-Before (有 solve-before) ```systemverilog class WithSolveBefore; rand bit [7:0] a, b; constraint c { a + b == 10; // 同样保持简单加法规则 solve a before b; // 明确指出 'a' 应该早于 'b' } endclass : WithSolveBefore ``` 在此版本里,我们强制规定了 `a` 必须先行确定下来之后再考虑如何设置 `b` 来达成目标总和等于十的要求。这样做的好处在于可以让后续逻辑更容易理解和调试,同时也提供了更多灵活性去定制所需模式下的数据样本特性。 --- #### 特殊注意事项 - **不影响合法性**: 即使应用了 `solve before`, 所产生的所有解决方案仍然必须符合所有的既定约束条件。 - **仅调节流程而非内容**: 这意味着即使改变了处理先后级次也不会新增或者减少任何原本就不可能达到的状态点. ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值