当前位置:网站首页>【数字IC验证快速入门】17、SystemVerilog学习之基本语法4(随机化Randomization)

【数字IC验证快速入门】17、SystemVerilog学习之基本语法4(随机化Randomization)

2022-07-07 04:43:00 luoganttcc

导读:作者有幸在中国电子信息领域的排头兵院校“电子科技大学”攻读研究生期间,接触到前沿的数字IC验证知识,旁听到诸如华为海思清华紫光联发科技等业界顶尖集成电路相关企业面授课程,对数字IC验证有了一些知识积累和学习心得。为帮助想入门前端IC验证的朋友,思忱一二后,特开此专栏,以期花最短的时间,走最少的弯路,学最多的IC验证技术知识。

一、内容概述

  • 为什么使用随机化验证策略
    • 1、验证空间很大(时间换空间,牺牲的是时间;不同的时间覆盖的不同的空间)
    • 2、边界条件人为想不到,随机化激励丰富,保证验证完备性
  • SystemVerilog 中的随机化
    • 范围、权重
  • 在类(class)中声明随机变量
  • 为随机变量设置约束(Constraints
  • 随机变量的权重分布(weighted distribution
  • 关闭或打开随机与约束(rand_mode() 和 constraint_mode()

二、随机化验证策略

2.1、为什么使用随机化验证策略(重要)

  • 设计复杂度提高之后,直接测试(定向测试)(directed testcase),没有办法通过穷举法验证所有的矢量
  • 定向测试案例用于检查确定的设计属性,仅仅用于检查可以预期的错误
  • 定向测试方式跟测试时间是线性关系
  • 定向测试案例不能检查隐形的错误

方案:带约束的随机化测试案例,对输入的激励随机化

随机化验证策略可以检测设计中的不可预期的错误和隐形的错误

2.2、随机内容有哪些(抽象,了解)

注:随机内容需要根据实际DUT要求来确定!

  • RTL设计的配置信息

    • 不同的设计配置(随机化)
    • 例如验证一个路由器,可以对输入和输出端口配置不同的数量
  • 验证环境的配置

    • 随机配置整个环境
      • 输入数据数量
      • 输入数据类型
  • 主要的输入数据

    • 对输入数据进行随机化
    • 在输入数据的有效范围内进行随机化
  • 封装的输入数据

    • 如果数据进行了一层层封装,不同层的封装可以随机化,比如TCP/IP(网络报文)
  • 协议例外,容错处理和协议违例(DFX)

    • 验证系统如何处理错误
    • 期望的错误类型,并将错误引入到系统中,确保系统设计可以正确处理这些错误
    • 随机的插入这些错误
  • 时间延迟(时钟周期)

    • 根据协议要求随机插入时间延迟(latency)
    • 检查设计对时钟周期的敏感性
    • 不需要对建立和保持时间进行验证

2.3、SystemVerilog 的随机化

  • 随机化允许用户自动生成随机的输入激励,用于验证功能
  • SystemVerilog允许用户使用特定的约束,将随机输入的数据页数在有效的范围
  • 必须在OOP中指定随机约束(放到一个Class中,语法规定)

2.3.1、rand 随机变量

  • 随机变量的值在指定范围内均匀分布
  • 如果不添加约束,随机变量的值可以是指定有效范围内的任何值

在这里插入图片描述

2.3.2、randc 随机变量

  • 周期性随机变量使用关键字randc进行声明
    • 其取值按照声明的有效范围周期性出现
    • 数据类型只可以是bit或者enum
    • randc 随机变量重复出现范围内的所有值,在依次循环过程中,不会重复出现相同的数值(一个循环介绍后,新的循环自动开始)

在这里插入图片描述

在这里插入图片描述

2.3.3、带随机变量的类

  • Bus类包含两个随机变量:addr 和 data
  • constraint名为 range1 指定了addr的数值范围
    • 确保约束没有冲突

在这里插入图片描述

2.3.4、randomize() 函数(启动随机变量)

  • 调用 randomize() 函数可以为对象中的所有随机变量赋值
    • 启动随机产生:类的句柄.randomize();,每调用一次产生一次随机结果
  • 随机变量的值要符合约束
  • randomize 函数成功时返回1,失败时返回0
  • 如果随机变量没有添加约束,那么它的随机值可以是有效范围内的任意值

在这里插入图片描述

  • 产生50个addr和data
  • b.randomize() 调用时刻对b这个句柄所指内存空间变量值进行随机化

2.3.5、约束解释器

  • 解析约束的关系

  • 相同的种子(seed)生成相同的随机数(伪随机)

    • 使用不同的种子,可以生成一组不同的随机数
  • 不同EDA工具厂商的约束解析器是定制的

2.3.6、constraint 约束语句块

  • 对随机变量的取值进行限制
    • 还可以对不同的变量之间的关系进行约束
    • 约束语句块是类的成员,类似于taskfunction和变量
    • 约束语句块声明
      • 约束语句的标识符:表示约束语句块的名字
      • 约束语句块:是一个表达式语句列表,对变量的取值范围或者变量之间的关系进行限制

在这里插入图片描述

  • 上述addr不是随机变量,所以会约束失败

Q:对于大空间验证,就算采取随机化验证,也一定有覆盖不到的地方,对于没覆盖的范围,怎么保证它的正确性

  • A:随机覆盖 + 定向用例。看功能覆盖率来判断随机的点达到没有,如果功能覆盖率没有达到,调整随机范围或者constraint,如果还不行,那就加定向用例!功能覆盖率是通过feature来分解的。(随机 + 功能覆盖率)
  • 功能覆盖率 CDV(coverage driven verification)

2.3.7、随机化的约束:简单的表达式

  • 约束变量必须具有固定的顺序(fixed order)
    • 只有一个关系操作符:<, <=, ==, >=, >
    • 多个变量使用多个表达式

在这里插入图片描述

2.3.8、随机化的约束:设置范围操作符

  • 如果没有其他的约束,inside操作符表示的数值范围内任何数值被选中的几率是一样的
  • inside操作符的取反操作符是!,表示取值范围不再inside操作符所指示的范围内

在这里插入图片描述

  • ! inside表示不在inside范围内的

2.3.9、随机化的约束:权重分布

  • 数值分布操作符:dist
    • 给部分数值增加权重(目的)
      • 属性1:测试案例需要相关的数值
      • 属性2:为了测试结果指定一定的数值分布
    • 两个操作符::=:/
      • :=操作符表示指定的数值具有相同的分布权重
      • :/操作符表示指定的数值均分权重,如果权重为w,数值有n个,则每一个数值的权重为w/n
    • 数值可以是一个数,也可以是一个数值范围:[lo:hi]
    • 权重不是百分数,相加之后不一定是100
    • randc 关键字声明的随机变量不能设置权重

在这里插入图片描述

在这里插入图片描述

2.3.10、随机化的约束:双向约束

  • 约束语句不是过程化语句(procedural)而是声明性语句(declarative
    • 所有约束语句同时生效

在这里插入图片描述

2.3.11、随机化的约束:条件约束

  • 约束语句提供了两种语法用于声明条件关系:
    • ->
    • if ... else ...

在这里插入图片描述

2.3.12、随机化的约束的结果可能性:无约束情况

  • 数值可能分布情况

在这里插入图片描述

  • 每一种组合等概分布

2.3.13、随机化的约束的结果可能性:有约束情况

条件操作符:->

  • -> 操作符会影响数值的分布情况
  • -> 操作符是双向操作符

  • y的数值取决于x,当 x = 0 时,y = 0;
  • 因此,当 x = 0 时,y 不可能取其他数值,即 x = 0 并且 y != 0 的几率为0

->是双向约束的理解:

  • 新增加的约束会影响分布

在这里插入图片描述

  • 当 x=0时,y=0,但是当y=0时,不满足y>0条件,所以x不为0,x只能为1!

条件操作符:solve … before …

  • solve ... before ...语法不会改变数值的有效范围,但是会改变数值出现的几率

在这里插入图片描述

  • solve y before x 不写这一句,除了不会出现的3种情况,其余5种情况出现的概率是1/5;
  • 写了solve y before x 这一句,会优先将y出现的组合分组,此处y有4种取值,所以可分为4组,每组两个。且每组的概率是1/4,如果一组两种情况都会出现,那么每种情况的概率是1/8,如果一组只有一种情况,那么该情况的概率是1/4!

迭代约束:foreach

  • 对于数组变量,可以使用循环变量进行约束

在这里插入图片描述

在这里插入图片描述

  • 记住核心:从左到右

2.3.14、随机化的约束:functions

约束语句中的函数

  • 一些属性不能使用简单的表达式进行约束
    • 例如使用循环计算一个数组中的数值的和
    • 如果不使用循环,那么就必须将循环展开
  • SystemVerilog 约束语句中的表达式可以调用函数
    • 函数中不能含有 output 或者 ref 参数
    • 函数必须是 automatic
    • 函数中的约束语句不能修改其他的约束语句
    • 必须在约束有效之前调用函数,并且函数的返回值必须看作是状态变量
    • 作为函数的参数的随机变量必须创建一个隐式的变量顺序或者优先级
      • 如下述代码中的y,必须创建一个约束!

在这里插入图片描述

2.3.15、随机化的约束:约束保护

  • 约束保护作为预测表示,其功能是保护约束的创建

    • 约束保护不是约束解释器必须满足的逻辑关系
    • 约束保护可以阻止约束解释器生成错误数据
  • 约束保护在约束解析之前实施,主要包括:

    • 常数
    • 状态变量
    • 对象句柄比较

在这里插入图片描述

2.3.16、激活或关闭随机变量(randomize 的大开关)

  • 使用 rand_mode() 函数可以关闭随机变量
    • 可以控制随机变量开始(active)还是关闭(inactive)
      • 随机变量处于非激活状态时,表示该变量不被声明为 rand 或 randc
      • rand_mode() 函数是SV内建的函数,不能被覆盖

在这里插入图片描述

2.3.17、激活或关闭约束(constraint 的大开关)

  • 激活或者关闭约束
    • 非激活状态的约束不能调用randomize()函数实现随机化
    • 所有的约束初始状态都是激活状态
    • constraint_mode()函数是SV内建的函数,不能被覆盖

在这里插入图片描述

  • 使用格式:句柄.约束名.constraint_mode()

2.3.18、测试题

在这里插入图片描述

  • 指针可能为null,需要加一个判断保护

原网站

版权声明
本文为[luoganttcc]所创,转载请带上原文链接,感谢
https://luogantt.blog.csdn.net/article/details/125644977