SystemVerilog 第6章 随机化


在这里插入图片描述


6.1 介绍

  • 定向测试可以找到你认为可能存在的bug,而CRT(受约束的随机测试方法)可以找到你都无法确定的bug

6.2 随机化用途

  • 器件配置、环境配置、原始输入数据、封装后的输入数据、协议异常、延时、事务状态、错误(error)和违规(violation)
  • 关于延时:时钟发生器应该位于测试平台之外的一个模块

6.3 SV的随机化

6.3.1 随机变量

  • 随机变量的声明和使用
class Packet;
	rand bit [31:0] src;
endclass

program test;
	Packet p=new();
	p.randomize();
endprogram
  • randc表示周期性随机,所有可能值都赋值过后随机值才会出现重复
  • 构造函数是用来初始化的变量的,不要在new()函数中对变量进行随机

6.3.2 检查randomize结果

  • 使用断言assert(p.randomize());检查随机化结果,成功返回1,失败返回0
  • 可以指定断言失败后的显示,格式如下:
//格式1:断言成功后跟语句,需要加分号
assert(p.randomize())
	command1;
else
	$fatal(0,"Packet::randomize failed");
	
//格式2:断言成功没有语句,不要加分号
assert(p.randomize())
else
	$fatal(0,"Packet::randomize failed");

6.3.3 约束求解

  • 约束表达式的求解式有SV的约束求解器完成的

6.3.4 可随机化的数据类型

  • 整型变量(integeral),有位组成的变量(bit类),packed struct,enum

6.4 约束

6.4.1 约束定义

  • 约束是一组关系表达式,约束用 “{}” 包住,每条关系表达式写成一条语句
  • 格式:用 {} 包住
class Packet;
	rand bit [31:0] src;

	constraint c_stim {
		src < 100;
		src > 10;
	}
endclass

6.4.2 布尔表达式

  • 一条关系表达式中只能使用一个关系操作符(<,<=<,==,>=,>)

6.4.3 等效表达式

  • 约束块中只能包含关系表达式,因此 == 关系表达式作用相当于赋值

6.4.4 权重分布

  • :=后面跟的权重值即为每个变量取值得的权重(相同)
  • : /后面跟的权重值要平均分到每一个变量取值
  • 变量取值可以是一个范围 [lo:hi],权重可以是变量
constraint c_dist {
	length dist {0:=40,[1:3]=60};
}

6.4.5 inside+集合(set)

  • inside后面跟的{}表示的是一个集合,里面元素用逗号 “,” 分割
  • $可以代表最大值和最小值
  • 集合的补集可以使用 ! 操作符
c inside {[$:4],[20:$]};
!(c inside {[$:4],[20:$]});

6.4.6 集合中使用数组

  • 可以将数组放入集合中,形成inside+集合的约束语句

6.4.7 条件约束

  • ->类似于case语句
  • if…else中的语句块要使用 {} 包住,不可以使用begin…end,因为约束是声明性语句,不是过程语句
//->
constraint c_io {
	io_space_mode -> addr == 1'b1;
}

//if...else
constraint c_len_rw {
	if(op==READ) {
		len inside {[lo:hi]};
	}
	else {
		len == LWRD;
	}
}

6.4.8 双向约束

  • 关系表达式中左边和右边的变量是相互牵制的,如果有一边的值已经确定下来,则另一边的选择会自动被约束

6.4.9 数学方法的选用

  • 约束求解器对简单的 加、减、位提取和移位处理快;对乘、除、取模(取余数)运算量大
  • 可以用位提取或 & "mask"操作代替取模;用移位代替除法和乘法

6.5 解的概率

  • 没有约束的类
    所有解的概率都相同
  • 关系操作的类
    所有满足约束的解的概率都相同
  • 关系操纵+randc
    ① 有randc时候,先对randc的变量进行随机,randc的变量每一个取值对应的系列解的”概率和”相等
    ② 当有多个randc变量时,randc的变量之间会相互制约,关系表达式作用方向式双向的,即 x==0 -> y==0约束中x, y都是randc的话,y==0时候x也必须为0
  • 关系操作+双向约束
    约束块里的条件表达式相互影响
  • solve…before…
    ① solve…before…控制变量随机的顺序,会改变解的概率,但不会改变解的值;其作用相当于randc
    ② solve…before…表达式中的变量不可以是randc类型的
constraint c_xy {
	x==0 -> y==0;
	solve x before y;
}

6.6 控制多个约束块

  • constraint_mode()
p.constraint_mode(0); //close all constraint
p.c_xy.constraint_mode(0); //only close c_xy constraint block
  • rand_mode()
