0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

简述SystemVerilog的随机约束方法

jf_78858299 来源:芯片学堂 作者:JKZHAN 2023-01-21 17:03 次阅读

上一篇文章介绍了SystemVerilog的各种随机化方法,本文将在其基础上引入SystemVerilog的随机约束方法(constraints)。通过使用随机约束,我们可以将随机限制在一定的空间内,有针对性地提高功能覆盖率。

SV随机约束的应用,就像是我们用陈述性(declarative)的语句告诉仿真器我们要的随机数要满足哪些条件,然后仿真器的约束解算器(constraint solver)就会去找到能够满足我们所有描述语句的解,再从这些解中随机选出来一个值作为随机的结果。

约束解算器

约束解算器是SV仿真器重要的一部分,它被专门用来求解约束。这里说的求解,就是指的仿真程序通过某种算法,找到能够满足我们所有约束条件的随机值的过程。如果随机被过约束(over-constraint)了,或者存在随机值的组合情况不能满足约束,则约束解算器就会解算失败。在实际应用中,仿真程序就会报错,然后打印出来告诉我们是哪段约束没有解算成功。

理解约束解算器的重要性,可以想想如果没有约束解算器会怎么样?举一个简单的栗子,现在我们有一个约束条件:变量A的随机值总是小于变量B的随机值。如果没有约束功能,代码可以这么实现:

do begin
    A = $urandom;
    B = $urandom;