p.rand_mode(0); //close all randmoize
p.x.rand_mode(0); //close x randmoize
  • randomize(variable)
    非随机变量被作用后也会被随机
p.randmoize(x); //only open x randmoize
  • randomize() with {}
    约束块的补充,和class中的约束块是平级的,解取两者交集
p.randomize() with {...}; //对class约束块的补充

6.7 有效性约束

6.8 内嵌约束

  • 即class内默认约束块,randomize() with {};语句是其补充

6.9 pre/post_randomize()

  • randomize()调用时候会默认调用pre/post_randomize()函数,不论randomize()时候调用成功,pre_randomize()都会执行;post_randomize()只有再randomize()函数成功执行后才会执行

6.9.1 浴缸型分布

  • 可以再pre_randomize()函数中调用$dist_exponential函数构造浴缸分布变量

6.9.2 void函数

  • pre/post_randomize()函数是void函数,因为是函数所以不含时序,不能有延时

6.10 随机函数

functiondistributiondatatype
$random()平均分布32 signed
$urandom()平均分布32 unsigned
$urandom_range()(指定区间)平均分布
$dist_exponential()指数衰落
$dist_normal()钟型分布
$dist_poisson()钟型分布
$dist_uniform()平均分布
  • $urandom_range(x,y)函数平均分布结果的范围为[x,y] (若x>y则为[y,x]);只有一个参数x时对应区间为[0:x]

6.11 约束的技巧和技术

6.11.1 带变量的约束

  • 布尔表达式中使用变量
  • dist约束中使用权重变量(设置权重为0即禁止)

6.11.2 使用非随机值

  • p.lenth.rand_mode(0) //关闭rand变量lenth的随机

6.11.3 用约束查看数据有效性

  • handle.randomize(null) //不随机变量,只查看数据是否满足约束条件

6.11.4 随机化个别变量

  • p.randomize(length) //只随机化length
  • 可以采用该方法对一个非随机变量进行随机

6.11.5 打开或关闭约束

  • 使用条件操作符从而执行不同约束(->或if…else…)
  • p.constraint_mode(0) //关闭所有constraint
  • p.c_length.constraint_mode(0) //关闭c_length
  • 关闭一个约束时候,也损失了该约束的有效性检测功能

6.11.6 测试过程中使用内嵌约束

  • class中定义的约束即为内嵌约束,可以使用randomize() with {…}来扩展内嵌约束

6.11.7 测试过程中使用外部约束

  • 可以像类的外部函数那样定义外部约束
  • 定义格式
class Packet;
	...
	constraint c_length;
endclass

constraint Packet::c_length {
	...
}
  • 注意:
    ①不用写 extern关键字
    ②外部约束和class一同放到program/module外的单独文件中
    ③用 `include “Packet.sv”+外部约束的形式放于top模块内部或外部皆可
    ④外部约束对所有的实例的对象都有效(因为涉及到class的作用域)

6.11.8 扩展类

  • 子类中定义和父类同名的constraint,约束会发生重载

6.12 随机化的常见错误

6.12.1 有符号变量

  • 符号:尽量避免使用有符号类型变量
  • 位宽: 约束值得位宽应比变量位宽多一位,避免数据溢出

6.12.2 提高求解器性能

  • 避免使用复杂运算:乘法,除法,取模(%)
  • 用移位代替乘除
  • 用 “&+掩模” 作用于变量代替取模

6.13 数组/队列约束

6.13.1 数组的大小

constraint c_len {
	len.size() inside {[1:10]};
	}

6.13.2 元素的和

  • len.sum()
  • 注意数据溢出:和的位宽是和数组元素相同的

6.13.3 数组约束

  • 变量的符号类型
  • 约束值得位宽应该比变量多一位
  • 使用foreach()循环对元素遍历

6.13.4 约束每一个元素

  • 即使用foreach()循环
  • 每个foreach约束中只能有一个数组名,不允许使用层次化引用(foreach中调用子类)

6.13.5 产生唯一元素值的数组

  • 使用包含randc变量得辅助类

6.13.6 随机化句柄数组

  • 随机前要分配好所有元素,然后再通过约束限定数组大小(约束求解器不能创建对象)
parameter max_size = 10;

class randstuff;
	rand int value;
endclass

class randarray;
	randstuff array[];

	constraint c_array {
		array.size() inside {[1:max_size]};
	}

	function new();
		array = new{max_size];
		foreach(array[i])
			array[i]=new();
	endfunction
endclass

6.14 产生原子激励和场景

wait update

6.15 随机控制

wait update

6.16 随机数发生器

wait update

6.17 随机器件配置

wait update

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值