end while (! (A

使用约束语句代码是这样的:

class ictalking;
    rand bit [7:0] A, B;
    constraint c_ab { A < B; }
endclass

可以看得出来,如果没有约束解算器,我们在描述约束的时候就会变得比较绕,通常会花掉很多时间去重复执行相同的一段代码,有时候甚至会跑了半天都撞不出来一个满足约束的随机值,更别说那些复杂的约束了。有了约束解算器,我们就可以在其框架内加入各种约束语句,它总能帮我们快速找到那个解。

约束关系和控制

约束的解算顺序: 约束的解算顺序可以使用solve-before来控制。约束解算器会优先求解before之前的约束,因此使用solve-before会影响随机数组合的概率分布情况。

class ictalking;
    rand bit [7:0] A, B;
    constraint c_a { A > B; }
    constraint c_order {solve A before B;}
    // 顺序约束可以写在同一个约束块中,    // 也可以分开写在不同的约束块中(如本例)endclass

硬约束和软约束: 当我们在不同的层次对随机变量附加约束的时候,软约束可以被后面指定的约束给覆盖。典型的应用场景是在UVM的sequence_item(或者叫transaction)定义时,我们可以通过软约束指定默认的随机约束,这样方便我们后面在继承或者例化的时候可以使用更高优先级的约束对其覆盖。

class ictalking;
    rand int count;
    constraint c_count {
           soft count inside {[666:888]}; // 指定软约束需要使用关键字soft
    }
endclass

ictalking ict = new();
ict.randomize() with { count inside {[123:456]}; }

约束的控制开关: 默认情况下,所有的约束一写上就默认使能,即约束解算器就会按照这些约束开始算。但SV提供约束条件的控制方法constraint_mode(),可以很方便的控制约束是否启用,以及查询约束的启用状态。

// 继续上面的例子
int con_status;
ictalking ict_obj1 = new();
ictalking ict_obj2 = new();

ict_obj1.c_count.constraint_mode(0); // 不启用ict_obj1中的约束c_count
ict_obj2.c_count.constraint_mode(1); // 启用ict_obj2中的约束c_count
ict_obj1.count.rand_mode(0); // 顺便提一嘴,随机变量类似的可以使用rand_mode开关随机功能

con_status = ict_obj1.c_count.constraint_mode(); // 获得ict_obj1中约束c_count的启用状态

五花八门的约束代码

SV中的约束非常灵活,下面给出一些常用的约束代码,可以作为参考和总结。

  • 范围约束: 使用inside指定随机数的范围或者枚举值
rand int temp_var;
constraint c_var_1 {temp_var inside {[2000:2021]}; }           // 限定范围
constraint c_var_2 {temp_var inside {2008, 2016, 2019}; } // 限定枚举值
constraint c_var_3 {! (temp_var inside {[1:2007]});              // 反向限定范围
  • 条件约束: SV中有两种写条件约束的方式:implication(有些地方会翻译成蕴藏或者关联等等)和 if-else,用来指定在某些条件下才做进一步的约束,这两种方法使用上几乎没有区别。
rand bit mode;
rand int count;
constraint c_var_1 { mode == 1 -> count < 2021; } // 使用implication操作符->
constraint c_var_2 { if (mode == 1) {count < 2021;} else {count > 6000;} } // 使用if-else
  • 权重约束: 约束可以指定随机值的权重,主要有两种方式:dist和randcase。dist一般用在constraint约束块中,但randcase一般用在程序执行块中,比如某个函数、任务或者initial块等。
rand bit mode;
rand int count;
constraint c_var_1 {
    mode == READ  -> count inside {[2008:2016]};
    mode == WRITE -> count inside {[2017:2021]};
    mode dist {READ := 4, WRITE := 6}; // mode随机成READ的概率为40%,WRITE为60%
}

initial begin
    repeat (100) begin
        randcase            2: $display("In 1st branch."); //100次循环中,执行分支1的概率是20%            7: $display("In 2nd branch."); //100次循环中,执行分支2的概率是70%
            1: $display("In 3rd branch."); //100次循环中,执行分支3的概率的10%
         endcase
     end
end
  • 唯一约束: 唯一约束使用unique关键字来限定变量之间的值是唯一的,即两两之间互不相等。
rand int a, b, c;
rand int array[5];
int q[$] = `{200, 53, 656};

constraint c_unique {
    unique {a, b, c};     // 该约束要求a和b和c两两之间互不相等
    unique {a, b, array}; // 该约束要求a和b和array中的所有值互不相等
    unique {array};       // 该约束要求array数组内的5个值互不相等
    unique {a, q};        // 该约束要求a随机出来的值不等于q中的任一值
}
  • 循环约束: 在对队列或者数组进行随机化的时候,可以使用foreach来对其循环施加约束。
rand int q[$];
constraint c_foreach {
    q.size() inside {[3:8]};
    foreach (q[i]) {
        if (i > 0) q[i] > q[i-1]; // 约束q队列的下一个值总比上一个值大
    }
}
  • 缩位约束: 缩位约束会相对复杂一些,但是很好理解。1. 缩位运算:比如对于数组arr[5],arr.sum就是arr[0] + arr[1] + ... + arr[4]。除sum之外,还有product、and、or、xor,分别表示乘积、与、或、异或运算。2. 这些缩减运算的方法的返回值类型,跟队列或者数组的元素类型一样,因此当类型不匹配的时候,需要做类型转换的操作。3. 缩减运算的方法可以可选的加with条件,用来筛选队列或者数组中的元素。另外关键字item表示当前的数组元素,item.index表示当前数组元素的索引
rand bit qbit[$];
rand int qint[$];

constraint c_qbit {
    qbit.size() inside {[4:6]};
    (qbit.sum with (int'(item))) == 3; // 将当前元素item转为int类型,并约束所有元素有且只有3个为1
}

constraint c_qint {
    qint.size() inside {[5:9]};
    (qint.sum with ((item.index < 3) ? item : 0)) == 45; // 约束qint队列的前三个加起来等于45
}
  • 静态约束: 静态约束使用的关键字static跟静态变量是一样的。静态约束表示的是所有的对象实例都使用的同一个约束,所以使用constraint_mode()进行开关控制的时候具有全局性。
class ictalking;
    rand int count;
    static constraint c_count {count > 34;}
endclass

module testbench;
    initial begin        ictalking ict_obj1 = new();        ictalkingict_obj2=new();        ict_obj1.c_count.constraint_mode(0); // 关掉的之后ict_obj2中的c_count也会失效  ...
     end
endmodule

参考文献

[1] IEEE Standard Association. "IEEE Standard for SystemVerilog-Unified Hardware Design, Specification, and Verification Language." (2013).

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Verilog
    +关注

    关注

    28

    文章

    1327

    浏览量

    109312
  • 代码
    +关注

    关注

    30

    文章

    4556

    浏览量

    66812
  • 约束
    +关注

    关注

    0

    文章

    82

    浏览量

    12637
收藏 人收藏

    评论

    相关推荐

    SystemVerilog 的VMM验证方法学教程教材

    SystemVerilog 的VMM 验证方法学教程教材包含大量经典的VMM源代码,可以实际操作练习的例子,更是ic从业人员的绝佳学习资料。SystemVerilog 的VMM 验证方法
    发表于 01-11 11:21

    验证方法简介

    则和指南。验证方法提供了构建稳健、可靠和完整的验证环境的方法。验证方法通过其预定义的库减少了验证工作。 验证方法进一步提供了一个框架,用于简化覆盖驱动的
    发表于 02-13 17:03

    设计验证中的随机约束

    随机约束在现代集成电路验证中已得到国际IC 设计业界的普遍认可,并逐渐开始普及。与传统的定向测试比较,它在验证效率、验证覆盖率等方面具有诸多优势。最新公布的Sys
    发表于 12-14 09:54 13次下载

    基于SystemVerilog语言的验证方法学介绍

    文章主要介绍《VMM for SystemVerilog》一书描述的如何利用SystemVerilog语言,采用验证方法学以及验证库开发出先进验证环境。文章分为四部分,第一部分概述了用Syst
    发表于 05-09 15:22 52次下载
    基于<b class='flag-5'>SystemVerilog</b>语言的验证<b class='flag-5'>方法</b>学介绍

    如何利用SystemVerilog仿真生成随机

    采用SystemVerilog进行仿真则更容易生成随机数,而且对随机数具有更强的可控性。对于随机变量,在SystemVerilog中可通过r
    的头像 发表于 10-30 10:33 9457次阅读
    如何利用<b class='flag-5'>SystemVerilog</b>仿真生成<b class='flag-5'>随机</b>数

    SystemVerilog中的操作方法

    SystemVerilog提供了几个内置方法来支持数组搜索、排序等功能。
    的头像 发表于 10-31 10:10 1839次阅读

    怎样去使用SystemVerilog中的Static方法

    systemverilog方法也可以声明为“static”。静态方法意味着对类的所有对象实例共享。在内存中,静态方法的声明存储在一个同一个地方,所有对象实例都可以访问。
    的头像 发表于 11-18 09:31 593次阅读

    简述SystemVerilog的各种随机方法

    我习惯将验证空间理解为:验证中原则上需要覆盖的芯片所有有可能出现的工作状态的集合。为了探索这片广袤的验证空间,验证的时候搞出了带有约束随机测试(constrainted-random testing),并搞了覆盖率(coverage)作为评估机制。这也是一套成熟可信的工
    的头像 发表于 01-21 16:59 4945次阅读
    <b class='flag-5'>简述</b><b class='flag-5'>SystemVerilog</b>的各种<b class='flag-5'>随机</b>化<b class='flag-5'>方法</b>

    一些有趣的数组相关的SystemVerilog约束

    我们在工作中常常会针对数组施加各式的约束,下面列举一下有趣的Systemverilog数组约束示例。
    的头像 发表于 03-08 13:12 625次阅读

    SystemVerilog中“软约束”与“硬约束”的应用示例

    示例中采用的是“硬约束”,因为定义在类中的约束随机时指定的内嵌约束“矛盾”,所以导致约束解析器解析随机
    发表于 03-15 16:56 2808次阅读

    systemverilog随机约束implication的概率分析

    在此设计三种不同的随机先后顺序,分析x和y取值的其概率分布。
    的头像 发表于 05-04 18:24 722次阅读
    <b class='flag-5'>systemverilog</b><b class='flag-5'>随机</b><b class='flag-5'>约束</b>implication的概率分析

    一些有趣的数组相关的SystemVerilog约束

    我们在工作中常常会针对数组施加各式的约束,下面列举一下有趣的**Systemverilog数组约束**示例
    的头像 发表于 05-30 11:13 451次阅读

    创建约束随机测试目标

    数据项的顺序。 这种方法提供了更多的灵活性和控制。 约束数据项  默认情况下,sequencers会生成完全随机的数据项。测试用例编写者可以控制生成的数据项数量,并向数据项添加约束。为
    的头像 发表于 06-17 14:06 359次阅读
    创建<b class='flag-5'>约束</b><b class='flag-5'>随机</b>测试目标

    SystemVerilog随机约束方法

    上一篇文章《暗藏玄机的SV随机化》介绍了SystemVerilog的各种随机方法,本文将在其基础上引入SystemVerilog
    的头像 发表于 09-24 12:15 474次阅读

    SV约束随机化总结

    constraint 约束随机化类中的变量 在main_phase 之前就已经提前产生一个变量的随机值。 用法:一般在类中定义一个rand 类型的变量, 然后根据需求写约束
    的头像 发表于 12-14 14:30 245次阅读
    SV<b class='flag-5'>约束</b><b class='flag-5'>随机</b>化总结